1 /*
2 * Copyright 2021-2023 NXP
3 *
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "fsl_device_registers.h"
10 #include "fsl_ocotp.h"
11 #include "fsl_reset.h"
12 #include "fsl_clock.h"
13
14 /*******************************************************************************
15 * Definitions
16 ******************************************************************************/
17 /* Component ID definition, used by tools. */
18 #ifndef FSL_COMPONENT_ID
19 #define FSL_COMPONENT_ID "platform.drivers.ocotp"
20 #endif
21
22 /* All error masks in STATUS1 register except for SEC (Single error correction)
23 When new error masks are added this macro needs to be updated */
24 #define OTP_STATUS1_ERRORS_MASK \
25 (OCOTP_OTP_NONMASK_STATUS1_NONMASK_PBRICK_ERR_MASK | OCOTP_OTP_NONMASK_STATUS1_NONMASK_OTP_STATE_ERR_MASK | \
26 OCOTP_OTP_NONMASK_STATUS1_NONMASK_DED_RELOAD_MASK | OCOTP_OTP_NONMASK_STATUS1_NONMASK_DED_MASK | \
27 OCOTP_OTP_NONMASK_STATUS1_NONMASK_CRC_LUT_SEL_ERR_MASK | \
28 OCOTP_OTP_NONMASK_STATUS1_NONMASK_CRC_ADDRESS_RANGE_ERR_MASK | \
29 OCOTP_OTP_NONMASK_STATUS1_NONMASK_CRC_WRITE_PROTECT_ERR_MASK | \
30 OCOTP_OTP_NONMASK_STATUS1_NONMASK_CRC_SECURTY_PROTECT_ERR_MASK | \
31 OCOTP_OTP_NONMASK_STATUS1_NONMASK_WRITE_ERR_MASK | OCOTP_OTP_NONMASK_STATUS1_NONMASK_LOAD_ERR_MASK | \
32 OCOTP_OTP_NONMASK_STATUS1_NONMASK_COUNTER_ERR_MASK | OCOTP_OTP_NONMASK_STATUS1_NONMASK_BITPROTECT_ERR_MASK | \
33 OCOTP_OTP_NONMASK_STATUS1_NONMASK_PRNG_O_FAULT_MASK | OCOTP_OTP_NONMASK_STATUS1_NONMASK_ECC_ZEROIZED_ERR_MASK | \
34 OCOTP_OTP_NONMASK_STATUS1_NONMASK_FUSE_ACCESS_ERR_MASK | OCOTP_OTP_NONMASK_STATUS1_NONMASK_RELOAD_REQ_ERR_MASK | \
35 OCOTP_OTP_NONMASK_STATUS1_NONMASK_WRITE_DURING_RELOAD_ERR_MASK | \
36 OCOTP_OTP_NONMASK_STATUS1_NONMASK_SHADOW_HVF_READ_ERR_MASK | \
37 OCOTP_OTP_NONMASK_STATUS1_NONMASK_SHADOW_HVF_WRITE_ERR_MASK | \
38 OCOTP_OTP_NONMASK_STATUS1_NONMASK_SHADOW_SRAM_READ_ERR_MASK | \
39 OCOTP_OTP_NONMASK_STATUS1_NONMASK_SHADOW_SRAM_WRITE_ERR_MASK | \
40 OCOTP_OTP_NONMASK_STATUS1_NONMASK_FUSE_READ_ERR_MASK | OCOTP_OTP_NONMASK_STATUS1_NONMASK_FUSE_PROG_ERR_MASK | \
41 OCOTP_OTP_NONMASK_STATUS1_NONMASK_SHADOW_NO_ACCESS_MASK)
42
43 #define OTP_SEC_NLINES 64U /* Max. SoC OTP lines */
44 #define OTP_SVC_TAG 0x24EU /* SVC words tag */
45 #define OTP_PKG_TAG 0x15DU /* Package words tag */
46 #define SOC_OTP_READ_DELAY_COUNT (0x2AU * 1000U) /* Give 1ms to read the value */
47 #define SOC_OTP_CMD_READ 0x00U
48
49 /*******************************************************************************
50 * Prototypes
51 *******************************************************************************/
52 /* @brief Wait until OTP controller is idle */
53 static status_t otp_wait_busy(void);
54
55 /* @brief Clear all error status */
56 static void otp_clear_status(void);
57
58 /* @brief Read nonmask_status1 register and returns precise result*/
59 static status_t otp_get_nonmask_status_result(void);
60
61 /*******************************************************************************
62 * Code
63 ******************************************************************************/
otp_get_nonmask_status_result(void)64 static status_t otp_get_nonmask_status_result(void)
65 {
66 uint32_t status_register = OCOTP->OTP_NONMASK_STATUS1;
67 status_t status;
68 int32_t i;
69
70 do
71 {
72 if ((status_register & OTP_STATUS1_ERRORS_MASK) != 0U)
73 {
74 for (i = 0; i < 32; i++)
75 {
76 if (((1UL << (uint32_t)i) & status_register) != 0U)
77 {
78 status = MAKE_STATUS(kStatusGroup_OtpGroup, i);
79 break;
80 }
81 }
82 }
83 status = kStatus_Success;
84 } while (false);
85
86 return status;
87 }
88
otp_wait_busy(void)89 static status_t otp_wait_busy(void)
90 {
91 /*
92 * Assume core clock is 300MHz, the general fuse operation should not exceed 100ms
93 * Maximum allowed ticks is 300MHz / 10
94 * The below loop needs at least 4 CPU cycles, so the timeout rounds for below loop is 300MHz / 10 / 4
95 */
96 uint32_t timeout = 300U * 1000U * 1000U / 10U / 4U;
97 status_t status;
98
99 while (((OCOTP->OTP_STATUS & OCOTP_OTP_STATUS_BUSY_MASK) != 0U) && (timeout > 0U))
100 {
101 timeout--;
102 }
103
104 if (timeout < 1U)
105 {
106 status = kStatus_OTP_Timeout;
107 }
108 else
109 {
110 status = kStatus_Success;
111 }
112
113 return status;
114 }
115
otp_clear_status(void)116 static void otp_clear_status(void)
117 {
118 /* Write 1s to clear all error status */
119 OCOTP->OTP_STATUS = OCOTP_OTP_STATUS_PROGFAIL_MASK;
120 OCOTP->OTP_NONMASK_STATUS1 = OTP_STATUS1_ERRORS_MASK;
121 }
122
OCOTP_OtpInit(void)123 status_t OCOTP_OtpInit(void)
124 {
125 CLOCK_EnableClock(kCLOCK_Otp);
126 RESET_ClearPeripheralReset(kOTP_RST_SHIFT_RSTn);
127
128 /* Bring SOC OTP out of reset */
129 SOC_OTP_CTRL->OTP_POR_B = SOC_OTP_CTRL_OTP_POR_B_OTP_POR_B_MASK;
130 SOC_OTP_CTRL->OTP_RST_B = SOC_OTP_CTRL_OTP_RST_B_OTP_RST_B_MASK;
131
132 return kStatus_Success;
133 }
134
OCOTP_OtpDeinit(void)135 status_t OCOTP_OtpDeinit(void)
136 {
137 status_t status;
138
139 status = otp_wait_busy();
140 if (status == kStatus_Success)
141 {
142 OCOTP->OTP_PDN = OCOTP_OTP_PDN_PDN_MASK;
143 CLOCK_DisableClock(kCLOCK_Otp);
144 }
145
146 SOC_OTP_CTRL->OTP_POR_B = 0U;
147 SOC_OTP_CTRL->OTP_RST_B = 0U;
148
149 return status;
150 }
151
OCOTP_OtpFuseRead(uint32_t addr,uint32_t * data)152 status_t OCOTP_OtpFuseRead(uint32_t addr, uint32_t *data)
153 {
154 status_t status = kStatus_InvalidArgument;
155
156 do
157 {
158 if (data == NULL)
159 {
160 break;
161 }
162
163 status = otp_wait_busy();
164 if (status != kStatus_Success)
165 {
166 break;
167 }
168
169 otp_clear_status();
170
171 /* Start reading */
172 OCOTP->OTP_CTRL = OCOTP_OTP_CTRL_ADDR(addr);
173 OCOTP->OTP_READ_CTRL = OCOTP_OTP_READ_CTRL_READ(1);
174
175 /* Wait until read completes */
176 status = otp_wait_busy();
177 if (status != kStatus_Success)
178 {
179 break;
180 }
181
182 /* Check whether errors happened or not. */
183 status = otp_get_nonmask_status_result();
184 if (status == kStatus_Success)
185 {
186 *data = OCOTP->OTP_READ_DATA;
187 }
188 } while (false);
189
190 return status;
191 }
192
OCOTP_ReadUniqueID(uint8_t * uid,uint32_t * idLen)193 status_t OCOTP_ReadUniqueID(uint8_t *uid, uint32_t *idLen)
194 {
195 status_t status = kStatus_InvalidArgument;
196 uint32_t offset = 0U;
197 uint32_t leftByte;
198 uint32_t cpyByte;
199 uint32_t data;
200
201 do
202 {
203 if ((uid == NULL) || (idLen == NULL))
204 {
205 break;
206 }
207
208 (void)OCOTP_OtpInit();
209
210 if ((*idLen) != 0U)
211 {
212 leftByte = *idLen;
213 do
214 {
215 status = OCOTP_OtpFuseRead((offset / 4U) + 46U, &data);
216 if (status != kStatus_Success)
217 {
218 break;
219 }
220 cpyByte = (leftByte > 4U) ? 4U : leftByte;
221 (void)memcpy((void *)&uid[offset], (void *)(uint8_t *)&data, cpyByte);
222 leftByte -= cpyByte;
223 offset += cpyByte;
224 } while ((leftByte > 0U) && (offset < FSL_OCOTP_UID_LENGTH));
225 *idLen -= leftByte;
226 }
227 } while (false);
228
229 return status;
230 }
231
soc_otp_read(uint32_t addr_line,uint64_t * value)232 static uint32_t soc_otp_read(uint32_t addr_line, uint64_t *value)
233 {
234 uint32_t dly = SOC_OTP_READ_DELAY_COUNT;
235 SOC_OTP_CTRL->OTP_ADDR = (uint16_t)addr_line;
236 SOC_OTP_CTRL->OTP_BYPASS_MODE1 = 0;
237 SOC_OTP_CTRL->OTP_CMD_START = SOC_OTP_CMD_READ;
238 SOC_OTP_CTRL->OTP_CMD_START |= SOC_OTP_CTRL_OTP_CMD_START_OTP_CMD_START_MASK;
239 while ((dly > 0U) && ((SOC_OTP_CTRL->OTP_CTRL0 & SOC_OTP_CTRL_OTP_CTRL0_CTRL_CMD_DONE_MASK) == 0U))
240 {
241 dly--; /* If something horrible happens, bail out after a delay */
242 }
243
244 if ((dly > 0U) && ((SOC_OTP_CTRL->OTP_WDATA4 & SOC_OTP_CTRL_OTP_WDATA4_DATA_LINE_VALID_BIT_MASK) != 0U))
245 {
246 *value = ((uint64_t)SOC_OTP_CTRL->OTP_WDATA3 << 48) | ((uint64_t)SOC_OTP_CTRL->OTP_WDATA2 << 32) |
247 ((uint64_t)SOC_OTP_CTRL->OTP_WDATA1 << 16) | ((uint64_t)SOC_OTP_CTRL->OTP_WDATA0);
248 return 1;
249 }
250
251 return 0;
252 }
253
OCOTP_ReadSocOtp(uint64_t * data,uint32_t tag)254 status_t OCOTP_ReadSocOtp(uint64_t *data, uint32_t tag)
255 {
256 status_t status = kStatus_Fail;
257 uint32_t i;
258
259 if (data == NULL)
260 {
261 status = kStatus_InvalidArgument;
262 }
263 else
264 {
265 /* Read SOC_OTP values */
266 for (i = 0U; i < OTP_SEC_NLINES; i++)
267 {
268 if (soc_otp_read(i, data) == 0U)
269 {
270 continue;
271 }
272
273 if ((*data & 0xFFFFU) == tag)
274 {
275 status = kStatus_Success;
276 break;
277 }
278 }
279 }
280
281 return status;
282 }
283
OCOTP_ReadSVC(uint64_t * svc)284 status_t OCOTP_ReadSVC(uint64_t *svc)
285 {
286 status_t status = kStatus_Fail;
287
288 assert(svc != NULL);
289
290 status = OCOTP_ReadSocOtp(svc, OTP_SVC_TAG);
291
292 return status;
293 }
294
OCOTP_ReadPackage(uint32_t * pack)295 status_t OCOTP_ReadPackage(uint32_t *pack)
296 {
297 status_t status = kStatus_Fail;
298 uint64_t data = 0ULL;
299
300 assert(pack != NULL);
301
302 status = OCOTP_ReadSocOtp(&data, OTP_PKG_TAG);
303 if (status == kStatus_Success)
304 {
305 *pack = ((uint32_t)data >> 16U) & 0xFFU;
306 }
307
308 return status;
309 }
310