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