1 /*
2  * Copyright 2019-2020 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "fsl_ocotp.h"
9 
10 /*******************************************************************************
11  * Definitions
12  ******************************************************************************/
13 /* Component ID definition, used by tools. */
14 #ifndef FSL_COMPONENT_ID
15 #define FSL_COMPONENT_ID "platform.drivers.ocotp"
16 #endif
17 
18 #if defined(FSL_FEATURE_OCOTP_HAS_STATUS) && FSL_FEATURE_OCOTP_HAS_STATUS
19 #define OCOTP_STATUS_READ_DED_MASK                                                             \
20     (OCOTP_OUT_STATUS0_DED0_MASK | OCOTP_OUT_STATUS0_DED1_MASK | OCOTP_OUT_STATUS0_DED2_MASK | \
21      OCOTP_OUT_STATUS0_DED3_MASK)
22 #endif
23 
24 /* Wait time should be not less than 150ns . */
25 #define OCOTP_TIMING_WAIT_NS (uint64_t)150
26 /* Relex time should be not less than 100ns . */
27 #define OCOTP_TIMING_RELEX_NS (uint64_t)100
28 /* Program time should be rang from 9000ns~11000ns. */
29 #define OCOTP_TIMING_PROGRAM_NS (uint64_t)10000
30 /* Read time should be less than 40ns. */
31 #define OCOTP_TIMING_READ_NS (uint64_t)40
32 
33 /* Unlock key is 0x3E77. */
34 #define OCOTP_WRITE_UNLOCK_KEY (0x3E77)
35 /*******************************************************************************
36  * Prototypes
37  ******************************************************************************/
38 
39 #if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
40 /*!
41  * @brief Set read timing configuration.
42  *
43  * @param base          OCOTP peripheral base addess.
44  * @param timingConfig  configuration of timing.
45  */
46 static void OCOTP_SetReadTiming(OCOTP_Type *base, ocotp_timing_t timingConfig);
47 
48 /*!
49  * @brief Set write timing configuration.
50  *
51  * @param base          OCOTP peripheral base addess.
52  * @param timingConfig  configuration of timing.
53  */
54 static void OCOTP_SetWriteTiming(OCOTP_Type *base, ocotp_timing_t timingConfig);
55 #endif
56 
57 /*******************************************************************************
58  * Variables
59  ******************************************************************************/
60 #if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
61 /* Timing configuration for OCOTP controller. */
62 static ocotp_timing_t s_timingConfig;
63 #endif
64 
65 /*******************************************************************************
66  * Code
67  *******************************************************************************/
68 /* Reload the shadow register. */
OCOTP_ReloadShadowRegister(OCOTP_Type * base)69 status_t OCOTP_ReloadShadowRegister(OCOTP_Type *base)
70 {
71     assert(NULL != base);
72 
73     status_t status = kStatus_Success;
74 
75     /* Make sure the OCOTP is ready, Overlapped accesses are not supported by the controller. */
76     while (OCOTP_CheckBusyStatus(base))
77     {
78     }
79 
80     /* Clear access error status bit. */
81     OCOTP_ClearErrorStatus(base);
82 
83 #if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
84     /* Set the read timing. */
85     OCOTP_SetReadTiming(base, s_timingConfig);
86 
87     /* Wait for the OCOTP controller not busy. */
88     while (OCOTP_CheckBusyStatus(base))
89     {
90     }
91 #endif
92 
93 #if defined(OCOTP_OUT_STATUS0_DED_RELOAD_MASK)
94     /* Clear reload error status. */
95     base->OUT_STATUS0_CLR = OCOTP_OUT_STATUS0_DED_RELOAD_MASK;
96 #endif
97 
98     /* Set reload bit. */
99     base->CTRL_SET = OCOTP_CTRL_RELOAD_SHADOWS(1);
100 
101     /* Wait for the OCOTP controller not busy. */
102     while (OCOTP_CheckBusyStatus(base))
103     {
104     }
105     /* Wait for shadow register reload complete. this bit will be auto clear by OCOTP once operation is complete. */
106     while (OCOTP_CTRL_RELOAD_SHADOWS_MASK == (base->CTRL & OCOTP_CTRL_RELOAD_SHADOWS_MASK))
107     {
108     }
109 
110 #if defined(OCOTP_OUT_STATUS0_DED_RELOAD_MASK)
111     if ((base->OUT_STATUS0 & OCOTP_OUT_STATUS0_DED_RELOAD_MASK) != 0U)
112     {
113         status = kStatus_OCOTP_ReloadError;
114     }
115 #endif
116 
117     return status;
118 }
119 
120 #if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
OCOTP_SetReadTiming(OCOTP_Type * base,ocotp_timing_t timingConfig)121 static void OCOTP_SetReadTiming(OCOTP_Type *base, ocotp_timing_t timingConfig)
122 {
123     uint32_t timingValue = base->TIMING;
124 
125     timingValue &= ~(OCOTP_TIMING_RELAX_MASK | OCOTP_TIMING_STROBE_READ_MASK | OCOTP_TIMING_WAIT_MASK);
126     timingValue |= OCOTP_TIMING_RELAX(timingConfig.relax) | OCOTP_TIMING_STROBE_READ(timingConfig.strobe_read) |
127                    OCOTP_TIMING_WAIT(timingConfig.wait);
128     base->TIMING = timingValue;
129 }
130 
OCOTP_SetWriteTiming(OCOTP_Type * base,ocotp_timing_t timingConfig)131 static void OCOTP_SetWriteTiming(OCOTP_Type *base, ocotp_timing_t timingConfig)
132 {
133     uint32_t timingValue = base->TIMING;
134 
135     timingValue &= ~(OCOTP_TIMING_RELAX_MASK | OCOTP_TIMING_STROBE_PROG_MASK | OCOTP_TIMING_WAIT_MASK);
136     timingValue |= OCOTP_TIMING_RELAX(timingConfig.relax) | OCOTP_TIMING_STROBE_PROG(timingConfig.strobe_prog) |
137                    OCOTP_TIMING_WAIT(timingConfig.wait);
138 
139     base->TIMING = timingValue;
140 }
141 #endif
142 
143 /* Initializes OCOTP controller. */
OCOTP_Init(OCOTP_Type * base,uint32_t srcClock_Hz)144 void OCOTP_Init(OCOTP_Type *base, uint32_t srcClock_Hz)
145 {
146     assert(NULL != base);
147 #if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
148     assert(0UL != srcClock_Hz);
149 #endif
150 
151 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
152     /* Enable OCOTP clock */
153     CLOCK_EnableClock(kCLOCK_Ocotp);
154 #endif
155 
156 #if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
157     /* tWait time shoule be higher than OCOTP_TIMING_WAIT_NS. */
158     s_timingConfig.wait = (uint32_t)((OCOTP_TIMING_WAIT_NS * srcClock_Hz + 1000000000U) / 1000000000U - 1U);
159 
160     /* tRelax time shoule be higher than OCOTP_TIMING_RELEX_NS. */
161     s_timingConfig.relax = (uint32_t)((OCOTP_TIMING_RELEX_NS * srcClock_Hz + 1000000000U) / 1000000000U - 1U);
162 
163     /* tStrobe_prog time should be close to OCOTP_TIMING_PROGRAM_NS, only add half of 1000000000. */
164     s_timingConfig.strobe_prog = (uint32_t)((OCOTP_TIMING_PROGRAM_NS * srcClock_Hz + 500000000U) / 1000000000U) +
165                                  2U * (s_timingConfig.relax + 1U) - 1U;
166 
167     /* tStrobe_read time should be higher than OCOTP_TIMING_READ_NS. */
168     s_timingConfig.strobe_read = (uint32_t)((OCOTP_TIMING_READ_NS * srcClock_Hz + 1000000000U) / 1000000000U) +
169                                  2U * (s_timingConfig.relax + 1U) - 1U;
170 #endif
171 }
172 
173 /* De-init OCOTP controller. */
OCOTP_Deinit(OCOTP_Type * base)174 void OCOTP_Deinit(OCOTP_Type *base)
175 {
176     assert(NULL != base);
177 
178 #if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
179     s_timingConfig.wait        = 0UL;
180     s_timingConfig.relax       = 0UL;
181     s_timingConfig.strobe_prog = 0UL;
182     s_timingConfig.strobe_read = 0UL;
183 #endif
184 
185 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
186     /* Disable OCOTP clock */
187     CLOCK_DisableClock(kCLOCK_Ocotp);
188 #endif
189 }
190 
191 /* Read the fuse shadow register. */
OCOTP_ReadFuseShadowRegister(OCOTP_Type * base,uint32_t address)192 uint32_t OCOTP_ReadFuseShadowRegister(OCOTP_Type *base, uint32_t address)
193 {
194     assert(NULL != base);
195 
196     uint32_t data = 0U;
197 
198     (void)OCOTP_ReadFuseShadowRegisterExt(base, address, &data, 1);
199 
200     return data;
201 }
202 
OCOTP_ReadFuseShadowRegisterExt(OCOTP_Type * base,uint32_t address,uint32_t * data,uint8_t fuseWords)203 status_t OCOTP_ReadFuseShadowRegisterExt(OCOTP_Type *base, uint32_t address, uint32_t *data, uint8_t fuseWords)
204 {
205     assert((fuseWords > 0U) && (fuseWords <= OCOTP_READ_FUSE_DATA_COUNT));
206     assert(NULL != data);
207 
208     status_t status = kStatus_Success;
209 
210 #if (OCOTP_READ_FUSE_DATA_COUNT > 1U)
211     uint32_t i;
212 #endif
213 
214     /* Make sure the OCOTP is ready, Overlapped accesses are not supported by the controller. */
215     while (OCOTP_CheckBusyStatus(base))
216     {
217     }
218 
219     /* If ERROR bit was set, clear access error status bit. */
220     if (OCOTP_CheckErrorStatus(base))
221     {
222         OCOTP_ClearErrorStatus(base);
223     }
224 
225 #if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
226     /* Set the read timing. */
227     OCOTP_SetReadTiming(base, s_timingConfig);
228 
229     /* Wait for busy bit is cleared. */
230     while (OCOTP_CheckBusyStatus(base))
231     {
232     }
233 
234     /* Clear access error status bit. */
235     if (OCOTP_CheckErrorStatus(base))
236     {
237         OCOTP_ClearErrorStatus(base);
238     }
239 #endif
240 
241 #if defined(OCOTP_STATUS_READ_DED_MASK)
242     /* Clear error flags. */
243     base->OUT_STATUS0_CLR = OCOTP_STATUS_READ_DED_MASK;
244 #endif
245 
246     /* Write requested address to register. */
247     base->CTRL_CLR = OCOTP_CTRL_CLR_ADDR_MASK;
248     base->CTRL_SET = OCOTP_CTRL_SET_ADDR(address);
249 
250     /* Set OCOTP auto read enable. */
251 #if defined(OCOTP_READ_CTRL_READ_NUM_MASK)
252     base->READ_CTRL = (base->READ_CTRL & ~(OCOTP_READ_CTRL_READ_NUM_MASK)) |
253                       OCOTP_READ_CTRL_READ_NUM((uint32_t)fuseWords - 1U) | OCOTP_READ_CTRL_READ_FUSE_MASK;
254 #else
255     base->READ_CTRL |= OCOTP_READ_CTRL_READ_FUSE_MASK;
256 #endif
257 
258     /* Wait for busy bit is cleared, and no error occurred on controller. */
259     while (OCOTP_CheckBusyStatus(base))
260     {
261     }
262 
263     /* If ERROR bit was set, this may be mean that the accsee to the register was wrong. */
264     if (OCOTP_CheckErrorStatus(base))
265     {
266         /* Clear access error status bit. */
267         OCOTP_ClearErrorStatus(base);
268 
269         status = kStatus_OCOTP_AccessError;
270     }
271 
272 #if defined(OCOTP_STATUS_READ_DED_MASK)
273     if ((base->OUT_STATUS0 & OCOTP_STATUS_READ_DED_MASK) != 0U)
274     {
275         status = kStatus_Fail;
276     }
277 #endif
278 
279 #if (OCOTP_READ_FUSE_DATA_COUNT == 1U)
280     *data = base->READ_FUSE_DATA;
281 #else
282     for (i = 0; i < fuseWords; i++)
283     {
284         data[i] = base->READ_FUSE_DATAS[i].READ_FUSE_DATA;
285     }
286 #endif
287 
288     return status;
289 }
290 
291 /* Write the fuse shadow register. */
OCOTP_WriteFuseShadowRegister(OCOTP_Type * base,uint32_t address,uint32_t data)292 status_t OCOTP_WriteFuseShadowRegister(OCOTP_Type *base, uint32_t address, uint32_t data)
293 {
294     return OCOTP_WriteFuseShadowRegisterWithLock(base, address, data, false);
295 }
296 
OCOTP_WriteFuseShadowRegisterWithLock(OCOTP_Type * base,uint32_t address,uint32_t data,bool lock)297 status_t OCOTP_WriteFuseShadowRegisterWithLock(OCOTP_Type *base, uint32_t address, uint32_t data, bool lock)
298 {
299     assert(NULL != base);
300 
301     status_t status = kStatus_Success;
302 
303 #if defined(FSL_FEATURE_OCOTP_HAS_STATUS) && FSL_FEATURE_OCOTP_HAS_STATUS
304     uint32_t regStatus;
305 #endif
306 
307 #if !(defined(FSL_FEATURE_OCOTP_HAS_WORDLOCK) && FSL_FEATURE_OCOTP_HAS_WORDLOCK)
308     if (lock)
309     {
310         return kStatus_InvalidArgument;
311     }
312 #endif
313 
314     /* Make sure the OCOTP is ready, Overlapped accesses are not supported by the controller. */
315     while (OCOTP_CheckBusyStatus(base))
316     {
317     }
318 
319     /* Clear access error status bit. */
320     if (OCOTP_CheckErrorStatus(base))
321     {
322         OCOTP_ClearErrorStatus(base);
323     }
324 
325 #if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
326     /* Set write timing for OCOTP controller. */
327     OCOTP_SetWriteTiming(base, s_timingConfig);
328 
329     /* Wait for busy bit is cleared. */
330     while (OCOTP_CheckBusyStatus(base))
331     {
332     }
333 
334     /* Clear access error status bit. */
335     if (OCOTP_CheckErrorStatus(base))
336     {
337         OCOTP_ClearErrorStatus(base);
338     }
339 #endif
340 
341 #if defined(FSL_FEATURE_OCOTP_HAS_STATUS) && FSL_FEATURE_OCOTP_HAS_STATUS
342     /* Clear errors. */
343     base->OUT_STATUS0_CLR = (OCOTP_OUT_STATUS0_PROGFAIL_MASK | OCOTP_OUT_STATUS0_LOCKED_MASK);
344 #endif
345 
346     /* Write requested address and unlock key to register. */
347 #if (defined(FSL_FEATURE_OCOTP_HAS_WORDLOCK) && FSL_FEATURE_OCOTP_HAS_WORDLOCK)
348     base->CTRL_CLR = OCOTP_CTRL_CLR_ADDR_MASK | OCOTP_CTRL_WR_UNLOCK_MASK | OCOTP_CTRL_WORDLOCK_MASK;
349 #else
350     base->CTRL_CLR = OCOTP_CTRL_CLR_ADDR_MASK | OCOTP_CTRL_WR_UNLOCK_MASK;
351 #endif
352 
353 #if (defined(FSL_FEATURE_OCOTP_HAS_WORDLOCK) && FSL_FEATURE_OCOTP_HAS_WORDLOCK)
354     if (lock)
355     {
356         base->CTRL_SET =
357             OCOTP_CTRL_SET_ADDR(address) | OCOTP_CTRL_WR_UNLOCK(OCOTP_WRITE_UNLOCK_KEY) | OCOTP_CTRL_WORDLOCK_MASK;
358     }
359     else
360 #endif
361     {
362         base->CTRL_SET = OCOTP_CTRL_SET_ADDR(address) | OCOTP_CTRL_WR_UNLOCK(OCOTP_WRITE_UNLOCK_KEY);
363     }
364 
365     /* Write data to register. */
366     base->DATA = data;
367 
368     /* Wait for busy bit is cleared, and no error occurred on controller. */
369     while (OCOTP_CheckBusyStatus(base))
370     {
371     }
372 
373     /* If ERROR bit was set, this may be mean that the accsee to the register was wrong. */
374     if (OCOTP_CheckErrorStatus(base))
375     {
376         /* Clear access error status bit. */
377         OCOTP_ClearErrorStatus(base);
378 
379         status = kStatus_OCOTP_AccessError;
380     }
381 
382 #if defined(FSL_FEATURE_OCOTP_HAS_STATUS) && FSL_FEATURE_OCOTP_HAS_STATUS
383     regStatus = base->OUT_STATUS0;
384 
385     if ((regStatus & OCOTP_OUT_STATUS0_PROGFAIL_MASK) != 0U)
386     {
387         status = kStatus_OCOTP_ProgramFail;
388     }
389     else if ((regStatus & OCOTP_OUT_STATUS0_LOCKED_MASK) != 0U)
390     {
391         status = kStatus_OCOTP_Locked;
392     }
393     else
394     {
395         /* For MISRA rules. */
396     }
397 #endif
398 
399     if (kStatus_Success == status)
400     {
401         /* Reload the fuse register. */
402         status = OCOTP_ReloadShadowRegister(base);
403     }
404 
405     return status;
406 }
407