1 /*
2  * Copyright 2020-2023 NXP
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 /**
8 *   @file Qspi_Ip_Controller.c
9 *
10 *   @addtogroup IPV_QSPI QSPI IPV Driver
11 *   @{
12 */
13 
14 /* implements Qspi_Ip_Controller.c_Artifact */
15 
16 #ifdef __cplusplus
17 extern "C"{
18 #endif
19 
20 #include "Mcal.h"
21 #include "OsIf.h"
22 #include "Qspi_Ip.h"
23 #include "Qspi_Ip_Controller.h"
24 #include "Qspi_Ip_HwAccess.h"
25 
26 /*==================================================================================================
27 *                              SOURCE FILE VERSION INFORMATION
28 ==================================================================================================*/
29 #define QSPI_IP_CONTROLLER_VENDOR_ID_C                       43
30 #define QSPI_IP_CONTROLLER_AR_RELEASE_MAJOR_VERSION_C        4
31 #define QSPI_IP_CONTROLLER_AR_RELEASE_MINOR_VERSION_C        7
32 #define QSPI_IP_CONTROLLER_AR_RELEASE_REVISION_VERSION_C     0
33 #define QSPI_IP_CONTROLLER_SW_MAJOR_VERSION_C                3
34 #define QSPI_IP_CONTROLLER_SW_MINOR_VERSION_C                0
35 #define QSPI_IP_CONTROLLER_SW_PATCH_VERSION_C                0
36 
37 /*==================================================================================================
38 *                                     FILE VERSION CHECKS
39 ==================================================================================================*/
40 #ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK
41     /* Check if current file and Mcal.h header file are of the same Autosar version */
42     #if ((QSPI_IP_CONTROLLER_AR_RELEASE_MAJOR_VERSION_C != MCAL_AR_RELEASE_MAJOR_VERSION) || \
43          (QSPI_IP_CONTROLLER_AR_RELEASE_MINOR_VERSION_C != MCAL_AR_RELEASE_MINOR_VERSION) \
44         )
45         #error "AutoSar Version Numbers of Qspi_Ip_Controller.c and Mcal.h are different"
46     #endif
47 
48     /* Check if current file and OsIf.h header file are of the same Autosar version */
49     #if ((QSPI_IP_CONTROLLER_AR_RELEASE_MAJOR_VERSION_C != OSIF_AR_RELEASE_MAJOR_VERSION) || \
50          (QSPI_IP_CONTROLLER_AR_RELEASE_MINOR_VERSION_C != OSIF_AR_RELEASE_MINOR_VERSION) \
51         )
52         #error "AutoSar Version Numbers of Qspi_Ip_Controller.c and OsIf.h are different"
53     #endif
54 #endif
55 
56 /* Check if current file and Qspi_Ip_Controller header file are of the same vendor */
57 #if (QSPI_IP_CONTROLLER_VENDOR_ID_C != QSPI_IP_CONTROLLER_VENDOR_ID_H)
58     #error "Qspi_Ip_Controller.c and Qspi_Ip_Controller.h have different vendor ids"
59 #endif
60 /* Check if current file and Qspi_Ip_Controller header file are of the same Autosar version */
61 #if ((QSPI_IP_CONTROLLER_AR_RELEASE_MAJOR_VERSION_C    != QSPI_IP_CONTROLLER_AR_RELEASE_MAJOR_VERSION_H) || \
62      (QSPI_IP_CONTROLLER_AR_RELEASE_MINOR_VERSION_C    != QSPI_IP_CONTROLLER_AR_RELEASE_MINOR_VERSION_H) || \
63      (QSPI_IP_CONTROLLER_AR_RELEASE_REVISION_VERSION_C != QSPI_IP_CONTROLLER_AR_RELEASE_REVISION_VERSION_H) \
64     )
65     #error "AutoSar Version Numbers of Qspi_Ip_Controller.c and Qspi_Ip_Controller.h are different"
66 #endif
67 /* Check if current file and Qspi_Ip_Controller header file are of the same Software version */
68 #if ((QSPI_IP_CONTROLLER_SW_MAJOR_VERSION_C != QSPI_IP_CONTROLLER_SW_MAJOR_VERSION_H) || \
69      (QSPI_IP_CONTROLLER_SW_MINOR_VERSION_C != QSPI_IP_CONTROLLER_SW_MINOR_VERSION_H) || \
70      (QSPI_IP_CONTROLLER_SW_PATCH_VERSION_C != QSPI_IP_CONTROLLER_SW_PATCH_VERSION_H) \
71     )
72     #error "Software Version Numbers of Qspi_Ip_Controller.c and Qspi_Ip_Controller.h are different"
73 #endif
74 
75 /* Check if current file and Qspi_Ip_HwAccess header file are of the same vendor */
76 #if (QSPI_IP_CONTROLLER_VENDOR_ID_C != QSPI_IP_HW_ACCESS_VENDOR_ID_H)
77     #error "Qspi_Ip_Controller.c and Qspi_Ip_HwAccess.h have different vendor ids"
78 #endif
79 /* Check if current file and Qspi_Ip_HwAccess header file are of the same Autosar version */
80 #if ((QSPI_IP_CONTROLLER_AR_RELEASE_MAJOR_VERSION_C    != QSPI_IP_HW_ACCESS_AR_RELEASE_MAJOR_VERSION_H) || \
81      (QSPI_IP_CONTROLLER_AR_RELEASE_MINOR_VERSION_C    != QSPI_IP_HW_ACCESS_AR_RELEASE_MINOR_VERSION_H) || \
82      (QSPI_IP_CONTROLLER_AR_RELEASE_REVISION_VERSION_C != QSPI_IP_HW_ACCESS_AR_RELEASE_REVISION_VERSION_H) \
83     )
84     #error "AutoSar Version Numbers of Qspi_Ip_Controller.c and Qspi_Ip_HwAccess.h are different"
85 #endif
86 /* Check if current file and Qspi_Ip_HwAccess header file are of the same Software version */
87 #if ((QSPI_IP_CONTROLLER_SW_MAJOR_VERSION_C != QSPI_IP_HW_ACCESS_SW_MAJOR_VERSION_H) || \
88      (QSPI_IP_CONTROLLER_SW_MINOR_VERSION_C != QSPI_IP_HW_ACCESS_SW_MINOR_VERSION_H) || \
89      (QSPI_IP_CONTROLLER_SW_PATCH_VERSION_C != QSPI_IP_HW_ACCESS_SW_PATCH_VERSION_H) \
90     )
91     #error "Software Version Numbers of Qspi_Ip_Controller.c and Qspi_Ip_HwAccess.h are different"
92 #endif
93 
94 /* Check if current file and Qspi_Ip header file are of the same vendor */
95 #if (QSPI_IP_CONTROLLER_VENDOR_ID_C != QSPI_IP_VENDOR_ID_H)
96     #error "Qspi_Ip_Controller.c and Qspi_Ip.h have different vendor ids"
97 #endif
98 /* Check if current file and Qspi_Ip header file are of the same Autosar version */
99 #if ((QSPI_IP_CONTROLLER_AR_RELEASE_MAJOR_VERSION_C    != QSPI_IP_AR_RELEASE_MAJOR_VERSION_H) || \
100      (QSPI_IP_CONTROLLER_AR_RELEASE_MINOR_VERSION_C    != QSPI_IP_AR_RELEASE_MINOR_VERSION_H) || \
101      (QSPI_IP_CONTROLLER_AR_RELEASE_REVISION_VERSION_C != QSPI_IP_AR_RELEASE_REVISION_VERSION_H) \
102     )
103     #error "AutoSar Version Numbers of Qspi_Ip_Controller.c and Qspi_Ip.h are different"
104 #endif
105 /* Check if current file and Qspi_Ip header file are of the same Software version */
106 #if ((QSPI_IP_CONTROLLER_SW_MAJOR_VERSION_C != QSPI_IP_SW_MAJOR_VERSION_H) || \
107      (QSPI_IP_CONTROLLER_SW_MINOR_VERSION_C != QSPI_IP_SW_MINOR_VERSION_H) || \
108      (QSPI_IP_CONTROLLER_SW_PATCH_VERSION_C != QSPI_IP_SW_PATCH_VERSION_H) \
109     )
110     #error "Software Version Numbers of Qspi_Ip_Controller.c and Qspi_Ip.h are different"
111 #endif
112 
113 #if (QSPI_IP_MEM_INSTANCE_COUNT > 0)
114 
115 /*******************************************************************************
116  * Definitions
117  ******************************************************************************/
118 #if defined(FEATURE_QSPI_CHIP_OPTIONS_S32K148)
119     /* Bit-fields of chip-specific MCR[SCLKCFG] field */
120     #define QSPI_MCR_SCLKCFG_INPUT_EN             0x80U    /* Enable input buffer of QSPI pads */
121     #define QSPI_MCR_SCLKCFG_CLK_MOD              0x40U    /* Quadspi Clocking mode selection  */
122     #define QSPI_MCR_SCLKCFG_EXT_DQS              0x20U    /* Use external DQS (HyperRAM mode) */
123     #define QSPI_MCR_SCLKCFG_CLK_SRC              0x10U    /* QuadSPI source clock selection   */
124     #define QSPI_MCR_SCLKCFG_DQS_INV_B            0x08U    /* B-side DQS invert                */
125     #define QSPI_MCR_SCLKCFG_DQS_SEL_B            0x04U    /* B-side DQS select                */
126     #define QSPI_MCR_SCLKCFG_DQS_INV_A            0x02U    /* A-side DQS invert                */
127     #define QSPI_MCR_SCLKCFG_DQS_SEL_A            0x01U    /* A-side DQS select                */
128 
129     /* Bit-fields of chip-specific SOCCR[SOCCFG] field */
130     /* Programmable Divider Selection */
131     #define QuadSPI_SOCCR_PD_MASK                 0xE0000000u
132     #define QuadSPI_SOCCR_PD_SHIFT                29u
133     #define QuadSPI_SOCCR_PD(x)                   (((uint32)(((uint32)(x))<<QuadSPI_SOCCR_PD_SHIFT))&QuadSPI_SOCCR_PD_MASK)
134     /* Programmable Divider Disable */
135     #define QuadSPI_SOCCR_PDD_MASK                0x10000000u
136 
137     #define QuadSPI_SOCCR_DSQ_DEL_B               8u
138     #define QuadSPI_SOCCR_DSQ_DEL_A               0u
139 #endif /* (FEATURE_QSPI_CHIP_OPTIONS_S32K148) */
140 
141 #if (FEATURE_QSPI_HAS_SFP == 1)
142 
143 #if (QSPI_IP_ENABLE_USER_MODE_SUPPORT == STD_ON)
144 
145 #define Qspi_Ip_Sfp_Configure(baseAddr, userConfigPtr) OsIf_Trusted_Call2params(Qspi_Ip_Sfp_Configure_Privileged, baseAddr, userConfigPtr)
146 #define Qspi_Ip_ResetPrivilegedRegisters(baseAddr) OsIf_Trusted_Call1param(Qspi_Ip_ResetPrivilegedRegisters_Privileged, baseAddr)
147 #define Qspi_Ip_Sfp_ClearLatchedErrors(baseAddr) OsIf_Trusted_Call1param(Qspi_Ip_Sfp_ClearLatchedErrors_Privileged, baseAddr)
148 
149 #else /* QSPI_IP_ENABLE_USER_MODE_SUPPORT */
150 
151 #define Qspi_Ip_Sfp_Configure(baseAddr, userConfigPtr) Qspi_Ip_Sfp_Configure_Privileged(baseAddr, userConfigPtr)
152 #define Qspi_Ip_ResetPrivilegedRegisters(baseAddr) Qspi_Ip_ResetPrivilegedRegisters_Privileged(baseAddr)
153 #define Qspi_Ip_Sfp_ClearLatchedErrors(baseAddr) Qspi_Ip_Sfp_ClearLatchedErrors_Privileged(baseAddr)
154 
155 #endif /* QSPI_IP_ENABLE_USER_MODE_SUPPORT */
156 
157 #endif /* FEATURE_QSPI_HAS_SFP */
158 
159 /*******************************************************************************
160  * Variables
161  ******************************************************************************/
162 
163 /*! @cond DRIVER_INTERNAL_USE_ONLY */
164 
165 /* Mask of QuadSPI IP-related error flags */
166 #ifndef QuadSPI_FR_IPAEF_MASK
167     #define QuadSPI_FR_IPAEF_MASK  (0U)
168 #endif
169 
170 #define QSPI_ERR_FLAGS_MASK    (QuadSPI_FR_TBUF_MASK | \
171                                 QuadSPI_FR_ILLINE_MASK | \
172                                 QuadSPI_FR_RBOF_MASK | \
173                                 QuadSPI_FR_IPAEF_MASK | \
174                                 QuadSPI_FR_IPIEF_MASK)
175 
176 
177 #define FLS_START_SEC_CONST_UNSPECIFIED
178 #include "Fls_MemMap.h"
179 
180 /* Table of base addresses for QuadSPI instances. */
181 QuadSPI_Type * const Qspi_Ip_BaseAddress[QuadSPI_INSTANCE_COUNT] = IP_QuadSPI_BASE_PTRS;
182 /* Table of AHB addresses for QuadSPI instances. */
183 const uint32 Qspi_Ip_AhbAddress[QuadSPI_INSTANCE_COUNT] = QuadSPI_AHB_PTRS;
184 
185 #define FLS_STOP_SEC_CONST_UNSPECIFIED
186 #include "Fls_MemMap.h"
187 
188 
189 #define FLS_START_SEC_VAR_CLEARED_8
190 #include "Fls_MemMap.h"
191 
192 /* The padding bytes information to handle unaligned read/write operation for QuadSPI instances:
193    - For read:
194         [7:0] the number of padding bytes to handle read from unaligned address
195    - For write:
196         [7:4] the number of pre-padding bytes to handle write from unaligned start address
197         [3:0] the number of post-padding bytes to handle write from unaligned end address
198  */
199 uint8 Qspi_Ip_MemoryPadding[QuadSPI_INSTANCE_COUNT];
200 
201 #define FLS_STOP_SEC_VAR_CLEARED_8
202 #include "Fls_MemMap.h"
203 
204 #define FLS_START_SEC_VAR_CLEARED_32
205 #include "Fls_MemMap.h"
206 
207 /* Pointer to runtime configuration structures (storing the DLL configuration for runtime usage) */
208 const Qspi_Ip_ControllerConfigType * Qspi_Ip_ControllerConfig[QuadSPI_INSTANCE_COUNT];
209 
210 #define FLS_STOP_SEC_VAR_CLEARED_32
211 #include "Fls_MemMap.h"
212 
213 /*******************************************************************************
214  * Private Functions
215  ******************************************************************************/
216 
217 #define FLS_START_SEC_CODE
218 #include "Fls_MemMap.h"
219 
220 static inline uint32 Qspi_Ip_GetWordSize(uint32 sizeRemaining);
221 
222 #if (FEATURE_QSPI_HAS_SFP == 1)
223 
224 void Qspi_Ip_Sfp_Configure_Privileged(QuadSPI_Type * baseAddr, Qspi_Ip_ControllerConfigType const * userConfigPtr);
225 void Qspi_Ip_ResetPrivilegedRegisters_Privileged(QuadSPI_Type *BaseAddr);
226 void Qspi_Ip_Sfp_ClearLatchedErrors_Privileged(QuadSPI_Type * BaseAddr);
227 
228 #endif /* FEATURE_QSPI_HAS_SFP */
229 
230 inline static void Qspi_Ip_ResetAllRegisters(QuadSPI_Type *BaseAddr);
231 
232 static Qspi_Ip_StatusType Qspi_Ip_CmdWaitComplete(uint32 instance);
233 
234 /*FUNCTION**********************************************************************
235  *
236  * Function Name : Qspi_Ip_GetWordSize
237  * Description   : Calculates the word size for the up coming loop
238  */
Qspi_Ip_GetWordSize(uint32 sizeRemaining)239 static inline uint32 Qspi_Ip_GetWordSize(uint32 sizeRemaining)
240 {
241     return (sizeRemaining > 4U) ? 4U : sizeRemaining;
242 }
243 
244 /*FUNCTION**********************************************************************
245  *
246  * Function Name : Qspi_Ip_ProcessDataRead
247  * Description   : Processes read data
248  * @implements     Qspi_Ip_ProcessDataRead_Activity */
Qspi_Ip_ProcessDataRead(uint8 * dataRead,uint32 size,const QuadSPI_Type * baseAddr,uint32 padding)249 static inline Qspi_Ip_StatusType Qspi_Ip_ProcessDataRead(uint8 *dataRead,
250                                                          uint32 size,
251                                                          const QuadSPI_Type *baseAddr,
252                                                          uint32 padding
253                                                         )
254 {
255     uint8 * data = dataRead;
256     uint32 cnt = 0U;
257     uint32 recvData;
258     const uint8 *recvDataPtr = (uint8 *)(&recvData);
259     uint32 wordSize;
260     uint32 byteCnt;
261     uint32 sizeRemaining = size;
262     uint32 paddingBytes = padding;
263 
264     if (0U != paddingBytes)
265     {
266         /* Ignore all padding words, jump to the fist data */
267         cnt            = paddingBytes >> 2U;
268         sizeRemaining -= cnt << 2U;
269         paddingBytes  &= 0x3U;
270 
271         /* Get first received word */
272         recvData = baseAddr->RBDR[cnt];
273         cnt++;
274         /* Get wordSize for the loop */
275         wordSize = Qspi_Ip_GetWordSize(sizeRemaining);
276 
277         /* Ignore padding bytes and copy the rest to buffer */
278         for (byteCnt = paddingBytes; byteCnt < wordSize; byteCnt++)
279         {
280             #if (defined(CORE_BIG_ENDIAN))
281             *data = recvDataPtr[3U - byteCnt];
282             #else
283             *data = recvDataPtr[byteCnt];
284             #endif
285 
286             data++;
287         }
288         sizeRemaining -= wordSize;
289     }
290 
291     /* Check user buffer alignment */
292     if (((Qspi_Ip_UintPtrType)data & 0x3U) == 0U)
293     {
294         /* Process 4 bytes at a time to speed up read */
295         while (sizeRemaining >= 4U)
296         {
297             *((uint32 *)((Qspi_Ip_UintPtrType)data)) = baseAddr->RBDR[cnt];  /* Casting through uint32 to avoid Misra 11.3 */
298             data = &(data[4U]);
299             cnt++;
300             sizeRemaining -= 4U;
301         }
302     }
303 
304     /* Process remaining bytes one by one */
305     while (sizeRemaining > 0U)
306     {
307         /* Get next received word */
308         recvData = baseAddr->RBDR[cnt];
309         /* get wordSize for the loop */
310         wordSize = Qspi_Ip_GetWordSize(sizeRemaining);
311         for (byteCnt = 0U; byteCnt < wordSize; byteCnt++)
312         {
313 #if (defined(CORE_BIG_ENDIAN))
314             *data = (uint8)(recvData >> 24U);
315             recvData <<= 8U;
316 #else
317             *data = (uint8)(recvData & 0xFFU);
318             recvData >>= 8U;
319 #endif
320             data++;
321             sizeRemaining--;
322         }
323         cnt++;
324     }
325     return STATUS_QSPI_IP_SUCCESS;
326 }
327 
328 
329 /*FUNCTION**********************************************************************
330  *
331  * Function Name : Qspi_Ip_ProcessDataVerify
332  * Description   : Processes program verify data
333  * @implements     Qspi_Ip_ProcessDataVerify_Activity */
Qspi_Ip_ProcessDataVerify(const uint8 * dataCmp,uint32 size,const QuadSPI_Type * baseAddr,uint32 padding)334 static inline Qspi_Ip_StatusType Qspi_Ip_ProcessDataVerify(const uint8 *dataCmp,
335                                                            uint32 size,
336                                                            const QuadSPI_Type *baseAddr,
337                                                            uint32 padding
338                                                           )
339 {
340     const uint8 * roData = dataCmp;
341     uint32 cnt = 0U;
342     uint32 recvData;
343     uint8 recvByte;
344     const uint8 *recvDataPtr = (uint8 *)(&recvData);
345     Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
346     uint32 byteCnt;
347     uint32 wordSize;
348     uint32 paddingBytes = padding;
349     uint32 sizeRemaining = size;
350 
351     if (0U != paddingBytes)
352     {
353         /* Ignore all padding words, jump to the fist data */
354         cnt            = paddingBytes >> 2U;
355         sizeRemaining -= cnt << 2U;
356         paddingBytes  &= 0x3U;
357 
358         /* Get first received word */
359         recvData = baseAddr->RBDR[cnt];
360         cnt++;
361         /* Get wordSize for the loop */
362         wordSize = Qspi_Ip_GetWordSize(sizeRemaining);
363         sizeRemaining -= wordSize;
364 
365         /* Ignore padding bytes and compare the rest with user buffer */
366         for (byteCnt = paddingBytes; byteCnt < wordSize; byteCnt++)
367         {
368             #if (defined(CORE_BIG_ENDIAN))
369             recvByte = recvDataPtr[3U - byteCnt];
370             #else
371             recvByte = recvDataPtr[byteCnt];
372             #endif
373 
374             /* return STATUS_QSPI_IP_ERROR_PROGRAM_VERIFY if the data is not match */
375             if (*roData != recvByte)
376             {
377                 status = STATUS_QSPI_IP_ERROR_PROGRAM_VERIFY;
378                 sizeRemaining = 0U;
379                 break;
380             }
381             roData++;
382         }
383     }
384 
385     /* Check user buffer alignment */
386     if (((Qspi_Ip_UintPtrType)roData & 0x3U) == 0U)
387     {
388         while (sizeRemaining >= 4U)
389         {
390             /* Process 4 bytes at a time to speed up read */
391             if (*((const uint32 *)((Qspi_Ip_UintPtrType)roData)) != baseAddr->RBDR[cnt])
392             {
393                 /* return STATUS_QSPI_IP_ERROR_PROGRAM_VERIFY if the data is not match */
394                 status = STATUS_QSPI_IP_ERROR_PROGRAM_VERIFY;
395                 sizeRemaining = 0U;
396                 break;
397             }
398             /* update the roData */
399             roData = &(roData[4U]);
400             cnt++;
401             sizeRemaining -= 4U;
402         }
403     }
404 
405     /* Process remaining bytes one by one */
406     while (sizeRemaining > 0U)
407     {
408         /* Get next received word */
409         recvData = baseAddr->RBDR[cnt];
410         /* get wordSize for the loop */
411         wordSize = Qspi_Ip_GetWordSize(sizeRemaining);
412         for (byteCnt = 0U; byteCnt < wordSize; byteCnt++)
413         {
414 #if (defined(CORE_BIG_ENDIAN))
415             recvByte = (uint8)(recvData >> 24U);
416             recvData <<= 8U;
417 #else
418             recvByte = (uint8)(recvData & 0xFFU);
419             recvData >>= 8U;
420 #endif
421             /* return STATUS_QSPI_IP_ERROR_PROGRAM_VERIFY if the data is not match */
422             if (*roData != recvByte)
423             {
424                 status = STATUS_QSPI_IP_ERROR_PROGRAM_VERIFY;
425                 sizeRemaining = 0U;
426                 break;
427             }
428             else
429             {
430                 /* update the roData, sizeRemaining */
431                 roData++;
432                 sizeRemaining--;
433             }
434         }
435         cnt++;
436     }
437     return status;
438 }
439 
440 
441 /*FUNCTION**********************************************************************
442  *
443  * Function Name : Qspi_Ip_ProcessDataBlankCheck
444  * Description   : Processes blank check data
445  * @implements     Qspi_Ip_ProcessDataBlankCheck_Activity */
Qspi_Ip_ProcessDataBlankCheck(uint32 size,const QuadSPI_Type * baseAddr,uint32 padding)446 static inline Qspi_Ip_StatusType Qspi_Ip_ProcessDataBlankCheck(uint32 size,
447                                                                const QuadSPI_Type *baseAddr,
448                                                                uint32 padding
449                                                               )
450 {
451     uint32 cnt = 0U;
452     uint32 recvData = 0U;
453     Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
454     uint32 dataSize;
455     uint32 sizeRemaining = size;
456     uint32 paddingBytes = padding;
457 
458     if (0U != paddingBytes)
459     {
460         /* Ignore all padding words, jump to the fist data */
461         cnt            = paddingBytes >> 2U;
462         sizeRemaining -= cnt << 2U;
463         paddingBytes  &= 0x3U;
464 
465         /* Get first received word */
466         recvData = ~(baseAddr->RBDR[cnt]);
467         cnt++;
468         /* Get wordSize for the blank check */
469         dataSize = Qspi_Ip_GetWordSize(sizeRemaining);
470         sizeRemaining -= dataSize;
471 
472         /* Mask data: ignore padding at the beginning and unused bytes at the end */
473 #if (defined(CORE_BIG_ENDIAN))
474         recvData &= 0xFFFFFFFFUL << ((4UL - dataSize) * 8UL);
475         recvData &= 0xFFFFFFFFUL >> (paddingBytes * 8UL);
476 #else
477         recvData &= 0xFFFFFFFFUL >> ((4UL - dataSize) * 8UL);
478         recvData &= 0xFFFFFFFFUL << (paddingBytes * 8UL);
479 #endif
480         if (recvData != 0U)
481         {
482             /* The data is not blank */
483             status = STATUS_QSPI_IP_ERROR;
484             sizeRemaining = 0U;
485         }
486     }
487 
488     /* Blank check */
489     while (sizeRemaining >= 4U)
490     {
491         if (baseAddr->RBDR[cnt] != 0xFFFFFFFFU)
492         {
493             /* The data is not blank */
494             status = STATUS_QSPI_IP_ERROR;
495             sizeRemaining = 0U;
496             break;
497         }
498         cnt++;
499         sizeRemaining -= 4U;
500     }
501 
502     if (sizeRemaining != 0U)
503     {
504         /* Process last few bytes */
505         recvData = baseAddr->RBDR[size >> 2U];
506 #if (defined(CORE_BIG_ENDIAN))
507         if ((~recvData & ~(((uint32)1U << (((uint32)4U - sizeRemaining) * 8U)) - 1U)) != 0U)
508 #else
509         if ((~recvData & (((uint32)1U << (sizeRemaining * 8U)) - 1U)) != 0U)
510 #endif
511         {
512             /* The data is not blank */
513             status = STATUS_QSPI_IP_ERROR;
514         }
515     }
516     return status;
517 }
518 
519 /*FUNCTION**********************************************************************
520  *
521  * Function Name : Qspi_Ip_FillTxBuf
522  * Description   : Fill Tx buffer with the specified number of 4-byte entries
523 * @implements      Qspi_Ip_FillTxBuf_Activity */
Qspi_Ip_FillTxBuf(QuadSPI_Type * baseAddr,const uint8 * roData,uint32 size,uint32 paddingInfo)524 static void Qspi_Ip_FillTxBuf(QuadSPI_Type *baseAddr,
525                               const uint8 *roData,
526                               uint32 size,
527                               uint32 paddingInfo
528                              )
529 {
530     uint32 sizeLeft = size;
531     uint32 wordSize;
532     uint32 data = 0xFFFFFFFFUL;
533     uint8 *dataPtr = (uint8 *)(&data);
534     uint32 byteCnt;
535     const uint8 * roDataPtr = roData;
536 
537     uint32 prePadding   = paddingInfo >> 4U;
538     uint32 postPadding  = paddingInfo & 0x0FU;
539 
540     /* Insert prePadding words */
541     while (prePadding >= 4U)
542     {
543         Qspi_Ip_WriteTxData(baseAddr, 0xFFFFFFFFUL);
544         prePadding -= 4U;
545     }
546 
547     if (prePadding != 0U)
548     {
549         wordSize = prePadding + sizeLeft;
550 
551         if (wordSize > 4U)
552         {
553             wordSize  = 4U;
554             sizeLeft -= (4U - prePadding);
555         }
556         else
557         {
558             /* Note for special case: prePadding + Data + postPadding are fit into a word
559                Decreaseing postPadding is not needed because out of user data, all branches below will be skipped
560              */
561             sizeLeft = 0U;
562         }
563 
564         /* Fill user data between prePadding and postPadding */
565         for (byteCnt = prePadding; byteCnt < wordSize; byteCnt++)
566         {
567             #if (defined(CORE_BIG_ENDIAN))
568             dataPtr[3U - byteCnt] = *roDataPtr;
569             #else
570             dataPtr[byteCnt] = *roDataPtr;
571             #endif
572 
573             roDataPtr++;
574         }
575         Qspi_Ip_WriteTxData(baseAddr, data);
576     }
577 
578     /* Check user buffer alignment */
579     if (((Qspi_Ip_UintPtrType)roDataPtr & 0x3U) == 0U)
580     {
581         /* Process 4 bytes at a time to speed things up */
582         while (sizeLeft >= 4U)
583         {
584             data = *(const uint32 *)((Qspi_Ip_UintPtrType)roDataPtr);  /* Casting through uint32 to avoid Misra 11.3 */
585             sizeLeft -= 4U;
586             roDataPtr = &(roDataPtr[4U]);
587             Qspi_Ip_WriteTxData(baseAddr, data);
588         }
589     }
590 
591     /* Process remaining bytes one by one */
592     while (sizeLeft > 0U)
593     {
594         /* Processes last few data bytes (less than 4) */
595         data = 0xFFFFFFFFUL;
596         wordSize = Qspi_Ip_GetWordSize(sizeLeft);
597 
598         for (byteCnt = 0U; byteCnt < wordSize; byteCnt++)
599         {
600             #if (defined(CORE_BIG_ENDIAN))
601             dataPtr[3U - byteCnt] = *roDataPtr;
602             #else
603             dataPtr[byteCnt] = *roDataPtr;
604             #endif
605 
606             roDataPtr++;
607         }
608         Qspi_Ip_WriteTxData(baseAddr, data);
609         sizeLeft -= wordSize;
610     }
611 
612     /* Insert postPadding words */
613     while (postPadding >= 4U)
614     {
615         Qspi_Ip_WriteTxData(baseAddr, 0xFFFFFFFFUL);
616         postPadding -= 4U;
617     }
618 }
619 
620 
621 /*FUNCTION**********************************************************************
622  *
623  * Function Name : Qspi_Ip_ErrorCheck
624  * Description   : Checks if there were errors during IP command execution
625 * @implements      Qspi_Ip_ErrorCheck_Activity */
Qspi_Ip_ErrorCheck(QuadSPI_Type * baseAddr)626 static inline Qspi_Ip_StatusType Qspi_Ip_ErrorCheck(QuadSPI_Type *baseAddr)
627 {
628     Qspi_Ip_StatusType status;
629 
630     if ((baseAddr->FR & QSPI_ERR_FLAGS_MASK) != 0U)
631     {
632         /* clear error flags */
633         baseAddr->FR = QSPI_ERR_FLAGS_MASK;
634         status = STATUS_QSPI_IP_ERROR;
635     }
636 #if (FEATURE_QSPI_HAS_SFP == 1)
637     else if (baseAddr->ERRSTAT != 0UL)
638     {
639         status = STATUS_QSPI_IP_ERROR;
640     }
641 #endif /* FEATURE_QSPI_HAS_SFP */
642     else
643     {
644         status = STATUS_QSPI_IP_SUCCESS;
645     }
646 
647     return status;
648 }
649 
650 
651 /*FUNCTION**********************************************************************
652  *
653  * Function Name : Qspi_Ip_SwResetDelay
654  * Description   : Insert waiting loops after changing the value of the software reset bits
655  */
Qspi_Ip_SwResetDelay(void)656 static inline void Qspi_Ip_SwResetDelay(void)
657 {
658     volatile uint32 u32CurrentTicks;
659     /* Prepare timeout counter */
660     u32CurrentTicks = QSPI_IP_SOFTWARE_RESET_DELAY;
661     /* Insert delay after changing the value of the software reset bits. */
662     while (u32CurrentTicks > 0U)
663     {
664         u32CurrentTicks--;
665     }
666 }
667 
668 
669 /*FUNCTION**********************************************************************
670  *
671  * Function Name : Qspi_Ip_SwReset
672  * Description   : Resets the QuadSPI device
673 * @implements      Qspi_Ip_SwReset_Activity */
Qspi_Ip_SwReset(QuadSPI_Type * baseAddr)674 static void Qspi_Ip_SwReset(QuadSPI_Type *baseAddr)
675 {
676     /* Software reset AHB domain and Serial Flash domain at the same time. */
677     Qspi_Ip_SwResetOn(baseAddr);
678     /* Insert delay after changing the value of the reset bits. */
679     Qspi_Ip_SwResetDelay();
680     /* Disable QuadSPI module before de-asserting the reset bits. */
681     Qspi_Ip_Disable(baseAddr);
682     /* De-asset Software reset AHB domain and Serial Flash domain bits. */
683     Qspi_Ip_SwResetOff(baseAddr);
684     /* Re-enable QuadSPI module after reset. */
685     Qspi_Ip_Enable(baseAddr);
686     /* Insert delay after changing the value of the reset bits. */
687     Qspi_Ip_SwResetDelay();
688 }
689 
690 /*FUNCTION**********************************************************************
691  *
692  * Function Name : Qspi_Ip_AhbFlush
693  * Description   : Reset AHB buffers
694  */
Qspi_Ip_AhbFlush(QuadSPI_Type * baseAddr)695 static void Qspi_Ip_AhbFlush(QuadSPI_Type *baseAddr)
696 {
697 #ifdef QuadSPI_SPTRCLR_ABRT_CLR_MASK
698     uint32  u32ElapsedTicks = 0UL;
699     uint32  u32TimeoutTicks;
700     uint32  u32CurrentTicks;
701 
702     /* Use the AHB buffer clear bit to avoid losing the DLL lock */
703     Qspi_Ip_ClearAhbBuf(baseAddr);
704 
705     /* Prepare timeout counter */
706     u32TimeoutTicks = OsIf_MicrosToTicks(QSPI_IP_CMD_COMPLETE_TIMEOUT, (OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
707     u32CurrentTicks = OsIf_GetCounter((OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
708 
709     /* Wait for clearing the AHB buffer pointers */
710     while (!Qspi_Ip_GetClrAhbStatus(baseAddr))
711     {
712         /* An exit point for safety purpose only, because this loop is not expected to happen in practice */
713         u32ElapsedTicks += OsIf_GetElapsed(&u32CurrentTicks, (OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
714         if ( u32ElapsedTicks >= u32TimeoutTicks )
715         {
716             break;
717         }
718     }
719 
720 #else
721     /* Otherwise use the software reset */
722     Qspi_Ip_SwReset(baseAddr);
723 #endif
724 }
725 
726 
727 /*FUNCTION**********************************************************************
728  *
729  * Function Name : Qspi_Ip_WaitDLLASlaveLock
730  * Description   : DLL side A - Wait for slave high lock status or DLL lock status
731  */
Qspi_Ip_WaitDLLASlaveLock(const QuadSPI_Type * baseAddr,boolean waitSlaveLock)732 static Qspi_Ip_StatusType Qspi_Ip_WaitDLLASlaveLock(const QuadSPI_Type *baseAddr,
733                                                     boolean waitSlaveLock
734                                                    )
735 {
736     Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
737     boolean LockStatus;
738 
739     /* Prepare timeout counter */
740     uint32 u32ElapsedTicks = 0UL;
741     uint32 u32TimeoutTicks = OsIf_MicrosToTicks(QSPI_IP_DLL_LOCK_TIMEOUT, (OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
742     uint32 u32CurrentTicks = OsIf_GetCounter((OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
743 
744     do
745     {
746         /* Wait for slave high lock status or DLL lock status */
747         LockStatus = (waitSlaveLock) ? Qspi_Ip_DLLGetSlaveLockStatusA(baseAddr) : Qspi_Ip_DLLGetLockStatusA(baseAddr);
748 
749         /* Check for errors reported by DLL */
750         if (Qspi_Ip_DLLGetErrorStatusA(baseAddr))
751         {
752             status = STATUS_QSPI_IP_ERROR;
753         }
754         else
755         {
756             /* Check for timeout */
757             u32ElapsedTicks += OsIf_GetElapsed(&u32CurrentTicks, (OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
758             if (u32ElapsedTicks >= u32TimeoutTicks)
759             {
760                 status = STATUS_QSPI_IP_TIMEOUT;
761             }
762         }
763 
764         if (STATUS_QSPI_IP_SUCCESS != status)
765         {
766             break;
767         }
768     }
769     while (!LockStatus);
770 
771     return status;
772 }
773 
774 /*FUNCTION**********************************************************************
775  *
776  * Function Name : Qspi_Ip_ConfigureDLLAByPass
777  * Description   : Configures DLL - Side A (bypass mode)
778  */
Qspi_Ip_ConfigureDLLAByPass(QuadSPI_Type * baseAddr,const Qspi_Ip_ControllerConfigType * userConfigPtr)779 static Qspi_Ip_StatusType Qspi_Ip_ConfigureDLLAByPass(QuadSPI_Type *baseAddr,
780                                                       const Qspi_Ip_ControllerConfigType *userConfigPtr
781                                                      )
782 {
783     Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
784 
785     /* Set DLL in bypass mode and configure coarse and fine delays */
786     Qspi_Ip_DLLSlaveBypassA(baseAddr, TRUE);
787 #ifdef QuadSPI_DLLCRA_SLAVE_AUTO_UPDT_MASK
788     Qspi_Ip_DLLSlaveAutoUpdateA(baseAddr, FALSE);
789 #endif /* QuadSPI_DLLCRA_SLAVE_AUTO_UPDT_MASK */
790     Qspi_Ip_DLLSetCoarseDelayA(baseAddr, userConfigPtr->dllSettingsA.coarseDelay);
791     Qspi_Ip_DLLSetFineOffsetA(baseAddr, userConfigPtr->dllSettingsA.fineDelay);
792     Qspi_Ip_DLLFreqEnA(baseAddr, userConfigPtr->dllSettingsA.freqEnable);
793 
794     /* Trigger slave chain update */
795     Qspi_Ip_DLLSlaveUpdateA(baseAddr, TRUE);
796 
797     /* Wait for slave delay chain update */
798     status = Qspi_Ip_WaitDLLASlaveLock(baseAddr, (boolean)TRUE);
799 
800     /* Disable slave chain update */
801     Qspi_Ip_DLLSlaveUpdateA(baseAddr, FALSE);
802 
803     return status;
804 }
805 
806 /*FUNCTION**********************************************************************
807  *
808  * Function Name : Qspi_Ip_ConfigureDLLAUpdate
809  * Description   : Configures DLL - Side A (manual update or auto update mode)
810  */
Qspi_Ip_ConfigureDLLAUpdate(QuadSPI_Type * baseAddr,const Qspi_Ip_ControllerConfigType * userConfigPtr)811 static Qspi_Ip_StatusType Qspi_Ip_ConfigureDLLAUpdate(QuadSPI_Type *baseAddr,
812                                                       const Qspi_Ip_ControllerConfigType *userConfigPtr
813                                                      )
814 {
815     Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
816 
817     /* Set DLL in auto update mode and configure coarse and fine delays */
818     Qspi_Ip_DLLSlaveBypassA(baseAddr, FALSE);
819 #ifdef QuadSPI_DLLCRA_SLAVE_AUTO_UPDT_MASK
820     Qspi_Ip_DLLSlaveAutoUpdateA(baseAddr, (QSPI_IP_DLL_AUTO_UPDATE == userConfigPtr->dllSettingsA.dllMode));
821 #endif /* QuadSPI_DLLCRA_SLAVE_AUTO_UPDT_MASK */
822     Qspi_Ip_DLLSetReferenceCounterA(baseAddr, userConfigPtr->dllSettingsA.referenceCounter);
823 #ifdef QuadSPI_DLLCRA_DLLRES_MASK
824     Qspi_Ip_DLLSetResolutionA(baseAddr, userConfigPtr->dllSettingsA.resolution);
825 #endif /* QuadSPI_DLLCRA_DLLRES_MASK */
826     Qspi_Ip_DLLSetCoarseOffsetA(baseAddr, userConfigPtr->dllSettingsA.coarseDelay);
827     Qspi_Ip_DLLSetFineOffsetA(baseAddr, userConfigPtr->dllSettingsA.fineDelay);
828     Qspi_Ip_DLLFreqEnA(baseAddr, userConfigPtr->dllSettingsA.freqEnable);
829 
830     if (QSPI_IP_DLL_AUTO_UPDATE == userConfigPtr->dllSettingsA.dllMode)
831     {
832         /* For auto update mode, trigger slave chain update */
833         Qspi_Ip_DLLSlaveUpdateA(baseAddr, TRUE);
834     }
835 #ifdef QuadSPI_DLLCRA_DLLEN_MASK
836     /* Enable DLL */
837     Qspi_Ip_DLLEnableA(baseAddr, TRUE);
838 #endif /* QuadSPI_DLLCRA_DLLEN_MASK */
839     if (QSPI_IP_DLL_MANUAL_UPDATE == userConfigPtr->dllSettingsA.dllMode)
840     {
841         /* For manual update mode, wait for DLL lock before triggering slave chain update */
842         status = Qspi_Ip_WaitDLLASlaveLock(baseAddr, (boolean)FALSE);
843 
844         Qspi_Ip_DLLSlaveUpdateA(baseAddr, TRUE);
845     }
846 
847     /* Wait for slave delay chain update */
848     if (STATUS_QSPI_IP_SUCCESS == status)
849     {
850         status = Qspi_Ip_WaitDLLASlaveLock(baseAddr, (boolean)TRUE);
851     }
852 
853     /* Disable slave chain update */
854     Qspi_Ip_DLLSlaveUpdateA(baseAddr, FALSE);
855 
856     return status;
857 }
858 
859 /*FUNCTION**********************************************************************
860  *
861  * Function Name : Qspi_Ip_ConfigureDLLA
862  * Description   : Configures DLL - Side A
863 * @implements      Qspi_Ip_ConfigureDLLA_Activity */
Qspi_Ip_ConfigureDLLA(uint32 instance,QuadSPI_Type * baseAddr,const Qspi_Ip_ControllerConfigType * userConfigPtr)864 static Qspi_Ip_StatusType Qspi_Ip_ConfigureDLLA(uint32 instance,
865                                                 QuadSPI_Type *baseAddr,
866                                                 const Qspi_Ip_ControllerConfigType *userConfigPtr
867                                                )
868 {
869     (void)instance;
870     Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
871 
872     /* Ensure DLL and slave chain update are off */
873     Qspi_Ip_DLLSlaveUpdateA(baseAddr, FALSE);
874 #ifdef QuadSPI_DLLCRA_DLLEN_MASK
875     Qspi_Ip_DLLEnableA(baseAddr, FALSE);
876 #endif /* QuadSPI_DLLCRA_DLLEN_MASK */
877 
878     /* Enable DQS slave delay chain before any settings take place */
879     Qspi_Ip_DLLSlaveEnA(baseAddr, TRUE);
880 
881     if (QSPI_IP_DLL_BYPASSED == userConfigPtr->dllSettingsA.dllMode)
882     {
883         status = Qspi_Ip_ConfigureDLLAByPass(baseAddr, userConfigPtr);
884     }
885     else /* QSPI_DLL_MANUAL_UPDATE or QSPI_DLL_AUTO_UPDATE */
886     {
887         status = Qspi_Ip_ConfigureDLLAUpdate(baseAddr, userConfigPtr);
888     }
889 
890     return status;
891 }
892 
893 
894 /*FUNCTION**********************************************************************
895  *
896  * Function Name : Qspi_Ip_ConfigureDLL
897  * Description   : Configure the DLL chain
898  *
899  *END**************************************************************************/
Qspi_Ip_ConfigureDLL(uint32 instance,const Qspi_Ip_ControllerConfigType * userConfigPtr)900 static Qspi_Ip_StatusType Qspi_Ip_ConfigureDLL(uint32 instance,
901                                                const Qspi_Ip_ControllerConfigType * userConfigPtr
902                                               )
903 {
904     Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
905     QuadSPI_Type *baseAddr = Qspi_Ip_BaseAddress[instance];
906 
907     /* Configure DLL */
908     if ((userConfigPtr->memSizeA1 + userConfigPtr->memSizeA2) > 0U)
909     {
910         status = Qspi_Ip_ConfigureDLLA(instance, baseAddr, userConfigPtr);
911     }
912 
913     return status;
914 }
915 
916 
917 /*FUNCTION**********************************************************************
918  *
919  * Function Name : Qspi_Ip_ConfigureChipOptions
920  * Description   : Configures chip-specific settings, e.g. SOCCR
921  ***********************************************************************/
922 #if defined(FEATURE_QSPI_CHIP_OPTIONS_S32K148)
Qspi_Ip_ConfigureChipOptions(QuadSPI_Type * baseAddr,const Qspi_Ip_ControllerConfigType * userConfigPtr)923 static void Qspi_Ip_ConfigureChipOptions(QuadSPI_Type *baseAddr,
924                                          const Qspi_Ip_ControllerConfigType *userConfigPtr
925                                         )
926 {
927     /* always enable pads input buffers */
928     uint8 clkOption = QSPI_MCR_SCLKCFG_INPUT_EN;
929     uint32 chipOption = 0U;
930 
931     /* Configure MCR_SCLKCFG options */
932     /* Configure module clock selection */
933     if (QSPI_IP_CLK_SRC_BUS_CLK == userConfigPtr->clockSrc)
934     {
935         clkOption |= QSPI_MCR_SCLKCFG_CLK_MOD;
936     }
937     /* Configure internal reference clock selection */
938     if (QSPI_IP_CLK_REF_FIRC_DIV1 == userConfigPtr->clockRef)
939     {
940         clkOption |= QSPI_MCR_SCLKCFG_CLK_SRC;
941     }
942     /* Configure external DQS mode for Flash B (HyperRAM Enabled) */
943     if (QSPI_IP_READ_MODE_EXTERNAL_DQS == userConfigPtr->readModeB)
944     {
945         clkOption |= QSPI_MCR_SCLKCFG_EXT_DQS;
946     }
947     /* Select reference clock for DQS for each side */
948     if (QSPI_IP_READ_MODE_LOOPBACK == userConfigPtr->readModeA)
949     {
950         clkOption |= (uint8)(QSPI_MCR_SCLKCFG_DQS_SEL_A);
951     }
952     if (QSPI_IP_READ_MODE_LOOPBACK == userConfigPtr->readModeB)
953     {
954         clkOption |= (uint8)(QSPI_MCR_SCLKCFG_DQS_SEL_B);
955     }
956     /* Configure inverted DQS: 0-Inverted / 1-Not Inverted */
957     if ((boolean)FALSE == userConfigPtr->dqsInvertA)
958     {
959         clkOption |= (uint8)(QSPI_MCR_SCLKCFG_DQS_INV_A);
960     }
961     if ((boolean)FALSE == userConfigPtr->dqsInvertB)
962     {
963         clkOption |= (uint8)(QSPI_MCR_SCLKCFG_DQS_INV_B);
964     }
965     Qspi_Ip_SetClockOptions(baseAddr, clkOption);
966 
967     /* Configure SOCCR options */
968     /* Disable divider before configuring it */
969     Qspi_Ip_SetChipOptions(baseAddr, QuadSPI_SOCCR_PDD_MASK);
970     chipOption |= QuadSPI_SOCCR_PD((uint32)userConfigPtr->clockRefDiv - 1U);
971     chipOption |= ((uint32)userConfigPtr->dqsDelayA << QuadSPI_SOCCR_DSQ_DEL_A) +
972                   ((uint32)userConfigPtr->dqsDelayB << QuadSPI_SOCCR_DSQ_DEL_B);
973     /* Write configuration, keep divider disabled */
974     Qspi_Ip_SetChipOptions(baseAddr, chipOption | QuadSPI_SOCCR_PDD_MASK);
975     /* Enable divider */
976     Qspi_Ip_SetChipOptions(baseAddr, chipOption);
977 }
978 
979 #elif defined(FEATURE_QSPI_CHIP_OPTIONS_S32K3)
Qspi_Ip_ConfigureChipOptions(QuadSPI_Type * baseAddr,const Qspi_Ip_ControllerConfigType * userConfigPtr)980 static void Qspi_Ip_ConfigureChipOptions(QuadSPI_Type *baseAddr, const Qspi_Ip_ControllerConfigType * userConfigPtr)
981 {
982     (void)userConfigPtr;
983     Qspi_Ip_SetChipOptions(baseAddr, 0x0000000E);  /* set ibe=1, obe=1, dse=1 and sre=0 */
984 }
985 
986 #else
Qspi_Ip_ConfigureChipOptions(const QuadSPI_Type * baseAddr,const Qspi_Ip_ControllerConfigType * userConfigPtr)987 static void Qspi_Ip_ConfigureChipOptions(const QuadSPI_Type *baseAddr, const Qspi_Ip_ControllerConfigType * userConfigPtr)
988 {
989     /* Do nothing */
990     (void)userConfigPtr;
991     (void)baseAddr;
992 }
993 #endif
994 
995 
996 /*FUNCTION**********************************************************************
997  *
998  * Function Name : Qspi_Ip_ConfigureReadOptions
999  * Description   : Configures data read settings
1000 * @implements      Qspi_Ip_ConfigureReadOptions_Activity */
Qspi_Ip_ConfigureReadOptions(QuadSPI_Type * baseAddr,const Qspi_Ip_ControllerConfigType * userConfigPtr)1001 static void Qspi_Ip_ConfigureReadOptions(QuadSPI_Type *baseAddr,
1002                                          const Qspi_Ip_ControllerConfigType *userConfigPtr
1003                                         )
1004 {
1005     /* Always enable DQS */
1006     QSPI_DQS_Enable(baseAddr);
1007 
1008     if (QSPI_IP_DATA_RATE_SDR == userConfigPtr->dataRate)
1009     {
1010 #ifdef QuadSPI_MCR_DDR_EN_MASK
1011         QSPI_DDR_Disable(baseAddr);
1012 #endif /* QuadSPI_MCR_DDR_EN_MASK */
1013 #ifdef QuadSPI_FLSHCR_TDH_MASK
1014         /* Ignore output data align setting in SDR mode */
1015         Qspi_Ip_SetDataInHoldTime(baseAddr, QSPI_IP_FLASH_DATA_ALIGN_REFCLK);
1016 #endif /* QuadSPI_FLSHCR_TDH_MASK */
1017     }
1018     else  /* QSPI_IP_DATA_RATE_DDR */
1019     {
1020 #ifdef QuadSPI_MCR_DDR_EN_MASK
1021         QSPI_DDR_Enable(baseAddr);
1022 #endif /* QuadSPI_MCR_DDR_EN_MASK */
1023 #ifdef QuadSPI_FLSHCR_TDH_MASK
1024         Qspi_Ip_SetDataInHoldTime(baseAddr, userConfigPtr->dataAlign);
1025 #endif /* QuadSPI_FLSHCR_TDH_MASK */
1026     }
1027 
1028     /* select DQS A source (internal/loopback/external) */
1029     Qspi_Ip_SetDQSSourceA(baseAddr, userConfigPtr->readModeA);
1030 
1031     /* Select DLL tap in SMPR register */
1032     Qspi_Ip_SetRxDLLTapA(baseAddr, userConfigPtr->dllSettingsA.tapSelect);
1033 
1034 
1035     (void)userConfigPtr;
1036 }
1037 
1038 
1039 /*FUNCTION**********************************************************************
1040  *
1041  * Function Name : Qspi_Ip_AhbSetup
1042  * Description   : Sets up AHB accesses to the serial flash
1043 * @implements      Qspi_Ip_AhbSetup_Activity */
Qspi_Ip_AhbSetup(uint32 instance,const Qspi_Ip_ControllerAhbConfigType * config)1044 static Qspi_Ip_StatusType Qspi_Ip_AhbSetup(uint32 instance,
1045                                            const Qspi_Ip_ControllerAhbConfigType *config
1046                                           )
1047 {
1048     QuadSPI_Type *baseAddr;
1049 
1050     DEV_ASSERT_QSPI(instance < QuadSPI_INSTANCE_COUNT);
1051     DEV_ASSERT_QSPI(0U == (config->sizes[0U] & 7U));
1052     DEV_ASSERT_QSPI(((uint32)config->sizes[0U] +
1053                (uint32)config->sizes[1U] +
1054                (uint32)config->sizes[2U] +
1055                (uint32)config->sizes[3U]) <= FEATURE_QSPI_AHB_BUF_SIZE);
1056     /* Get base address of instance */
1057     baseAddr = Qspi_Ip_BaseAddress[instance];
1058 
1059     /* configure AHB transfer sizes to match the buffer sizes */
1060     /* Set AHB buffer 0 */
1061     Qspi_Ip_SetAhbBuf0(baseAddr, config->sizes[0U], config->masters[0U]);
1062     /* Set AHB buffer 1 */
1063     Qspi_Ip_SetAhbBuf1(baseAddr, config->sizes[1U], config->masters[1U]);
1064     /* Set AHB buffer 2 */
1065     Qspi_Ip_SetAhbBuf2(baseAddr, config->sizes[2U], config->masters[2U]);
1066     /* Set AHB buffer 3 */
1067     Qspi_Ip_SetAhbBuf3(baseAddr, config->sizes[3U], config->masters[3U], config->allMasters);
1068     /* Set AHB buffer index 0 */
1069     Qspi_Ip_SetAhbBuf0Ind(baseAddr, (uint32)config->sizes[0U]);
1070     /* Set AHB buffer index 1 */
1071     Qspi_Ip_SetAhbBuf1Ind(baseAddr, (uint32)config->sizes[0U] + (uint32)config->sizes[1U]);
1072     /* Set AHB buffer index 2 */
1073     Qspi_Ip_SetAhbBuf2Ind(baseAddr, (uint32)config->sizes[0U] + (uint32)config->sizes[1U] + (uint32)config->sizes[2U]);
1074 
1075     return STATUS_QSPI_IP_SUCCESS;
1076 }
1077 
1078 /** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1079  * @brief Program the SFAR & IPCR registers.
1080  *
1081  * @param[in] BaseAddress base address of the given QuadSPI instance
1082  * @param[in] Address address to be written into SFAR
1083  * @param[in] DataSize data size to be written into IPCR
1084  * @param[in] SeqId sequence id where the command is stored in the physical lut
1085  *
1086  * @retval STATUS_QSPI_IP_SUCCESS SFAR and IPCR writes passed the MDAD checks
1087  * @retval STATUS_QSPI_IP_ERROR a common or a queue error has occurred
1088  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
Qspi_Ip_NewIpsTransaction(QuadSPI_Type * BaseAddress,uint32 Address,uint16 DataSize,uint8 SeqId)1089 static void Qspi_Ip_NewIpsTransaction
1090 (
1091     QuadSPI_Type * BaseAddress,
1092     uint32 Address,
1093     uint16 DataSize,
1094     uint8 SeqId)
1095 {
1096     #if (FEATURE_QSPI_HAS_SFP == 1)
1097     Qspi_Ip_Sfp_ClearLatchedErrors(BaseAddress);
1098     #endif
1099 
1100     Qspi_Ip_SetIpAddr(BaseAddress, Address);
1101     Qspi_Ip_IpTrigger(BaseAddress, SeqId, DataSize);
1102 }
1103 
1104 #if (FEATURE_QSPI_HAS_SFP == 1)
1105 
1106 /** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1107  * @brief Clear the errors latched in SFP registers.
1108  *
1109  * Error Status (ERRSTAT):
1110  * - FRADn Access Error (FRADnACC)
1111  * - No FRAD Match Error (FRADMTCH)
1112  * FlashSeq Request (FLSEQREQ):
1113  * - Clear (CLR)
1114  * IPS Error (IPSERROR):
1115  * - Clear (CLR)
1116  * Target Group n SFAR Status (TG0SFARS - TG1SFARS):
1117  * - Clear (CLR)
1118  * Target Group n IPCR Status (TG0IPCRS - TG1IPCRS):
1119  * - Clear (CLR)
1120  *
1121  * @param[in] BaseAddr base address of the given QuadSPI instance
1122  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
Qspi_Ip_Sfp_ClearLatchedErrors_Privileged(QuadSPI_Type * BaseAddr)1123 void Qspi_Ip_Sfp_ClearLatchedErrors_Privileged
1124 (
1125     QuadSPI_Type * BaseAddr)
1126 {
1127     BaseAddr->ERRSTAT |= 0x1FFUL;
1128     BaseAddr->FLSEQREQ |= QuadSPI_FLSEQREQ_CLR_MASK;
1129     BaseAddr->IPSERROR |= QuadSPI_IPSERROR_CLR_MASK;
1130 
1131     for (uint8 Mdad = 0U; Mdad < QuadSPI_MDAD_COUNT; ++Mdad)
1132     {
1133         BaseAddr->MDAD[Mdad].TGSFARS |= QuadSPI_TGSFARS_CLR_MASK;
1134         BaseAddr->MDAD[Mdad].TGIPCRS |= QuadSPI_TGIPCRS_CLR_MASK;
1135     }
1136 }
1137 
1138 /** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1139  * @brief Wait for the current transaction to reach a given state
1140  *
1141  * @param[in] BaseAddress base address of the given QuadSPI instance
1142  * @param[in] State the STATE field value that is to be expected
1143  *
1144  * @retval STATUS_QSPI_IP_SUCCESS
1145  * @retval STATUS_QSPI_IP_TIMEOUT
1146  * @retval STATUS_QSPI_IP_ERROR
1147  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
Qspi_Ip_Sfp_WaitFsmState(QuadSPI_Type const * BaseAddress,uint32 State)1148 static Qspi_Ip_StatusType Qspi_Ip_Sfp_WaitFsmState
1149 (
1150     QuadSPI_Type const * BaseAddress,
1151     uint32 State)
1152 {
1153     Qspi_Ip_StatusType Status = STATUS_QSPI_IP_ERROR;
1154     uint32 FsmStat = 0U;
1155     uint32 FsmStatValid = 0U;
1156     uint32 FsmStatState = 0U;
1157     uint32 ElapsedTicks = 0U;
1158     uint32 TimeoutTicks = OsIf_MicrosToTicks(QSPI_IP_QSPI_IDLE_TIMEOUT, QSPI_IP_TIMEOUT_TYPE);;
1159     uint32 CurrentTicks = OsIf_GetCounter(QSPI_IP_TIMEOUT_TYPE);;
1160 
1161     do
1162     {
1163         FsmStat = BaseAddress->FSMSTAT;
1164         FsmStatValid = (FsmStat & QuadSPI_FSMSTAT_VLD_MASK) >> QuadSPI_FSMSTAT_VLD_SHIFT;
1165         FsmStatState = (FsmStat & QuadSPI_FSMSTAT_STATE_MASK) >> QuadSPI_FSMSTAT_STATE_SHIFT;
1166         if ((FsmStatValid != 0U) && (FsmStatState == State))
1167         {
1168             Status = STATUS_QSPI_IP_SUCCESS;
1169             break;
1170         }
1171 
1172         ElapsedTicks += OsIf_GetElapsed(&CurrentTicks, QSPI_IP_TIMEOUT_TYPE);
1173     } while (ElapsedTicks < TimeoutTicks);
1174 
1175     if (ElapsedTicks >= TimeoutTicks)
1176     {
1177         Status = STATUS_QSPI_IP_TIMEOUT;
1178     }
1179 
1180     return Status;
1181 }
1182 
1183 #endif /* FEATURE_QSPI_HAS_SFP */
1184 
1185 /*! @endcond */
1186 
1187 /*******************************************************************************
1188  * Code
1189  ******************************************************************************/
1190 
1191 /*FUNCTION**********************************************************************
1192  *
1193  * Function Name : Qspi_Ip_SetLut
1194  * Description   : Configures a pair of LUT commands in the specified LUT register
1195  *
1196  *END**************************************************************************/
Qspi_Ip_SetLut(uint32 instance,uint8 LutRegister,Qspi_Ip_InstrOpType operation0,Qspi_Ip_InstrOpType operation1)1197 void Qspi_Ip_SetLut(uint32 instance,
1198                     uint8 LutRegister,
1199                     Qspi_Ip_InstrOpType operation0,
1200                     Qspi_Ip_InstrOpType operation1
1201                    )
1202 {
1203     QuadSPI_Type *baseAddr;
1204 
1205     DEV_ASSERT_QSPI(instance < QuadSPI_INSTANCE_COUNT);
1206     DEV_ASSERT_QSPI(LutRegister < QuadSPI_LUT_COUNT);
1207     baseAddr = Qspi_Ip_BaseAddress[instance];
1208     baseAddr->LUT[LutRegister] = QSPI_IP_PACK_LUT_REG(operation0, operation1);
1209 }
1210 
1211 
1212 /*FUNCTION**********************************************************************
1213  *
1214  * Function Name : Qspi_Ip_WriteLuts_Privileged
1215  * Description   : Configures pairs of LUT commands from the specified LUT register
1216  *
1217  *END**************************************************************************/
Qspi_Ip_WriteLuts_Privileged(uint32 Instance,uint8 StartLutRegister,const uint32 * Data,uint8 Size)1218 void Qspi_Ip_WriteLuts_Privileged(uint32 Instance,
1219                                   uint8 StartLutRegister,
1220                                   const uint32 *Data,
1221                                   uint8 Size
1222                                  )
1223 {
1224     DEV_ASSERT_QSPI(Instance < QuadSPI_INSTANCE_COUNT);
1225     DEV_ASSERT_QSPI(StartLutRegister < QuadSPI_LUT_COUNT);
1226     DEV_ASSERT_QSPI(Size <= FEATURE_QSPI_LUT_SEQUENCE_SIZE);
1227     DEV_ASSERT_QSPI((StartLutRegister + Size) <= QuadSPI_LUT_COUNT);
1228 
1229     QuadSPI_Type *BaseAddr = Qspi_Ip_BaseAddress[Instance];
1230     uint8 Idx;
1231 
1232     for (Idx = 0U; Idx < Size; Idx++)
1233     {
1234         BaseAddr->LUT[StartLutRegister + Idx] = Data[Idx];
1235     }
1236 }
1237 
1238 
1239 /*FUNCTION**********************************************************************
1240  *
1241  * Function Name : Qspi_Ip_SetAhbSeqId_Privileged
1242  * Description   : Sets sequence ID for AHB operations
1243  *
1244  *END**************************************************************************/
Qspi_Ip_SetAhbSeqId_Privileged(uint32 instance,uint8 seqID)1245 void Qspi_Ip_SetAhbSeqId_Privileged(uint32 instance,
1246                                     uint8 seqID
1247                                    )
1248 {
1249     QuadSPI_Type *baseAddr;
1250 
1251     DEV_ASSERT_QSPI(instance < QuadSPI_INSTANCE_COUNT);
1252     baseAddr = Qspi_Ip_BaseAddress[instance];
1253     baseAddr->BFGENCR =  QuadSPI_BFGENCR_SEQID(seqID);
1254 }
1255 
1256 
1257 /*FUNCTION**********************************************************************
1258  *
1259  * Function Name : Qspi_Ip_SetSerialFlashAddr
1260  * Description   : Configure the Serial Flash Memory Address
1261  *
1262  *END**************************************************************************/
Qspi_Ip_SetSerialFlashAddress(QuadSPI_Type * baseAddr,const Qspi_Ip_ControllerConfigType * userConfigPtr)1263 static inline void Qspi_Ip_SetSerialFlashAddress(QuadSPI_Type *baseAddr,
1264                                                  const Qspi_Ip_ControllerConfigType * userConfigPtr
1265                                                 )
1266 {
1267     Qspi_Ip_SetAddrOptions(baseAddr, userConfigPtr->columnAddr, userConfigPtr->wordAddresable);
1268 
1269     Qspi_Ip_SetByteSwap(baseAddr, userConfigPtr->byteSwap);
1270 }
1271 
1272 
1273 /*FUNCTION**********************************************************************
1274  *
1275  * Function Name : Qspi_Ip_SetCsTime
1276  * Description   : Configure the CS holdtime and CS setup time
1277  *
1278  *END**************************************************************************/
Qspi_Ip_SetCsTime(QuadSPI_Type * baseAddr,const Qspi_Ip_ControllerConfigType * userConfigPtr)1279 static inline void Qspi_Ip_SetCsTime(QuadSPI_Type *baseAddr,
1280                                      const Qspi_Ip_ControllerConfigType * userConfigPtr
1281                                     )
1282 {
1283     /* Configure the CS holdtime and CS setup time */
1284     Qspi_Ip_SetCsHoldTime(baseAddr, userConfigPtr->csHoldTime);
1285     Qspi_Ip_SetCsSetupTime(baseAddr, userConfigPtr->csSetupTime);
1286 }
1287 
1288 
1289 /*FUNCTION**********************************************************************
1290  *
1291  * Function Name : Qspi_Ip_ConfigureBuffers
1292  * Description   : Configure the Tx, Rx and AHB buffers
1293  *
1294  *END**************************************************************************/
Qspi_Ip_ConfigureBuffers(uint32 instance,QuadSPI_Type * baseAddr,const Qspi_Ip_ControllerConfigType * userConfigPtr)1295 static inline void Qspi_Ip_ConfigureBuffers(uint32 instance,
1296                                             QuadSPI_Type *baseAddr,
1297                                             const Qspi_Ip_ControllerConfigType * userConfigPtr
1298                                            )
1299 {
1300 #ifdef QuadSPI_RBCT_RXBRD_MASK
1301     /* Read Rx buffer through RBDR registers */
1302     Qspi_Ip_SetRxBufReadout(baseAddr, QSPI_IP_RX_READOUT_IP);
1303 #endif
1304     /* Set watermarks */
1305     Qspi_Ip_SetTxWatermark(baseAddr, 1U);
1306     Qspi_Ip_SetRxWatermark(baseAddr, 1U);
1307     /* Configure AHB buffers settings */
1308     (void)Qspi_Ip_AhbSetup(instance, &(userConfigPtr->ahbConfig));
1309 }
1310 
1311 
1312 /*FUNCTION**********************************************************************
1313  *
1314  * Function Name : Qspi_Ip_ConfigureControllerA
1315  * Description   : Configure for side A
1316  *
1317  *END**************************************************************************/
Qspi_Ip_ConfigureControllerA(uint32 instance,const Qspi_Ip_ControllerConfigType * userConfigPtr)1318 static inline void Qspi_Ip_ConfigureControllerA(uint32 instance,
1319                                                 const Qspi_Ip_ControllerConfigType *userConfigPtr)
1320 {
1321     QuadSPI_Type *baseAddr = Qspi_Ip_BaseAddress[instance];
1322 
1323     /* Configure external flash memory map Size A */
1324     Qspi_Ip_SetMemMapSizeA(instance, baseAddr, userConfigPtr->memSizeA1, userConfigPtr->memSizeA2);
1325 
1326     /* Configure idle line value side A */
1327     Qspi_Ip_SetIdleLineValuesA(baseAddr, userConfigPtr->io2IdleValueA, userConfigPtr->io3IdleValueA);
1328 
1329 
1330 }
1331 
1332 
1333 
1334 
1335 /*FUNCTION**********************************************************************
1336  *
1337  * Function Name : Qspi_Ip_ConfigureController
1338  * Description   : Configure the controller register following user configurations
1339  *
1340  *END**************************************************************************/
Qspi_Ip_ConfigureController(uint32 instance,const Qspi_Ip_ControllerConfigType * userConfigPtr)1341 static inline void Qspi_Ip_ConfigureController(uint32 instance,
1342                                                const Qspi_Ip_ControllerConfigType * userConfigPtr
1343                                               )
1344 {
1345     QuadSPI_Type *baseAddr = Qspi_Ip_BaseAddress[instance];
1346 
1347     Qspi_Ip_ConfigureControllerA(instance, userConfigPtr);
1348 
1349 
1350     /* Configure the Serial Flash Memory Address */
1351     Qspi_Ip_SetSerialFlashAddress(baseAddr, userConfigPtr);
1352 
1353     Qspi_Ip_SetRxCfg(baseAddr, userConfigPtr->sampleDelay, userConfigPtr->samplePhase);
1354 
1355     /* Configure the CS holdtime and CS setup time */
1356     Qspi_Ip_SetCsTime(baseAddr, userConfigPtr);
1357 
1358     /* Configure buffers */
1359     Qspi_Ip_ConfigureBuffers(instance, baseAddr, userConfigPtr);
1360 
1361     /* Configure read options */
1362     Qspi_Ip_ConfigureReadOptions(baseAddr, userConfigPtr);
1363 
1364     /* Configure chip-specific options */
1365     Qspi_Ip_ConfigureChipOptions(baseAddr, userConfigPtr);
1366 
1367     #if (FEATURE_QSPI_HAS_SFP == 1)
1368     Qspi_Ip_Sfp_Configure(baseAddr, userConfigPtr);
1369     #endif
1370 }
1371 
1372 
1373 /*FUNCTION**********************************************************************
1374  *
1375  * Function Name : Qspi_Ip_ControllerInit
1376  * Description   : Initializes the qspi controller
1377  * @implements     Qspi_Ip_ControllerInit_Activity */
Qspi_Ip_ControllerInit(uint32 instance,const Qspi_Ip_ControllerConfigType * userConfigPtr)1378 Qspi_Ip_StatusType Qspi_Ip_ControllerInit(uint32 instance,
1379                                           const Qspi_Ip_ControllerConfigType * userConfigPtr
1380                                          )
1381 {
1382     QuadSPI_Type *baseAddr;
1383     Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
1384 
1385     DEV_ASSERT_QSPI(instance < QuadSPI_INSTANCE_COUNT);
1386     DEV_ASSERT_QSPI(userConfigPtr != NULL_PTR);
1387     /* Initialize driver status structure */
1388 
1389     baseAddr = Qspi_Ip_BaseAddress[instance];
1390 
1391     /* Ensure module is disabled */
1392     Qspi_Ip_Disable(baseAddr);
1393 
1394     /* Ensure all registers contain their reset value */
1395     Qspi_Ip_ResetAllRegisters(baseAddr);
1396 
1397     /* Configure the controller following the user configurations */
1398     Qspi_Ip_ConfigureController(instance, userConfigPtr);
1399 
1400     /* Enable QuadSPI module */
1401     Qspi_Ip_Enable(baseAddr);
1402 
1403     /* Reset serial flash and AHB domains */
1404     Qspi_Ip_SwReset(baseAddr);
1405 
1406     /* Store user configuration for runtime usage */
1407     Qspi_Ip_ControllerConfig[instance] = userConfigPtr;
1408     /* Configure the DLL */
1409     status = Qspi_Ip_ConfigureDLL(instance, userConfigPtr);
1410 
1411     /* Workaround to clear CRC and ECC errors flags */
1412     baseAddr->FR = (uint32)0xFFFFFFFFUL;
1413 
1414     return status;
1415 }
1416 
1417 
1418 /*FUNCTION**********************************************************************
1419  *
1420  * Function Name : Qspi_Ip_ControllerDeinit
1421  * Description   : De-initialize the qspi driver
1422  * @implements     Qspi_Ip_ControllerDeinit_Activity */
Qspi_Ip_ControllerDeinit(uint32 instance)1423 Qspi_Ip_StatusType Qspi_Ip_ControllerDeinit(uint32 instance)
1424 {
1425     QuadSPI_Type *baseAddr;
1426 
1427     DEV_ASSERT_QSPI(instance < QuadSPI_INSTANCE_COUNT);
1428     baseAddr = Qspi_Ip_BaseAddress[instance];
1429 
1430     /* Disable QuadSPI module */
1431     Qspi_Ip_Disable(baseAddr);
1432 
1433     /* Detach the configuration pointer */
1434     Qspi_Ip_ControllerConfig[instance] = NULL_PTR;
1435 
1436     return STATUS_QSPI_IP_SUCCESS;
1437 }
1438 
1439 /*FUNCTION**********************************************************************
1440  *
1441  * Function Name : Qspi_Ip_Abort
1442  * Description   : Force the Qspi controller to cancel any on-going transactions by performing the software reset requence.
1443  *                 This can be used to recover the hardware controller from being stuck in BUSY state.
1444  *                 Re-configure DLL is needed to avoid side-effects on the DLL after the S/W reset.
1445  */
Qspi_Ip_Abort(uint32 instance)1446 Qspi_Ip_StatusType Qspi_Ip_Abort(uint32 instance)
1447 {
1448     DEV_ASSERT_QSPI(instance < QuadSPI_INSTANCE_COUNT);
1449 
1450     QuadSPI_Type *baseAddr = Qspi_Ip_BaseAddress[instance];
1451     Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
1452 
1453     /* Reset serial flash and AHB domains */
1454     Qspi_Ip_SwReset(baseAddr);
1455 
1456     /* S/W reset would also loose any Slave-chain upate, therefore re-configure DLL sequence is needed */
1457     if (Qspi_Ip_ControllerConfig[instance] != NULL_PTR)
1458     {
1459         /* Perform the DLL config only if the user configuration is available.
1460            Because there will be the case when user skip the controller configuration at initialization time.
1461          */
1462         status = Qspi_Ip_ConfigureDLL(instance, Qspi_Ip_ControllerConfig[instance]);
1463     }
1464 
1465     return status;
1466 }
1467 
1468 
1469 /*FUNCTION**********************************************************************
1470  *
1471  * Function Name : Qspi_Ip_GetBaseAdress
1472  * Description   : Returns the physical base address of a flash device on the AHB bus.
1473  *                 The controller must be initialized prior to calling this function.
1474  * @implements     Qspi_Ip_GetBaseAdress_Activity */
Qspi_Ip_GetBaseAdress(uint32 instance,Qspi_Ip_ConnectionType connectionType)1475 uint32 Qspi_Ip_GetBaseAdress(uint32 instance,
1476                              Qspi_Ip_ConnectionType connectionType
1477                             )
1478 {
1479     const QuadSPI_Type *baseAddr;
1480     uint32 address = 0U;
1481 
1482     DEV_ASSERT_QSPI(instance < QuadSPI_INSTANCE_COUNT);
1483     /* get the base address base on the instance */
1484     baseAddr = Qspi_Ip_BaseAddress[instance];
1485 
1486     switch (connectionType)
1487     {
1488         case QSPI_IP_SIDE_A1:
1489             /* get base address of side A1 */
1490             address = Qspi_Ip_AhbAddress[instance];
1491             break;
1492         case QSPI_IP_SIDE_A2:
1493             /* get base address of side A2 */
1494             address = baseAddr->SFA1AD;
1495             break;
1496         default:
1497             ; /* Not possible */
1498             break;
1499     }
1500 
1501     return address;
1502 }
1503 
1504 /*FUNCTION**********************************************************************
1505  *
1506  * Function Name : Qspi_Ip_IpCommand
1507  * Description   : Launches a simple IP command
1508  * @implements     Qspi_Ip_IpCommand_Activity */
Qspi_Ip_IpCommand(uint32 instance,uint8 SeqId,uint32 addr)1509 Qspi_Ip_StatusType Qspi_Ip_IpCommand(uint32 instance,
1510                                      uint8 SeqId,
1511                                      uint32 addr
1512                                     )
1513 {
1514     QuadSPI_Type *baseAddr;
1515     Qspi_Ip_StatusType status;
1516 
1517     DEV_ASSERT_QSPI(instance < QuadSPI_INSTANCE_COUNT);
1518     DEV_ASSERT_QSPI(SeqId < (QuadSPI_LUT_COUNT / FEATURE_QSPI_LUT_SEQUENCE_SIZE));
1519     baseAddr = Qspi_Ip_BaseAddress[instance];
1520 
1521     /* Reset AHB buffers to force re-read from memory after erase operation */
1522     Qspi_Ip_AhbFlush(baseAddr);
1523 
1524     /* Launch the IP command */
1525     Qspi_Ip_NewIpsTransaction(baseAddr, addr, 0U, SeqId);
1526 
1527     /* Add Fault Injection point for FR_ILLINE flag */
1528     MCAL_FAULT_INJECTION_POINT(FLS_FIP_FR_ERROR_IPCOMMAND);
1529 
1530     status = Qspi_Ip_CmdWaitComplete(instance);
1531 
1532     /* Make sure there is no garbage in Rx fifo in case of triggering a dummy READ instruction.
1533        This clears RBSR[RDBFL] to ensure QuadSPI is idle from SFP point of view and avoid the Master timeout error.
1534      */
1535     Qspi_Ip_ClearRxBuf(baseAddr);
1536 
1537     return status;
1538 }
1539 
1540 /*FUNCTION**********************************************************************
1541  *
1542  * Function Name : Qspi_Ip_CmdWaitComplete
1543  * Description   : Wait until Qspi controller is not busy or timeout
1544  */
Qspi_Ip_CmdWaitComplete(uint32 instance)1545 static Qspi_Ip_StatusType Qspi_Ip_CmdWaitComplete(uint32 instance)
1546 {
1547     Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
1548     uint32  u32ElapsedTicks = 0UL;
1549     uint32  u32TimeoutTicks;
1550     uint32  u32CurrentTicks;
1551 
1552     /* Prepare timeout counter */
1553     u32TimeoutTicks = OsIf_MicrosToTicks(QSPI_IP_CMD_COMPLETE_TIMEOUT, (OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
1554     u32CurrentTicks = OsIf_GetCounter((OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
1555 
1556     MCAL_FAULT_INJECTION_POINT(QSPI_IP_FMEA_WAIT_TRANSACTION_COMPLETE);
1557 
1558     /* Wait for command to be completed */
1559     do
1560     {
1561         u32ElapsedTicks += OsIf_GetElapsed(&u32CurrentTicks, (OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
1562         status = Qspi_Ip_ControllerGetStatus(instance);
1563     }
1564     while ((u32ElapsedTicks < u32TimeoutTicks) && (STATUS_QSPI_IP_BUSY == status));
1565 
1566     if (STATUS_QSPI_IP_BUSY == status)
1567     {
1568         status = STATUS_QSPI_IP_TIMEOUT;
1569     }
1570 
1571     return status;
1572 }
1573 
1574 /*FUNCTION**********************************************************************
1575  *
1576  * Function Name : Qspi_Ip_IpRead
1577  * Description   : Launches an IP read command
1578  * @implements     Qspi_Ip_IpRead_Activity */
Qspi_Ip_IpRead(uint32 instance,uint8 SeqId,uint32 addr,uint8 * dataRead,const uint8 * dataCmp,uint32 size)1579 Qspi_Ip_StatusType Qspi_Ip_IpRead(uint32 instance,
1580                                   uint8 SeqId,
1581                                   uint32 addr,
1582                                   uint8 * dataRead,
1583                                   const uint8 * dataCmp,
1584                                   uint32 size
1585                                  )
1586 {
1587     Qspi_Ip_StatusType status = STATUS_QSPI_IP_ERROR;
1588     QuadSPI_Type *baseAddr;
1589     uint32 padding;
1590     uint16 Idatsz = 0U;
1591 
1592     DEV_ASSERT_QSPI(instance < QuadSPI_INSTANCE_COUNT);
1593     DEV_ASSERT_QSPI(SeqId < (QuadSPI_LUT_COUNT / FEATURE_QSPI_LUT_SEQUENCE_SIZE));
1594     DEV_ASSERT_QSPI(size <= FEATURE_QSPI_RX_BUF_SIZE);
1595 
1596     baseAddr = Qspi_Ip_BaseAddress[instance];
1597     padding  = (uint32)(Qspi_Ip_MemoryPadding[instance]);
1598 
1599     /* If size is odd, round up to even size; this is needed in octal DDR mode */
1600     Idatsz = (uint16)((size + 1U) & (~1U));
1601 
1602     /* Make sure there is no garbage in Rx fifo */
1603     Qspi_Ip_ClearRxBuf(baseAddr);
1604 
1605     Qspi_Ip_NewIpsTransaction(baseAddr, addr, Idatsz, SeqId);
1606 
1607     /* Add Fault Injection point for FR_ILLINE flag */
1608     MCAL_FAULT_INJECTION_POINT(FLS_FIP_FR_ERROR_IPREAD);
1609 
1610     /* Wait until the command is sent */
1611     status = Qspi_Ip_CmdWaitComplete(instance);
1612 
1613     if (STATUS_QSPI_IP_SUCCESS == status)
1614     {
1615         /* Process received data */
1616         if (dataRead != NULL_PTR)
1617         {
1618             /* Normal read */
1619             status = Qspi_Ip_ProcessDataRead(dataRead, size, baseAddr, padding);
1620         }
1621         else if (dataCmp != NULL_PTR)
1622         {
1623             /* Verify */
1624             status = Qspi_Ip_ProcessDataVerify(dataCmp, size, baseAddr, padding);
1625         }
1626         else
1627         {
1628             /* Blank check */
1629             status = Qspi_Ip_ProcessDataBlankCheck(size, baseAddr, padding);
1630         }
1631     }
1632 
1633     /* Reset Rx fifo */
1634     Qspi_Ip_ClearRxBuf(baseAddr);
1635 
1636     /* Clear padding, only needed for the first read */
1637     Qspi_Ip_MemoryPadding[instance] = 0U;
1638 
1639     return status;
1640 }
1641 
1642 /*FUNCTION**********************************************************************
1643  *
1644  * Function Name : Qspi_Ip_InvalidateTxBuf
1645  * Description   : Invalidates the TX buffer content and wait until it is completed or timed out
1646  * @implements     Qspi_Ip_InvalidateTxBuf_Activity */
Qspi_Ip_InvalidateTxBuf(uint32 instance)1647 static inline void Qspi_Ip_InvalidateTxBuf(uint32 instance)
1648 {
1649     QuadSPI_Type *baseAddr = Qspi_Ip_BaseAddress[instance];
1650     volatile uint32 u32CurrentTicks;
1651 
1652     /* Start TX FIFO reset */
1653     Qspi_Ip_ClearTxBuf(baseAddr);
1654 
1655     /* Prepare timeout counter */
1656     u32CurrentTicks = QSPI_IP_TX_BUFFER_RESET_DELAY;
1657     /* Insert delay to ensure TX FIFO reset is complete */
1658     while (u32CurrentTicks > 0U)
1659     {
1660         u32CurrentTicks--;
1661     }
1662 }
1663 
1664 
1665 /*FUNCTION**********************************************************************
1666  *
1667  * Function Name : Qspi_Ip_PadTxBuf
1668  * Description   : Pad Tx buffer up to a minimum number of entries required
1669  *                 by the device for transmission to start
1670  *
1671  *END**************************************************************************/
1672 #if (FEATURE_QSPI_TX_MIN_BUF_FILL > 1)
Qspi_Ip_PadTxBuf(QuadSPI_Type * baseAddr)1673 static void Qspi_Ip_PadTxBuf(QuadSPI_Type *baseAddr)
1674 {
1675     uint32 bufFill = Qspi_Ip_GetTxBufFill(baseAddr);
1676     /* Pad buffer will blank data */
1677     while ((bufFill < FEATURE_QSPI_TX_MIN_BUF_FILL) || ((bufFill & 3U) != 0U))
1678     {
1679         Qspi_Ip_WriteTxData(baseAddr, 0xFFFFFFFFU);
1680         bufFill++;
1681     }
1682 }
1683 #else
Qspi_Ip_PadTxBuf(const QuadSPI_Type * baseAddr)1684 static void Qspi_Ip_PadTxBuf(const QuadSPI_Type *baseAddr)
1685 {
1686     /* Remove unused variable */
1687     (void)baseAddr;
1688 }
1689 #endif
1690 
1691 
1692 /*FUNCTION**********************************************************************
1693  *
1694  * Function Name : Qspi_Ip_IpWrite
1695  * Description   : Launches an IP write command
1696  * @implements     Qspi_Ip_IpWrite_Activity */
Qspi_Ip_IpWrite(uint32 instance,uint8 SeqId,uint32 addr,const uint8 * data,uint32 size)1697 Qspi_Ip_StatusType Qspi_Ip_IpWrite(uint32 instance,
1698                                    uint8 SeqId,
1699                                    uint32 addr,
1700                                    const uint8 * data,
1701                                    uint32 size
1702                                   )
1703 {
1704     QuadSPI_Type *baseAddr;
1705     Qspi_Ip_StatusType status = STATUS_QSPI_IP_ERROR;
1706     uint32 padding;
1707     uint16 TotalSize = 0U;
1708 
1709     baseAddr = Qspi_Ip_BaseAddress[instance];
1710     DEV_ASSERT_QSPI(instance < QuadSPI_INSTANCE_COUNT);
1711     DEV_ASSERT_QSPI(size <= (uint16)FEATURE_QSPI_TX_BUF_SIZE);
1712     DEV_ASSERT_QSPI(SeqId < (QuadSPI_LUT_COUNT / FEATURE_QSPI_LUT_SEQUENCE_SIZE));
1713     DEV_ASSERT_QSPI(data != NULL_PTR);
1714 
1715     /* Reset AHB buffers to force re-read from memory after write operation */
1716     Qspi_Ip_AhbFlush(baseAddr);
1717 
1718     /* Ensure there is no garbage in Tx FIFO */
1719     Qspi_Ip_InvalidateTxBuf(instance);
1720 
1721     padding = Qspi_Ip_MemoryPadding[instance];
1722     TotalSize = (uint16)(size + (padding >> 4U) + (padding & 0x0FU));
1723     Qspi_Ip_MemoryPadding[instance] = 0U;  /* Clear padding */
1724 
1725 #if (FEATURE_QSPI_HAS_SFP == 1)
1726 
1727     /* Setup water mark according to the transfer size to avoid underrun issue. */
1728     Qspi_Ip_SetTxWatermark( baseAddr, (uint8)( (FEATURE_QSPI_TX_BUF_SIZE / 4U) - ((TotalSize / 4U) - 1U) ) );
1729 
1730     Qspi_Ip_NewIpsTransaction(baseAddr, addr, TotalSize, SeqId);
1731 
1732     /* 01 - TBDR lock is open. QuadSPI considers IPS transfer. Master counter is started. */
1733     if (STATUS_QSPI_IP_SUCCESS == Qspi_Ip_Sfp_WaitFsmState(baseAddr, 1U))
1734     {
1735         /* Fill Tx buffer */
1736         Qspi_Ip_FillTxBuf(baseAddr, data, size, padding);
1737 
1738         /* Pad Tx buffer up to the minimum number of entries required by the device */
1739         Qspi_Ip_PadTxBuf(baseAddr);
1740 
1741         MCAL_DATA_SYNC_BARRIER();
1742         MCAL_INSTRUCTION_SYNC_BARRIER();
1743         /* 10 - TX buffer filled above threshold. Write transfer is triggered. SEQID is written. */
1744         if (((baseAddr->FSMSTAT & QuadSPI_FSMSTAT_STATE_MASK) >> QuadSPI_FSMSTAT_STATE_SHIFT) == 2U)
1745         {
1746             /* Add Fault Injection point for FR_TBUF flag */
1747             MCAL_FAULT_INJECTION_POINT(FLS_FIP_FR_ERROR_IPWRITE);
1748 
1749             /* Wait until the command is sent */
1750             status = Qspi_Ip_CmdWaitComplete(instance);
1751         }
1752     }
1753 
1754 #else /* FEATURE_QSPI_HAS_SFP */
1755 
1756     /* Set write address */
1757     Qspi_Ip_SetIpAddr(baseAddr, addr);
1758 
1759     /* Fill Tx buffer */
1760     Qspi_Ip_FillTxBuf(baseAddr, data, size, padding);
1761 
1762     /* Pad Tx buffer up to the minimum number of entries required by the device */
1763     Qspi_Ip_PadTxBuf(baseAddr);
1764 
1765     /* Trigger IP command with specified sequence and size */
1766     Qspi_Ip_IpTrigger(baseAddr, SeqId, TotalSize);
1767 
1768     /* Add Fault Injection point for FR_TBUF flag */
1769     MCAL_FAULT_INJECTION_POINT(FLS_FIP_FR_ERROR_IPWRITE);
1770 
1771     /* Wait until the command is sent */
1772     status = Qspi_Ip_CmdWaitComplete(instance);
1773 
1774 #endif /* FEATURE_QSPI_HAS_SFP */
1775 
1776     return status;
1777 }
1778 
1779 
1780 /*FUNCTION**********************************************************************
1781  *
1782  * Function Name : Qspi_Ip_ControllerGetStatus
1783  * Description   : Checks the status of the currently running IP command
1784  * @implements     Qspi_Ip_ControllerGetStatus_Activity */
Qspi_Ip_ControllerGetStatus(uint32 instance)1785 Qspi_Ip_StatusType Qspi_Ip_ControllerGetStatus(uint32 instance)
1786 {
1787     QuadSPI_Type *baseAddr;
1788     Qspi_Ip_StatusType status;
1789 
1790     DEV_ASSERT_QSPI((instance < QuadSPI_INSTANCE_COUNT));
1791     baseAddr = Qspi_Ip_BaseAddress[instance];
1792 
1793     MCAL_FAULT_INJECTION_POINT(QSPI_IP_FMEA_CONTROLLER_GET_STATUS);
1794     /* Check device for busy status */
1795     if (Qspi_Ip_GetBusyStatus(baseAddr))
1796     {
1797         status = STATUS_QSPI_IP_BUSY;
1798     }
1799     else
1800     {
1801         /* Check for errors reported by the QuadSPI */
1802         status = Qspi_Ip_ErrorCheck(baseAddr);
1803     }
1804     return status;
1805 }
1806 
1807 #if (FEATURE_QSPI_HAS_SFP == 1)
1808 #if (QSPI_IP_SFP_ENABLE_GLOBAL == STD_ON)
1809 
1810 #if (QSPI_IP_SFP_ENABLE_MDAD == STD_ON)
1811 /**
1812  * Configure the MDAD registers.
1813  */
Qspi_Ip_Sfp_Configure_Mdad(QuadSPI_Type * baseAddr,Qspi_Ip_ControllerConfigType const * userConfigPtr)1814 static void Qspi_Ip_Sfp_Configure_Mdad(QuadSPI_Type *baseAddr,
1815                                        Qspi_Ip_ControllerConfigType const *userConfigPtr)
1816 {
1817     for (uint8 Index = 0U; Index < QuadSPI_MDAD_COUNT; ++Index)
1818     {
1819         if (TRUE == userConfigPtr->SfpCfg.Tg[Index].Valid)
1820         {
1821             Qspi_Ip_Sfp_SetTgSecureAttribute(baseAddr, Index, userConfigPtr->SfpCfg.Tg[Index].SecureAttribute);
1822             Qspi_Ip_Sfp_SetTgMaskType(baseAddr, Index, userConfigPtr->SfpCfg.Tg[Index].MaskType);
1823             Qspi_Ip_Sfp_SetTgMask(baseAddr, Index, userConfigPtr->SfpCfg.Tg[Index].Mask);
1824             Qspi_Ip_Sfp_SetTgDomainIdMatch(baseAddr, Index, userConfigPtr->SfpCfg.Tg[Index].DomainId);
1825             Qspi_Ip_Sfp_SetTgValid(baseAddr, Index, userConfigPtr->SfpCfg.Tg[Index].Valid);
1826         }
1827     }
1828 }
1829 #endif /* QSPI_IP_SFP_ENABLE_MDAD */
1830 
1831 
1832 #if (QSPI_IP_SFP_ENABLE_FRAD == STD_ON)
1833 /**
1834  * Configure the FRAD registers.
1835  */
Qspi_Ip_Sfp_Configure_Frad(QuadSPI_Type * baseAddr,Qspi_Ip_ControllerConfigType const * userConfigPtr)1836 static void Qspi_Ip_Sfp_Configure_Frad(QuadSPI_Type *baseAddr,
1837                                        Qspi_Ip_ControllerConfigType const *userConfigPtr)
1838 {
1839     for (uint8 Index = 0U; Index < QuadSPI_FRAD_COUNT; ++Index)
1840     {
1841         if (TRUE == userConfigPtr->SfpCfg.Frad[Index].Valid)
1842         {
1843             Qspi_Ip_Sfp_SetFradStartAddress(baseAddr, Index, userConfigPtr->SfpCfg.Frad[Index].StartAddress);
1844             Qspi_Ip_Sfp_SetFradEndAddress(baseAddr, Index, userConfigPtr->SfpCfg.Frad[Index].EndAddress);
1845             Qspi_Ip_Sfp_SetFradMd0Acp(baseAddr, Index, (uint8)userConfigPtr->SfpCfg.Frad[Index].Md0Acp);
1846             Qspi_Ip_Sfp_SetFradMd1Acp(baseAddr, Index, (uint8)userConfigPtr->SfpCfg.Frad[Index].Md1Acp);
1847             Qspi_Ip_Sfp_SetFradEaLock(baseAddr, Index, userConfigPtr->SfpCfg.Frad[Index].ExclusiveAccessLock);
1848             Qspi_Ip_Sfp_SetFradEaOwner(baseAddr, Index, userConfigPtr->SfpCfg.Frad[Index].ExclusiveAccessOwner);
1849             Qspi_Ip_Sfp_SetFradValid(baseAddr, Index, userConfigPtr->SfpCfg.Frad[Index].Valid);
1850         }
1851     }
1852 }
1853 #endif /* QSPI_IP_SFP_ENABLE_FRAD */
1854 
1855 #endif /* QSPI_IP_SFP_ENABLE_GLOBAL */
1856 
1857 /** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1858  * @brief Configure the SFP registers.
1859  *
1860  * @param[in] BaseAddr base address of the given QuadSPI instance
1861  * @param[in] userConfigPtr QSPI controller configuration structure
1862  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
Qspi_Ip_Sfp_Configure_Privileged(QuadSPI_Type * baseAddr,Qspi_Ip_ControllerConfigType const * userConfigPtr)1863 void Qspi_Ip_Sfp_Configure_Privileged(QuadSPI_Type * baseAddr,
1864                                       Qspi_Ip_ControllerConfigType const * userConfigPtr)
1865 {
1866     /* Workaround for K396: QSPI must be enabled in order to write into SFP registers */
1867     /* Enable QuadSPI module */
1868     Qspi_Ip_Enable(baseAddr);
1869 
1870     Qspi_Ip_Sfp_SetAccessControls(baseAddr, QSPI_IP_SFP_ALL, QSPI_IP_SFP_ENABLE_GLOBAL);
1871     Qspi_Ip_Sfp_SetAccessControls(baseAddr, QSPI_IP_SFP_MDAD, QSPI_IP_SFP_ENABLE_MDAD);
1872     Qspi_Ip_Sfp_SetAccessControls(baseAddr, QSPI_IP_SFP_FRAD, QSPI_IP_SFP_ENABLE_FRAD);
1873 
1874 #if (QSPI_IP_SFP_ENABLE_GLOBAL == STD_ON)
1875 
1876 #if (QSPI_IP_SFP_ENABLE_MDAD == STD_ON)
1877     Qspi_Ip_Sfp_Configure_Mdad(baseAddr, userConfigPtr);
1878 #endif
1879 
1880 #if (QSPI_IP_SFP_ENABLE_FRAD == STD_ON)
1881     Qspi_Ip_Sfp_Configure_Frad(baseAddr, userConfigPtr);
1882 #endif
1883 
1884     Qspi_Ip_Sfp_SetMasterTimeout(baseAddr, userConfigPtr->SfpCfg.MasterTimeout);
1885 
1886 #else
1887     (void)userConfigPtr;
1888 #endif /* QSPI_IP_SFP_ENABLE_GLOBAL */
1889 
1890 }
1891 
1892 /**
1893  * Reset the registers the require privilege access for programming.
1894  */
Qspi_Ip_ResetPrivilegedRegisters_Privileged(QuadSPI_Type * BaseAddr)1895 void Qspi_Ip_ResetPrivilegedRegisters_Privileged(QuadSPI_Type *BaseAddr)
1896 {
1897     uint8 cnt;
1898 
1899     /* reset BFGENCR register */
1900     BaseAddr->BFGENCR  = (uint32)0x00000000UL;
1901 
1902     /* reset LUT0 register */
1903     BaseAddr->LUT[0]   = (uint32)0x08180403UL;
1904     /* reset LUT1 register */
1905     BaseAddr->LUT[1]   = (uint32)0x24001C08UL;
1906     for (cnt = 2U; cnt < QuadSPI_LUT_COUNT; cnt++)
1907     {
1908         BaseAddr->LUT[cnt] = (uint32)0x00000000UL;
1909     }
1910 
1911     /* reset Secure Flash Protection registers */
1912     for (cnt = 0U; cnt < QuadSPI_FRAD_COUNT; ++cnt)
1913     {
1914         BaseAddr->FRAD[cnt].WORD0 = 0x00000000UL;
1915         BaseAddr->FRAD[cnt].WORD1 = 0x0000FFFFUL;
1916         BaseAddr->FRAD[cnt].WORD2 = 0x00000000UL;
1917         BaseAddr->FRAD[cnt].WORD3 = 0x00000000UL;
1918     }
1919     for (cnt = 0U; cnt < QuadSPI_MDAD_COUNT; ++cnt)
1920     {
1921         BaseAddr->MDAD[cnt].TGMDAD  = 0x00000000UL;
1922         BaseAddr->MDAD[cnt].TGSFARS = 0x00000000UL;
1923         BaseAddr->MDAD[cnt].TGIPCRS = 0x00000000UL;
1924     }
1925     BaseAddr->MGC      = 0xA8000000UL;
1926     BaseAddr->MRC      = 0x00500E07UL;
1927     BaseAddr->MTO      = 0xFFFFFFFFUL;
1928     BaseAddr->FLSEQREQ = 0x20000000UL;
1929     BaseAddr->IPSERROR = 0x20000000UL;
1930     BaseAddr->ERRSTAT  = 0x000001FFUL;
1931     BaseAddr->INT_EN   = 0x00000000UL;
1932 }
1933 
1934 #endif /* FEATURE_QSPI_HAS_SFP */
1935 
1936 /*
1937  * Set all hardware registers to their reset value
1938  */
Qspi_Ip_ResetAllRegisters(QuadSPI_Type * BaseAddr)1939 inline static void Qspi_Ip_ResetAllRegisters(QuadSPI_Type *BaseAddr)
1940 {
1941     uint8 cnt = 0U;
1942 
1943 #if (FEATURE_QSPI_HAS_SFP == 1)  /* platforms support SFP */
1944 
1945     /* reset MCR register */
1946     BaseAddr->MCR      = (uint32)0x000F404CUL;
1947     /* reset FLSHCR register */
1948     BaseAddr->FLSHCR   = (uint32)0x00000303UL;
1949     /* reset BUF0CR register */
1950     BaseAddr->BUF0CR   = (uint32)0x00000003UL;
1951     /* reset BUF1CR register */
1952     BaseAddr->BUF1CR   = (uint32)0x00000002UL;
1953     /* reset BUF2CR register */
1954     BaseAddr->BUF2CR   = (uint32)0x00000001UL;
1955     /* reset BUF3CR register */
1956     BaseAddr->BUF3CR   = (uint32)0x80000000UL;
1957     /* reset SOCCR register */
1958     BaseAddr->SOCCR   = (uint32)0x00000000UL;
1959     /* reset BUF0IND register */
1960     BaseAddr->BUF0IND  = (uint32)0x00000000UL;
1961     /* reset BUF1IND register */
1962     BaseAddr->BUF1IND  = (uint32)0x00000000UL;
1963     /* reset BUF2IND register */
1964     BaseAddr->BUF2IND  = (uint32)0x00000000UL;
1965 #ifdef QuadSPI_AWRCR_AWTRGLVL_MASK
1966     /* reset AWRCR register */
1967     BaseAddr->AWRCR    = (uint32)0x00000000UL;
1968 #endif
1969     /* reset DLLCRA register */
1970     BaseAddr->DLLCRA   = (uint32)0x01200000UL;
1971 #ifdef QuadSPI_PARITYCR_CRCBIN_FA_MASK
1972     /* reset PARITYCR register */
1973     BaseAddr->PARITYCR = (uint32)0x00000000UL;
1974 #endif
1975     /* reset SFACR register */
1976     BaseAddr->SFACR    = (uint32)0x00000800UL;
1977     /* reset SMPR register */
1978     BaseAddr->SMPR     = (uint32)0x00000000UL;
1979     /* reset RBCT register */
1980     BaseAddr->RBCT     = (uint32)0x00000000UL;
1981 #ifdef QuadSPI_DLCR_DLP_SEL_FA_MASK
1982     /* reset DLCR register */
1983     BaseAddr->DLCR     = (uint32)0x40FF40FFUL;
1984 #endif
1985     /* reset FR register, Write 1 to clear */
1986     BaseAddr->FR       = (uint32)0x9D83F541UL;
1987     /* reset RSER register */
1988     BaseAddr->RSER     = (uint32)0x00000000UL;
1989     /* reset SPTRCLR register: clear both IP and AHB sequence pointers */
1990     BaseAddr->SPTRCLR  = (uint32)0x01000000UL | (uint32)QuadSPI_SPTRCLR_BFPTRC_MASK | (uint32)QuadSPI_SPTRCLR_IPPTRC_MASK;
1991     /* reset SFA1AD register */
1992     BaseAddr->SFA1AD  = (uint32)0x70000000UL;
1993     /* reset SFA2AD register */
1994     BaseAddr->SFA2AD  = (uint32)0x70000000UL;
1995 #ifdef QuadSPI_DLPR_DLPV_MASK
1996     /* reset DLPR register */
1997     BaseAddr->DLPR     = (uint32)0xAA553443UL;
1998 #endif
1999     /* reset LUTKEY register */
2000     BaseAddr->LUTKEY   = (uint32)0x5AF05AF0UL;
2001     /* reset LCKCR register */
2002     BaseAddr->LCKCR    = (uint32)0x00000002UL;
2003 
2004     Qspi_Ip_ResetPrivilegedRegisters(BaseAddr);
2005 
2006 #else  /* platforms do not support SFP */
2007 
2008     /* reset MCR register */
2009     BaseAddr->MCR     = (uint32)0x000F404CUL;
2010     /* reset IPCR register */
2011     BaseAddr->IPCR    = (uint32)0x00000000UL;
2012     /* reset FLSHCR register */
2013     BaseAddr->FLSHCR  = (uint32)0x00000303UL;
2014     /* reset BUF0CR register */
2015     BaseAddr->BUF0CR  = (uint32)0x00000003UL;
2016     /* reset BUF1CR register */
2017     BaseAddr->BUF1CR  = (uint32)0x00000002UL;
2018     /* reset BUF2CR register */
2019     BaseAddr->BUF2CR  = (uint32)0x00000001UL;
2020     /* reset BUF3CR register */
2021     BaseAddr->BUF3CR  = (uint32)0x80000000UL;
2022     /* reset BFGENCR register */
2023     BaseAddr->BFGENCR = (uint32)0x00000000UL;
2024     /* reset SOCCR register */
2025     BaseAddr->SOCCR   = (uint32)0x00000000UL;
2026     /* reset BUF0IND register */
2027     BaseAddr->BUF0IND = (uint32)0x00000000UL;
2028     /* reset BUF1IND register */
2029     BaseAddr->BUF1IND = (uint32)0x00000000UL;
2030     /* reset BUF2IND register */
2031     BaseAddr->BUF2IND = (uint32)0x00000000UL;
2032     /* reset DLLCRA register */
2033     BaseAddr->DLLCRA  = (uint32)0x01200000UL;
2034     /* reset SFAR register */
2035     BaseAddr->SFAR    = (uint32)0x00000000UL;
2036     /* reset SMPR register */
2037     BaseAddr->SMPR    = (uint32)0xFF000000UL;
2038     /* reset RBCT register */
2039     BaseAddr->RBCT    = (uint32)0x00000000UL;
2040     /* reset TBDR register */
2041     BaseAddr->TBDR    = (uint32)0x00000000UL;
2042     /* reset TBCT register */
2043     BaseAddr->TBCT    = (uint32)0x00000000UL;
2044     /* reset FR register - Write 1 to clear */
2045     BaseAddr->FR      = (uint32)0x0C8378C1UL;
2046     /* reset RSER register */
2047     BaseAddr->RSER    = (uint32)0x00000000UL;
2048     /* reset SPTRCLR register: clear both IP and AHB sequence pointers */
2049     BaseAddr->SPTRCLR = (uint32)QuadSPI_SPTRCLR_BFPTRC_MASK | (uint32)QuadSPI_SPTRCLR_IPPTRC_MASK;
2050     /* reset SFA1AD register */
2051     BaseAddr->SFA1AD  = (uint32)0x70000000UL;
2052     /* reset SFA2AD register */
2053     BaseAddr->SFA2AD  = (uint32)0x70000000UL;
2054     /* reset LUTKEY register */
2055     BaseAddr->LUTKEY  = (uint32)0x5AF05AF0UL;
2056     /* reset LCKCR register */
2057     BaseAddr->LCKCR   = (uint32)0x00000002UL;
2058     /* reset LUT0 register */
2059     BaseAddr->LUT[0]  = (uint32)0x08180403UL;
2060     /* reset LUT1 register */
2061     BaseAddr->LUT[1]  = (uint32)0x24001C08UL;
2062     for (cnt = 2U; cnt < QuadSPI_LUT_COUNT; cnt++)
2063     {
2064         BaseAddr->LUT[cnt] = (uint32)0x00000000UL;
2065     }
2066 #endif
2067 
2068     /* avoid warning unused variable */
2069     (void)cnt;
2070 }
2071 
2072 #define FLS_STOP_SEC_CODE
2073 #include "Fls_MemMap.h"
2074 
2075 #endif /* (QSPI_IP_MEM_INSTANCE_COUNT > 0) */
2076 
2077 
2078 #ifdef __cplusplus
2079 }
2080 #endif
2081 
2082 /** @} */
2083