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