1 /*
2  * Copyright 2021-2024 NXP
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 /**
8 *   @file Qspi_Ip_Sfdp.c
9 *
10 *   @addtogroup IPV_QSPI
11 *   @{
12 */
13 
14 
15 #ifdef __cplusplus
16 extern "C"{
17 #endif
18 
19 #include "OsIf.h"
20 #include "Qspi_Ip_Controller.h"
21 #include "Qspi_Ip.h"
22 #include "Qspi_Ip_Common.h"
23 
24 /*==================================================================================================
25 *                              SOURCE FILE VERSION INFORMATION
26 ==================================================================================================*/
27 #define QSPI_IP_VENDOR_ID_C                    43
28 #define QSPI_IP_AR_RELEASE_MAJOR_VERSION_C     4
29 #define QSPI_IP_AR_RELEASE_MINOR_VERSION_C     7
30 #define QSPI_IP_AR_RELEASE_REVISION_VERSION_C  0
31 #define QSPI_IP_SW_MAJOR_VERSION_C             2
32 #define QSPI_IP_SW_MINOR_VERSION_C             0
33 #define QSPI_IP_SW_PATCH_VERSION_C             0
34 /*==================================================================================================
35 *                                     FILE VERSION CHECKS
36 ==================================================================================================*/
37 #ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK
38     /* Check if current file and OsIf.h header file are of the same Autosar version */
39     #if ((QSPI_IP_AR_RELEASE_MAJOR_VERSION_C != OSIF_AR_RELEASE_MAJOR_VERSION) || \
40          (QSPI_IP_AR_RELEASE_MINOR_VERSION_C != OSIF_AR_RELEASE_MINOR_VERSION) \
41         )
42         #error "AutoSar Version Numbers of Qspi_Ip_Sfdp.c and OsIf.h are different"
43     #endif
44 #endif
45 
46 /* Check if current file and Qspi_Ip_Controller header file are of the same vendor */
47 #if (QSPI_IP_VENDOR_ID_C != QSPI_IP_CONTROLLER_VENDOR_ID_H)
48     #error "Qspi_Ip_Sfdp.c and Qspi_Ip_Controller.h have different vendor ids"
49 #endif
50 /* Check if current file and Qspi_Ip_Controller header file are of the same Autosar version */
51 #if ((QSPI_IP_AR_RELEASE_MAJOR_VERSION_C    != QSPI_IP_CONTROLLER_AR_RELEASE_MAJOR_VERSION_H) || \
52      (QSPI_IP_AR_RELEASE_MINOR_VERSION_C    != QSPI_IP_CONTROLLER_AR_RELEASE_MINOR_VERSION_H) || \
53      (QSPI_IP_AR_RELEASE_REVISION_VERSION_C != QSPI_IP_CONTROLLER_AR_RELEASE_REVISION_VERSION_H) \
54     )
55     #error "AutoSar Version Numbers of Qspi_Ip_Sfdp.c and Qspi_Ip_Controller.h are different"
56 #endif
57 /* Check if current file and Qspi_Ip_Controller header file are of the same Software version */
58 #if ((QSPI_IP_SW_MAJOR_VERSION_C != QSPI_IP_CONTROLLER_SW_MAJOR_VERSION_H) || \
59      (QSPI_IP_SW_MINOR_VERSION_C != QSPI_IP_CONTROLLER_SW_MINOR_VERSION_H) || \
60      (QSPI_IP_SW_PATCH_VERSION_C != QSPI_IP_CONTROLLER_SW_PATCH_VERSION_H) \
61     )
62     #error "Software Version Numbers of Qspi_Ip_Sfdp.c and Qspi_Ip_Controller.h are different"
63 #endif
64 
65 /* Check if current file and Qspi_Ip_Common header file are of the same vendor */
66 #if (QSPI_IP_VENDOR_ID_C != QSPI_IP_COMMON_VENDOR_ID_H)
67     #error "Qspi_Ip_Sfdp.c and Qspi_Ip_Common.h have different vendor ids"
68 #endif
69 /* Check if current file and Qspi_Ip_Common header file are of the same Autosar version */
70 #if ((QSPI_IP_AR_RELEASE_MAJOR_VERSION_C    != QSPI_IP_COMMON_AR_RELEASE_MAJOR_VERSION_H) || \
71      (QSPI_IP_AR_RELEASE_MINOR_VERSION_C    != QSPI_IP_COMMON_AR_RELEASE_MINOR_VERSION_H) || \
72      (QSPI_IP_AR_RELEASE_REVISION_VERSION_C != QSPI_IP_COMMON_AR_RELEASE_REVISION_VERSION_H) \
73     )
74     #error "AutoSar Version Numbers of Qspi_Ip_Sfdp.c and Qspi_Ip_Common.h are different"
75 #endif
76 /* Check if current file and Qspi_Ip_Common header file are of the same Software version */
77 #if ((QSPI_IP_SW_MAJOR_VERSION_C != QSPI_IP_COMMON_SW_MAJOR_VERSION_H) || \
78      (QSPI_IP_SW_MINOR_VERSION_C != QSPI_IP_COMMON_SW_MINOR_VERSION_H) || \
79      (QSPI_IP_SW_PATCH_VERSION_C != QSPI_IP_COMMON_SW_PATCH_VERSION_H) \
80     )
81     #error "Software Version Numbers of Qspi_Ip_Sfdp.c and Qspi_Ip_Common.h are different"
82 #endif
83 
84 /* Check if current file and Qspi_Ip header file are of the same vendor */
85 #if (QSPI_IP_VENDOR_ID_C != QSPI_IP_VENDOR_ID_H)
86     #error "Qspi_Ip_Sfdp.c and Qspi_Ip.h have different vendor ids"
87 #endif
88 /* Check if current file and Qspi_Ip header file are of the same Autosar version */
89 #if ((QSPI_IP_AR_RELEASE_MAJOR_VERSION_C    != QSPI_IP_AR_RELEASE_MAJOR_VERSION_H) || \
90      (QSPI_IP_AR_RELEASE_MINOR_VERSION_C    != QSPI_IP_AR_RELEASE_MINOR_VERSION_H) || \
91      (QSPI_IP_AR_RELEASE_REVISION_VERSION_C != QSPI_IP_AR_RELEASE_REVISION_VERSION_H) \
92     )
93     #error "AutoSar Version Numbers of Qspi_Ip_Sfdp.c and Qspi_Ip.h are different"
94 #endif
95 /* Check if current file and Qspi_Ip header file are of the same Software version */
96 #if ((QSPI_IP_SW_MAJOR_VERSION_C != QSPI_IP_SW_MAJOR_VERSION_H) || \
97      (QSPI_IP_SW_MINOR_VERSION_C != QSPI_IP_SW_MINOR_VERSION_H) || \
98      (QSPI_IP_SW_PATCH_VERSION_C != QSPI_IP_SW_PATCH_VERSION_H) \
99     )
100     #error "Software Version Numbers of Qspi_Ip_Sfdp.c and Qspi_Ip.h are different"
101 #endif
102 
103 /*******************************************************************************
104  * Definitions.
105  ******************************************************************************/
106 
107 #define QSPI_IP_CMD_SFDP_READ            0x5AU    /* Instruction for Read SFDP command */
108 #define QSPI_IP_CMD_BASIC_READ           0x03U    /* Basic read instruction  */
109 #define QSPI_IP_CMD_BASIC_READ_4B        0x13U    /* Basic read instruction - 4 bytes address */
110 #define QSPI_IP_CMD_BASIC_WRITE          0x02U    /* Basic write (page program) instruction  */
111 #define QSPI_IP_CMD_BASIC_READ_SR        0x05U    /* Basic instruction for read status reg. command */
112 #define QSPI_IP_CMD_BASIC_WRITE_SR       0x01U    /* Basic instruction for write status reg. command */
113 #define QSPI_IP_CMD_BASIC_WRITE_ENABLE   0x06U    /* Basic instruction for write enable command */
114 #define QSPI_IP_CMD_BASIC_CHIP_ERASE     0x60U    /* Basic instruction for chip erase command */
115 #define QSPI_IP_CMD_XSPI_WRITE           0x12U    /* XSPI profile 1.0 Instruction for Program command */
116 #define QSPI_IP_CMD_XSPI_CHIP_ERASE      0xC7U    /* XSPI profile 1.0 Instruction for Chip Erase command */
117 #define QSPI_IP_CMD_XSPI_READ_SR         0x05U    /* XSPI profile 1.0 Instruction for read status reg. command */
118 #define QSPI_IP_CMD_XSPI_WRITE_SR        0x01U    /* XSPI profile 1.0 Instruction for write status reg. command */
119 #define QSPI_IP_CMD_XSPI_WRITE_ENABLE    0x06U    /* XSPI profile 1.0 Instruction for write enable command */
120 #define QSPI_IP_CMD_XSPI_RESET           0xF0U    /* XSPI profile 1.0 Instruction for soft reset command */
121 #define QSPI_IP_CMD_XSPI_RESET_ENABLE    0x66U    /* XSPI profile 1.0 Instruction for reset enable command */
122 #define QSPI_IP_CMD_XSPI_RESET_DEF       0x99U    /* XSPI profile 1.0 Instruction for soft reset and enter default protocol mode command */
123 
124 #define QSPI_IP_TABLE_SIZE_BASIC     20U     /* Max basic flash parameter table length                      */
125 #define QSPI_IP_TABLE_SIZE_4BADD     2U      /* Max 4-byte address instruction table length                 */
126 #define QSPI_IP_TABLE_SIZE_XSPI1     5U      /* Max extended serial peripheral interface table length       */
127 #define QSPI_IP_TABLE_SIZE_SRMAP     28U     /* Max status, control and configuration register map length   */
128 #define QSPI_IP_TABLE_SIZE_2DOPI     8U      /* Max command sequence to change to octal ddr length          */
129 
130 #define QSPI_IP_SFDP_MAJOR_REVISION              1U
131 #define QSPI_IP_SFDP_MINOR_REVISION_REV_0        0U
132 #define QSPI_IP_SFDP_MINOR_REVISION_REV_A        5U
133 
134 #define QSPI_IP_SFDP_ACCESS_PROTOCOL_HYPERBUS    0xFAU  /* xSPI NOR Profile 2 HYPERBUS, (8D, 8D, 8D) operation */
135 #define QSPI_IP_SFDP_ACCESS_PROTOCOL_LEGACY      0xFFU  /* Legacy option (1S-1S-1S), (2S-2S-2S) or (4S-4S-4S) operation, 3-byte addressing for SFDP */
136 
137     /**** Constants for retrieving SFDP parameters - Basic flash parameters table *****/
138 
139     /* Flash Size */
140 #define QSPI_IP_SFDP_BASIC_MEM_SIZE_DWORD         2U
141 #define QSPI_IP_SFDP_BASIC_MEM_SIZE_SHIFT         0U
142 #define QSPI_IP_SFDP_BASIC_MEM_SIZE_WIDTH         32U
143     /* Page Size */
144 #define QSPI_IP_SFDP_BASIC_PAGE_SIZE_DWORD        11U
145 #define QSPI_IP_SFDP_BASIC_PAGE_SIZE_SHIFT        4U
146 #define QSPI_IP_SFDP_BASIC_PAGE_SIZE_WIDTH        4U
147     /* Octal DTR (8D-8D-8D) Command and Command Extension */
148 #define QSPI_IP_SFDP_BASIC_CMD_EXT_DWORD          18U
149 #define QSPI_IP_SFDP_BASIC_CMD_EXT_SHIFT          29U
150 #define QSPI_IP_SFDP_BASIC_CMD_EXT_WIDTH          2U
151     /* Erase type 1 - instruction and size */
152 #define QSPI_IP_SFDP_BASIC_ERASE1_INST_DWORD          8U
153 #define QSPI_IP_SFDP_BASIC_ERASE1_INST_SHIFT          8U
154 #define QSPI_IP_SFDP_BASIC_ERASE1_INST_WIDTH          8U
155 #define QSPI_IP_SFDP_BASIC_ERASE1_SIZE_DWORD          8U
156 #define QSPI_IP_SFDP_BASIC_ERASE1_SIZE_SHIFT          0U
157 #define QSPI_IP_SFDP_BASIC_ERASE1_SIZE_WIDTH          8U
158     /* Erase type 2 - instruction and size */
159 #define QSPI_IP_SFDP_BASIC_ERASE2_INST_DWORD          8U
160 #define QSPI_IP_SFDP_BASIC_ERASE2_INST_SHIFT          24U
161 #define QSPI_IP_SFDP_BASIC_ERASE2_INST_WIDTH          8U
162 #define QSPI_IP_SFDP_BASIC_ERASE2_SIZE_DWORD          8U
163 #define QSPI_IP_SFDP_BASIC_ERASE2_SIZE_SHIFT          16U
164 #define QSPI_IP_SFDP_BASIC_ERASE2_SIZE_WIDTH          8U
165     /* Erase type 3 - instruction and size */
166 #define QSPI_IP_SFDP_BASIC_ERASE3_INST_DWORD          9U
167 #define QSPI_IP_SFDP_BASIC_ERASE3_INST_SHIFT          8U
168 #define QSPI_IP_SFDP_BASIC_ERASE3_INST_WIDTH          8U
169 #define QSPI_IP_SFDP_BASIC_ERASE3_SIZE_DWORD          9U
170 #define QSPI_IP_SFDP_BASIC_ERASE3_SIZE_SHIFT          0U
171 #define QSPI_IP_SFDP_BASIC_ERASE3_SIZE_WIDTH          8U
172     /* Erase type 4 - instruction and size */
173 #define QSPI_IP_SFDP_BASIC_ERASE4_INST_DWORD          9U
174 #define QSPI_IP_SFDP_BASIC_ERASE4_INST_SHIFT          24U
175 #define QSPI_IP_SFDP_BASIC_ERASE4_INST_WIDTH          8U
176 #define QSPI_IP_SFDP_BASIC_ERASE4_SIZE_DWORD          9U
177 #define QSPI_IP_SFDP_BASIC_ERASE4_SIZE_SHIFT          16U
178 #define QSPI_IP_SFDP_BASIC_ERASE4_SIZE_WIDTH          8U
179     /* Erase suspend instruction */
180 #define QSPI_IP_SFDP_BASIC_ESUS_INSTR_DWORD          13U
181 #define QSPI_IP_SFDP_BASIC_ESUS_INSTR_SHIFT          24U
182 #define QSPI_IP_SFDP_BASIC_ESUS_INSTR_WIDTH          8U
183     /* Erase resume instruction */
184 #define QSPI_IP_SFDP_BASIC_ERES_INSTR_DWORD          13U
185 #define QSPI_IP_SFDP_BASIC_ERES_INSTR_SHIFT          16U
186 #define QSPI_IP_SFDP_BASIC_ERES_INSTR_WIDTH          8U
187     /* Program suspend instruction */
188 #define QSPI_IP_SFDP_BASIC_PSUS_INSTR_DWORD          13U
189 #define QSPI_IP_SFDP_BASIC_PSUS_INSTR_SHIFT          8U
190 #define QSPI_IP_SFDP_BASIC_PSUS_INSTR_WIDTH          8U
191     /* Program resume instruction */
192 #define QSPI_IP_SFDP_BASIC_PRES_INSTR_DWORD          13U
193 #define QSPI_IP_SFDP_BASIC_PRES_INSTR_SHIFT          0U
194 #define QSPI_IP_SFDP_BASIC_PRES_INSTR_WIDTH          8U
195     /* Quad Enable Requirements */
196 #define QSPI_IP_SFDP_BASIC_QE_REQ_DWORD              15U
197 #define QSPI_IP_SFDP_BASIC_QE_REQ_SHIFT              20U
198 #define QSPI_IP_SFDP_BASIC_QE_REQ_WIDTH              3U
199     /* Soft Reset */
200 #define QSPI_IP_SFDP_BASIC_SW_RESET_DWORD            16U
201 #define QSPI_IP_SFDP_BASIC_SW_RESET_SHIFT            8U
202 #define QSPI_IP_SFDP_BASIC_SW_RESET_WIDTH            6U
203     /* Write Enable Instruction Select for Writing to Volatile Status Register */
204 #define QSPI_IP_SFDP_BASIC_WREN_SR_DWORD             1U
205 #define QSPI_IP_SFDP_BASIC_WREN_SR_SHIFT             3U
206 #define QSPI_IP_SFDP_BASIC_WREN_SR_WIDTH             2U
207     /* 4-4-4 mode enable sequences */
208 #define QSPI_IP_SFDP_BASIC_444_SWITCH_DWORD          15U
209 #define QSPI_IP_SFDP_BASIC_444_SWITCH_SHIFT          4U
210 #define QSPI_IP_SFDP_BASIC_444_SWITCH_WIDTH          5U
211 
212     /* Fast read instructions/mode bits/dummy bits */
213 #define  QSPI_IP_SFDP_BASIC_READ112_SUP_DWORD           1U
214 #define  QSPI_IP_SFDP_BASIC_READ122_SUP_DWORD           1U
215 #define  QSPI_IP_SFDP_BASIC_READ114_SUP_DWORD           1U
216 #define  QSPI_IP_SFDP_BASIC_READ144_SUP_DWORD           1U
217 #define  QSPI_IP_SFDP_BASIC_READ444_SUP_DWORD           5U
218 #define  QSPI_IP_SFDP_BASIC_READ118_SUP_DWORD           17U
219 #define  QSPI_IP_SFDP_BASIC_READ188_SUP_DWORD           17U
220 
221 #define  QSPI_IP_SFDP_BASIC_READ112_SUP_SHIFT           16U
222 #define  QSPI_IP_SFDP_BASIC_READ122_SUP_SHIFT           20U
223 #define  QSPI_IP_SFDP_BASIC_READ114_SUP_SHIFT           22U
224 #define  QSPI_IP_SFDP_BASIC_READ144_SUP_SHIFT           21U
225 #define  QSPI_IP_SFDP_BASIC_READ444_SUP_SHIFT           4U
226 #define  QSPI_IP_SFDP_BASIC_READ118_SUP_SHIFT           24U
227 #define  QSPI_IP_SFDP_BASIC_READ188_SUP_SHIFT           8U
228 
229 #define  QSPI_IP_SFDP_BASIC_READ112_SUP_WIDTH           1U
230 #define  QSPI_IP_SFDP_BASIC_READ122_SUP_WIDTH           1U
231 #define  QSPI_IP_SFDP_BASIC_READ114_SUP_WIDTH           1U
232 #define  QSPI_IP_SFDP_BASIC_READ144_SUP_WIDTH           1U
233 #define  QSPI_IP_SFDP_BASIC_READ444_SUP_WIDTH           1U
234 #define  QSPI_IP_SFDP_BASIC_READ118_SUP_WIDTH           8U
235 #define  QSPI_IP_SFDP_BASIC_READ188_SUP_WIDTH           8U
236 
237 #define  QSPI_IP_SFDP_BASIC_READ112_INST_DWORD           4U
238 #define  QSPI_IP_SFDP_BASIC_READ122_INST_DWORD           4U
239 #define  QSPI_IP_SFDP_BASIC_READ114_INST_DWORD           3U
240 #define  QSPI_IP_SFDP_BASIC_READ144_INST_DWORD           3U
241 #define  QSPI_IP_SFDP_BASIC_READ444_INST_DWORD           7U
242 #define  QSPI_IP_SFDP_BASIC_READ118_INST_DWORD           17U
243 #define  QSPI_IP_SFDP_BASIC_READ188_INST_DWORD           17U
244 
245 #define  QSPI_IP_SFDP_BASIC_READ112_INST_SHIFT           8U
246 #define  QSPI_IP_SFDP_BASIC_READ122_INST_SHIFT           24U
247 #define  QSPI_IP_SFDP_BASIC_READ114_INST_SHIFT           24U
248 #define  QSPI_IP_SFDP_BASIC_READ144_INST_SHIFT           8U
249 #define  QSPI_IP_SFDP_BASIC_READ444_INST_SHIFT           24U
250 #define  QSPI_IP_SFDP_BASIC_READ118_INST_SHIFT           24U
251 #define  QSPI_IP_SFDP_BASIC_READ188_INST_SHIFT           8U
252 
253 #define  QSPI_IP_SFDP_BASIC_READ112_INST_WIDTH           8U
254 #define  QSPI_IP_SFDP_BASIC_READ122_INST_WIDTH           8U
255 #define  QSPI_IP_SFDP_BASIC_READ114_INST_WIDTH           8U
256 #define  QSPI_IP_SFDP_BASIC_READ144_INST_WIDTH           8U
257 #define  QSPI_IP_SFDP_BASIC_READ444_INST_WIDTH           8U
258 #define  QSPI_IP_SFDP_BASIC_READ118_INST_WIDTH           8U
259 #define  QSPI_IP_SFDP_BASIC_READ188_INST_WIDTH           8U
260 
261 #define  QSPI_IP_SFDP_BASIC_READ112_MODE_DWORD           4U
262 #define  QSPI_IP_SFDP_BASIC_READ122_MODE_DWORD           4U
263 #define  QSPI_IP_SFDP_BASIC_READ114_MODE_DWORD           3U
264 #define  QSPI_IP_SFDP_BASIC_READ144_MODE_DWORD           3U
265 #define  QSPI_IP_SFDP_BASIC_READ444_MODE_DWORD           7U
266 #define  QSPI_IP_SFDP_BASIC_READ118_MODE_DWORD           17U
267 #define  QSPI_IP_SFDP_BASIC_READ188_MODE_DWORD           17U
268 
269 #define  QSPI_IP_SFDP_BASIC_READ112_MODE_SHIFT           5U
270 #define  QSPI_IP_SFDP_BASIC_READ122_MODE_SHIFT           21U
271 #define  QSPI_IP_SFDP_BASIC_READ114_MODE_SHIFT           21U
272 #define  QSPI_IP_SFDP_BASIC_READ144_MODE_SHIFT           5U
273 #define  QSPI_IP_SFDP_BASIC_READ444_MODE_SHIFT           21U
274 #define  QSPI_IP_SFDP_BASIC_READ118_MODE_SHIFT           21U
275 #define  QSPI_IP_SFDP_BASIC_READ188_MODE_SHIFT           5U
276 
277 #define  QSPI_IP_SFDP_BASIC_READ112_MODE_WIDTH           3U
278 #define  QSPI_IP_SFDP_BASIC_READ122_MODE_WIDTH           3U
279 #define  QSPI_IP_SFDP_BASIC_READ114_MODE_WIDTH           3U
280 #define  QSPI_IP_SFDP_BASIC_READ144_MODE_WIDTH           3U
281 #define  QSPI_IP_SFDP_BASIC_READ444_MODE_WIDTH           3U
282 #define  QSPI_IP_SFDP_BASIC_READ118_MODE_WIDTH           3U
283 #define  QSPI_IP_SFDP_BASIC_READ188_MODE_WIDTH           3U
284 
285 #define  QSPI_IP_SFDP_BASIC_READ112_DUMMY_DWORD           4U
286 #define  QSPI_IP_SFDP_BASIC_READ122_DUMMY_DWORD           4U
287 #define  QSPI_IP_SFDP_BASIC_READ114_DUMMY_DWORD           3U
288 #define  QSPI_IP_SFDP_BASIC_READ144_DUMMY_DWORD           3U
289 #define  QSPI_IP_SFDP_BASIC_READ444_DUMMY_DWORD           7U
290 #define  QSPI_IP_SFDP_BASIC_READ118_DUMMY_DWORD           17U
291 #define  QSPI_IP_SFDP_BASIC_READ188_DUMMY_DWORD           17U
292 
293 #define  QSPI_IP_SFDP_BASIC_READ112_DUMMY_SHIFT           0U
294 #define  QSPI_IP_SFDP_BASIC_READ122_DUMMY_SHIFT           16U
295 #define  QSPI_IP_SFDP_BASIC_READ114_DUMMY_SHIFT           16U
296 #define  QSPI_IP_SFDP_BASIC_READ144_DUMMY_SHIFT           0U
297 #define  QSPI_IP_SFDP_BASIC_READ444_DUMMY_SHIFT           16U
298 #define  QSPI_IP_SFDP_BASIC_READ118_DUMMY_SHIFT           16U
299 #define  QSPI_IP_SFDP_BASIC_READ188_DUMMY_SHIFT           0U
300 
301 #define  QSPI_IP_SFDP_BASIC_READ112_DUMMY_WIDTH           5U
302 #define  QSPI_IP_SFDP_BASIC_READ122_DUMMY_WIDTH           5U
303 #define  QSPI_IP_SFDP_BASIC_READ114_DUMMY_WIDTH           5U
304 #define  QSPI_IP_SFDP_BASIC_READ144_DUMMY_WIDTH           5U
305 #define  QSPI_IP_SFDP_BASIC_READ444_DUMMY_WIDTH           5U
306 #define  QSPI_IP_SFDP_BASIC_READ118_DUMMY_WIDTH           5U
307 #define  QSPI_IP_SFDP_BASIC_READ188_DUMMY_WIDTH           5U
308 
309 #define  QSPI_IP_SFDP_BASIC_ADDR_BYTES_DWORD           1U
310 #define  QSPI_IP_SFDP_BASIC_ADDR_BYTES_SHIFT           17U
311 #define  QSPI_IP_SFDP_BASIC_ADDR_BYTES_WIDTH           2U
312 
313 #define  QSPI_IP_SFDP_BASIC_ADDR_SWITCH_DWORD          16U
314 #define  QSPI_IP_SFDP_BASIC_ADDR_SWITCH_SHIFT          24U
315 #define  QSPI_IP_SFDP_BASIC_ADDR_SWITCH_WIDTH          8U
316 
317 
318     /**** Constants for retrieving SFDP parameters - xSPI 1.0 table *****/
319 
320     /* Read fast command */
321 #define QSPI_IP_SFDP_XSPI1_READ_FAST_DWORD          1U
322 #define QSPI_IP_SFDP_XSPI1_READ_FAST_SHIFT          8U
323 #define QSPI_IP_SFDP_XSPI1_READ_FAST_WIDTH          8U
324     /* Max. number of dummy cycles */
325 #define QSPI_IP_SFDP_XSPI1_DUMMY_DWORD              4U
326 #define QSPI_IP_SFDP_XSPI1_DUMMY_SHIFT              7U
327 #define QSPI_IP_SFDP_XSPI1_DUMMY_WIDTH              5U
328     /* Chip erase support */
329 #define QSPI_IP_SFDP_XSPI1_CHIP_ERASE_DWORD         3U
330 #define QSPI_IP_SFDP_XSPI1_CHIP_ERASE_SHIFT         26U
331 #define QSPI_IP_SFDP_XSPI1_CHIP_ERASE_WIDTH         1U
332     /* Soft Reset support */
333 #define QSPI_IP_SFDP_XSPI1_RESET_DWORD              3U
334 #define QSPI_IP_SFDP_XSPI1_RESET_SHIFT              13U
335 #define QSPI_IP_SFDP_XSPI1_RESET_WIDTH              1U
336     /* Reset Enable support */
337 #define QSPI_IP_SFDP_XSPI1_RESET_EN_DWORD           3U
338 #define QSPI_IP_SFDP_XSPI1_RESET_EN_SHIFT           12U
339 #define QSPI_IP_SFDP_XSPI1_RESET_EN_WIDTH           1U
340     /* Soft Reset and Enter default protocol mode support */
341 #define QSPI_IP_SFDP_XSPI1_RESET_DEF_DWORD          3U
342 #define QSPI_IP_SFDP_XSPI1_RESET_DEF_SHIFT          11U
343 #define QSPI_IP_SFDP_XSPI1_RESET_DEF_WIDTH          1U
344 
345     /**** Constants for retrieving SFDP parameters - Status, Control and Configuration Register Map *****/
346 
347     /* Busy (WIP) flag offset */
348 #define QSPI_IP_SFDP_SRMAP_WIP_OFFSET_DWORD          5U
349 #define QSPI_IP_SFDP_SRMAP_WIP_OFFSET_SHIFT          24U
350 #define QSPI_IP_SFDP_SRMAP_WIP_OFFSET_WIDTH          3U
351     /* Busy (WIP) flag value */
352 #define QSPI_IP_SFDP_SRMAP_WIP_VALUE_DWORD          5U
353 #define QSPI_IP_SFDP_SRMAP_WIP_VALUE_SHIFT          30U
354 #define QSPI_IP_SFDP_SRMAP_WIP_VALUE_WIDTH          1U
355     /* Write Enable (WEL) flag offset */
356 #define QSPI_IP_SFDP_SRMAP_WEL_OFFSET_DWORD          6U
357 #define QSPI_IP_SFDP_SRMAP_WEL_OFFSET_SHIFT          24U
358 #define QSPI_IP_SFDP_SRMAP_WEL_OFFSET_WIDTH          3U
359     /* Dummy cycles in 8D-8D-8D mode */
360 #define QSPI_IP_SFDP_SRMAP_DUMMY_8D_DWORD          3U
361 #define QSPI_IP_SFDP_SRMAP_DUMMY_8D_SHIFT          6U
362 #define QSPI_IP_SFDP_SRMAP_DUMMY_8D_WIDTH          4U
363     /* SR read is direct command (not using address) */
364 #define QSPI_IP_SFDP_SRMAP_USE_ADDR_DWORD          5U
365 #define QSPI_IP_SFDP_SRMAP_USE_ADDR_SHIFT          28U
366 #define QSPI_IP_SFDP_SRMAP_USE_ADDR_WIDTH          1U
367     /* Address offset for volatile registers */
368 #define QSPI_IP_SFDP_SRMAP_OFFSET_DWORD          1U
369 #define QSPI_IP_SFDP_SRMAP_OFFSET_SHIFT          0U
370 #define QSPI_IP_SFDP_SRMAP_OFFSET_WIDTH          32U
371     /* Number of address bytes used for Generic Addressable Read/Write Status/Control register commands for volatile registers */
372 #define QSPI_IP_SFDP_SRMAP_NBYTES_DWORD          3U
373 #define QSPI_IP_SFDP_SRMAP_NBYTES_SHIFT          28U
374 #define QSPI_IP_SFDP_SRMAP_NBYTES_WIDTH          2U
375     /* SR local address */
376 #define QSPI_IP_SFDP_SRMAP_SR_ADDR_DWORD          5U
377 #define QSPI_IP_SFDP_SRMAP_SR_ADDR_SHIFT          16U
378 #define QSPI_IP_SFDP_SRMAP_SR_ADDR_WIDTH          8U
379     /* SR address shift (before adding to the offset) */
380 #define QSPI_IP_SFDP_SRMAP_SR_SHIFT_DWORD          5U
381 #define QSPI_IP_SFDP_SRMAP_SR_SHIFT_SHIFT          27U
382 #define QSPI_IP_SFDP_SRMAP_SR_SHIFT_WIDTH          1U
383 
384     /**** Constants for retrieving SFDP parameters - Command Sequences to Change to Octal DDR (8D-8D-8D) mode *****/
385 
386     /* Length of command sequence */
387 #define QSPI_IP_SFDP_2DOPI_CMD_LEN_SHIFT          24U
388 #define QSPI_IP_SFDP_2DOPI_CMD_LEN_WIDTH          8U
389     /* Bytes of command sequence */
390 #define QSPI_IP_SFDP_2DOPI_CMD_BYTE1_SHIFT          16U
391 #define QSPI_IP_SFDP_2DOPI_CMD_BYTE2_SHIFT          8U
392 #define QSPI_IP_SFDP_2DOPI_CMD_BYTE3_SHIFT          0U
393 #define QSPI_IP_SFDP_2DOPI_CMD_BYTE4_SHIFT          24U
394 #define QSPI_IP_SFDP_2DOPI_CMD_BYTE5_SHIFT          16U
395 #define QSPI_IP_SFDP_2DOPI_CMD_BYTE6_SHIFT          8U
396 #define QSPI_IP_SFDP_2DOPI_CMD_BYTE7_SHIFT          0U
397 
398     /**** Constants for retrieving SFDP parameters - 4-byte Address Instructions *****/
399 
400 #define QSPI_IP_SFDP_4BADD_INSTR_SUP_DWORD           1U
401 #define QSPI_IP_SFDP_4BADD_INSTR_SUP_WIDTH           1U
402 #define QSPI_IP_SFDP_4BADD_ERASE_INST_DWORD          2U
403 #define QSPI_IP_SFDP_4BADD_ERASE_INST_WIDTH          8U
404 #define QSPI_IP_SFDP_4BADD_ERASE1_SUP_SHIFT          9U
405 #define QSPI_IP_SFDP_4BADD_ERASE2_SUP_SHIFT          10U
406 #define QSPI_IP_SFDP_4BADD_ERASE3_SUP_SHIFT          11U
407 #define QSPI_IP_SFDP_4BADD_ERASE4_SUP_SHIFT          12U
408 #define QSPI_IP_SFDP_4BADD_ERASE1_INST_SHIFT         0U
409 #define QSPI_IP_SFDP_4BADD_ERASE2_INST_SHIFT         8U
410 #define QSPI_IP_SFDP_4BADD_ERASE3_INST_SHIFT         16U
411 #define QSPI_IP_SFDP_4BADD_ERASE4_INST_SHIFT         24U
412 
413 #define  QSPI_IP_SFDP_4BADD_READ112_SUP_DWORD           1U
414 #define  QSPI_IP_SFDP_4BADD_READ122_SUP_DWORD           1U
415 #define  QSPI_IP_SFDP_4BADD_READ114_SUP_DWORD           1U
416 #define  QSPI_IP_SFDP_4BADD_READ144_SUP_DWORD           1U
417 #define  QSPI_IP_SFDP_4BADD_READ444_SUP_DWORD           0xFFU     /* invalid */
418 #define  QSPI_IP_SFDP_4BADD_READ118_SUP_DWORD           1U
419 #define  QSPI_IP_SFDP_4BADD_READ188_SUP_DWORD           1U
420 
421 #define  QSPI_IP_SFDP_4BADD_READ111_SUP_SHIFT           0U
422 #define  QSPI_IP_SFDP_4BADD_READ112_SUP_SHIFT           2U
423 #define  QSPI_IP_SFDP_4BADD_READ122_SUP_SHIFT           3U
424 #define  QSPI_IP_SFDP_4BADD_READ114_SUP_SHIFT           4U
425 #define  QSPI_IP_SFDP_4BADD_READ144_SUP_SHIFT           5U
426 #define  QSPI_IP_SFDP_4BADD_READ444_SUP_SHIFT           1U       /* use 1-1-1 fast read */
427 #define  QSPI_IP_SFDP_4BADD_READ118_SUP_SHIFT           20U
428 #define  QSPI_IP_SFDP_4BADD_READ188_SUP_SHIFT           21U
429 
430 
431 #define  QSPI_IP_SFDP_4BADD_WRITE112_SUP_DWORD           0xFFU     /* invalid */
432 #define  QSPI_IP_SFDP_4BADD_WRITE122_SUP_DWORD           0xFFU     /* invalid */
433 #define  QSPI_IP_SFDP_4BADD_WRITE114_SUP_DWORD           1U
434 #define  QSPI_IP_SFDP_4BADD_WRITE144_SUP_DWORD           1U
435 #define  QSPI_IP_SFDP_4BADD_WRITE444_SUP_DWORD           1U
436 #define  QSPI_IP_SFDP_4BADD_WRITE118_SUP_DWORD           1U
437 #define  QSPI_IP_SFDP_4BADD_WRITE188_SUP_DWORD           1U
438 
439 #define  QSPI_IP_SFDP_4BADD_WRITE112_SUP_SHIFT           0U
440 #define  QSPI_IP_SFDP_4BADD_WRITE122_SUP_SHIFT           0U
441 #define  QSPI_IP_SFDP_4BADD_WRITE114_SUP_SHIFT           7U
442 #define  QSPI_IP_SFDP_4BADD_WRITE144_SUP_SHIFT           8U
443 #define  QSPI_IP_SFDP_4BADD_WRITE444_SUP_SHIFT           6U      /* use 1-1-1 write */
444 #define  QSPI_IP_SFDP_4BADD_WRITE118_SUP_SHIFT           23U
445 #define  QSPI_IP_SFDP_4BADD_WRITE188_SUP_SHIFT           24U
446 
447 /* fast read modes */
448 #define  QSPI_IP_SFDP_READ_MODE_112                      0x00U  /* 1-1-2 fast read mode            */
449 #define  QSPI_IP_SFDP_READ_MODE_122                      0x01U  /* 1-2-2 fast read mode            */
450 #define  QSPI_IP_SFDP_READ_MODE_114                      0x02U  /* 1-1-4 fast read mode            */
451 #define  QSPI_IP_SFDP_READ_MODE_144                      0x03U  /* 1-4-4 fast read mode            */
452 #define  QSPI_IP_SFDP_READ_MODE_444                      0x04U  /* 4-4-4 fast read mode            */
453 #define  QSPI_IP_SFDP_READ_MODE_118                      0x05U  /* 1-1-8 fast read mode            */
454 #define  QSPI_IP_SFDP_READ_MODE_188                      0x06U  /* 1-8-8 fast read mode            */
455 #define  QSPI_IP_SFDP_READ_MODE_MAX                      0x07U  /* Number of read modes            */
456 
457 
458 /*******************************************************************************
459  * Enumerations.
460  ******************************************************************************/
461 
462 #if (QSPI_IP_MEM_INSTANCE_COUNT > 0)
463 
464 /* sfdp modes */
465 typedef enum
466 {
467     QSPI_IP_SFDP_1S_1S_1S  = 0x00U,   /*!< 1S-1S-1S mode */
468     QSPI_IP_SFDP_2S_2S_2S  = 0x01U,   /*!< 2S-2S-2S mode */
469     QSPI_IP_SFDP_4S_4S_4S  = 0x02U,   /*!< 4S-4S-4S mode */
470     QSPI_IP_SFDP_4S_4D_4D  = 0x03U,   /*!< 4S-4D-4D mode */
471     QSPI_IP_SFDP_8D_8D_8D  = 0x04U,   /*!< 8D-8D-8D mode */
472 } Qspi_Ip_SfdpModes;
473 
474 /* sfdp table types */
475 typedef enum
476 {
477     QSPI_IP_SFDP_TABLE_BASIC   = 0x00U,   /*!< Basic flash parameter table                               */
478     QSPI_IP_SFDP_TABLE_4BADD   = 0x84U,   /*!< 4-byte Address Instruction Table                          */
479     QSPI_IP_SFDP_TABLE_XSPI1   = 0x05U,   /*!< eXtended Serial Peripheral Interface (xSPI) Profile 1.0   */
480     QSPI_IP_SFDP_TABLE_SRMAP   = 0x87U,   /*!< Status, Control and Configuration Register Map            */
481     QSPI_IP_SFDP_TABLE_2DOPI   = 0x0AU,   /*!< Command Sequences to change to DOPI (8D-8D-8D) mode       */
482 } Qspi_Ip_SfdpTables;
483 
484 /* structure containing sfdp tables */
485 typedef struct
486 {
487     uint32 paramTable_basic[QSPI_IP_TABLE_SIZE_BASIC];
488     uint32 paramTable_4badd[QSPI_IP_TABLE_SIZE_4BADD];
489     uint32 paramTable_xspi1[QSPI_IP_TABLE_SIZE_XSPI1];
490     uint32 paramTable_srmap[QSPI_IP_TABLE_SIZE_SRMAP];
491     uint32 paramTable_2dopi[QSPI_IP_TABLE_SIZE_2DOPI];
492     uint8 paramTableLength_basic;
493     uint8 paramTableLength_4badd;
494     uint8 paramTableLength_xspi1;
495     uint8 paramTableLength_srmap;
496     uint8 paramTableLength_2dopi;
497 } Qspi_Ip_SfdpTablesContainer;
498 
499 /*******************************************************************************
500  * Local Variables
501  ******************************************************************************/
502 
503 #define MEM_43_EXFLS_START_SEC_VAR_CLEARED_16
504 #include "Mem_43_EXFLS_MemMap.h"
505 
506 static uint16 lutCount;                     /* Current number of operations in the LUT table                               */
507 
508 #define MEM_43_EXFLS_STOP_SEC_VAR_CLEARED_16
509 #include "Mem_43_EXFLS_MemMap.h"
510 
511 
512 #define MEM_43_EXFLS_START_SEC_VAR_CLEARED_8
513 #include "Mem_43_EXFLS_MemMap.h"
514 
515 static uint8 initOpCount;                  /* Current number of operations in the initial operations list                 */
516 static uint8 basicAddrBits;                /* Current number of operations in the initial operations list                 */
517 static uint8 modeIndex;                    /* Index of the selected read mode                                             */
518 
519 #define MEM_43_EXFLS_STOP_SEC_VAR_CLEARED_8
520 #include "Mem_43_EXFLS_MemMap.h"
521 
522 
523 #define MEM_43_EXFLS_START_SEC_VAR_CLEARED_UNSPECIFIED
524 #include "Mem_43_EXFLS_MemMap.h"
525 
526 static Qspi_Ip_LutPadsType cmdPads;         /* Pads to use for commands (e.g. 4 if the selected operation mode is 4-4-4)   */
527 static Qspi_Ip_LutPadsType cmdPadsInit;     /* Number of pads used for commands in the initial state                       */
528 
529 #define MEM_43_EXFLS_STOP_SEC_VAR_CLEARED_UNSPECIFIED
530 #include "Mem_43_EXFLS_MemMap.h"
531 
532 
533 #define MEM_43_EXFLS_START_SEC_VAR_CLEARED_BOOLEAN
534 #include "Mem_43_EXFLS_MemMap.h"
535 
536 static boolean overflow;                    /* Either LUT or initial operations list was not big enough                    */
537 static boolean quadAvailable;               /* Quad mode can be used                                                       */
538 
539 #define MEM_43_EXFLS_STOP_SEC_VAR_CLEARED_BOOLEAN
540 #include "Mem_43_EXFLS_MemMap.h"
541 
542 
543 #define MEM_43_EXFLS_START_SEC_VAR_INIT_BOOLEAN
544 #include "Mem_43_EXFLS_MemMap.h"
545 
546 static boolean bootModeLegacyXPI = (boolean)TRUE;    /* Memory device boots up in xSPI or HyperBus mode (default is XPI)   */
547 
548 #define MEM_43_EXFLS_STOP_SEC_VAR_INIT_BOOLEAN
549 #include "Mem_43_EXFLS_MemMap.h"
550 
551 /* tables for extracting parameters from SFDP table */
552 
553 #define MEM_43_EXFLS_START_SEC_VAR_INIT_8
554 #include "Mem_43_EXFLS_MemMap.h"
555 
556 static uint8 eraseInstDword[4U] = {
557     QSPI_IP_SFDP_BASIC_ERASE1_INST_DWORD,
558     QSPI_IP_SFDP_BASIC_ERASE2_INST_DWORD,
559     QSPI_IP_SFDP_BASIC_ERASE3_INST_DWORD,
560     QSPI_IP_SFDP_BASIC_ERASE4_INST_DWORD
561 };
562 static uint8 eraseInstShift[4U] = {
563     QSPI_IP_SFDP_BASIC_ERASE1_INST_SHIFT,
564     QSPI_IP_SFDP_BASIC_ERASE2_INST_SHIFT,
565     QSPI_IP_SFDP_BASIC_ERASE3_INST_SHIFT,
566     QSPI_IP_SFDP_BASIC_ERASE4_INST_SHIFT
567 };
568 static uint8 eraseInstWidth[4U] = {
569     QSPI_IP_SFDP_BASIC_ERASE1_INST_WIDTH,
570     QSPI_IP_SFDP_BASIC_ERASE2_INST_WIDTH,
571     QSPI_IP_SFDP_BASIC_ERASE3_INST_WIDTH,
572     QSPI_IP_SFDP_BASIC_ERASE4_INST_WIDTH
573 };
574 static uint8 eraseSizeDword[4U] = {
575     QSPI_IP_SFDP_BASIC_ERASE1_SIZE_DWORD,
576     QSPI_IP_SFDP_BASIC_ERASE2_SIZE_DWORD,
577     QSPI_IP_SFDP_BASIC_ERASE3_SIZE_DWORD,
578     QSPI_IP_SFDP_BASIC_ERASE4_SIZE_DWORD
579 };
580 static uint8 eraseSizeShift[4U] = {
581     QSPI_IP_SFDP_BASIC_ERASE1_SIZE_SHIFT,
582     QSPI_IP_SFDP_BASIC_ERASE2_SIZE_SHIFT,
583     QSPI_IP_SFDP_BASIC_ERASE3_SIZE_SHIFT,
584     QSPI_IP_SFDP_BASIC_ERASE4_SIZE_SHIFT
585 };
586 static uint8 eraseSizeWidth[4U] = {
587     QSPI_IP_SFDP_BASIC_ERASE1_SIZE_WIDTH,
588     QSPI_IP_SFDP_BASIC_ERASE2_SIZE_WIDTH,
589     QSPI_IP_SFDP_BASIC_ERASE3_SIZE_WIDTH,
590     QSPI_IP_SFDP_BASIC_ERASE4_SIZE_WIDTH
591 };
592 
593 static uint8 erase4ByteSupShift[4U] = {
594     QSPI_IP_SFDP_4BADD_ERASE1_SUP_SHIFT,
595     QSPI_IP_SFDP_4BADD_ERASE2_SUP_SHIFT,
596     QSPI_IP_SFDP_4BADD_ERASE3_SUP_SHIFT,
597     QSPI_IP_SFDP_4BADD_ERASE4_SUP_SHIFT
598 };
599 
600 static uint8 erase4ByteInstShift[4U] = {
601     QSPI_IP_SFDP_4BADD_ERASE1_INST_SHIFT,
602     QSPI_IP_SFDP_4BADD_ERASE2_INST_SHIFT,
603     QSPI_IP_SFDP_4BADD_ERASE3_INST_SHIFT,
604     QSPI_IP_SFDP_4BADD_ERASE4_INST_SHIFT
605 };
606 
607 /* Erase instruction with 4-Byte Address, specified by JESD216D */
608 static uint8 erase4ByteInst[4U] = {
609     0x21U,                                  /*   4-KB erase */
610     0x5CU,                                  /*  32-KB erase */
611     0xDCU,                                  /*  64-KB erase */
612     0xDCU                                   /* 256-KB erase */
613 };
614 
615 static uint8 dopiSwitchShift[7U] = {
616     QSPI_IP_SFDP_2DOPI_CMD_BYTE1_SHIFT,
617     QSPI_IP_SFDP_2DOPI_CMD_BYTE2_SHIFT,
618     QSPI_IP_SFDP_2DOPI_CMD_BYTE3_SHIFT,
619     QSPI_IP_SFDP_2DOPI_CMD_BYTE4_SHIFT,
620     QSPI_IP_SFDP_2DOPI_CMD_BYTE5_SHIFT,
621     QSPI_IP_SFDP_2DOPI_CMD_BYTE6_SHIFT,
622     QSPI_IP_SFDP_2DOPI_CMD_BYTE7_SHIFT,
623 };
624 static uint8 dopiSwitchWord[7U] = {
625     0U,
626     0U,
627     0U,
628     1U,
629     1U,
630     1U,
631     1U,
632 };
633 
634 static uint8 readSupDword[QSPI_IP_SFDP_READ_MODE_MAX] = {
635     QSPI_IP_SFDP_BASIC_READ112_SUP_DWORD,
636     QSPI_IP_SFDP_BASIC_READ122_SUP_DWORD,
637     QSPI_IP_SFDP_BASIC_READ114_SUP_DWORD,
638     QSPI_IP_SFDP_BASIC_READ144_SUP_DWORD,
639     QSPI_IP_SFDP_BASIC_READ444_SUP_DWORD,
640     QSPI_IP_SFDP_BASIC_READ118_SUP_DWORD,
641     QSPI_IP_SFDP_BASIC_READ188_SUP_DWORD
642 };
643 
644 static uint8 readSupShift[QSPI_IP_SFDP_READ_MODE_MAX] = {
645     QSPI_IP_SFDP_BASIC_READ112_SUP_SHIFT,
646     QSPI_IP_SFDP_BASIC_READ122_SUP_SHIFT,
647     QSPI_IP_SFDP_BASIC_READ114_SUP_SHIFT,
648     QSPI_IP_SFDP_BASIC_READ144_SUP_SHIFT,
649     QSPI_IP_SFDP_BASIC_READ444_SUP_SHIFT,
650     QSPI_IP_SFDP_BASIC_READ118_SUP_SHIFT,
651     QSPI_IP_SFDP_BASIC_READ188_SUP_SHIFT
652 };
653 
654 static uint8 readSupWitdh[QSPI_IP_SFDP_READ_MODE_MAX] = {
655     QSPI_IP_SFDP_BASIC_READ112_SUP_WIDTH,
656     QSPI_IP_SFDP_BASIC_READ122_SUP_WIDTH,
657     QSPI_IP_SFDP_BASIC_READ114_SUP_WIDTH,
658     QSPI_IP_SFDP_BASIC_READ144_SUP_WIDTH,
659     QSPI_IP_SFDP_BASIC_READ444_SUP_WIDTH,
660     QSPI_IP_SFDP_BASIC_READ118_SUP_WIDTH,
661     QSPI_IP_SFDP_BASIC_READ188_SUP_WIDTH
662 };
663 
664 static uint8 read4ByteSupDword[QSPI_IP_SFDP_READ_MODE_MAX] = {
665     QSPI_IP_SFDP_4BADD_READ112_SUP_DWORD,
666     QSPI_IP_SFDP_4BADD_READ122_SUP_DWORD,
667     QSPI_IP_SFDP_4BADD_READ114_SUP_DWORD,
668     QSPI_IP_SFDP_4BADD_READ144_SUP_DWORD,
669     QSPI_IP_SFDP_4BADD_READ444_SUP_DWORD,
670     QSPI_IP_SFDP_4BADD_READ118_SUP_DWORD,
671     QSPI_IP_SFDP_4BADD_READ188_SUP_DWORD
672 };
673 
674 static uint8 read4ByteSupShift[QSPI_IP_SFDP_READ_MODE_MAX] = {
675     QSPI_IP_SFDP_4BADD_READ112_SUP_SHIFT,
676     QSPI_IP_SFDP_4BADD_READ122_SUP_SHIFT,
677     QSPI_IP_SFDP_4BADD_READ114_SUP_SHIFT,
678     QSPI_IP_SFDP_4BADD_READ144_SUP_SHIFT,
679     QSPI_IP_SFDP_4BADD_READ444_SUP_SHIFT,
680     QSPI_IP_SFDP_4BADD_READ118_SUP_SHIFT,
681     QSPI_IP_SFDP_4BADD_READ188_SUP_SHIFT
682 };
683 
684 static uint8 write4ByteSupDword[QSPI_IP_SFDP_READ_MODE_MAX] = {
685     QSPI_IP_SFDP_4BADD_WRITE112_SUP_DWORD,
686     QSPI_IP_SFDP_4BADD_WRITE122_SUP_DWORD,
687     QSPI_IP_SFDP_4BADD_WRITE114_SUP_DWORD,
688     QSPI_IP_SFDP_4BADD_WRITE144_SUP_DWORD,
689     QSPI_IP_SFDP_4BADD_WRITE444_SUP_DWORD,
690     QSPI_IP_SFDP_4BADD_WRITE118_SUP_DWORD,
691     QSPI_IP_SFDP_4BADD_WRITE188_SUP_DWORD
692 };
693 
694 static uint8 write4ByteSupShift[QSPI_IP_SFDP_READ_MODE_MAX] = {
695     QSPI_IP_SFDP_4BADD_WRITE112_SUP_SHIFT,
696     QSPI_IP_SFDP_4BADD_WRITE122_SUP_SHIFT,
697     QSPI_IP_SFDP_4BADD_WRITE114_SUP_SHIFT,
698     QSPI_IP_SFDP_4BADD_WRITE144_SUP_SHIFT,
699     QSPI_IP_SFDP_4BADD_WRITE444_SUP_SHIFT,
700     QSPI_IP_SFDP_4BADD_WRITE118_SUP_SHIFT,
701     QSPI_IP_SFDP_4BADD_WRITE188_SUP_SHIFT
702 };
703 
704 static uint8 read4ByteInst[QSPI_IP_SFDP_READ_MODE_MAX] = {
705     0x3CU,
706     0xBCU,
707     0x6CU,
708     0xECU,
709     0x13U,
710     0x7CU,
711     0xCCU
712 };
713 
714 static uint8 write4ByteInst[QSPI_IP_SFDP_READ_MODE_MAX] = {
715     0x00U,
716     0x00U,
717     0x34U,
718     0x3EU,
719     0x12U,
720     0x84U,
721     0x8EU
722 };
723 
724 static uint8 readInstDword[QSPI_IP_SFDP_READ_MODE_MAX] = {
725     QSPI_IP_SFDP_BASIC_READ112_INST_DWORD,
726     QSPI_IP_SFDP_BASIC_READ122_INST_DWORD,
727     QSPI_IP_SFDP_BASIC_READ114_INST_DWORD,
728     QSPI_IP_SFDP_BASIC_READ144_INST_DWORD,
729     QSPI_IP_SFDP_BASIC_READ444_INST_DWORD,
730     QSPI_IP_SFDP_BASIC_READ118_INST_DWORD,
731     QSPI_IP_SFDP_BASIC_READ188_INST_DWORD
732 };
733 
734 static uint8 readInstShift[QSPI_IP_SFDP_READ_MODE_MAX] = {
735     QSPI_IP_SFDP_BASIC_READ112_INST_SHIFT,
736     QSPI_IP_SFDP_BASIC_READ122_INST_SHIFT,
737     QSPI_IP_SFDP_BASIC_READ114_INST_SHIFT,
738     QSPI_IP_SFDP_BASIC_READ144_INST_SHIFT,
739     QSPI_IP_SFDP_BASIC_READ444_INST_SHIFT,
740     QSPI_IP_SFDP_BASIC_READ118_INST_SHIFT,
741     QSPI_IP_SFDP_BASIC_READ188_INST_SHIFT
742 };
743 
744 static uint8 readInstWidth[QSPI_IP_SFDP_READ_MODE_MAX] = {
745     QSPI_IP_SFDP_BASIC_READ112_INST_WIDTH,
746     QSPI_IP_SFDP_BASIC_READ122_INST_WIDTH,
747     QSPI_IP_SFDP_BASIC_READ114_INST_WIDTH,
748     QSPI_IP_SFDP_BASIC_READ144_INST_WIDTH,
749     QSPI_IP_SFDP_BASIC_READ444_INST_WIDTH,
750     QSPI_IP_SFDP_BASIC_READ118_INST_WIDTH,
751     QSPI_IP_SFDP_BASIC_READ188_INST_WIDTH
752 };
753 
754 static uint8 readModeDword[QSPI_IP_SFDP_READ_MODE_MAX] = {
755     QSPI_IP_SFDP_BASIC_READ112_MODE_DWORD,
756     QSPI_IP_SFDP_BASIC_READ122_MODE_DWORD,
757     QSPI_IP_SFDP_BASIC_READ114_MODE_DWORD,
758     QSPI_IP_SFDP_BASIC_READ144_MODE_DWORD,
759     QSPI_IP_SFDP_BASIC_READ444_MODE_DWORD,
760     QSPI_IP_SFDP_BASIC_READ118_MODE_DWORD,
761     QSPI_IP_SFDP_BASIC_READ188_MODE_DWORD
762 };
763 
764 static uint8 readModeShift[QSPI_IP_SFDP_READ_MODE_MAX] = {
765     QSPI_IP_SFDP_BASIC_READ112_MODE_SHIFT,
766     QSPI_IP_SFDP_BASIC_READ122_MODE_SHIFT,
767     QSPI_IP_SFDP_BASIC_READ114_MODE_SHIFT,
768     QSPI_IP_SFDP_BASIC_READ144_MODE_SHIFT,
769     QSPI_IP_SFDP_BASIC_READ444_MODE_SHIFT,
770     QSPI_IP_SFDP_BASIC_READ118_MODE_SHIFT,
771     QSPI_IP_SFDP_BASIC_READ188_MODE_SHIFT
772 };
773 
774 static uint8 readModeWidth[QSPI_IP_SFDP_READ_MODE_MAX] = {
775     QSPI_IP_SFDP_BASIC_READ112_MODE_WIDTH,
776     QSPI_IP_SFDP_BASIC_READ122_MODE_WIDTH,
777     QSPI_IP_SFDP_BASIC_READ114_MODE_WIDTH,
778     QSPI_IP_SFDP_BASIC_READ144_MODE_WIDTH,
779     QSPI_IP_SFDP_BASIC_READ444_MODE_WIDTH,
780     QSPI_IP_SFDP_BASIC_READ118_MODE_WIDTH,
781     QSPI_IP_SFDP_BASIC_READ188_MODE_WIDTH
782 };
783 
784 static uint8 readDummyDword[QSPI_IP_SFDP_READ_MODE_MAX] = {
785     QSPI_IP_SFDP_BASIC_READ112_DUMMY_DWORD,
786     QSPI_IP_SFDP_BASIC_READ122_DUMMY_DWORD,
787     QSPI_IP_SFDP_BASIC_READ114_DUMMY_DWORD,
788     QSPI_IP_SFDP_BASIC_READ144_DUMMY_DWORD,
789     QSPI_IP_SFDP_BASIC_READ444_DUMMY_DWORD,
790     QSPI_IP_SFDP_BASIC_READ118_DUMMY_DWORD,
791     QSPI_IP_SFDP_BASIC_READ188_DUMMY_DWORD
792 };
793 
794 static uint8 readDummyShift[QSPI_IP_SFDP_READ_MODE_MAX] = {
795     QSPI_IP_SFDP_BASIC_READ112_DUMMY_SHIFT,
796     QSPI_IP_SFDP_BASIC_READ122_DUMMY_SHIFT,
797     QSPI_IP_SFDP_BASIC_READ114_DUMMY_SHIFT,
798     QSPI_IP_SFDP_BASIC_READ144_DUMMY_SHIFT,
799     QSPI_IP_SFDP_BASIC_READ444_DUMMY_SHIFT,
800     QSPI_IP_SFDP_BASIC_READ118_DUMMY_SHIFT,
801     QSPI_IP_SFDP_BASIC_READ188_DUMMY_SHIFT
802 };
803 
804 static uint8 readDummyWidth[QSPI_IP_SFDP_READ_MODE_MAX] = {
805     QSPI_IP_SFDP_BASIC_READ112_DUMMY_WIDTH,
806     QSPI_IP_SFDP_BASIC_READ122_DUMMY_WIDTH,
807     QSPI_IP_SFDP_BASIC_READ114_DUMMY_WIDTH,
808     QSPI_IP_SFDP_BASIC_READ144_DUMMY_WIDTH,
809     QSPI_IP_SFDP_BASIC_READ444_DUMMY_WIDTH,
810     QSPI_IP_SFDP_BASIC_READ118_DUMMY_WIDTH,
811     QSPI_IP_SFDP_BASIC_READ188_DUMMY_WIDTH
812 };
813 
814 #define MEM_43_EXFLS_STOP_SEC_VAR_INIT_8
815 #include "Mem_43_EXFLS_MemMap.h"
816 
817 
818 #define MEM_43_EXFLS_START_SEC_VAR_INIT_UNSPECIFIED
819 #include "Mem_43_EXFLS_MemMap.h"
820 
821 static Qspi_Ip_LutPadsType readModeInstPads[QSPI_IP_SFDP_READ_MODE_MAX] = {
822     QSPI_IP_LUT_PADS_1,
823     QSPI_IP_LUT_PADS_1,
824     QSPI_IP_LUT_PADS_1,
825     QSPI_IP_LUT_PADS_1,
826     QSPI_IP_LUT_PADS_4,
827     QSPI_IP_LUT_PADS_1,
828     QSPI_IP_LUT_PADS_1
829 };
830 
831 static Qspi_Ip_LutPadsType readModeAddrPads[QSPI_IP_SFDP_READ_MODE_MAX] = {
832     QSPI_IP_LUT_PADS_1,
833     QSPI_IP_LUT_PADS_2,
834     QSPI_IP_LUT_PADS_1,
835     QSPI_IP_LUT_PADS_4,
836     QSPI_IP_LUT_PADS_4,
837     QSPI_IP_LUT_PADS_1,
838     QSPI_IP_LUT_PADS_8
839 };
840 
841 static Qspi_Ip_LutPadsType readModeDataPads[QSPI_IP_SFDP_READ_MODE_MAX] = {
842     QSPI_IP_LUT_PADS_2,
843     QSPI_IP_LUT_PADS_2,
844     QSPI_IP_LUT_PADS_4,
845     QSPI_IP_LUT_PADS_4,
846     QSPI_IP_LUT_PADS_4,
847     QSPI_IP_LUT_PADS_8,
848     QSPI_IP_LUT_PADS_8
849 };
850 
851 #define MEM_43_EXFLS_STOP_SEC_VAR_INIT_UNSPECIFIED
852 #include "Mem_43_EXFLS_MemMap.h"
853 
854 
855 /*==================================================================================================
856  *LOCAL FUNCTION PROTOTYPES
857 ==================================================================================================*/
858 #define MEM_43_EXFLS_START_SEC_CODE
859 #include "Mem_43_EXFLS_MemMap.h"
860 
861 static inline Qspi_Ip_InstrOpType Qspi_Ip_PackLut(Qspi_Ip_LutCommandsType cmd,
862                                                   Qspi_Ip_LutPadsType pad,
863                                                   uint8 op
864                                                  );
865 
866 static inline void Qspi_Ip_SfdpLutInit(void);
867 
868 static inline void Qspi_Ip_SfdpLutAdd(const Qspi_Ip_LutConfigType *lutSequences,
869                                       Qspi_Ip_InstrOpType instr
870                                      );
871 
872 static inline uint32 Qspi_Ip_SfdpGetBasicParam(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
873                                                uint8 dword,
874                                                uint8 shift,
875                                                uint8 width,
876                                                uint32 defaultValue
877                                               );
878 
879 static inline uint32 Qspi_Ip_SfdpGet4BAddParam(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
880                                                uint8 dword,
881                                                uint8 shift,
882                                                uint8 width,
883                                                uint32 defaultValue
884                                               );
885 
886 static inline uint32 Qspi_Ip_SfdpGetXspi1Param(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
887                                                uint8 dword,
888                                                uint8 shift,
889                                                uint8 width,
890                                                uint32 defaultValue
891                                               );
892 
893 static inline uint32 Qspi_Ip_SfdpGetSRMapParam(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
894                                                uint8 dword,
895                                                uint8 shift,
896                                                uint8 width,
897                                                uint32 defaultValue
898                                               );
899 
900 static inline uint32 Qspi_Ip_SfdpGet2DopiParam(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
901                                                uint8 dword,
902                                                uint8 shift,
903                                                uint8 width,
904                                                uint32 defaultValue
905                                               );
906 
907 static void Qspi_Ip_SfdpLutAddSrAddr(const Qspi_Ip_LutConfigType *lutSequences,
908                                      const Qspi_Ip_SfdpTablesContainer *sfdpTables
909                                     );
910 
911 static inline boolean Qspi_Ip_SfdpSignatureCheck(const uint8 *data);
912 
913 static inline void Qspi_Ip_SfdpInitLut(uint32 instance,
914                                        Qspi_Ip_SfdpModes mode
915                                       );
916 
917 static void Qspi_Ip_WaitAfterReset(void);
918 
919 static void Qspi_Ip_SfdpInitReset(uint32 instance,
920                                   uint32 baseAddress
921                                  );
922 
923 static void Qspi_Ip_SfdpInitReset_4S4S4S(uint32 instance,
924                                          uint32 baseAddress
925                                         );
926 
927 static void Qspi_Ip_SfdpExitQPI(uint32 instance,
928                                 uint32 baseAddress
929                                );
930 
931 
932 static void Qspi_Ip_SfdpInitReset_8D8D8D(uint32 instance,
933                                          uint32 baseAddress
934                                         );
935 
936 static void Qspi_Ip_SfdpPackLutEnterLegacySPI(uint32 sequenceIndex,
937                                               uint32 *lutData
938                                              );
939 
940 static void Qspi_Ip_SfdpLutInitEnterLegacySPI(Qspi_Ip_MemoryConfigType const *pConfig);
941 
942 static void Qspi_Ip_SfdpEnterLegacySPI(uint32 instance,
943                                        uint32 baseAddress
944                                       );
945 
946 static void Qspi_Ip_SfdpExitDOPI(uint32 instance,
947                                  uint32 baseAddress
948                                 );
949 
950 static Qspi_Ip_StatusType Qspi_Ip_SfdpCheck(uint32 instance,
951                                             uint32 baseAddress
952                                            );
953 
954 static Qspi_Ip_StatusType Qspi_Ip_SfdpFindWorkingMode(uint32 instance,
955                                                       uint32 baseAddress
956                                                      );
957 
958 static inline boolean Qspi_Ip_SfdpCheckMinorRevision(uint8 minorRevision);
959 
960 static inline uint8 Qspi_Ip_SfdpGetCmdExt(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
961                                           uint8 instruction
962                                          );
963 
964 static inline uint32 Qspi_Ip_SfdpGetParamTableAddress(const uint8 * paramHeader,
965                                                       uint8 accessProtocol
966                                                      );
967 
968 static inline boolean Qspi_Ip_SfdpCheckNewerRevision(uint8 paramIdLSB,
969                                                      uint8 tableType,
970                                                      uint8 majorRevision,
971                                                      uint8 minorRevision,
972                                                      sint16 minorRevisionMax
973                                                     );
974 
975 static Qspi_Ip_StatusType Qspi_Ip_SfdpFindTable(uint32 instance,
976                                                 uint32 baseAddress,
977                                                 Qspi_Ip_SfdpTables tableType,
978                                                 uint32 * paramTable,
979                                                 uint8 * paramTableLength
980                                                );
981 
982 static Qspi_Ip_StatusType Qspi_Ip_SfdpReadTables(uint32 instance,
983                                                  uint32 baseAddress,
984                                                  Qspi_Ip_SfdpTablesContainer *sfdpTables
985                                                 );
986 
987 static void Qspi_Ip_SfdpInitSimpleCmd(uint8 cmd,
988                                       const Qspi_Ip_MemoryConfigType *pConfig
989                                      );
990 
991 static uint8 Qspi_Ip_SfdpGetWeSrInstr(const Qspi_Ip_SfdpTablesContainer *sfdpTables);
992 
993 static void Qspi_Ip_SfdpInitWriteReg(uint8 cmd,
994                                      uint8 wrenCmd,
995                                      uint8 size,
996                                      uint32 value,
997                                      const Qspi_Ip_MemoryConfigType *pConfig
998                                     );
999 
1000 static Qspi_Ip_StatusType Qspi_Ip_Sfdp4byteAddrSwitch_01(const Qspi_Ip_MemoryConfigType * pConfig);
1001 static Qspi_Ip_StatusType Qspi_Ip_Sfdp4byteAddrSwitch_02(const Qspi_Ip_MemoryConfigType * pConfig);
1002 static Qspi_Ip_StatusType Qspi_Ip_Sfdp4byteAddrSwitch_08(const Qspi_Ip_MemoryConfigType * pConfig);
1003 static Qspi_Ip_StatusType Qspi_Ip_Sfdp4byteAddrSwitch_16(const Qspi_Ip_MemoryConfigType * pConfig);
1004 
1005 static Qspi_Ip_StatusType Qspi_Ip_Sfdp4byteAddrSwitch(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1006                                                       const Qspi_Ip_MemoryConfigType *pConfig
1007                                                      );
1008 
1009 static void Qspi_Ip_SfdpGetBasicAddrBits(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1010                                          const Qspi_Ip_MemoryConfigType *pConfig
1011                                         );
1012 
1013 static void Qspi_Ip_SfdpConfigureQE(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1014                                     const Qspi_Ip_MemoryConfigType *pConfig
1015                                    );
1016 
1017 static Qspi_Ip_LutCommandsType Qspi_Ip_SfdpGetModeInstr(uint8 modeClocks,
1018                                                         Qspi_Ip_LutPadsType addrPads
1019                                                        );
1020 
1021 static void Qspi_Ip_SfdpGetSpiReadInstr(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1022                                         uint8 cnt,
1023                                         uint8 *instruction,
1024                                         uint8 *addrBits
1025                                        );
1026 
1027 static void Qspi_Ip_SfdpConfigBasicRead(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1028                                         Qspi_Ip_MemoryConfigType *pConfig
1029                                        );
1030 
1031 static Qspi_Ip_StatusType Qspi_Ip_Sfdp444Switch_01(const Qspi_Ip_MemoryConfigType * pConfig);
1032 static Qspi_Ip_StatusType Qspi_Ip_Sfdp444Switch_04(const Qspi_Ip_MemoryConfigType * pConfig);
1033 static Qspi_Ip_StatusType Qspi_Ip_Sfdp444Switch_08(const Qspi_Ip_MemoryConfigType * pConfig);
1034 static Qspi_Ip_StatusType Qspi_Ip_Sfdp444Switch_16(const Qspi_Ip_MemoryConfigType * pConfig);
1035 
1036 static Qspi_Ip_StatusType Qspi_Ip_Sfdp444Switch(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1037                                                 const Qspi_Ip_MemoryConfigType *pConfig
1038                                                );
1039 
1040 static void Qspi_Ip_SfdpGetBasicReadInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1041                                          Qspi_Ip_MemoryConfigType *pConfig
1042                                         );
1043 
1044 static void Qspi_Ip_SfdpGetBasicWriteInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1045                                           Qspi_Ip_MemoryConfigType *pConfig
1046                                          );
1047 
1048 static void Qspi_Ip_SfdpGetXspi1ReadInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1049                                          Qspi_Ip_MemoryConfigType * pConfig
1050                                         );
1051 
1052 static void Qspi_Ip_SfdpGetXspi1WriteInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1053                                           Qspi_Ip_MemoryConfigType *pConfig
1054                                          );
1055 
1056 static uint8 Qspi_Ip_SfdpGetBasicEraseInstr(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1057                                             uint8 cnt,
1058                                             uint8 *addrbits
1059                                            );
1060 
1061 static uint8 Qspi_Ip_SfdpGetXspi1EraseInstr(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1062                                             uint8 cnt);
1063 
1064 static void Qspi_Ip_SfdpGetBasicEraseInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1065                                           Qspi_Ip_MemoryConfigType *pConfig
1066                                          );
1067 
1068 static void Qspi_Ip_SfdpGetXspi1EraseInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1069                                           Qspi_Ip_MemoryConfigType *pConfig
1070                                          );
1071 
1072 static void Qspi_Ip_SfdpConfigureInitReadStatus(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1073                                                 Qspi_Ip_MemoryConfigType *pConfig,
1074                                                 uint8 instruction
1075                                                );
1076 
1077 static void Qspi_Ip_SfdpGetBasicStatusInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1078                                            Qspi_Ip_MemoryConfigType *pConfig
1079                                           );
1080 
1081 static void Qspi_Ip_SfdpGetXspi1StatusInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1082                                            Qspi_Ip_MemoryConfigType *pConfig
1083                                           );
1084 
1085 static void Qspi_Ip_SfdpConfigReset1(const Qspi_Ip_MemoryConfigType *pConfig,
1086                                      const Qspi_Ip_ResetConfigType *resetSettings,
1087                                      Qspi_Ip_LutPadsType pads
1088                                     );
1089 
1090 static void Qspi_Ip_SfdpConfigReset2(const Qspi_Ip_MemoryConfigType *pConfig,
1091                                      const Qspi_Ip_ResetConfigType *resetSettings,
1092                                      Qspi_Ip_LutPadsType pads
1093                                     );
1094 
1095 static void Qspi_Ip_SfdpConfigReset4(const Qspi_Ip_MemoryConfigType *pConfig,
1096                                      const Qspi_Ip_ResetConfigType *resetSettings,
1097                                      Qspi_Ip_LutPadsType pads
1098                                     );
1099 
1100 static void Qspi_Ip_SfdpConfigReset8(const Qspi_Ip_MemoryConfigType *pConfig,
1101                                      Qspi_Ip_ResetConfigType *resetSettings,
1102                                      Qspi_Ip_LutPadsType pads
1103                                     );
1104 
1105 static void Qspi_Ip_SfdpConfigReset16(const Qspi_Ip_MemoryConfigType *pConfig,
1106                                       Qspi_Ip_ResetConfigType *resetSettings,
1107                                       Qspi_Ip_LutPadsType pads
1108                                      );
1109 
1110 static void Qspi_Ip_SfdpConfigResetOthers(uint8 resetOption,
1111                                           const Qspi_Ip_MemoryConfigType * pConfig,
1112                                           Qspi_Ip_ResetConfigType *resetSettings,
1113                                           Qspi_Ip_LutPadsType pads
1114                                          );
1115 
1116 static void Qspi_Ip_SfdpGetBasicResetInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1117                                           const Qspi_Ip_MemoryConfigType *pConfig,
1118                                           Qspi_Ip_ResetConfigType *resetSettings,
1119                                           Qspi_Ip_LutPadsType pads
1120                                          );
1121 
1122 static void Qspi_Ip_SfdpGetXspi1ResetInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1123                                           Qspi_Ip_MemoryConfigType *pConfig
1124                                          );
1125 
1126 static void Qspi_Ip_SfdpGetXspi1InitResetInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1127                                               Qspi_Ip_MemoryConfigType *pConfig
1128                                              );
1129 
1130 static void Qspi_Ip_SfdpGetBasicSuspendInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1131                                             Qspi_Ip_MemoryConfigType *pConfig
1132                                            );
1133 
1134 static void Qspi_Ip_SfdpGetXspi1SuspendInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1135                                             Qspi_Ip_MemoryConfigType *pConfig
1136                                            );
1137 
1138 static void Qspi_Ip_SfdpAdd2dopiOperation(const Qspi_Ip_MemoryConfigType *pConfig,
1139                                           uint8 seqSize,
1140                                           const uint32 *words
1141                                          );
1142 
1143 static void Qspi_Ip_SfdpAddCheckBusyOperation(const Qspi_Ip_MemoryConfigType *pConfig);
1144 
1145 static void Qspi_Ip_SfdpGetXspi1InitOpInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1146                                            Qspi_Ip_MemoryConfigType *pConfig
1147                                           );
1148 
1149 static void Qspi_Ip_SfdpGetBasicInitOpInfo(Qspi_Ip_MemoryConfigType *pConfig);
1150 
1151 static void Qspi_Ip_SfdpGet0xxInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1152                                    Qspi_Ip_MemoryConfigType *pConfig
1153                                   );
1154 
1155 static void Qspi_Ip_SfdpConfigureOther(Qspi_Ip_MemoryConfigType *pConfig);
1156 
1157 static void Qspi_Ip_SfdpGetSize(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1158                                 Qspi_Ip_MemoryConfigType *pConfig
1159                                );
1160 
1161 static Qspi_Ip_StatusType Qspi_Ip_ConfigureBasic(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1162                                                  Qspi_Ip_MemoryConfigType *pConfig
1163                                                 );
1164 
1165 static Qspi_Ip_StatusType Qspi_Ip_ConfigureXspi1(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1166                                                  Qspi_Ip_MemoryConfigType *pConfig
1167                                                 );
1168 
1169 static inline void Qspi_Ip_SfdpGetBasicInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1170                                             Qspi_Ip_MemoryConfigType *pConfig
1171                                            );
1172 
1173 static inline void Qspi_Ip_SfdpGetXspi1Info(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1174                                             Qspi_Ip_MemoryConfigType *pConfig
1175                                            );
1176 
1177 #define MEM_43_EXFLS_STOP_SEC_CODE
1178 #include "Mem_43_EXFLS_MemMap.h"
1179 
1180 
1181 /*******************************************************************************
1182  * Private Functions
1183  ******************************************************************************/
1184 
1185 #define MEM_43_EXFLS_START_SEC_CODE
1186 #include "Mem_43_EXFLS_MemMap.h"
1187 
1188 
1189 /*FUNCTION**********************************************************************
1190  *
1191  * Function Name : Qspi_Ip_PackLut
1192  * Description   : Packs command, pads count and operand in a LUT entry
1193  */
Qspi_Ip_PackLut(Qspi_Ip_LutCommandsType cmd,Qspi_Ip_LutPadsType pad,uint8 op)1194 static inline Qspi_Ip_InstrOpType Qspi_Ip_PackLut(Qspi_Ip_LutCommandsType cmd,
1195                                                   Qspi_Ip_LutPadsType pad,
1196                                                   uint8 op
1197                                                  )
1198 {
1199     return (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)cmd | (Qspi_Ip_InstrOpType)pad | (Qspi_Ip_InstrOpType)op);
1200 }
1201 
1202 
1203 /*FUNCTION**********************************************************************
1204  *
1205  * Function Name : Qspi_Ip_SfdpLutInit
1206  * Description   : Initializes LUT and init operations counters
1207  */
Qspi_Ip_SfdpLutInit(void)1208 static inline void Qspi_Ip_SfdpLutInit(void)
1209 {
1210     lutCount = 0U;
1211     initOpCount = 0U;
1212     overflow = FALSE;
1213     quadAvailable = TRUE;
1214 }
1215 
1216 
1217 /*FUNCTION**********************************************************************
1218  *
1219  * Function Name : Qspi_Ip_SfdpLutAdd
1220  * Description   : Initializes LUT and init operations counters
1221  */
Qspi_Ip_SfdpLutAdd(const Qspi_Ip_LutConfigType * lutSequences,Qspi_Ip_InstrOpType instr)1222 static inline void Qspi_Ip_SfdpLutAdd(const Qspi_Ip_LutConfigType *lutSequences,
1223                                       Qspi_Ip_InstrOpType instr
1224                                      )
1225 {
1226     if (lutCount < lutSequences->opCount)
1227     {
1228         lutSequences->lutOps[lutCount] = instr;
1229         lutCount++;
1230     }
1231     else
1232     {
1233         overflow = TRUE;
1234     }
1235 }
1236 
1237 
1238 /*FUNCTION**********************************************************************
1239  *
1240  * Function Name : Qspi_Ip_SfdpGetBasicParam
1241  * Description   : Returns a bitfield from the SFDP tables
1242  */
Qspi_Ip_SfdpGetBasicParam(const Qspi_Ip_SfdpTablesContainer * sfdpTables,uint8 dword,uint8 shift,uint8 width,uint32 defaultValue)1243 static inline uint32 Qspi_Ip_SfdpGetBasicParam(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1244                                                uint8 dword,
1245                                                uint8 shift,
1246                                                uint8 width,
1247                                                uint32 defaultValue
1248                                               )
1249 {
1250     const uint32* tablePtr  = NULL_PTR;
1251     uint8 tableSize         = 0U;
1252     volatile uint32 mask    = 0UL;
1253     volatile uint32 result  = 0UL;
1254 
1255     tablePtr  = sfdpTables->paramTable_basic;
1256     tableSize = sfdpTables->paramTableLength_basic;
1257 
1258     if ((NULL_PTR != tablePtr) && (dword <= tableSize) )
1259     {
1260         /* get required field */
1261         mask   = (1UL << (uint32)(width)) - 1UL;
1262         result = ((uint32)(tablePtr[dword - 1U] >> shift)) & mask;
1263     }
1264     else
1265     {
1266         /* table too short, use default */
1267         result = defaultValue;
1268     }
1269 
1270     return result;
1271 }
1272 
1273 /*FUNCTION**********************************************************************
1274  *
1275  * Function Name : Qspi_Ip_SfdpGet4BAddParam
1276  * Description   : Returns a bitfield from the SFDP tables
1277  */
Qspi_Ip_SfdpGet4BAddParam(const Qspi_Ip_SfdpTablesContainer * sfdpTables,uint8 dword,uint8 shift,uint8 width,uint32 defaultValue)1278 static inline uint32 Qspi_Ip_SfdpGet4BAddParam(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1279                                                uint8 dword,
1280                                                uint8 shift,
1281                                                uint8 width,
1282                                                uint32 defaultValue
1283                                               )
1284 {
1285     const uint32* tablePtr  = NULL_PTR;
1286     uint8 tableSize         = 0U;
1287     volatile uint32 mask    = 0UL;
1288     volatile uint32 result  = 0UL;
1289 
1290     tablePtr  = sfdpTables->paramTable_4badd;
1291     tableSize = sfdpTables->paramTableLength_4badd;
1292 
1293     if ((NULL_PTR != tablePtr) && (dword <= tableSize) )
1294     {
1295         /* get required field */
1296         mask   = (1UL << (uint32)(width)) - 1UL;
1297         result = ((uint32)(tablePtr[dword - 1U] >> shift)) & mask;
1298     }
1299     else
1300     {
1301         /* table too short, use default */
1302         result = defaultValue;
1303     }
1304 
1305     return result;
1306 }
1307 
1308 /*FUNCTION**********************************************************************
1309  *
1310  * Function Name : Qspi_Ip_SfdpGetXspi1Param
1311  * Description   : Returns a bitfield from the SFDP tables
1312  */
Qspi_Ip_SfdpGetXspi1Param(const Qspi_Ip_SfdpTablesContainer * sfdpTables,uint8 dword,uint8 shift,uint8 width,uint32 defaultValue)1313 static inline uint32 Qspi_Ip_SfdpGetXspi1Param(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1314                                                uint8 dword,
1315                                                uint8 shift,
1316                                                uint8 width,
1317                                                uint32 defaultValue
1318                                               )
1319 {
1320     const uint32* tablePtr  = NULL_PTR;
1321     uint8 tableSize         = 0U;
1322     volatile uint32 mask    = 0UL;
1323     volatile uint32 result  = 0UL;
1324 
1325     tablePtr  = sfdpTables->paramTable_xspi1;
1326     tableSize = sfdpTables->paramTableLength_xspi1;
1327 
1328     if ((NULL_PTR != tablePtr) && (dword <= tableSize) )
1329     {
1330         /* get required field */
1331         mask   = (1UL << (uint32)(width)) - 1UL;
1332         result = ((uint32)(tablePtr[dword - 1U] >> shift)) & mask;
1333     }
1334     else
1335     {
1336         /* table too short, use default */
1337         result = defaultValue;
1338     }
1339 
1340     return result;
1341 }
1342 
1343 /*FUNCTION**********************************************************************
1344  *
1345  * Function Name : Qspi_Ip_SfdpGetSRMapParam
1346  * Description   : Returns a bitfield from the SFDP tables
1347  */
Qspi_Ip_SfdpGetSRMapParam(const Qspi_Ip_SfdpTablesContainer * sfdpTables,uint8 dword,uint8 shift,uint8 width,uint32 defaultValue)1348 static inline uint32 Qspi_Ip_SfdpGetSRMapParam(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1349                                                uint8 dword,
1350                                                uint8 shift,
1351                                                uint8 width,
1352                                                uint32 defaultValue
1353                                               )
1354 {
1355     const uint32* tablePtr  = NULL_PTR;
1356     uint8 tableSize         = 0U;
1357     volatile uint32 mask    = 0UL;
1358     volatile uint32 result  = 0UL;
1359 
1360     tablePtr  = sfdpTables->paramTable_srmap;
1361     tableSize = sfdpTables->paramTableLength_srmap;
1362 
1363     if ((NULL_PTR != tablePtr) && (dword <= tableSize) )
1364     {
1365         /* get required field */
1366         mask   = (1UL << (uint32)(width)) - 1UL;
1367         result = ((uint32)(tablePtr[dword - 1U] >> shift)) & mask;
1368     }
1369     else
1370     {
1371         /* table too short, use default */
1372         result = defaultValue;
1373     }
1374 
1375     return result;
1376 }
1377 
1378 /*FUNCTION**********************************************************************
1379  *
1380  * Function Name : Qspi_Ip_SfdpGet2DopiParam
1381  * Description   : Returns a bitfield from the SFDP tables
1382  */
Qspi_Ip_SfdpGet2DopiParam(const Qspi_Ip_SfdpTablesContainer * sfdpTables,uint8 dword,uint8 shift,uint8 width,uint32 defaultValue)1383 static inline uint32 Qspi_Ip_SfdpGet2DopiParam(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1384                                                uint8 dword,
1385                                                uint8 shift,
1386                                                uint8 width,
1387                                                uint32 defaultValue
1388                                               )
1389 {
1390     const uint32* tablePtr  = NULL_PTR;
1391     uint8 tableSize         = 0U;
1392     volatile uint32 mask    = 0UL;
1393     volatile uint32 result  = 0UL;
1394 
1395     tablePtr  = sfdpTables->paramTable_2dopi;
1396     tableSize = sfdpTables->paramTableLength_2dopi;
1397 
1398     if ((NULL_PTR != tablePtr) && (dword <= tableSize) )
1399     {
1400         /* get required field */
1401         mask   = (1UL << (uint32)(width)) - 1UL;
1402         result = ((uint32)(tablePtr[dword - 1U] >> shift)) & mask;
1403     }
1404     else
1405     {
1406         /* table too short, use default */
1407         result = defaultValue;
1408     }
1409 
1410     return result;
1411 }
1412 
1413 
1414 /*FUNCTION**********************************************************************
1415  *
1416  * Function Name : Qspi_Ip_SfdpLutAddSrAddr
1417  * Description   : Initializes LUT and init operations counters
1418  */
Qspi_Ip_SfdpLutAddSrAddr(const Qspi_Ip_LutConfigType * lutSequences,const Qspi_Ip_SfdpTablesContainer * sfdpTables)1419 static void Qspi_Ip_SfdpLutAddSrAddr(const Qspi_Ip_LutConfigType *lutSequences,
1420                                      const Qspi_Ip_SfdpTablesContainer *sfdpTables
1421                                     )
1422 {
1423     uint32 addrOffset;
1424     uint8 srAddr;
1425     uint8 srShift;
1426     uint8 nBytes;
1427     sint8 cnt;
1428     uint8 directCmd;
1429 
1430     /* SR read is direct command (not using address */
1431     directCmd = (uint8)Qspi_Ip_SfdpGetSRMapParam(sfdpTables, QSPI_IP_SFDP_SRMAP_USE_ADDR_DWORD,
1432                                                  QSPI_IP_SFDP_SRMAP_USE_ADDR_SHIFT, QSPI_IP_SFDP_SRMAP_USE_ADDR_WIDTH, 0x0U);
1433     if (directCmd == 0U)
1434     {
1435         /* direct command - nothing to do */
1436     }
1437     else
1438     {
1439         /* Address offset for volatile registers */
1440         addrOffset = (uint32)Qspi_Ip_SfdpGetSRMapParam(sfdpTables, QSPI_IP_SFDP_SRMAP_OFFSET_DWORD,
1441                                                        QSPI_IP_SFDP_SRMAP_OFFSET_SHIFT, QSPI_IP_SFDP_SRMAP_OFFSET_WIDTH, 0x0U);
1442         /* Number of address bytes used for Generic Addressable Read/Write Status/Control register commands for volatile registers */
1443         nBytes = (uint8)Qspi_Ip_SfdpGetSRMapParam(sfdpTables, QSPI_IP_SFDP_SRMAP_NBYTES_DWORD,
1444                                                   QSPI_IP_SFDP_SRMAP_NBYTES_SHIFT, QSPI_IP_SFDP_SRMAP_NBYTES_WIDTH, 0x0U);
1445         /* SR local address */
1446         srAddr = (uint8)Qspi_Ip_SfdpGetSRMapParam(sfdpTables, QSPI_IP_SFDP_SRMAP_SR_ADDR_DWORD,
1447                                                   QSPI_IP_SFDP_SRMAP_SR_ADDR_SHIFT, QSPI_IP_SFDP_SRMAP_SR_ADDR_WIDTH, 0x0U);
1448         /* SR address shift (before adding to the offset) */
1449         srShift = (uint8)Qspi_Ip_SfdpGetSRMapParam(sfdpTables, QSPI_IP_SFDP_SRMAP_SR_SHIFT_DWORD,
1450                                                    QSPI_IP_SFDP_SRMAP_SR_SHIFT_SHIFT, QSPI_IP_SFDP_SRMAP_SR_SHIFT_WIDTH, 0x0U);
1451 
1452         /* compute SR address */
1453         addrOffset = addrOffset + ((uint32)srAddr << (srShift * 8U));
1454         /* add address to LUT sequence. Use CMD in case addr is out of range */
1455         for (cnt = (sint8)nBytes; cnt >= 0; cnt--)
1456         {
1457             srAddr = (uint8)((addrOffset >> ((uint8)cnt * 8U)) & 0xFFU);
1458             Qspi_Ip_SfdpLutAdd(lutSequences, Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, srAddr));
1459         }
1460     }
1461 
1462     return;
1463 }
1464 
1465 
1466 /*FUNCTION**********************************************************************
1467  *
1468  * Function Name : Qspi_Ip_SfdpSignatureCheck
1469  * Description   : Checks SFDP signature
1470  */
Qspi_Ip_SfdpSignatureCheck(const uint8 * data)1471 static inline boolean Qspi_Ip_SfdpSignatureCheck(const uint8 *data)
1472 {
1473     boolean retCode = FALSE;
1474 
1475     if ((data[0] == 0x53U) && (data[1] == 0x46U) && (data[2] == 0x44U) && (data[3] == 0x50U))
1476     {
1477         retCode = TRUE;
1478     }
1479 
1480     return retCode;
1481 }
1482 
1483 
1484 /*FUNCTION**********************************************************************
1485  *
1486  * Function Name : Qspi_Ip_SfdpInitLut
1487  * Description   : Initializes LUT table for reading SFDP information, using the specified format
1488  */
Qspi_Ip_SfdpInitLut(uint32 instance,Qspi_Ip_SfdpModes mode)1489 static inline void Qspi_Ip_SfdpInitLut(uint32 instance,
1490                                        Qspi_Ip_SfdpModes mode
1491                                       )
1492 {
1493     Qspi_Ip_LutCommandsType instCmd;
1494     Qspi_Ip_LutCommandsType addrCmd;
1495     Qspi_Ip_LutCommandsType dataCmd;
1496     Qspi_Ip_LutPadsType pads;
1497     uint32 lutData[3U];  /* Data to be written to the physical LUTs */
1498 
1499     /* Set command parameters according to mode */
1500     instCmd = QSPI_IP_LUT_INSTR_CMD;
1501     addrCmd = QSPI_IP_LUT_INSTR_ADDR;
1502     dataCmd = QSPI_IP_LUT_INSTR_READ;
1503     if (QSPI_IP_SFDP_8D_8D_8D == mode)
1504     {
1505         pads = QSPI_IP_LUT_PADS_8;
1506         instCmd = QSPI_IP_LUT_INSTR_CMD_DDR;
1507         addrCmd = QSPI_IP_LUT_INSTR_ADDR_DDR;
1508         dataCmd = QSPI_IP_LUT_INSTR_READ_DDR;
1509     }
1510     else if (QSPI_IP_SFDP_4S_4D_4D == mode)
1511     {
1512         pads = QSPI_IP_LUT_PADS_4;
1513         addrCmd = QSPI_IP_LUT_INSTR_ADDR_DDR;
1514         dataCmd = QSPI_IP_LUT_INSTR_READ_DDR;
1515     }
1516     else if (QSPI_IP_SFDP_4S_4S_4S == mode)
1517     {
1518         pads = QSPI_IP_LUT_PADS_4;
1519     }
1520     else if (QSPI_IP_SFDP_2S_2S_2S == mode)
1521     {
1522         pads = QSPI_IP_LUT_PADS_2;
1523     }
1524     else
1525     {
1526         pads = QSPI_IP_LUT_PADS_1;
1527     }
1528 
1529     /* Build SFDP Read Sequence */
1530     lutData[0] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(instCmd, pads, QSPI_IP_CMD_SFDP_READ),  /* READ SFDP command on 1 data line */
1531                                       Qspi_Ip_PackLut(addrCmd, pads, 24U));                   /* 24-bit address on 1 data line */
1532 
1533     lutData[1] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_DUMMY, pads, 8U),     /* 8 Dummy cycles */
1534                                       Qspi_Ip_PackLut(dataCmd, pads, 0x10U));                 /* Read data on "pads" data lines */
1535 
1536     lutData[2] = QSPI_IP_PACK_LUT_REG(QSPI_IP_LUT_SEQ_END, QSPI_IP_LUT_SEQ_END);              /* End of sequence */
1537 
1538     /* Write the SFDP Read Sequence into physical LUT registers */
1539     Qspi_Ip_WriteLuts(instance, QSPI_IP_COMMAND_LUT * FEATURE_QSPI_LUT_SEQUENCE_SIZE, lutData, 3U);
1540 }
1541 
1542 
1543 /*FUNCTION**********************************************************************
1544  *
1545  * Function Name : Qspi_Ip_WaitAfterReset
1546  * Description   : Wait until external memory is available for operation after a reset
1547  */
Qspi_Ip_WaitAfterReset(void)1548 static void Qspi_Ip_WaitAfterReset(void)
1549 {
1550     uint32  u32ElapsedTicks = 0U;
1551     uint32  u32TimeoutTicks;
1552     uint32  u32CurrentTicks;
1553 
1554     /* Prepare timeout counter */
1555     u32TimeoutTicks = OsIf_MicrosToTicks(QSPI_IP_RESET_TIMEOUT, (OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
1556     u32CurrentTicks = OsIf_GetCounter((OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
1557     /* Wait for the specified time */
1558     do
1559     {
1560         u32ElapsedTicks += OsIf_GetElapsed(&u32CurrentTicks, (OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
1561     }
1562     while (u32ElapsedTicks < u32TimeoutTicks);
1563 }
1564 
1565 
1566 /*FUNCTION**********************************************************************
1567  *
1568  * Function Name : Qspi_Ip_SfdpInitReset_4S4S4S
1569  * Description   : Sends 4S-4S-4S reset commands to force device to exit the QPI mode.
1570  */
Qspi_Ip_SfdpInitReset_4S4S4S(uint32 instance,uint32 baseAddress)1571 static void Qspi_Ip_SfdpInitReset_4S4S4S(uint32 instance,
1572                                          uint32 baseAddress
1573                                         )
1574 {
1575     /* Data to be written to the physical LUTs */
1576     uint32 lutData;
1577 
1578     const uint8 lutRegister = QSPI_IP_COMMAND_LUT * FEATURE_QSPI_LUT_SEQUENCE_SIZE;
1579 
1580     const Qspi_Ip_LutCommandsType cmd = QSPI_IP_LUT_INSTR_CMD;
1581     const Qspi_Ip_LutPadsType     pad = QSPI_IP_LUT_PADS_4;
1582 
1583     /* Send Reset Enable Command */
1584     lutData = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(cmd, pad, (uint8)QSPI_IP_CMD_XSPI_RESET_ENABLE),
1585                                    QSPI_IP_LUT_SEQ_END);
1586     Qspi_Ip_WriteLuts(instance, lutRegister, &lutData, 1U);
1587     (void)Qspi_Ip_IpCommand(instance, QSPI_IP_COMMAND_LUT, baseAddress);
1588 
1589     /* Send Reset Command */
1590     lutData = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(cmd, pad, (uint8)QSPI_IP_CMD_XSPI_RESET_DEF),
1591                                    QSPI_IP_LUT_SEQ_END);
1592     Qspi_Ip_WriteLuts(instance, lutRegister, &lutData, 1U);
1593     (void)Qspi_Ip_IpCommand(instance, QSPI_IP_COMMAND_LUT, baseAddress);
1594 
1595     /* Wait for reset to complete */
1596     Qspi_Ip_WaitAfterReset();
1597 }
1598 
1599 
1600 /*FUNCTION**********************************************************************
1601  *
1602  * Function Name : Qspi_Ip_SfdpExitQPI
1603  * Description   : Attempt to exit the memory device from QPI (4-4-4) mode.
1604  */
Qspi_Ip_SfdpExitQPI(uint32 instance,uint32 baseAddress)1605 static void Qspi_Ip_SfdpExitQPI(uint32 instance,
1606                                 uint32 baseAddress
1607                                )
1608 {
1609     /* Workaround: send 4S-4S-4S reset command */
1610     Qspi_Ip_SfdpInitReset_4S4S4S(instance, baseAddress);
1611 }
1612 
1613 
1614 
1615 /*FUNCTION**********************************************************************
1616  *
1617  * Function Name : Qspi_Ip_SfdpInitReset_8D8D8D
1618  * Description   : Sends 8D-8D-8D reset commands to force device to enter SPI mode.
1619  */
Qspi_Ip_SfdpInitReset_8D8D8D(uint32 instance,uint32 baseAddress)1620 static void Qspi_Ip_SfdpInitReset_8D8D8D(uint32 instance,
1621                                          uint32 baseAddress
1622                                         )
1623 {
1624     /* Data to be written to the physical LUTs */
1625     uint32 lutData[2U] =
1626     {
1627         QSPI_IP_PACK_LUT_REG(QSPI_IP_LUT_SEQ_END, QSPI_IP_LUT_SEQ_END),
1628         QSPI_IP_PACK_LUT_REG(QSPI_IP_LUT_SEQ_END, QSPI_IP_LUT_SEQ_END)
1629     };
1630 
1631     const uint8 lutRegister = QSPI_IP_COMMAND_LUT * FEATURE_QSPI_LUT_SEQUENCE_SIZE;
1632 
1633     const Qspi_Ip_LutCommandsType cmd = QSPI_IP_LUT_INSTR_CMD_DDR;
1634     const Qspi_Ip_LutPadsType     pad = QSPI_IP_LUT_PADS_8;
1635 
1636     /* As we don't know yet the command extension convention of the device, try both ways */
1637     /* 1. Command Extension is the inverse of the Command */
1638     /* Send Reset Enable Command */
1639     lutData[0] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(cmd, pad, (uint8)QSPI_IP_CMD_XSPI_RESET_ENABLE),    /* Reset Enable command in DOPI Mode */
1640                                       Qspi_Ip_PackLut(cmd, pad, (uint8)~QSPI_IP_CMD_XSPI_RESET_ENABLE));  /* command extension */
1641     Qspi_Ip_WriteLuts(instance, lutRegister, lutData, 2U);
1642     (void)Qspi_Ip_IpCommand(instance, QSPI_IP_COMMAND_LUT, baseAddress);
1643 
1644     /* Send Reset Command */
1645     lutData[0] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(cmd, pad, (uint8)QSPI_IP_CMD_XSPI_RESET_DEF),       /* Reset command in DOPI Mode */
1646                                       Qspi_Ip_PackLut(cmd, pad, (uint8)~QSPI_IP_CMD_XSPI_RESET_DEF));     /* command extension */
1647     Qspi_Ip_WriteLuts(instance, lutRegister, lutData, 2U);
1648     (void)Qspi_Ip_IpCommand(instance, QSPI_IP_COMMAND_LUT, baseAddress);
1649 
1650     /* 2. Command Extension is the same as the Command */
1651     /* Send Reset Enable Command */
1652     lutData[0] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(cmd, pad, (uint8)QSPI_IP_CMD_XSPI_RESET_ENABLE),    /* Reset Enable command in DOPI Mode */
1653                                       Qspi_Ip_PackLut(cmd, pad, (uint8)QSPI_IP_CMD_XSPI_RESET_ENABLE));   /* command extension */
1654     Qspi_Ip_WriteLuts(instance, lutRegister, lutData, 2U);
1655     (void)Qspi_Ip_IpCommand(instance, QSPI_IP_COMMAND_LUT, baseAddress);
1656 
1657     /* Send Reset Command */
1658     lutData[0] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(cmd, pad, (uint8)QSPI_IP_CMD_XSPI_RESET_DEF),       /* Reset command in DOPI Mode */
1659                                       Qspi_Ip_PackLut(cmd, pad, (uint8)QSPI_IP_CMD_XSPI_RESET_DEF));      /* command extension */
1660     Qspi_Ip_WriteLuts(instance, lutRegister, lutData, 2U);
1661     (void)Qspi_Ip_IpCommand(instance, QSPI_IP_COMMAND_LUT, baseAddress);
1662 
1663     /* Wait for reset to complete */
1664     Qspi_Ip_WaitAfterReset();
1665 }
1666 
1667 
1668 /*FUNCTION**********************************************************************
1669  *
1670  * Function Name : Qspi_Ip_SfdpPackLutEnterLegacySPI
1671  * Description   : Pack the Enter Default Protocol Mode command is a sequence of three Write Register Linear commands.
1672  */
Qspi_Ip_SfdpPackLutEnterLegacySPI(uint32 sequenceIndex,uint32 * lutData)1673 static void Qspi_Ip_SfdpPackLutEnterLegacySPI(uint32 sequenceIndex, uint32 *lutData)
1674 {
1675     /* - Hyperbus Write Transaction: 6-byte Command/Address + 2-byte Data
1676        - The address is split into 2 parts: half-page address and word address
1677        - With DDR timing, using four clock cycles (eight clock edges) to send 8-byte
1678 
1679                     ____    Address=555h, Data=00AAh     ___
1680             CS#         \_______________________________/
1681 
1682                            ___     ___     ___     ___
1683             CK      ______/ 1 \___/ 2 \___/ 3 \___/ 4 \_____
1684 
1685                          __  __  __  __  __  __  __  __
1686             DQ[7-0] ____/00\/00\/00\/AA\/00\/05\/00\/AA\____
1687                         \__/\__/\__/\__/\__/\__/\__/\__/
1688     */
1689 
1690     if (0U == sequenceIndex)
1691     {
1692         /* First command: Write Register Linear with Address=555h, Data=00AAh */
1693         lutData[0] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U),
1694                                           Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U));
1695 
1696         lutData[1] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U),
1697                                           Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0xAAU));
1698 
1699         lutData[2] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U),
1700                                           Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x05U));
1701 
1702         lutData[3] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U),
1703                                           Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0xAAU));
1704     }
1705     else if (1U == sequenceIndex)
1706     {
1707         /* Second command: Write Register Linear with Address=2AAh, Data=0055h */
1708         lutData[0] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U),
1709                                           Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U));
1710 
1711         lutData[1] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U),
1712                                           Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x55U));
1713 
1714         lutData[2] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U),
1715                                           Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x02U));
1716 
1717         lutData[3] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U),
1718                                           Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x55U));
1719     }
1720     else  /* sequenceIndex is 2U */
1721     {
1722         /* Third command: Write Register Linear with Address=555h, Data=00F5h */
1723         lutData[0] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U),
1724                                           Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U));
1725 
1726         lutData[1] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U),
1727                                           Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0xAAU));
1728 
1729         lutData[2] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U),
1730                                           Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x05U));
1731 
1732         lutData[3] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U),
1733                                           Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0xF5U));
1734     }
1735 }
1736 
1737 
1738 /*FUNCTION**********************************************************************
1739  *
1740  * Function Name : Qspi_Ip_SfdpLutInitEnterLegacySPI
1741  * Description   : Builds the enter XPI protocol initial operations (needed for devices booting-up in Hyperbus mode)
1742  */
Qspi_Ip_SfdpLutInitEnterLegacySPI(Qspi_Ip_MemoryConfigType const * pConfig)1743 static void Qspi_Ip_SfdpLutInitEnterLegacySPI(Qspi_Ip_MemoryConfigType const *pConfig)
1744 {
1745     Qspi_Ip_InitOperationType *operation;
1746     uint32 lutData[4U];  /* Data to be written to the physical LUTs */
1747     uint32 sequenceIndex;
1748 
1749     /* Only needed for devices do not boot in legacy XPI mode */
1750     if ((boolean)FALSE == bootModeLegacyXPI)
1751     {
1752         for (sequenceIndex = 0U; sequenceIndex < 3U; sequenceIndex++)
1753         {
1754             operation = &(pConfig->initConfiguration.operations[initOpCount]);
1755             initOpCount++;
1756 
1757             /* Build operation */
1758             operation->opType      = QSPI_IP_OP_TYPE_CMD;
1759             operation->command1Lut = lutCount;
1760             operation->addr        = 0U;
1761 
1762             /* Pack the command sequence */
1763             Qspi_Ip_SfdpPackLutEnterLegacySPI(sequenceIndex, lutData);
1764 
1765             /* Build LUT sequence (copy into the virtual LUT table of the configuration) */
1766             Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), (uint16)(lutData[0] >>  0U));
1767             Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), (uint16)(lutData[0] >> 16U));
1768             Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), (uint16)(lutData[1] >>  0U));
1769             Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), (uint16)(lutData[1] >> 16U));
1770             Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), (uint16)(lutData[2] >>  0U));
1771             Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), (uint16)(lutData[2] >> 16U));
1772             Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), (uint16)(lutData[3] >>  0U));
1773             Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), (uint16)(lutData[3] >> 16U));
1774             Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), QSPI_IP_LUT_SEQ_END);  /* End of sequence */
1775 
1776             /* Other operation fields are unused */
1777             operation->command2Lut = QSPI_IP_LUT_INVALID;
1778             operation->weLut       = QSPI_IP_LUT_INVALID;
1779             operation->size        = 0U;
1780             operation->shift       = 0U;
1781             operation->width       = 0U;
1782             operation->value       = 0U;
1783             operation->ctrlCfgPtr  = NULL_PTR;
1784         }
1785     }
1786 }
1787 
1788 
1789 /*FUNCTION**********************************************************************
1790  *
1791  * Function Name : Qspi_Ip_SfdpEnterLegacySPI
1792  * Description   : The Enter Default Protocol Mode command is a sequence of three Write Register Linear commands.
1793  */
Qspi_Ip_SfdpEnterLegacySPI(uint32 instance,uint32 baseAddress)1794 static void Qspi_Ip_SfdpEnterLegacySPI(uint32 instance,
1795                                        uint32 baseAddress
1796                                       )
1797 {
1798     uint32 sequenceIndex;
1799     uint32 lutData[5U];  /* Data to be written to the physical LUTs */
1800     lutData[4] = QSPI_IP_PACK_LUT_REG(QSPI_IP_LUT_SEQ_END, QSPI_IP_LUT_SEQ_END);  /* End of sequence */
1801 
1802     const uint8 lutRegister = QSPI_IP_COMMAND_LUT * FEATURE_QSPI_LUT_SEQUENCE_SIZE;
1803 
1804     /* We need 5 LUT registers: 4 for the command sequence, plus 1 for the end of sequence.
1805        - For platforms that have 4 LUT registers that make up a LUT sequence:
1806             only the first 4 LUT registers will be written to avoid overwriting the next sequence
1807 
1808        - For platforms that have 5 LUT registers that make up a LUT sequence:
1809             all 5 LUT registers will be written
1810 
1811        Because: The instructions are executed sequentially until the last instruction or the STOP instruction is encountered.
1812 
1813        Note:
1814            - This will not work if FEATURE_QSPI_LUT_SEQUENCE_SIZE is less than 4
1815            - In that case, QSPI_IP_LUT_INSTR_WRITE_DDR must be used (data will be placed in the TBDR to save the number of LUTs)
1816      */
1817     uint8 lutSize = 5U;
1818 
1819     #if (FEATURE_QSPI_LUT_SEQUENCE_SIZE == 4)
1820         lutSize = 4U;
1821     #elif (FEATURE_QSPI_LUT_SEQUENCE_SIZE < 4)
1822         /* Note for future platforms */
1823         #error LUT sequence is not big enough.
1824     #endif
1825 
1826     /* Issue the three command sequences */
1827     for (sequenceIndex = 0U; sequenceIndex < 3U; sequenceIndex++)
1828     {
1829         Qspi_Ip_SfdpPackLutEnterLegacySPI(sequenceIndex, lutData);              /* Pack the command sequence                     */
1830         Qspi_Ip_WriteLuts(instance, lutRegister, lutData, lutSize);             /* Write them to physical hardware LUT registers */
1831         (void)Qspi_Ip_IpCommand(instance, QSPI_IP_COMMAND_LUT, baseAddress);    /* Issue the command sequence                    */
1832     }
1833 }
1834 
1835 
1836 /*FUNCTION**********************************************************************
1837  *
1838  * Function Name : Qspi_Ip_SfdpExitDOPI
1839  * Description   : Attempt to exit the memory device from DTR-Octal (8D-8D-8D) mode.
1840  */
Qspi_Ip_SfdpExitDOPI(uint32 instance,uint32 baseAddress)1841 static void Qspi_Ip_SfdpExitDOPI(uint32 instance,
1842                                  uint32 baseAddress
1843                                 )
1844 {
1845     /* Workaround 1: send 8D-8D-8D reset commands as specified by xSPI Profile 1.0 */
1846     Qspi_Ip_SfdpInitReset_8D8D8D(instance, baseAddress);
1847 
1848     /* Workaround 2: send Enter Default Protocol Mode command sequence (1S-1S-1S) as specified by xSPI Profile 2.0 */
1849     Qspi_Ip_SfdpEnterLegacySPI(instance, baseAddress);
1850 }
1851 
1852 
1853 /*FUNCTION**********************************************************************
1854  *
1855  * Function Name : Qspi_Ip_SfdpInitReset
1856  * Description   : Sends reset commands to force device to enter SPI mode.
1857  */
Qspi_Ip_SfdpInitReset(uint32 instance,uint32 baseAddress)1858 static void Qspi_Ip_SfdpInitReset(uint32 instance,
1859                                   uint32 baseAddress
1860                                  )
1861 {
1862     /* Attempt to read SFDP in DOPI mode */
1863     Qspi_Ip_SfdpExitDOPI(instance, baseAddress);
1864 
1865     /* Attempt to read SFDP in QPI mode */
1866     Qspi_Ip_SfdpExitQPI(instance, baseAddress);
1867 }
1868 
1869 /*FUNCTION**********************************************************************
1870  *
1871  * Function Name : Qspi_Ip_SfdpFindWorkingMode
1872  * Description   : Tries each mode to find the mode in which the flash device is working.
1873  */
Qspi_Ip_SfdpFindWorkingMode(uint32 instance,uint32 baseAddress)1874 static Qspi_Ip_StatusType Qspi_Ip_SfdpFindWorkingMode(uint32 instance,
1875                                                       uint32 baseAddress
1876                                                      )
1877 {
1878     /* List of sfdp modes attempt to read and the corresponding pad return values */
1879     const Qspi_Ip_SfdpModes  modes[4U] = {QSPI_IP_SFDP_4S_4D_4D, QSPI_IP_SFDP_4S_4S_4S, QSPI_IP_SFDP_2S_2S_2S, QSPI_IP_SFDP_1S_1S_1S};
1880     const Qspi_Ip_LutPadsType pads[4U] = {QSPI_IP_LUT_PADS_4,    QSPI_IP_LUT_PADS_4,    QSPI_IP_LUT_PADS_2,    QSPI_IP_LUT_PADS_1   };
1881     const uint32 maxAttempts = 4U;
1882     Qspi_Ip_StatusType status;
1883     uint8 data[4U];
1884     uint32 idx;
1885 
1886     /* Attempt to read SFDP modes */
1887     for (idx = 0U; idx < maxAttempts; idx++)
1888     {
1889         Qspi_Ip_SfdpInitLut(instance, modes[idx]);
1890         status = Qspi_Ip_IpRead(instance, QSPI_IP_COMMAND_LUT, baseAddress, data, NULL_PTR, 4U);
1891         if ((STATUS_QSPI_IP_SUCCESS == status) && Qspi_Ip_SfdpSignatureCheck(data))
1892         {
1893             /* Found a supported mode */
1894             cmdPadsInit = pads[idx];
1895             break;
1896         }
1897     }
1898 
1899     /* All read attempts failed, device does not support SFDP */
1900     if (idx >= maxAttempts)
1901     {
1902         status = STATUS_QSPI_IP_ERROR;
1903     }
1904 
1905     return status;
1906 }
1907 
1908 
1909 /*FUNCTION**********************************************************************
1910  *
1911  * Function Name : Qspi_Ip_SfdpCheck
1912  * Description   : Checks the existence of SFDP support.
1913  */
Qspi_Ip_SfdpCheck(uint32 instance,uint32 baseAddress)1914 static Qspi_Ip_StatusType Qspi_Ip_SfdpCheck(uint32 instance,
1915                                             uint32 baseAddress
1916                                            )
1917 {
1918     Qspi_Ip_StatusType status;
1919 
1920     /* First attempt to check if SFDP is supported or not */
1921     status = Qspi_Ip_SfdpFindWorkingMode(instance, baseAddress);
1922     if (STATUS_QSPI_IP_SUCCESS != status)
1923     {
1924         /* The first check has failed, try to issue reset commands in various modes */
1925         Qspi_Ip_SfdpInitReset(instance, baseAddress);
1926         /* Then try for the second attempt */
1927         status = Qspi_Ip_SfdpFindWorkingMode(instance, baseAddress);
1928     }
1929 
1930     return status;
1931 }
1932 
1933 
1934 /*FUNCTION**********************************************************************
1935  *
1936  * Function Name : Qspi_Ip_SfdpCheckMinorRevision
1937  * Description   : Verifies validity of sfdp minor revision
1938  *
1939  *END**************************************************************************/
Qspi_Ip_SfdpCheckMinorRevision(uint8 minorRevision)1940 static inline boolean Qspi_Ip_SfdpCheckMinorRevision(uint8 minorRevision)
1941 {
1942     /* Revision and size must match the specifications of JESD216, JESD216A or JESD216B; also accept newer revisions */
1943     return ((QSPI_IP_SFDP_MINOR_REVISION_REV_0 == minorRevision) ||
1944             (minorRevision >= QSPI_IP_SFDP_MINOR_REVISION_REV_A));
1945 }
1946 
1947 
1948 /*FUNCTION**********************************************************************
1949  *
1950  * Function Name : Qspi_Ip_SfdpGetCmdExt
1951  * Description   : Builds configuration for octal DDR (DOPI) mode.
1952  */
Qspi_Ip_SfdpGetCmdExt(const Qspi_Ip_SfdpTablesContainer * sfdpTables,uint8 instruction)1953 static inline uint8 Qspi_Ip_SfdpGetCmdExt(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1954                                           uint8 instruction
1955                                          )
1956 {
1957     uint8 cmdExt;
1958 
1959     /* Get Command Extension */
1960     cmdExt = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_CMD_EXT_DWORD,
1961                                               QSPI_IP_SFDP_BASIC_CMD_EXT_SHIFT, QSPI_IP_SFDP_BASIC_CMD_EXT_WIDTH, 0x1U);
1962     if (cmdExt == 0U)
1963     {
1964         cmdExt = instruction;
1965     }
1966     else
1967     {
1968         cmdExt = ~instruction;
1969     }
1970     return cmdExt;
1971 }
1972 
1973 
1974 /*FUNCTION**********************************************************************
1975  *
1976  * Function Name : Qspi_Ip_SfdpClearTable
1977  * Description   : Clears parameter table before reading it. This is to avoid MISRA non-initialized value errors.
1978  */
Qspi_Ip_SfdpClearTable(uint32 * paramTable,uint8 paramTableLength)1979 static void Qspi_Ip_SfdpClearTable(uint32 * paramTable,
1980                                    uint8 paramTableLength
1981                                   )
1982 {
1983     uint8 count;
1984     for (count = 0U; count < paramTableLength; count++)
1985     {
1986         paramTable[count] = 0U;
1987     }
1988 }
1989 
1990 /*FUNCTION**********************************************************************
1991  *
1992  * Function Name : Qspi_Ip_SfdpCheckNewerRevision
1993  * Description   : Check SFDP Parameter Table revision is newer or not
1994  */
Qspi_Ip_SfdpCheckNewerRevision(uint8 paramIdLSB,uint8 tableType,uint8 majorRevision,uint8 minorRevision,sint16 minorRevisionMax)1995 static inline boolean Qspi_Ip_SfdpCheckNewerRevision(uint8 paramIdLSB,
1996                                                      uint8 tableType,
1997                                                      uint8 majorRevision,
1998                                                      uint8 minorRevision,
1999                                                      sint16 minorRevisionMax
2000                                                     )
2001 {
2002     boolean retVal;
2003 
2004     if ((paramIdLSB == (uint8)tableType) &&
2005         (QSPI_IP_SFDP_MAJOR_REVISION == majorRevision) &&
2006         ((sint16)minorRevision > minorRevisionMax))
2007     {
2008         retVal = TRUE;
2009     }
2010     else
2011     {
2012         retVal = FALSE;
2013     }
2014 
2015     return retVal;
2016 }
2017 
2018 /*FUNCTION**********************************************************************
2019  *
2020  * Function Name : Qspi_Ip_SfdpGetParamTableAddress
2021  * Description   : Gets the address of parameter table from the parameter header.
2022  *                 Converts to byte address if the device is hyperbus.
2023  */
Qspi_Ip_SfdpGetParamTableAddress(const uint8 * paramHeader,uint8 accessProtocol)2024 static inline uint32 Qspi_Ip_SfdpGetParamTableAddress(const uint8 * paramHeader,
2025                                                       uint8 accessProtocol
2026                                                      )
2027 {
2028     /* Get the table address from pointer byte 2, 1 and 0 */
2029     uint32 paramTableAddress = ((uint32)paramHeader[6U] << 16U) | ((uint32)paramHeader[5U] << 8U) | (uint32)paramHeader[4U];
2030 
2031     /* The memory is a hyperbus device, convert from word address to byte address */
2032     if (accessProtocol == QSPI_IP_SFDP_ACCESS_PROTOCOL_HYPERBUS)
2033     {
2034         bootModeLegacyXPI = (boolean)FALSE;  /* The memory device booting up in xSPI NOR Profile 2 HYPERBUS */
2035         paramTableAddress <<= 1U;
2036     }
2037 
2038     return paramTableAddress;
2039 }
2040 
2041 /*FUNCTION**********************************************************************
2042  *
2043  * Function Name : Qspi_Ip_SfdpFindTable
2044  * Description   : Finds requested parameters table in SFDP table, if it exists.
2045  */
Qspi_Ip_SfdpFindTable(uint32 instance,uint32 baseAddress,Qspi_Ip_SfdpTables tableType,uint32 * paramTable,uint8 * paramTableLength)2046 static Qspi_Ip_StatusType Qspi_Ip_SfdpFindTable(uint32 instance,
2047                                                 uint32 baseAddress,
2048                                                 Qspi_Ip_SfdpTables tableType,
2049                                                 uint32 * paramTable,
2050                                                 uint8 * paramTableLength
2051                                                )
2052 {
2053     Qspi_Ip_StatusType status;
2054     uint8 data[8U];
2055     uint8 paramHeaders = 0U;
2056     uint8 majorRevision;
2057     uint8 minorRevision;
2058     sint16 minorRevisionMax = -1;
2059     uint8 paramIdLSB;
2060     uint32 currAddr;
2061     uint32 paramTableBaseAddr = 0U;
2062     uint8 tableLength;
2063     uint8 tableLengthMax = 0U;
2064     boolean minorVerFlag = FALSE;
2065     uint8 accessProtocol = QSPI_IP_SFDP_ACCESS_PROTOCOL_LEGACY;  /* default value as Legacy option */
2066 
2067     Qspi_Ip_SfdpClearTable(paramTable, *paramTableLength);
2068     /* read second part of SFDP header to check version and get number of parameter headers */
2069     status = Qspi_Ip_IpRead(instance, QSPI_IP_COMMAND_LUT, baseAddress + 4U, data, NULL_PTR, 4U);
2070     if (STATUS_QSPI_IP_SUCCESS == status)
2071     {
2072         /* check SFDP revision; minor revision can be greater than expected, because backward compatibility is guaranteed */
2073         majorRevision = data[1];
2074         minorRevision = data[0];
2075         paramHeaders = (uint8)(data[2] + 1U);
2076         accessProtocol = data[3];  /* [31:24] SFDP Access Protocol field */
2077         minorVerFlag = Qspi_Ip_SfdpCheckMinorRevision(minorRevision);
2078         if ((QSPI_IP_SFDP_MAJOR_REVISION != majorRevision) || (TRUE != minorVerFlag))
2079         {
2080             paramHeaders = 0U;
2081             status = STATUS_QSPI_IP_ERROR;
2082         }
2083     }
2084 
2085     /* If paramHeaders is greater than zero means the SFDP revision is correct */
2086     /* iterate through parameter headers */
2087     currAddr = 8U;
2088     for (; paramHeaders > (uint8)0U; paramHeaders--)
2089     {
2090         /* read current parameter header */
2091         status = Qspi_Ip_IpRead(instance, QSPI_IP_COMMAND_LUT, baseAddress + currAddr, data, NULL_PTR, 8U);
2092         if (status != STATUS_QSPI_IP_SUCCESS)
2093         {
2094             break;
2095         }
2096         majorRevision = data[2];
2097         minorRevision = data[1];
2098         paramIdLSB = data[0];
2099         tableLength = data[3];
2100         if (TRUE == Qspi_Ip_SfdpCheckNewerRevision(paramIdLSB, (uint8)tableType, majorRevision, minorRevision, minorRevisionMax))
2101         {
2102             /* Found SFDP Basic Parameter Table with newer revision */
2103             paramTableBaseAddr = Qspi_Ip_SfdpGetParamTableAddress(data, accessProtocol);
2104             minorRevisionMax = (sint16)minorRevision;
2105             tableLengthMax = tableLength;
2106         }
2107         currAddr += 8U;
2108     }
2109 
2110     /* If minorRevisionMax is not negative, it means that a SFDP table was found */
2111     if (minorRevisionMax >= 0)
2112     {
2113         /* Adjust table length in case of newer revisions */
2114         if (tableLengthMax > *paramTableLength)
2115         {
2116             tableLengthMax = *paramTableLength;
2117         }
2118         /* Read parameter table */
2119         status = Qspi_Ip_IpRead(instance, QSPI_IP_COMMAND_LUT, baseAddress + paramTableBaseAddr, (uint8 *)paramTable, NULL_PTR, (uint32)tableLengthMax * 4U);
2120         if (STATUS_QSPI_IP_SUCCESS == status)
2121         {
2122             *paramTableLength = tableLengthMax;
2123         }
2124     }
2125     else
2126     {
2127         /* Could not find a table of the requested kind */
2128         *paramTableLength = 0U;
2129     }
2130 
2131     return status;
2132 }
2133 
2134 
2135 /*FUNCTION**********************************************************************
2136  *
2137  * Function Name : Qspi_Ip_SfdpReadTables
2138  * Description   : Finds requested parameters table in SFDP table, if it exists.
2139  */
Qspi_Ip_SfdpReadTables(uint32 instance,uint32 baseAddress,Qspi_Ip_SfdpTablesContainer * sfdpTables)2140 static Qspi_Ip_StatusType Qspi_Ip_SfdpReadTables(uint32 instance,
2141                                                  uint32 baseAddress,
2142                                                  Qspi_Ip_SfdpTablesContainer *sfdpTables
2143                                                 )
2144 {
2145     Qspi_Ip_StatusType status;
2146 
2147     /* Initialize each table length to max specified by JESD216 rev. D */
2148     sfdpTables->paramTableLength_basic = QSPI_IP_TABLE_SIZE_BASIC;
2149     sfdpTables->paramTableLength_4badd = QSPI_IP_TABLE_SIZE_4BADD;
2150     sfdpTables->paramTableLength_xspi1 = QSPI_IP_TABLE_SIZE_XSPI1;
2151     sfdpTables->paramTableLength_srmap = QSPI_IP_TABLE_SIZE_SRMAP;
2152     sfdpTables->paramTableLength_2dopi = QSPI_IP_TABLE_SIZE_2DOPI;
2153 
2154     /* Search Basic Flash Parameter Table */
2155     status = Qspi_Ip_SfdpFindTable(instance, baseAddress, QSPI_IP_SFDP_TABLE_BASIC,
2156                                    sfdpTables->paramTable_basic, &(sfdpTables->paramTableLength_basic));
2157     if ((status != STATUS_QSPI_IP_SUCCESS) || (sfdpTables->paramTableLength_basic == 0U))
2158     {
2159         status = STATUS_QSPI_IP_ERROR;
2160     }
2161 
2162     if (STATUS_QSPI_IP_SUCCESS == status)
2163     {
2164         /* Search 4-byte Address Instruction Table */
2165         status = Qspi_Ip_SfdpFindTable(instance, baseAddress, QSPI_IP_SFDP_TABLE_4BADD,
2166                                        sfdpTables->paramTable_4badd, &(sfdpTables->paramTableLength_4badd));
2167     }
2168 
2169     if (STATUS_QSPI_IP_SUCCESS == status)
2170     {
2171         /* Search eXtended Serial Peripheral Interface (xSPI) Profile 1.0 Table */
2172         status = Qspi_Ip_SfdpFindTable(instance, baseAddress, QSPI_IP_SFDP_TABLE_XSPI1,
2173                                        sfdpTables->paramTable_xspi1, &(sfdpTables->paramTableLength_xspi1));
2174     }
2175 
2176     if (STATUS_QSPI_IP_SUCCESS == status)
2177     {
2178         /* Search Status, Control and Configuration Register Map Table */
2179         status = Qspi_Ip_SfdpFindTable(instance, baseAddress, QSPI_IP_SFDP_TABLE_SRMAP,
2180                                        sfdpTables->paramTable_srmap, &(sfdpTables->paramTableLength_srmap));
2181     }
2182 
2183     if (STATUS_QSPI_IP_SUCCESS == status)
2184     {
2185         /* Command Sequences to change to DOPI (8D-8D-8D) mode */
2186         status = Qspi_Ip_SfdpFindTable(instance, baseAddress, QSPI_IP_SFDP_TABLE_2DOPI,
2187                                        sfdpTables->paramTable_2dopi, &(sfdpTables->paramTableLength_2dopi));
2188     }
2189 
2190     return status;
2191 }
2192 
2193 
2194 /*FUNCTION**********************************************************************
2195  *
2196  * Function Name : Qspi_Ip_SfdpInitSimpleCmd
2197  * Description   : Builds an initial operation containing a simple command.
2198  */
Qspi_Ip_SfdpInitSimpleCmd(uint8 cmd,const Qspi_Ip_MemoryConfigType * pConfig)2199 static void Qspi_Ip_SfdpInitSimpleCmd(uint8 cmd,
2200                                       const Qspi_Ip_MemoryConfigType *pConfig
2201                                      )
2202 {
2203     Qspi_Ip_InitOperationType *operation;
2204 
2205     if (initOpCount >= pConfig->initConfiguration.opCount)
2206     {
2207         /* operations list not big enough */
2208         overflow = TRUE;
2209     }
2210     else
2211     {
2212         operation = &(pConfig->initConfiguration.operations[initOpCount]);
2213         initOpCount++;
2214         /* Build operation */
2215         operation->opType = QSPI_IP_OP_TYPE_CMD;
2216         operation->command1Lut = lutCount;
2217         operation->addr = 0U;
2218         /* Build LUT sequence */
2219         Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, QSPI_IP_LUT_PADS_1, cmd));
2220         Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
2221         /* Other operation fields are unused */
2222         operation->command2Lut = QSPI_IP_LUT_INVALID;
2223         operation->weLut = QSPI_IP_LUT_INVALID;
2224         operation->size  = 0U;
2225         operation->shift = 0U;
2226         operation->width = 0U;
2227         operation->value = 0U;
2228         operation->ctrlCfgPtr = NULL_PTR;
2229     }
2230 
2231     return;
2232 }
2233 
2234 
2235 /*FUNCTION**********************************************************************
2236  *
2237  * Function Name : Qspi_Ip_SfdpGetWeSrInstr
2238  * Description   : Returns instruction for write enable on SR register.
2239  */
Qspi_Ip_SfdpGetWeSrInstr(const Qspi_Ip_SfdpTablesContainer * sfdpTables)2240 static uint8 Qspi_Ip_SfdpGetWeSrInstr(const Qspi_Ip_SfdpTablesContainer *sfdpTables)
2241 {
2242     uint8 wrEnSr;
2243 
2244     /* Check "Write Enable Instruction Select for Writing to Volatile Status Register" bitfield */
2245     wrEnSr = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_WREN_SR_DWORD,
2246                                               QSPI_IP_SFDP_BASIC_WREN_SR_SHIFT, QSPI_IP_SFDP_BASIC_WREN_SR_WIDTH, 0x1U);
2247     if (wrEnSr == 1U)
2248     {
2249         wrEnSr = 0x50U;
2250     }
2251     else
2252     {
2253         wrEnSr = 0x06U;
2254     }
2255     return wrEnSr;
2256 }
2257 
2258 
2259 /*FUNCTION**********************************************************************
2260  *
2261  * Function Name : Qspi_Ip_SfdpInitWriteReg
2262  * Description   : Builds an initial operation containing a register write command.
2263  */
Qspi_Ip_SfdpInitWriteReg(uint8 cmd,uint8 wrenCmd,uint8 size,uint32 value,const Qspi_Ip_MemoryConfigType * pConfig)2264 static void Qspi_Ip_SfdpInitWriteReg(uint8 cmd,
2265                                      uint8 wrenCmd,
2266                                      uint8 size,
2267                                      uint32 value,
2268                                      const Qspi_Ip_MemoryConfigType *pConfig
2269                                     )
2270 {
2271     Qspi_Ip_InitOperationType *operation;
2272 
2273     if (initOpCount >= pConfig->initConfiguration.opCount)
2274     {
2275         /* operations list not big enough */
2276         overflow = TRUE;
2277     }
2278     else
2279     {
2280         operation = &(pConfig->initConfiguration.operations[initOpCount]);
2281         initOpCount++;
2282         /* Build operation */
2283         operation->opType = QSPI_IP_OP_TYPE_WRITE_REG;
2284         operation->addr = 0U;
2285         operation->weLut = lutCount;
2286         operation->size = size;
2287         operation->value = value;
2288         /* Build WE LUT sequence */
2289         Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, QSPI_IP_LUT_PADS_1, wrenCmd));
2290         Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
2291         operation->command1Lut = lutCount;
2292         /* Build write SR LUT sequence */
2293         Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, QSPI_IP_LUT_PADS_1, cmd));
2294         Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_WRITE, QSPI_IP_LUT_PADS_1, 0x1U));
2295         Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
2296 
2297         /* Other operation fields are unused */
2298         operation->command2Lut = QSPI_IP_LUT_INVALID;
2299         operation->shift = 0U;
2300         operation->width = 0U;
2301         operation->ctrlCfgPtr = NULL_PTR;
2302     }
2303 
2304     return;
2305 }
2306 
2307 
2308 /*FUNCTION**********************************************************************
2309  *
2310  * Function Name : Qspi_Ip_Sfdp4byteAddrSwitch_01
2311  * Description   : Switch to 4-byte addressing mode.
2312  */
Qspi_Ip_Sfdp4byteAddrSwitch_01(const Qspi_Ip_MemoryConfigType * pConfig)2313 static Qspi_Ip_StatusType Qspi_Ip_Sfdp4byteAddrSwitch_01(const Qspi_Ip_MemoryConfigType * pConfig)
2314 {
2315     /* issue instruction B7h (preceding write enable not required) */
2316     Qspi_Ip_SfdpInitSimpleCmd(0xB7U, pConfig);
2317     return STATUS_QSPI_IP_SUCCESS;
2318 }
2319 
2320 
2321 /*FUNCTION**********************************************************************
2322  *
2323  * Function Name : Qspi_Ip_Sfdp4byteAddrSwitch_02
2324  * Description   : Switch to 4-byte addressing mode.
2325  */
Qspi_Ip_Sfdp4byteAddrSwitch_02(const Qspi_Ip_MemoryConfigType * pConfig)2326 static Qspi_Ip_StatusType Qspi_Ip_Sfdp4byteAddrSwitch_02(const Qspi_Ip_MemoryConfigType * pConfig)
2327 {
2328     /* issue write enable instruction 06h, then issue instruction B7h */
2329     Qspi_Ip_SfdpInitSimpleCmd(0x06U, pConfig);
2330     Qspi_Ip_SfdpInitSimpleCmd(0xB7U, pConfig);
2331     return STATUS_QSPI_IP_SUCCESS;
2332 }
2333 
2334 
2335 /*FUNCTION**********************************************************************
2336  *
2337  * Function Name : Qspi_Ip_Sfdp4byteAddrSwitch_08
2338  * Description   : Switch to 4-byte addressing mode.
2339  */
Qspi_Ip_Sfdp4byteAddrSwitch_08(const Qspi_Ip_MemoryConfigType * pConfig)2340 static Qspi_Ip_StatusType Qspi_Ip_Sfdp4byteAddrSwitch_08(const Qspi_Ip_MemoryConfigType * pConfig)
2341 {
2342     /* 8-bit volatile bank register used to define A[30:A24] bits. MSB (bit[7]) is used to enable/disable 4-byte address mode.
2343        When MSB is set to ‘1’, 4-byte address mode is active and A[30:24] bits are don’t care. Read with instruction 16h.
2344        Write instruction is 17h with 1 byte of data. When MSB is cleared to ‘0’, select the active 128 Mbit segment by setting
2345        the appropriate A[30:24] bits and use 3-Byte addressing */
2346     /* Not implemented */
2347     (void)pConfig;
2348     return STATUS_QSPI_IP_ERROR;
2349 }
2350 
2351 
2352 /*FUNCTION**********************************************************************
2353  *
2354  * Function Name : Qspi_Ip_Sfdp4byteAddrSwitch_16
2355  * Description   : Switch to 4-byte addressing mode.
2356  */
Qspi_Ip_Sfdp4byteAddrSwitch_16(const Qspi_Ip_MemoryConfigType * pConfig)2357 static Qspi_Ip_StatusType Qspi_Ip_Sfdp4byteAddrSwitch_16(const Qspi_Ip_MemoryConfigType * pConfig)
2358 {
2359     /* A 16-bit nonvolatile configuration register controls 3-Byte/4-Byte address mode. Read instruction is B5h.
2360        Bit[0] controls address mode [0=3-Byte; 1=4-Byte]. Write configuration register instruction is B1h, data length is 2 bytes */
2361     /* Not implemented */
2362     (void)pConfig;
2363     return STATUS_QSPI_IP_ERROR;
2364 }
2365 
2366 
2367 /*FUNCTION**********************************************************************
2368  *
2369  * Function Name : Qspi_Ip_Sfdp4byteAddrSwitch
2370  * Description   : Switch to 4-byte addressing mode.
2371  */
Qspi_Ip_Sfdp4byteAddrSwitch(const Qspi_Ip_SfdpTablesContainer * sfdpTables,const Qspi_Ip_MemoryConfigType * pConfig)2372 static Qspi_Ip_StatusType Qspi_Ip_Sfdp4byteAddrSwitch(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
2373                                                       const Qspi_Ip_MemoryConfigType * pConfig
2374                                                      )
2375 {
2376     Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
2377     uint8 addrSwitch;
2378 
2379     /* Check 4-byte addr enable mode */
2380     addrSwitch = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_ADDR_SWITCH_DWORD,
2381                                                   QSPI_IP_SFDP_BASIC_ADDR_SWITCH_SHIFT, QSPI_IP_SFDP_BASIC_ADDR_SWITCH_WIDTH, 0x0U);
2382     if ((addrSwitch & 0x01U) != 0U)
2383     {
2384         /* issue instruction B7h (preceding write enable not required) */
2385         status = Qspi_Ip_Sfdp4byteAddrSwitch_01(pConfig);
2386     }
2387     else if ((addrSwitch & 0x02U) != 0U)
2388     {
2389         /* issue write enable instruction 06h, then issue instruction B7h */
2390         status = Qspi_Ip_Sfdp4byteAddrSwitch_02(pConfig);
2391     }
2392     else if ((addrSwitch & 0x08U) != 0U)
2393     {
2394         /* 8-bit volatile bank register used to define A[30:A24] bits. MSB (bit[7]) is used to enable/disable 4-byte address mode */
2395         status = Qspi_Ip_Sfdp4byteAddrSwitch_08(pConfig);
2396     }
2397     else if ((addrSwitch & 0x10U) != 0U)
2398     {
2399         /* A 16-bit nonvolatile configuration register controls 3-Byte/4-Byte address mode. */
2400         status = Qspi_Ip_Sfdp4byteAddrSwitch_16(pConfig);
2401     }
2402     else
2403     {
2404         /* Can't switch to 4-byte addr. mode */
2405         status = STATUS_QSPI_IP_ERROR;
2406     }
2407     return status;
2408 }
2409 
2410 
2411 /*FUNCTION**********************************************************************
2412  *
2413  * Function Name : Qspi_Ip_SfdpGetBasicAddrBits
2414  * Description   : Returns number of address bits.
2415  */
Qspi_Ip_SfdpGetBasicAddrBits(const Qspi_Ip_SfdpTablesContainer * sfdpTables,const Qspi_Ip_MemoryConfigType * pConfig)2416 static void Qspi_Ip_SfdpGetBasicAddrBits(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
2417                                          const Qspi_Ip_MemoryConfigType * pConfig
2418                                         )
2419 {
2420     uint8 addrBytes;
2421     Qspi_Ip_StatusType status;
2422 
2423     /* Check number of address bytes */
2424     addrBytes = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_ADDR_BYTES_DWORD,
2425                                                  QSPI_IP_SFDP_BASIC_ADDR_BYTES_SHIFT, QSPI_IP_SFDP_BASIC_ADDR_BYTES_WIDTH, 0x0U);
2426     switch (addrBytes)
2427     {
2428         case 0U:
2429             /* 3-Byte only addressing */
2430             basicAddrBits = 24U;
2431             break;
2432         case 1U:
2433             /* 3 or 4 byte addressing, try to switch to 4 */
2434             status = Qspi_Ip_Sfdp4byteAddrSwitch(sfdpTables, pConfig);
2435             if (STATUS_QSPI_IP_SUCCESS == status)
2436             {
2437                 basicAddrBits = 32U;
2438             }
2439             else
2440             {
2441                 basicAddrBits = 24U;
2442             }
2443             break;
2444         case 2U:
2445             /* 4-Byte only addressing */
2446             basicAddrBits = 32U;
2447             break;
2448         default:
2449             /* reseved, should not happen, default to 3-byte */
2450             basicAddrBits = 24U;
2451             break;
2452     }
2453 }
2454 
2455 
2456 /*FUNCTION**********************************************************************
2457  *
2458  * Function Name : Qspi_Ip_SfdpConfigureQE
2459  * Description   : Adds initial operation to set QE bit, if required.
2460  */
Qspi_Ip_SfdpConfigureQE(const Qspi_Ip_SfdpTablesContainer * sfdpTables,const Qspi_Ip_MemoryConfigType * pConfig)2461 static void Qspi_Ip_SfdpConfigureQE(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
2462                                     const Qspi_Ip_MemoryConfigType *pConfig
2463                                    )
2464 {
2465     uint8 qeReq;
2466     uint8 wrenCmd;
2467     boolean qeBit = TRUE;
2468 
2469     /* Check "Quad Enable Requirements (QER)" field */
2470     qeReq = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_QE_REQ_DWORD,
2471                                              QSPI_IP_SFDP_BASIC_QE_REQ_SHIFT, QSPI_IP_SFDP_BASIC_QE_REQ_WIDTH, 0x7U);
2472     wrenCmd = Qspi_Ip_SfdpGetWeSrInstr(sfdpTables);
2473     switch (qeReq)
2474     {
2475         case 0U:
2476             /* Device does not have a QE bit. Device detects 1-1-4 and 1-4-4 reads based on instruction.
2477               (the quad commands are available without setting any bits) */
2478             qeBit = FALSE;
2479             break;
2480         case 1U:
2481             /* QE is bit 1 of status register 2. It is set via Write Status with two data bytes where bit 1 of the second byte is one. It is cleared via
2482                Write Status with two data bytes where bit 1 of the second byte is zero. Writing only one byte to the status register has the side-effect
2483                of clearing status register 2, including the QE bit */
2484             Qspi_Ip_SfdpInitWriteReg(0x01U, wrenCmd, 2U, 0x0002U, pConfig);
2485             break;
2486         case 2U:
2487             /* QE is bit 6 of status register 1. It is set via Write Status with one data byte where bit 6 is one.
2488                It is cleared via Write Status with one data byte where bit 6 is zero. */
2489             Qspi_Ip_SfdpInitWriteReg(0x01U, wrenCmd, 1U, 0x40U, pConfig);
2490             break;
2491         case 3U:
2492             /* QE is bit 7 of status register 2. It is set via Write status register 2 instruction 3Eh with one data byte where bit 7 is one.
2493                It is cleared via Write status register 2 instruction 3Eh with one data byte where bit 7 is zero. The status register 2 is read using instruction 3Fh. */
2494             Qspi_Ip_SfdpInitWriteReg(0x3EU, wrenCmd, 1U, 0x80U, pConfig);
2495             break;
2496         case 4U:
2497             /* QE is bit 1 of status register 2. It is set via Write Status with two data bytes where bit 1 of the second byte is one. It is cleared via
2498                Write Status with two data bytes where bit 1 of the second byte is zero. In contrast to the 001b code, writing one byte to the status
2499                register does not modify status register 2. */
2500             Qspi_Ip_SfdpInitWriteReg(0x01U, wrenCmd, 2U, 0x0002U, pConfig);
2501             break;
2502         case 5U:
2503             /* QE is bit 1 of the status register 2. Status register 1 is read using Read Status instruction 05h. Status register 2 is read using instruction 35h.
2504                QE is set via Write Status instruction 01h with two data bytes where bit 1 of the second byte is one. It is cleared via Write Status with
2505                two data bytes where bit 1 of the second byte is zero. */
2506             Qspi_Ip_SfdpInitWriteReg(0x01U, wrenCmd, 2U, 0x0002U, pConfig);
2507             break;
2508         case 6U:
2509             /* QE is bit 1 of the status register 2. Status register 1 is read using Read Status instruction 05h. Status register 2 is read using instruction
2510                35h, and status register 3 is read using instruction 15h. QE is set via Write Status Register instruction 31h with one data byte where
2511                bit 1 is one. It is cleared via Write Status Register instruction 31h with one data byte where bit 1 is zero. */
2512             Qspi_Ip_SfdpInitWriteReg(0x31U, wrenCmd, 1U, 0x02U, pConfig);
2513             break;
2514         default:
2515             /* Unknown QE bit setting procedure or table too short, disable quad commands */
2516             quadAvailable = FALSE;
2517             qeBit = FALSE;
2518             break;
2519     }
2520 
2521     if (TRUE == qeBit)
2522     {
2523         /* Add a wait operation to ensure the write to non-volatile QE bit is completed */
2524         Qspi_Ip_SfdpAddCheckBusyOperation(pConfig);
2525     }
2526 }
2527 
2528 
2529 /*FUNCTION**********************************************************************
2530  *
2531  * Function Name : Qspi_Ip_SfdpGetModeInstr
2532  * Description   : Returns MODE instructions to use for read commands.
2533  */
Qspi_Ip_SfdpGetModeInstr(uint8 modeClocks,Qspi_Ip_LutPadsType addrPads)2534 static Qspi_Ip_LutCommandsType Qspi_Ip_SfdpGetModeInstr(uint8 modeClocks,
2535                                                         Qspi_Ip_LutPadsType addrPads
2536                                                        )
2537 {
2538     uint8 modeBits;
2539     Qspi_Ip_LutCommandsType mode = QSPI_IP_LUT_INSTR_MODE;
2540 
2541     /* compute the number of mode bits from pads and mode clocks */
2542     modeBits = modeClocks * (1U << (uint8)((uint32)addrPads >> 8U));
2543     switch (modeBits)
2544     {
2545         case 2U:
2546             mode = QSPI_IP_LUT_INSTR_MODE2;
2547             break;
2548         case 4U:
2549             mode = QSPI_IP_LUT_INSTR_MODE4;
2550             break;
2551         case 8U:
2552             mode = QSPI_IP_LUT_INSTR_MODE;
2553             break;
2554         default:
2555             /* unsupported mode */
2556             break;
2557     }
2558     return mode;
2559 }
2560 
2561 
2562 /*FUNCTION**********************************************************************
2563  *
2564  * Function Name : Qspi_Ip_SfdpGetSpiReadInstr
2565  * Description   : Returns instructions for read type <cnt>.
2566  */
Qspi_Ip_SfdpGetSpiReadInstr(const Qspi_Ip_SfdpTablesContainer * sfdpTables,uint8 cnt,uint8 * instruction,uint8 * addrBits)2567 static void Qspi_Ip_SfdpGetSpiReadInstr(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
2568                                         uint8 cnt,
2569                                         uint8 *instruction,
2570                                         uint8 *addrBits
2571                                        )
2572 {
2573     uint8 sup4badd;
2574 
2575     /* Check 4-byte instr. support */
2576     sup4badd = (uint8)Qspi_Ip_SfdpGet4BAddParam(sfdpTables, read4ByteSupDword[cnt],
2577                                                 read4ByteSupShift[cnt], QSPI_IP_SFDP_4BADD_INSTR_SUP_WIDTH, 0x0U);
2578     if (sup4badd == 1U)
2579     {
2580         /* Use 4-byte address instruction specified in SFDP standard */
2581         *instruction = read4ByteInst[cnt];
2582         *addrBits = 32U;
2583     }
2584     else
2585     {
2586         /* Get instruction from basic parameters table */
2587         *instruction = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, readInstDword[cnt],
2588                                                         readInstShift[cnt], readInstWidth[cnt], 0x0U);
2589         *addrBits = basicAddrBits;
2590     }
2591 }
2592 
2593 
2594 /*FUNCTION**********************************************************************
2595  *
2596  * Function Name : Qspi_Ip_SfdpConfigBasicRead
2597  * Description   : Configures basic 1-1-1 read.
2598  */
Qspi_Ip_SfdpConfigBasicRead(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)2599 static void Qspi_Ip_SfdpConfigBasicRead(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
2600                                         Qspi_Ip_MemoryConfigType *pConfig
2601                                        )
2602 {
2603     uint8 addrBits;
2604     uint8 instruction;
2605 
2606     /* Check 4-byte instr. support */
2607     addrBits = (uint8)Qspi_Ip_SfdpGet4BAddParam(sfdpTables, QSPI_IP_SFDP_4BADD_INSTR_SUP_DWORD,
2608                                                 QSPI_IP_SFDP_4BADD_READ111_SUP_SHIFT, QSPI_IP_SFDP_4BADD_INSTR_SUP_WIDTH, 0x0U);
2609     if (addrBits == 0U)
2610     {
2611         instruction = QSPI_IP_CMD_BASIC_READ;
2612         addrBits = basicAddrBits;
2613     }
2614     else
2615     {
2616         instruction = QSPI_IP_CMD_BASIC_READ_4B;
2617         addrBits = 32U;
2618     }
2619     /* Get LUT index */
2620     pConfig->readLut = lutCount;
2621     /* Build LUT */
2622     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, QSPI_IP_LUT_PADS_1, instruction));
2623     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_ADDR, QSPI_IP_LUT_PADS_1, addrBits));
2624     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_READ, QSPI_IP_LUT_PADS_1, 0x10U));
2625     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
2626 }
2627 
2628 
2629 /*FUNCTION**********************************************************************
2630  *
2631  * Function Name : Qspi_Ip_Sfdp444Switch
2632  * Description   : Add commands to switch to 4-4-4 mode in operations list
2633  */
Qspi_Ip_Sfdp444Switch_01(const Qspi_Ip_MemoryConfigType * pConfig)2634 static Qspi_Ip_StatusType Qspi_Ip_Sfdp444Switch_01(const Qspi_Ip_MemoryConfigType * pConfig)
2635 {
2636         /* 01: set QE per QER description above, then issue instruction 38h */
2637         /* 02: issue instruction 38h */
2638     Qspi_Ip_SfdpInitSimpleCmd(0x38U, pConfig);
2639     return STATUS_QSPI_IP_SUCCESS;
2640 }
2641 
2642 
2643 /*FUNCTION**********************************************************************
2644  *
2645  * Function Name : Qspi_Ip_Sfdp444Switch
2646  * Description   : Add commands to switch to 4-4-4 mode in operations list
2647  */
Qspi_Ip_Sfdp444Switch_04(const Qspi_Ip_MemoryConfigType * pConfig)2648 static Qspi_Ip_StatusType Qspi_Ip_Sfdp444Switch_04(const Qspi_Ip_MemoryConfigType * pConfig)
2649 {
2650         /* issue instruction 35h */
2651     Qspi_Ip_SfdpInitSimpleCmd(0x35U, pConfig);
2652     return STATUS_QSPI_IP_SUCCESS;
2653 }
2654 
2655 
2656 /*FUNCTION**********************************************************************
2657  *
2658  * Function Name : Qspi_Ip_Sfdp444Switch
2659  * Description   : Add commands to switch to 4-4-4 mode in operations list
2660  */
Qspi_Ip_Sfdp444Switch_08(const Qspi_Ip_MemoryConfigType * pConfig)2661 static Qspi_Ip_StatusType Qspi_Ip_Sfdp444Switch_08(const Qspi_Ip_MemoryConfigType * pConfig)
2662 {
2663         /* device uses a read-modify-write sequence of operations: read configuration using instruction 65h followed by address 800003h, set bit 6,
2664            write configuration using instruction 71h followed by address 800003h. This configuration is volatile. */
2665     /* Not implemented */
2666     (void)pConfig;
2667     return STATUS_QSPI_IP_ERROR;
2668 }
2669 
2670 
2671 /*FUNCTION**********************************************************************
2672  *
2673  * Function Name : Qspi_Ip_Sfdp444Switch
2674  * Description   : Add commands to switch to 4-4-4 mode in operations list
2675  */
Qspi_Ip_Sfdp444Switch_16(const Qspi_Ip_MemoryConfigType * pConfig)2676 static Qspi_Ip_StatusType Qspi_Ip_Sfdp444Switch_16(const Qspi_Ip_MemoryConfigType * pConfig)
2677 {
2678         /* Device uses a read-modify-write sequence of operations: Read Volatile Enhanced Configuration Register using instruction 65h,
2679            no address is required, reset bit 7 to 0. Write Volatile Enhanced Configuration Register using instruction 61h,
2680            no address is required. This configuration is volatile. */
2681     /* Not implemented */
2682     (void)pConfig;
2683     return STATUS_QSPI_IP_ERROR;
2684 }
2685 
2686 
2687 /*FUNCTION**********************************************************************
2688  *
2689  * Function Name : Qspi_Ip_Sfdp444Switch
2690  * Description   : Add commands to switch to 4-4-4 mode in operations list
2691  */
Qspi_Ip_Sfdp444Switch(const Qspi_Ip_SfdpTablesContainer * sfdpTables,const Qspi_Ip_MemoryConfigType * pConfig)2692 static Qspi_Ip_StatusType Qspi_Ip_Sfdp444Switch(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
2693                                                 const Qspi_Ip_MemoryConfigType * pConfig
2694                                                )
2695 {
2696     uint8 quadSwitch;
2697     Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
2698 
2699     /* Check 4-4-4 mode enable sequences */
2700     quadSwitch = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_444_SWITCH_DWORD,
2701                                                   QSPI_IP_SFDP_BASIC_444_SWITCH_SHIFT, QSPI_IP_SFDP_BASIC_444_SWITCH_WIDTH, 0x0U);
2702     if ((quadSwitch & 0x3U) != 0U)
2703     {
2704         /* 01: set QE per QER description above, then issue instruction 38h */
2705         /* 02: issue instruction 38h */
2706         status = Qspi_Ip_Sfdp444Switch_01(pConfig);
2707     }
2708     else if ((quadSwitch & 0x4U) != 0U)
2709     {
2710         /* issue instruction 35h */
2711         status = Qspi_Ip_Sfdp444Switch_04(pConfig);
2712     }
2713     else if ((quadSwitch & 0x8U) != 0U)
2714     {   /* device uses a read-modify-write sequence of operations */
2715         status = Qspi_Ip_Sfdp444Switch_08(pConfig);
2716     }
2717     else if ((quadSwitch & 0x16U) != 0U)
2718     {   /* device uses a read-modify-write sequence of operations */
2719         status = Qspi_Ip_Sfdp444Switch_16(pConfig);
2720     }
2721     else
2722     {
2723         /* can't do the switch to 4-4-4 mode */
2724         status = STATUS_QSPI_IP_ERROR;
2725     }
2726     return status;
2727 }
2728 
2729 
2730 /*FUNCTION**********************************************************************
2731  *
2732  * Function Name : Qspi_Ip_SfdpGetBasicReadInfo
2733  * Description   : Builds configuration for basic (SPI) read.
2734  */
Qspi_Ip_SfdpGetBasicReadInfo(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)2735 static void Qspi_Ip_SfdpGetBasicReadInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
2736                                          Qspi_Ip_MemoryConfigType * pConfig
2737                                         )
2738 {
2739     uint8 supported = 0U;
2740     uint8 crtMode;
2741     uint8 modeClocks;
2742     uint8 dummyClocks;
2743     Qspi_Ip_LutPadsType instPads;
2744     Qspi_Ip_LutPadsType addrPads;
2745     Qspi_Ip_LutPadsType dataPads;
2746     uint8 addrBits;
2747     uint8 instruction;
2748     Qspi_Ip_LutCommandsType modeInstr;
2749     Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
2750 
2751     /* Find the best supported fast read mode */
2752     /* Check if read mode is supported */
2753     for (crtMode = (uint8)QSPI_IP_SFDP_READ_MODE_MAX; crtMode > 0U; crtMode-- )
2754     {
2755         modeIndex = (uint8)(crtMode - 1U);
2756         if ((QSPI_IP_LUT_PADS_4 == readModeDataPads[modeIndex]) && (FALSE == quadAvailable))
2757         {
2758             /* Quad mode not available ignore quad commands */
2759             continue;
2760         }
2761         supported = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, readSupDword[modeIndex],
2762                                                      readSupShift[modeIndex], readSupWitdh[modeIndex], 0x0U);
2763         if (supported != 0U)
2764         {
2765             if ((uint8)QSPI_IP_SFDP_READ_MODE_444 == modeIndex)
2766             {
2767                 /* 4-4-4 read mode, add commands to switch to this mode in operation list */
2768                 status = Qspi_Ip_Sfdp444Switch(sfdpTables, pConfig);
2769                 /* Will use 4 cmd pads for all commands */
2770                 cmdPads = QSPI_IP_LUT_PADS_4;
2771             }
2772             else
2773             {
2774                 status = STATUS_QSPI_IP_SUCCESS;
2775                 cmdPads = QSPI_IP_LUT_PADS_1;
2776             }
2777             if (STATUS_QSPI_IP_SUCCESS == status)
2778             {
2779                 /* Get read instruction */
2780                 Qspi_Ip_SfdpGetSpiReadInstr(sfdpTables, modeIndex, &instruction, &addrBits);
2781                 /* Get mode and dummy clocks */
2782                 modeClocks = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, readModeDword[modeIndex],
2783                                                               readModeShift[modeIndex], readModeWidth[modeIndex], 0x0U);
2784                 dummyClocks = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, readDummyDword[modeIndex],
2785                                                                readDummyShift[modeIndex], readDummyWidth[modeIndex], 0x0U);
2786                 /* Get other command parameters */
2787                 instPads = readModeInstPads[modeIndex];
2788                 addrPads = readModeAddrPads[modeIndex];
2789                 dataPads = readModeDataPads[modeIndex];
2790                 /* Build LUT */
2791                 pConfig->readLut = lutCount;
2792                 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, instPads, instruction));
2793                 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_ADDR, addrPads, addrBits));
2794                 if (modeClocks > 0U)
2795                 {
2796                     modeInstr = Qspi_Ip_SfdpGetModeInstr(modeClocks, addrPads);
2797                     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(modeInstr, addrPads, 0x0U));
2798                 }
2799                 if (dummyClocks > 0U)
2800                 {
2801                     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_DUMMY, addrPads, dummyClocks));
2802                 }
2803                 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_READ, dataPads, 0x10U));
2804                 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
2805                 /* Found read command, exit loop */
2806                 break;
2807             }
2808         }
2809     }
2810 
2811     if (supported == 0U)
2812     {
2813         /* No supported fast read mode found, use default */
2814         Qspi_Ip_SfdpConfigBasicRead(sfdpTables, pConfig);
2815     }
2816 }
2817 
2818 
2819 /*FUNCTION**********************************************************************
2820  *
2821  * Function Name : Qspi_Ip_SfdpGetBasicWriteInfo
2822  * Description   : Builds configuration for basic (SPI) write
2823  */
Qspi_Ip_SfdpGetBasicWriteInfo(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)2824 static void Qspi_Ip_SfdpGetBasicWriteInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
2825                                           Qspi_Ip_MemoryConfigType * pConfig
2826                                          )
2827 {
2828     uint8 supported;
2829     Qspi_Ip_LutPadsType instPads;
2830     Qspi_Ip_LutPadsType addrPads;
2831     Qspi_Ip_LutPadsType dataPads;
2832     uint8 addrBits;
2833     uint8 instruction;
2834 
2835     /* check if 4-byte write corresponding to the current read mode is supported */
2836     supported = (uint8)Qspi_Ip_SfdpGet4BAddParam(sfdpTables, write4ByteSupDword[modeIndex],
2837                                                  write4ByteSupShift[modeIndex], QSPI_IP_SFDP_4BADD_INSTR_SUP_DWORD, 0x0);
2838     if (supported == 1U)
2839     {
2840         addrBits = 32U;
2841         instruction = write4ByteInst[modeIndex];
2842         instPads = readModeInstPads[modeIndex];
2843         addrPads = readModeAddrPads[modeIndex];
2844         dataPads = readModeDataPads[modeIndex];
2845     }
2846     else
2847     {
2848         /* No 4-byte write support, use basic write since SFDP does not specify other write modes */
2849         addrBits = basicAddrBits;
2850         instruction = QSPI_IP_CMD_BASIC_WRITE;
2851         instPads = cmdPads;
2852         addrPads = cmdPads;
2853         dataPads = cmdPads;
2854     }
2855     /* Get LUT index */
2856     pConfig->writeLut = lutCount;
2857     /* Build LUT */
2858     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, instPads, instruction));
2859     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_ADDR, addrPads, addrBits));
2860     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_WRITE, dataPads, 0x10U));
2861     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
2862 }
2863 
2864 
2865 /*FUNCTION**********************************************************************
2866  *
2867  * Function Name : Qspi_Ip_SfdpGetXspi1ReadInfo
2868  * Description   : Builds configuration for octal DDR (DOPI) mode.
2869  */
Qspi_Ip_SfdpGetXspi1ReadInfo(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)2870 static void Qspi_Ip_SfdpGetXspi1ReadInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
2871                                          Qspi_Ip_MemoryConfigType *pConfig
2872                                         )
2873 {
2874     uint8 readInst;
2875     uint8 cmdExt;
2876     uint8 dummy;
2877 
2878     /* Get fast read instruction */
2879     readInst = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_XSPI1_READ_FAST_DWORD,
2880                                                 QSPI_IP_SFDP_XSPI1_READ_FAST_SHIFT, QSPI_IP_SFDP_XSPI1_READ_FAST_WIDTH, 0xEEU);
2881     /* Get Command Extension */
2882     cmdExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, readInst);
2883     /* Get Dummy cycles */
2884     dummy = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_XSPI1_DUMMY_DWORD,
2885                                              QSPI_IP_SFDP_XSPI1_DUMMY_SHIFT, QSPI_IP_SFDP_XSPI1_DUMMY_WIDTH, 20U);
2886 
2887     /* Get LUT index */
2888     pConfig->readLut = lutCount;
2889     /* Build LUT command */
2890     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, readInst));
2891     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, cmdExt));
2892     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_ADDR_DDR, QSPI_IP_LUT_PADS_8, (uint8)32U));
2893     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_DUMMY, QSPI_IP_LUT_PADS_8, dummy));
2894     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_READ_DDR, QSPI_IP_LUT_PADS_8, 0x10U));
2895     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
2896 }
2897 
2898 
2899 /*FUNCTION**********************************************************************
2900  *
2901  * Function Name : Qspi_Ip_SfdpGetXspi1WriteInfo
2902  * Description   : Builds configuration for octal DDR (DOPI) mode.
2903  */
Qspi_Ip_SfdpGetXspi1WriteInfo(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)2904 static void Qspi_Ip_SfdpGetXspi1WriteInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
2905                                           Qspi_Ip_MemoryConfigType *pConfig
2906                                          )
2907 {
2908     uint8 writeInst;
2909     uint8 cmdExt;
2910 
2911     /* Page program instruction - not in SFDP table */
2912     writeInst = QSPI_IP_CMD_XSPI_WRITE;
2913     /* Get Command Extension */
2914     cmdExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, writeInst);
2915 
2916     /* Get LUT index */
2917     pConfig->writeLut = lutCount;
2918     /* Build LUT command */
2919     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, writeInst));
2920     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, cmdExt));
2921     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_ADDR_DDR, QSPI_IP_LUT_PADS_8, (uint8)32U));
2922     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_WRITE_DDR, QSPI_IP_LUT_PADS_8, 0x10U));
2923     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
2924 }
2925 
2926 
2927 /*FUNCTION**********************************************************************
2928  *
2929  * Function Name : Qspi_Ip_SfdpGetBasicEraseInstr
2930  * Description   : Returns instructions for erase type <cnt>.
2931  */
Qspi_Ip_SfdpGetBasicEraseInstr(const Qspi_Ip_SfdpTablesContainer * sfdpTables,uint8 cnt,uint8 * addrbits)2932 static uint8 Qspi_Ip_SfdpGetBasicEraseInstr(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
2933                                             uint8 cnt,
2934                                             uint8 *addrbits
2935                                            )
2936 {
2937     uint8 addr4;
2938     uint8 eraseInst;
2939 
2940     /* Check 4-byte instr. support */
2941     addr4 = (uint8)Qspi_Ip_SfdpGet4BAddParam(sfdpTables, QSPI_IP_SFDP_4BADD_INSTR_SUP_DWORD,
2942                                              erase4ByteSupShift[cnt], QSPI_IP_SFDP_4BADD_INSTR_SUP_WIDTH, 0x0U);
2943     if (addr4 == 1U)
2944     {
2945         /* Get erase instruction from 4-byte address instructions table */
2946         eraseInst = (uint8)Qspi_Ip_SfdpGet4BAddParam(sfdpTables, QSPI_IP_SFDP_4BADD_ERASE_INST_DWORD,
2947                                                      erase4ByteInstShift[cnt], QSPI_IP_SFDP_4BADD_ERASE_INST_WIDTH, 0x0U);
2948         *addrbits = 32U;
2949     }
2950     else
2951     {
2952         /* Get erase instruction from basic parameters table */
2953         eraseInst = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, eraseInstDword[cnt],
2954                                                      eraseInstShift[cnt], eraseInstWidth[cnt], 0x0U);
2955 
2956         /* No matter the device is operating in 3-Byte or 4-byte Address Mode,
2957            the Erase with 4-Byte Address instruction will always require 32-bit address */
2958         if (eraseInst == erase4ByteInst[cnt])
2959         {
2960             *addrbits = 32U;
2961         }
2962         else
2963         {
2964             *addrbits = basicAddrBits;
2965         }
2966     }
2967     return eraseInst;
2968 }
2969 
2970 
2971 /*FUNCTION**********************************************************************
2972  *
2973  * Function Name : Qspi_Ip_SfdpGetXspi1EraseInstr
2974  * Description   : Returns instructions for erase type <cnt>.
2975  */
Qspi_Ip_SfdpGetXspi1EraseInstr(const Qspi_Ip_SfdpTablesContainer * sfdpTables,uint8 cnt)2976 static uint8 Qspi_Ip_SfdpGetXspi1EraseInstr(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
2977                                             uint8 cnt
2978                                            )
2979 {
2980     uint8 addr4;
2981     uint8 eraseInst;
2982 
2983     /* Check 4-byte instr. support */
2984     addr4 = (uint8)Qspi_Ip_SfdpGet4BAddParam(sfdpTables, QSPI_IP_SFDP_4BADD_INSTR_SUP_DWORD,
2985                                              erase4ByteSupShift[cnt], QSPI_IP_SFDP_4BADD_INSTR_SUP_WIDTH, 0x0U);
2986     if (addr4 == 1U)
2987     {
2988         /* Get erase instruction from 4-byte address instructions table */
2989         eraseInst = (uint8)Qspi_Ip_SfdpGet4BAddParam(sfdpTables, QSPI_IP_SFDP_4BADD_ERASE_INST_DWORD,
2990                                                      erase4ByteInstShift[cnt], QSPI_IP_SFDP_4BADD_ERASE_INST_WIDTH, 0x0U);
2991     }
2992     else
2993     {
2994         /* Get erase instruction from basic parameters table */
2995         eraseInst = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, eraseInstDword[cnt],
2996                                                      eraseInstShift[cnt], eraseInstWidth[cnt], 0x0U);
2997     }
2998     return eraseInst;
2999 }
3000 
3001 
3002 /*FUNCTION**********************************************************************
3003  *
3004  * Function Name : Qspi_Ip_SfdpGetBasicEraseInfo
3005  * Description   : Builds configuration for SPI mode.
3006  */
Qspi_Ip_SfdpGetBasicEraseInfo(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)3007 static void Qspi_Ip_SfdpGetBasicEraseInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3008                                           Qspi_Ip_MemoryConfigType * pConfig
3009                                          )
3010 {
3011     uint8 eraseInst;
3012     uint8 eraseSize;
3013     uint8 addrbits;
3014     uint8 cnt;
3015 
3016     /* Loop through the 4 possible erase types */
3017     for (cnt = 0U; cnt < 4U; cnt++)
3018     {
3019         /* Get erase size */
3020         eraseSize = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, eraseSizeDword[cnt],
3021                                                      eraseSizeShift[cnt], eraseSizeWidth[cnt], 0x0U);
3022         pConfig->eraseSettings.eraseTypes[cnt].size = eraseSize;
3023         if (eraseSize > 0U)
3024         {
3025             /* Get erase instruction */
3026             eraseInst = Qspi_Ip_SfdpGetBasicEraseInstr(sfdpTables, cnt, &addrbits);
3027             /* Get LUT index */
3028             pConfig->eraseSettings.eraseTypes[cnt].eraseLut = lutCount;
3029             /* Build LUT command */
3030             Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPads, eraseInst));
3031             Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_ADDR, cmdPads, (uint8)addrbits));
3032             Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3033         }
3034         else
3035         {
3036             /* Erase type not supported */
3037             pConfig->eraseSettings.eraseTypes[cnt].eraseLut = QSPI_IP_LUT_INVALID;
3038         }
3039     }
3040 
3041     /* Chip erase */
3042     eraseInst = QSPI_IP_CMD_BASIC_CHIP_ERASE;
3043     pConfig->eraseSettings.chipEraseLut = lutCount;
3044     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPads, eraseInst));
3045     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3046 }
3047 
3048 
3049 /*FUNCTION**********************************************************************
3050  *
3051  * Function Name : Qspi_Ip_SfdpGetXspi1EraseInfo
3052  * Description   : Builds configuration for octal DDR (DOPI) mode.
3053  */
Qspi_Ip_SfdpGetXspi1EraseInfo(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)3054 static void Qspi_Ip_SfdpGetXspi1EraseInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3055                                           Qspi_Ip_MemoryConfigType *pConfig
3056                                          )
3057 {
3058     uint8 eraseInst;
3059     uint8 eraseSize;
3060     uint8 eraseExt;
3061     uint8 cnt;
3062 
3063     /* Loop through the 4 possible erase types */
3064     for (cnt = 0U; cnt < 4U; cnt++)
3065     {
3066         /* Get erase size */
3067         eraseSize = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, eraseSizeDword[cnt],
3068                                                      eraseSizeShift[cnt], eraseSizeWidth[cnt], 0x0U);
3069         pConfig->eraseSettings.eraseTypes[cnt].size = eraseSize;
3070         if (eraseSize > 0U)
3071         {
3072             /* Get erase instruction */
3073             eraseInst = Qspi_Ip_SfdpGetXspi1EraseInstr(sfdpTables, cnt);
3074             eraseExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, eraseInst);
3075             /* Get LUT index */
3076             pConfig->eraseSettings.eraseTypes[cnt].eraseLut = lutCount;
3077             /* Build LUT command */
3078             Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, eraseInst));
3079             Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, eraseExt));
3080             Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_ADDR_DDR, QSPI_IP_LUT_PADS_8, (uint8)32U));
3081             Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3082         }
3083         else
3084         {
3085             /* Erase type not supported */
3086             pConfig->eraseSettings.eraseTypes[cnt].eraseLut = QSPI_IP_LUT_INVALID;
3087         }
3088     }
3089 
3090     /* Check chip erase support */
3091     eraseInst = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_XSPI1_CHIP_ERASE_DWORD,
3092                                                  QSPI_IP_SFDP_XSPI1_CHIP_ERASE_SHIFT, QSPI_IP_SFDP_XSPI1_CHIP_ERASE_WIDTH, 0x0U);
3093     if (eraseInst == 0U)
3094     {
3095         pConfig->eraseSettings.chipEraseLut = QSPI_IP_LUT_INVALID;
3096     }
3097     else
3098     {
3099         pConfig->eraseSettings.chipEraseLut = lutCount;
3100         /* Build LUT command */
3101         eraseInst = QSPI_IP_CMD_XSPI_CHIP_ERASE;
3102         eraseExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, eraseInst);
3103         Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, eraseInst));
3104         Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, eraseExt));
3105         Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3106     }
3107 }
3108 
3109 
3110 /*FUNCTION**********************************************************************
3111  *
3112  * Function Name : Qspi_Ip_SfdpGetBasicStatusInfo
3113  * Description   : Builds configuration for SPI mode.
3114  */
Qspi_Ip_SfdpGetBasicStatusInfo(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)3115 static void Qspi_Ip_SfdpGetBasicStatusInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3116                                            Qspi_Ip_MemoryConfigType *pConfig
3117                                           )
3118 {
3119     uint8 instruction;
3120     Qspi_Ip_StatusConfigType *statusConfig;
3121 
3122     statusConfig = &(pConfig->statusConfig);
3123 
3124     /* Build LUT sequence for read status reg. */
3125     if (QSPI_IP_LUT_PADS_1 == cmdPads)
3126     {
3127         /* Use same sequence */
3128         statusConfig->statusRegReadLut = statusConfig->statusRegInitReadLut;
3129     }
3130     else
3131     {
3132         statusConfig->statusRegReadLut = lutCount;
3133         instruction = QSPI_IP_CMD_BASIC_READ_SR;
3134         Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPads, instruction));
3135         Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_READ, cmdPads, 0x10));
3136         Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3137     }
3138 
3139     /* Build LUT sequence for write status reg. */
3140     statusConfig->statusRegWriteLut = lutCount;
3141     instruction = QSPI_IP_CMD_BASIC_WRITE_SR;
3142     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPads, instruction));
3143     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_WRITE, cmdPads, 0x1U));
3144     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3145 
3146     /* Build LUT sequence for write enable */
3147     statusConfig->writeEnableLut = lutCount;
3148     instruction = QSPI_IP_CMD_BASIC_WRITE_ENABLE;
3149     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPads, instruction));
3150     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3151 
3152     /* Build LUT sequence for SR write enable */
3153     instruction = Qspi_Ip_SfdpGetWeSrInstr(sfdpTables);
3154     if (QSPI_IP_CMD_BASIC_WRITE_ENABLE == instruction)
3155     {
3156         statusConfig->writeEnableSRLut = statusConfig->writeEnableLut;
3157     }
3158     else
3159     {
3160         statusConfig->writeEnableSRLut = lutCount;
3161         Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPads, instruction));
3162         Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3163     }
3164 }
3165 
3166 
3167 /*FUNCTION**********************************************************************
3168  *
3169  * Function Name : Qspi_Ip_SfdpGetXspi1StatusInfo
3170  * Description   : Builds configuration for octal DDR (DOPI) mode.
3171  */
Qspi_Ip_SfdpGetXspi1StatusInfo(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)3172 static void Qspi_Ip_SfdpGetXspi1StatusInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3173                                            Qspi_Ip_MemoryConfigType *pConfig
3174                                           )
3175 {
3176     uint8 instruction;
3177     uint8 cmdExt;
3178     uint8 dummy;
3179     Qspi_Ip_StatusConfigType *statusConfig;
3180 
3181     statusConfig = &(pConfig->statusConfig);
3182 
3183     /* Build LUT sequence for read status reg. */
3184     statusConfig->statusRegReadLut = lutCount;
3185     instruction = QSPI_IP_CMD_XSPI_READ_SR;
3186     cmdExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, instruction);
3187     dummy = (uint8)Qspi_Ip_SfdpGetSRMapParam(sfdpTables, QSPI_IP_SFDP_SRMAP_DUMMY_8D_DWORD,
3188                                              QSPI_IP_SFDP_SRMAP_DUMMY_8D_SHIFT, QSPI_IP_SFDP_SRMAP_DUMMY_8D_WIDTH, 0x0U);
3189     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, instruction));
3190     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, cmdExt));
3191     Qspi_Ip_SfdpLutAddSrAddr(&(pConfig->lutSequences), sfdpTables);
3192     if (dummy != 0U)
3193     {
3194         Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_DUMMY, QSPI_IP_LUT_PADS_8, dummy));
3195     }
3196     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_READ_DDR, QSPI_IP_LUT_PADS_8, 0x10));
3197     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3198 
3199     /* Build LUT sequence for write status reg. */
3200     statusConfig->statusRegWriteLut = lutCount;
3201     instruction = QSPI_IP_CMD_XSPI_WRITE_SR;
3202     cmdExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, instruction);
3203     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, instruction));
3204     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, cmdExt));
3205     Qspi_Ip_SfdpLutAddSrAddr(&(pConfig->lutSequences), sfdpTables);
3206     /* Use SDR write because reg. size is 1 */
3207     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_WRITE, QSPI_IP_LUT_PADS_8, 0x2U));
3208     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3209 
3210     /* Build LUT sequence for write enable */
3211     statusConfig->writeEnableSRLut = lutCount;
3212     statusConfig->writeEnableLut = lutCount;
3213     instruction = QSPI_IP_CMD_XSPI_WRITE_ENABLE;
3214     cmdExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, instruction);
3215     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, instruction));
3216     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, cmdExt));
3217     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3218 }
3219 
3220 
3221 /*FUNCTION**********************************************************************
3222  *
3223  * Function Name : Qspi_Ip_SfdpConfigReset1
3224  * Description   : Configure reset settings - option 1.
3225  */
Qspi_Ip_SfdpConfigReset1(const Qspi_Ip_MemoryConfigType * pConfig,const Qspi_Ip_ResetConfigType * resetSettings,Qspi_Ip_LutPadsType pads)3226 static void Qspi_Ip_SfdpConfigReset1(const Qspi_Ip_MemoryConfigType * pConfig,
3227                                      const Qspi_Ip_ResetConfigType *resetSettings,
3228                                      Qspi_Ip_LutPadsType pads
3229                                     )
3230 {
3231     /* drive Fh on all 4 data wires for 8 clocks */
3232     /* Not implemented */
3233     (void)pConfig;
3234     (void)resetSettings;
3235     (void)pads;
3236 }
3237 
3238 
3239 /*FUNCTION**********************************************************************
3240  *
3241  * Function Name : Qspi_Ip_SfdpConfigReset2
3242  * Description   : Configure reset settings - option 2.
3243  */
Qspi_Ip_SfdpConfigReset2(const Qspi_Ip_MemoryConfigType * pConfig,const Qspi_Ip_ResetConfigType * resetSettings,Qspi_Ip_LutPadsType pads)3244 static void Qspi_Ip_SfdpConfigReset2(const Qspi_Ip_MemoryConfigType * pConfig,
3245                                      const Qspi_Ip_ResetConfigType *resetSettings,
3246                                      Qspi_Ip_LutPadsType pads
3247                                     )
3248 {
3249     /* drive Fh on all 4 data wires for 10 clocks if device is operating in 4-byte address mode */
3250     /* Not implemented */
3251     (void)pConfig;
3252     (void)resetSettings;
3253     (void)pads;
3254 }
3255 
3256 
3257 /*FUNCTION**********************************************************************
3258  *
3259  * Function Name : Qspi_Ip_SfdpConfigReset4
3260  * Description   : Configure reset settings - option 4.
3261  */
Qspi_Ip_SfdpConfigReset4(const Qspi_Ip_MemoryConfigType * pConfig,const Qspi_Ip_ResetConfigType * resetSettings,Qspi_Ip_LutPadsType pads)3262 static void Qspi_Ip_SfdpConfigReset4(const Qspi_Ip_MemoryConfigType * pConfig,
3263                                      const Qspi_Ip_ResetConfigType *resetSettings,
3264                                      Qspi_Ip_LutPadsType pads
3265                                     )
3266 {
3267     /* drive Fh on all 4 data wires for 16 clocks */
3268     /* Not implemented */
3269     (void)pConfig;
3270     (void)resetSettings;
3271     (void)pads;
3272 }
3273 
3274 
3275 /*FUNCTION**********************************************************************
3276  *
3277  * Function Name : Qspi_Ip_SfdpConfigReset8
3278  * Description   : Configure reset settings - option 8.
3279  */
Qspi_Ip_SfdpConfigReset8(const Qspi_Ip_MemoryConfigType * pConfig,Qspi_Ip_ResetConfigType * resetSettings,Qspi_Ip_LutPadsType pads)3280 static void Qspi_Ip_SfdpConfigReset8(const Qspi_Ip_MemoryConfigType * pConfig,
3281                                      Qspi_Ip_ResetConfigType *resetSettings,
3282                                      Qspi_Ip_LutPadsType pads
3283                                     )
3284 {
3285     /* issue instruction F0h */
3286     resetSettings->resetCmdLut = lutCount;
3287     resetSettings->resetCmdCount = 1U;
3288     /* Build LUT sequence */
3289     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, pads, 0xF0U));
3290     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3291 }
3292 
3293 
3294 /*FUNCTION**********************************************************************
3295  *
3296  * Function Name : Qspi_Ip_SfdpConfigReset16
3297  * Description   : Configure reset settings - option 16.
3298  */
Qspi_Ip_SfdpConfigReset16(const Qspi_Ip_MemoryConfigType * pConfig,Qspi_Ip_ResetConfigType * resetSettings,Qspi_Ip_LutPadsType pads)3299 static void Qspi_Ip_SfdpConfigReset16(const Qspi_Ip_MemoryConfigType * pConfig,
3300                                       Qspi_Ip_ResetConfigType *resetSettings,
3301                                       Qspi_Ip_LutPadsType pads
3302                                      )
3303 {
3304     /* issue reset enable instruction 66h, then issue reset instruction 99h.
3305        The reset enable, reset sequence may be issued on 1, 2, 4, or 8 wires depending on the device operating mode. */
3306     resetSettings->resetCmdLut = lutCount;
3307     resetSettings->resetCmdCount = 2U;
3308     /* 1st LUT sequence - 0x66 */
3309     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, pads, 0x66U));
3310     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3311     /* 2nd LUT sequence - 0x99 */
3312     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, pads, 0x99U));
3313     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3314 }
3315 
3316 /*FUNCTION**********************************************************************
3317  *
3318  * Function Name : Qspi_Ip_SfdpConfigResetOthers
3319  * Description   : Configure reset settings for 1, 2, 4 wires
3320  */
Qspi_Ip_SfdpConfigResetOthers(uint8 resetOption,const Qspi_Ip_MemoryConfigType * pConfig,Qspi_Ip_ResetConfigType * resetSettings,Qspi_Ip_LutPadsType pads)3321 static void Qspi_Ip_SfdpConfigResetOthers(uint8 resetOption,
3322                                           const Qspi_Ip_MemoryConfigType * pConfig,
3323                                           Qspi_Ip_ResetConfigType *resetSettings,
3324                                           Qspi_Ip_LutPadsType pads
3325                                          )
3326 {
3327     if ((resetOption & 0x1U) != 0U)
3328     {
3329         Qspi_Ip_SfdpConfigReset1(pConfig, resetSettings, pads);
3330         /* drive Fh on all 4 data wires for 8 clocks */
3331     }
3332     else if ((resetOption & 0x2U) != 0U)
3333     {
3334         Qspi_Ip_SfdpConfigReset2(pConfig, resetSettings, pads);
3335         /* drive Fh on all 4 data wires for 10 clocks if device is operating in 4-byte address mode */
3336     }
3337     else if ((resetOption & 0x4U) != 0U)
3338     {
3339         Qspi_Ip_SfdpConfigReset4(pConfig, resetSettings, pads);
3340         /* drive Fh on all 4 data wires for 16 clocks */
3341     }
3342     else
3343     {
3344         /* unknown reset sequence */
3345         resetSettings->resetCmdLut = QSPI_IP_LUT_INVALID;
3346         resetSettings->resetCmdCount = 0U;
3347     }
3348 }
3349 
3350 /*FUNCTION**********************************************************************
3351  *
3352  * Function Name : Qspi_Ip_SfdpGetBasicResetInfo
3353  * Description   : Configure reset settings - XPI mode.
3354  */
Qspi_Ip_SfdpGetBasicResetInfo(const Qspi_Ip_SfdpTablesContainer * sfdpTables,const Qspi_Ip_MemoryConfigType * pConfig,Qspi_Ip_ResetConfigType * resetSettings,Qspi_Ip_LutPadsType pads)3355 static void Qspi_Ip_SfdpGetBasicResetInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3356                                           const Qspi_Ip_MemoryConfigType *pConfig,
3357                                           Qspi_Ip_ResetConfigType *resetSettings,
3358                                           Qspi_Ip_LutPadsType pads
3359                                          )
3360 {
3361     uint8 resetOption;
3362 
3363     resetOption = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_SW_RESET_DWORD,
3364                                                    QSPI_IP_SFDP_BASIC_SW_RESET_SHIFT, QSPI_IP_SFDP_BASIC_SW_RESET_WIDTH, 0x0U);
3365     if ((resetOption & 0x10U) != 0U)
3366     {
3367         /* issue reset enable instruction 66h, then issue reset instruction 99h.
3368            The reset enable, reset sequence may be issued on 1, 2, 4, or 8 wires depending on the device operating mode. */
3369         Qspi_Ip_SfdpConfigReset16(pConfig, resetSettings, pads);
3370     }
3371     else if ((resetOption & 0x8U) != 0U)
3372     {
3373         Qspi_Ip_SfdpConfigReset8(pConfig, resetSettings, pads);
3374         /* issue instruction F0h */
3375     }
3376     else
3377     {
3378         Qspi_Ip_SfdpConfigResetOthers(resetOption, pConfig, resetSettings, pads);
3379     }
3380 }
3381 
3382 
3383 /*FUNCTION**********************************************************************
3384  *
3385  * Function Name : Qspi_Ip_SfdpGetXspi1ResetInfo
3386  * Description   : Configure reset settings - XPI mode.
3387  */
Qspi_Ip_SfdpGetXspi1ResetInfo(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)3388 static void Qspi_Ip_SfdpGetXspi1ResetInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3389                                           Qspi_Ip_MemoryConfigType *pConfig
3390                                          )
3391 {
3392     uint8 rSup;
3393     uint8 rEnSup;
3394     uint8 instruction;
3395     uint8 cmdExt;
3396 
3397     pConfig->resetSettings.resetCmdLut = QSPI_IP_LUT_INVALID;
3398     pConfig->resetSettings.resetCmdCount = 0U;
3399 
3400     rEnSup = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_XSPI1_RESET_EN_DWORD,
3401                                               QSPI_IP_SFDP_XSPI1_RESET_EN_SHIFT, QSPI_IP_SFDP_XSPI1_RESET_EN_WIDTH, 0x0U);
3402     rSup = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_XSPI1_RESET_DEF_DWORD,
3403                                             QSPI_IP_SFDP_XSPI1_RESET_DEF_SHIFT, QSPI_IP_SFDP_XSPI1_RESET_DEF_WIDTH, 0x0U);
3404     if ((rEnSup == 1U) && (rSup == 1U))
3405     {
3406         /* 0x66, 0x99 reset sequence */
3407         pConfig->resetSettings.resetCmdLut = lutCount;
3408         pConfig->resetSettings.resetCmdCount = 2U;
3409         instruction = QSPI_IP_CMD_XSPI_RESET_ENABLE;
3410         cmdExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, instruction);
3411         Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, instruction));
3412         Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, cmdExt));
3413         Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3414 
3415         instruction = QSPI_IP_CMD_XSPI_RESET_DEF;
3416         cmdExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, instruction);
3417         Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, instruction));
3418         Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, cmdExt));
3419         Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3420     }
3421     else
3422     {
3423         rSup = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_XSPI1_RESET_DWORD,
3424                                                 QSPI_IP_SFDP_XSPI1_RESET_SHIFT, QSPI_IP_SFDP_XSPI1_RESET_WIDTH, 0x0U);
3425         if (rSup == 1U)
3426         {
3427             /* 0xF0 reset command */
3428             pConfig->resetSettings.resetCmdLut = lutCount;
3429             pConfig->resetSettings.resetCmdCount = 1U;
3430             instruction = QSPI_IP_CMD_XSPI_RESET;
3431             cmdExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, instruction);
3432             Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, instruction));
3433             Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, cmdExt));
3434             Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3435         }
3436     }
3437 }
3438 
3439 
3440 /*FUNCTION**********************************************************************
3441  *
3442  * Function Name : Qspi_Ip_SfdpGetXspi1InitResetInfo
3443  * Description   : Configure initial reset settings - XPI mode
3444  */
Qspi_Ip_SfdpGetXspi1InitResetInfo(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)3445 static void Qspi_Ip_SfdpGetXspi1InitResetInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3446                                               Qspi_Ip_MemoryConfigType *pConfig
3447                                              )
3448 {
3449     uint8 rSup;
3450     uint8 rEnSup;
3451     uint8 instruction;
3452 
3453     /* Set the default value to be disabled */
3454     pConfig->initResetSettings.resetCmdLut = QSPI_IP_LUT_INVALID;
3455     pConfig->initResetSettings.resetCmdCount = 0U;
3456 
3457     rEnSup = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_XSPI1_RESET_EN_DWORD,
3458                                               QSPI_IP_SFDP_XSPI1_RESET_EN_SHIFT, QSPI_IP_SFDP_XSPI1_RESET_EN_WIDTH, 0x0U);
3459     rSup = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_XSPI1_RESET_DEF_DWORD,
3460                                             QSPI_IP_SFDP_XSPI1_RESET_DEF_SHIFT, QSPI_IP_SFDP_XSPI1_RESET_DEF_WIDTH, 0x0U);
3461     if ((rEnSup == 1U) && (rSup == 1U))
3462     {
3463         /* 0x66, 0x99 reset sequence */
3464         pConfig->initResetSettings.resetCmdLut = lutCount;
3465         pConfig->initResetSettings.resetCmdCount = 2U;
3466         instruction = QSPI_IP_CMD_XSPI_RESET_ENABLE;
3467         Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPadsInit, instruction));
3468         Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, cmdPadsInit, 0x0U));
3469 
3470         instruction = QSPI_IP_CMD_XSPI_RESET_DEF;
3471         Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPadsInit, instruction));
3472         Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, cmdPadsInit, 0x0U));
3473     }
3474     else
3475     {
3476         rSup = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_XSPI1_RESET_DWORD,
3477                                                 QSPI_IP_SFDP_XSPI1_RESET_SHIFT, QSPI_IP_SFDP_XSPI1_RESET_WIDTH, 0x0U);
3478         if (rSup == 1U)
3479         {
3480             /* 0xF0 reset command */
3481             pConfig->initResetSettings.resetCmdLut = lutCount;
3482             pConfig->initResetSettings.resetCmdCount = 1U;
3483             instruction = QSPI_IP_CMD_XSPI_RESET;
3484             Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPadsInit, instruction));
3485             Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, cmdPadsInit, 0x0U));
3486         }
3487     }
3488 }
3489 
3490 
3491 /*FUNCTION**********************************************************************
3492  *
3493  * Function Name : Qspi_Ip_SfdpGetBasicSuspendInfo
3494  * Description   : Configure  suspend settings - SPI mode
3495  */
Qspi_Ip_SfdpGetBasicSuspendInfo(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)3496 static void Qspi_Ip_SfdpGetBasicSuspendInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3497                                             Qspi_Ip_MemoryConfigType * pConfig
3498                                            )
3499 {
3500     uint8 esus;
3501     uint8 eres;
3502     uint8 psus;
3503     uint8 pres;
3504 
3505     esus = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_ESUS_INSTR_DWORD,
3506                                             QSPI_IP_SFDP_BASIC_ESUS_INSTR_SHIFT, QSPI_IP_SFDP_BASIC_ESUS_INSTR_WIDTH, 0xB0U);
3507     eres = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_ERES_INSTR_DWORD,
3508                                             QSPI_IP_SFDP_BASIC_ERES_INSTR_SHIFT, QSPI_IP_SFDP_BASIC_ERES_INSTR_WIDTH, 0x30U);
3509     psus = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_PSUS_INSTR_DWORD,
3510                                             QSPI_IP_SFDP_BASIC_PSUS_INSTR_SHIFT, QSPI_IP_SFDP_BASIC_PSUS_INSTR_WIDTH, 0xB0U);
3511     pres = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_PRES_INSTR_DWORD,
3512                                             QSPI_IP_SFDP_BASIC_PRES_INSTR_SHIFT, QSPI_IP_SFDP_BASIC_PRES_INSTR_WIDTH, 0x30U);
3513 
3514     /* Erase suspend sequence */
3515     pConfig->suspendSettings.eraseSuspendLut = lutCount;
3516     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPads, esus));
3517     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3518     /* Erase resume sequence */
3519     pConfig->suspendSettings.eraseResumeLut = lutCount;
3520     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPads, eres));
3521     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3522     /* Program suspend sequence */
3523     if (esus == psus)
3524     {
3525         pConfig->suspendSettings.programSuspendLut = pConfig->suspendSettings.eraseSuspendLut;
3526     }
3527     else
3528     {
3529         pConfig->suspendSettings.programSuspendLut = lutCount;
3530         Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPads, psus));
3531         Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3532     }
3533     /* Program resume sequence */
3534     if (eres == pres)
3535     {
3536         pConfig->suspendSettings.programResumeLut = pConfig->suspendSettings.eraseResumeLut;
3537     }
3538     else
3539     {
3540         pConfig->suspendSettings.programResumeLut = lutCount;
3541         Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPads, pres));
3542         Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3543     }
3544 }
3545 
3546 
3547 /*FUNCTION**********************************************************************
3548  *
3549  * Function Name : Qspi_Ip_SfdpGetXspi1SuspendInfo
3550  * Description   : Configure  suspend settings - XPI mode
3551  */
Qspi_Ip_SfdpGetXspi1SuspendInfo(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)3552 static void Qspi_Ip_SfdpGetXspi1SuspendInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3553                                             Qspi_Ip_MemoryConfigType *pConfig
3554                                            )
3555 {
3556     uint8 esus;
3557     uint8 eres;
3558     uint8 psus;
3559     uint8 pres;
3560     uint8 cmdExt;
3561 
3562     esus = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_BASIC_ESUS_INSTR_DWORD,
3563                                             QSPI_IP_SFDP_BASIC_ESUS_INSTR_SHIFT, QSPI_IP_SFDP_BASIC_ESUS_INSTR_WIDTH, 0xB0U);
3564     eres = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_BASIC_ERES_INSTR_DWORD,
3565                                             QSPI_IP_SFDP_BASIC_ERES_INSTR_SHIFT, QSPI_IP_SFDP_BASIC_ERES_INSTR_WIDTH, 0x30U);
3566     psus = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_BASIC_PSUS_INSTR_DWORD,
3567                                             QSPI_IP_SFDP_BASIC_PSUS_INSTR_SHIFT, QSPI_IP_SFDP_BASIC_PSUS_INSTR_WIDTH, 0xB0U);
3568     pres = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_BASIC_PRES_INSTR_DWORD,
3569                                             QSPI_IP_SFDP_BASIC_PRES_INSTR_SHIFT, QSPI_IP_SFDP_BASIC_PRES_INSTR_WIDTH, 0x30U);
3570 
3571     /* Erase suspend sequence */
3572     pConfig->suspendSettings.eraseSuspendLut = lutCount;
3573     cmdExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, esus);
3574     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, esus));
3575     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, cmdExt));
3576     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3577     /* Erase resume sequence */
3578     pConfig->suspendSettings.eraseResumeLut = lutCount;
3579     cmdExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, eres);
3580     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, eres));
3581     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, cmdExt));
3582     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3583     /* Program suspend sequence */
3584     if (esus == psus)
3585     {
3586         pConfig->suspendSettings.programSuspendLut = pConfig->suspendSettings.eraseSuspendLut;
3587     }
3588     else
3589     {
3590         pConfig->suspendSettings.programSuspendLut = lutCount;
3591         cmdExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, psus);
3592         Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, psus));
3593         Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, cmdExt));
3594         Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3595     }
3596     /* Program resume sequence */
3597     if (eres == pres)
3598     {
3599         pConfig->suspendSettings.programResumeLut = pConfig->suspendSettings.eraseResumeLut;
3600     }
3601     else
3602     {
3603         pConfig->suspendSettings.programResumeLut = lutCount;
3604         cmdExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, pres);
3605         Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, pres));
3606         Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, cmdExt));
3607         Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3608     }
3609 }
3610 
3611 
3612 /*FUNCTION**********************************************************************
3613  *
3614  * Function Name : Qspi_Ip_SfdpAdd2dopiOperation
3615  * Description   : Add a DOPI switch command to the operation list
3616  */
Qspi_Ip_SfdpAdd2dopiOperation(const Qspi_Ip_MemoryConfigType * pConfig,uint8 seqSize,const uint32 * words)3617 static void Qspi_Ip_SfdpAdd2dopiOperation(const Qspi_Ip_MemoryConfigType *pConfig,
3618                                           uint8 seqSize,
3619                                           const uint32 *words
3620                                          )
3621 {
3622     Qspi_Ip_InitOperationType *operation;
3623     uint8 nextByte;
3624     uint8 cnt;
3625 
3626     if (initOpCount >= pConfig->initConfiguration.opCount)
3627     {
3628         /* operations list not big enough */
3629         overflow = TRUE;
3630     }
3631     else
3632     {
3633         operation = &(pConfig->initConfiguration.operations[initOpCount]);
3634         initOpCount++;
3635         operation->opType = QSPI_IP_OP_TYPE_CMD;
3636         operation->command1Lut = lutCount;
3637         operation->addr = 0U;
3638         /* Build LUT sequence for this command */
3639         for (cnt = 0U; cnt < seqSize; cnt++)
3640         {
3641             nextByte = (uint8)((words[dopiSwitchWord[cnt]] >> dopiSwitchShift[cnt]) & 0xFFU);
3642             Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, QSPI_IP_LUT_PADS_1, nextByte));
3643         }
3644         /* Add STOP instruction */
3645         Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3646         /* Other operation fields are unused */
3647         operation->command2Lut = QSPI_IP_LUT_INVALID;
3648         operation->weLut = QSPI_IP_LUT_INVALID;
3649         operation->size  = 0U;
3650         operation->shift = 0U;
3651         operation->width = 0U;
3652         operation->value = 0U;
3653         operation->ctrlCfgPtr = NULL_PTR;
3654     }
3655 
3656     return;
3657 }
3658 
3659 
3660 /*FUNCTION**********************************************************************
3661  *
3662  * Function Name : Qspi_Ip_SfdpAddCheckBusyOperation
3663  * Description   : Add a READ_REG operation to check the BUSY flag of the status register.
3664  */
Qspi_Ip_SfdpAddCheckBusyOperation(const Qspi_Ip_MemoryConfigType * pConfig)3665 static void Qspi_Ip_SfdpAddCheckBusyOperation(const Qspi_Ip_MemoryConfigType *pConfig)
3666 {
3667     Qspi_Ip_InitOperationType *operation;
3668     const Qspi_Ip_StatusConfigType *statusConfig;
3669 
3670     if (initOpCount >= pConfig->initConfiguration.opCount)
3671     {
3672         /* operations list not big enough */
3673         overflow = TRUE;
3674     }
3675     else
3676     {
3677         /* Build a read operation to check the BUSY flag of the status register */
3678         operation = &(pConfig->initConfiguration.operations[initOpCount]);
3679         initOpCount++;
3680 
3681         /* Use the initial read status reg that was configured before */
3682         statusConfig = &(pConfig->statusConfig);
3683 
3684         operation->opType      = QSPI_IP_OP_TYPE_READ_REG;
3685         operation->command1Lut = statusConfig->statusRegInitReadLut;
3686         operation->size        = statusConfig->regSize;
3687         operation->shift       = statusConfig->busyOffset;
3688         operation->value       = 1U - (uint32)statusConfig->busyValue;  /* Reverse: wait until not busy */
3689         operation->width       = 1U;
3690 
3691         /* Other operation fields are unused */
3692         operation->command2Lut = QSPI_IP_LUT_INVALID;
3693         operation->weLut       = QSPI_IP_LUT_INVALID;
3694         operation->addr        = 0U;
3695         operation->ctrlCfgPtr  = NULL_PTR;
3696     }
3697 }
3698 
3699 
3700 
3701 /*FUNCTION**********************************************************************
3702  *
3703  * Function Name : Qspi_Ip_SfdpGetXspi1InitOpInfo
3704  * Description   : Configure initial operations list - XPI mode
3705  */
Qspi_Ip_SfdpGetXspi1InitOpInfo(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)3706 static void Qspi_Ip_SfdpGetXspi1InitOpInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3707                                            Qspi_Ip_MemoryConfigType *pConfig
3708                                           )
3709 {
3710     uint8 cnt;
3711     uint8 seqSize;
3712 
3713     if (sfdpTables->paramTableLength_2dopi > 0U)
3714     {
3715         for (cnt = 0U; cnt < (sfdpTables->paramTableLength_2dopi - 1U); cnt += 2U)
3716         {
3717             seqSize = (uint8)Qspi_Ip_SfdpGet2DopiParam(sfdpTables, cnt + 1U,
3718                                                        QSPI_IP_SFDP_2DOPI_CMD_LEN_SHIFT, QSPI_IP_SFDP_2DOPI_CMD_LEN_WIDTH, 0x0U);
3719             if (seqSize == 0U)
3720             {
3721                 /* No more commands */
3722                 break;
3723             }
3724             /* Add a wait operation to ensure the previous command is completed, needed for write in a non-volatile register */
3725             Qspi_Ip_SfdpAddCheckBusyOperation(pConfig);
3726 
3727             Qspi_Ip_SfdpAdd2dopiOperation(pConfig, seqSize, &sfdpTables->paramTable_2dopi[cnt]);
3728         }
3729     }
3730     /* Update operations count */
3731     pConfig->initConfiguration.opCount = initOpCount;
3732 }
3733 
3734 
3735 /*FUNCTION**********************************************************************
3736  *
3737  * Function Name : Qspi_Ip_SfdpGetBasicInitOpInfo
3738  * Description   : Configure initial operations list - XPI mode
3739  */
Qspi_Ip_SfdpGetBasicInitOpInfo(Qspi_Ip_MemoryConfigType * pConfig)3740 static void Qspi_Ip_SfdpGetBasicInitOpInfo(Qspi_Ip_MemoryConfigType * pConfig)
3741 {
3742     /* Init operations already added, update operations count */
3743     pConfig->initConfiguration.opCount = initOpCount;
3744 }
3745 
3746 
3747 /*FUNCTION**********************************************************************
3748  *
3749  * Function Name : Qspi_Ip_SfdpGet0xxInfo
3750  * Description   : Configure 0xx capabilities - XPI mode
3751  */
Qspi_Ip_SfdpGet0xxInfo(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)3752 static void Qspi_Ip_SfdpGet0xxInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3753                                    Qspi_Ip_MemoryConfigType * pConfig
3754                                   )
3755 {
3756     /* Not implemented */
3757     (void)sfdpTables;
3758     pConfig->read0xxLut = QSPI_IP_LUT_INVALID;
3759     pConfig->read0xxLutAHB = QSPI_IP_LUT_INVALID;
3760 }
3761 
3762 
3763 /*FUNCTION**********************************************************************
3764  *
3765  * Function Name : Qspi_Ip_SfdpConfigureOther
3766  * Description   : Configure unsupported features
3767  */
Qspi_Ip_SfdpConfigureOther(Qspi_Ip_MemoryConfigType * pConfig)3768 static void Qspi_Ip_SfdpConfigureOther(Qspi_Ip_MemoryConfigType * pConfig)
3769 {
3770     pConfig->readIdSettings.readIdLut = QSPI_IP_LUT_INVALID;
3771     pConfig->initCallout = NULL_PTR;
3772     pConfig->resetCallout = NULL_PTR;
3773     pConfig->errorCheckCallout = NULL_PTR;
3774     pConfig->ctrlAutoCfgPtr = NULL_PTR;
3775 }
3776 
3777 
3778 
3779 /*FUNCTION**********************************************************************
3780  *
3781  * Function Name : Qspi_Ip_SfdpGetSize
3782  * Description   : Builds configuration for octal DDR (DOPI) mode.
3783  */
Qspi_Ip_SfdpGetSize(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)3784 static void Qspi_Ip_SfdpGetSize(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3785                                 Qspi_Ip_MemoryConfigType *pConfig
3786                                )
3787 {
3788     uint32 size;
3789 
3790     /* Dword 2 of parameter table: Flash Memory Density */
3791     size = Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_MEM_SIZE_DWORD,
3792                                      QSPI_IP_SFDP_BASIC_MEM_SIZE_SHIFT, QSPI_IP_SFDP_BASIC_MEM_SIZE_WIDTH, 0xFFFFFU);
3793     /* check MSB */
3794     if ((size & 0x80000000U) == 0U)
3795     {
3796         pConfig->memSize = (size + 1U) >> 3U;
3797     }
3798     else
3799     {
3800         pConfig->memSize = ((uint32)1U << ((size & (~(uint32)0x80000000U)) - (uint32)3U));
3801     }
3802 
3803     /* Dword 11 of parameter table: Page Size */
3804     size = Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_PAGE_SIZE_DWORD,
3805                                      QSPI_IP_SFDP_BASIC_PAGE_SIZE_SHIFT, QSPI_IP_SFDP_BASIC_PAGE_SIZE_WIDTH, 8U);
3806     pConfig->pageSize = ((uint32)1U << size);
3807 }
3808 
3809 
3810 /*FUNCTION**********************************************************************
3811  *
3812  * Function Name : Qspi_Ip_GetBasicInfo
3813  * Description   : Builds basic configurations
3814  */
Qspi_Ip_SfdpGetBasicInfo(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)3815 static inline void Qspi_Ip_SfdpGetBasicInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3816                                             Qspi_Ip_MemoryConfigType * pConfig
3817                                            )
3818 {
3819     /* Configure read command */
3820     Qspi_Ip_SfdpGetBasicReadInfo(sfdpTables, pConfig);
3821     /* Configure write command */
3822     Qspi_Ip_SfdpGetBasicWriteInfo(sfdpTables, pConfig);
3823     /* Configure erase commands */
3824     Qspi_Ip_SfdpGetBasicEraseInfo(sfdpTables, pConfig);
3825     /* Configure status register */
3826     Qspi_Ip_SfdpGetBasicStatusInfo(sfdpTables, pConfig);
3827 
3828     /* Configure reset settings */
3829     Qspi_Ip_SfdpGetBasicResetInfo(sfdpTables, pConfig, &(pConfig->resetSettings), cmdPads);
3830     /* Configure initial reset settings */
3831     Qspi_Ip_SfdpGetBasicResetInfo(sfdpTables, pConfig, &(pConfig->initResetSettings), cmdPadsInit);
3832 
3833     /* Configure suspend settings */
3834     Qspi_Ip_SfdpGetBasicSuspendInfo(sfdpTables, pConfig);
3835     /* Configure initial operations list */
3836     Qspi_Ip_SfdpGetBasicInitOpInfo(pConfig);
3837 }
3838 
3839 
3840 /*FUNCTION**********************************************************************
3841  *
3842  * Function Name : Qspi_Ip_SfdpConfigureInitReadStatus
3843  * Description   : Builds configuration for initial read status reg.
3844  */
Qspi_Ip_SfdpConfigureInitReadStatus(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig,uint8 instruction)3845 static void Qspi_Ip_SfdpConfigureInitReadStatus(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3846                                                 Qspi_Ip_MemoryConfigType *pConfig,
3847                                                 uint8 instruction
3848                                                )
3849 {
3850     Qspi_Ip_StatusConfigType *statusConfig;
3851 
3852     statusConfig = &(pConfig->statusConfig);
3853 
3854     statusConfig->regSize = 1U;
3855     statusConfig->blockProtectionOffset = 0U;
3856     statusConfig->blockProtectionWidth = 0U;
3857     statusConfig->blockProtectionValue = 0U;
3858     statusConfig->busyOffset = (uint8)Qspi_Ip_SfdpGetSRMapParam(sfdpTables, QSPI_IP_SFDP_SRMAP_WIP_OFFSET_DWORD,
3859                                                                 QSPI_IP_SFDP_SRMAP_WIP_OFFSET_SHIFT, QSPI_IP_SFDP_SRMAP_WIP_OFFSET_WIDTH, 0x0U);
3860     /* Busy bit meaning is reversed (0: Positive (WIP=1 means write is in progress); 1: Inverted (WIP=0 means write is in progress) */
3861     statusConfig->busyValue = (uint8)(1U - Qspi_Ip_SfdpGetSRMapParam(sfdpTables, QSPI_IP_SFDP_SRMAP_WIP_VALUE_DWORD,
3862                                                                      QSPI_IP_SFDP_SRMAP_WIP_VALUE_SHIFT, QSPI_IP_SFDP_SRMAP_WIP_VALUE_WIDTH, 0x0U));
3863     statusConfig->writeEnableOffset = (uint8)Qspi_Ip_SfdpGetSRMapParam(sfdpTables, QSPI_IP_SFDP_SRMAP_WEL_OFFSET_DWORD,
3864                                                                        QSPI_IP_SFDP_SRMAP_WEL_OFFSET_SHIFT, QSPI_IP_SFDP_SRMAP_WEL_OFFSET_WIDTH, 0x1U);
3865     /* Build LUT sequence for initial read status reg. */
3866     statusConfig->statusRegInitReadLut = lutCount;
3867     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, QSPI_IP_LUT_PADS_1, instruction));
3868     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_READ, QSPI_IP_LUT_PADS_1, 0x1U));
3869     Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3870 }
3871 
3872 
3873 /*FUNCTION**********************************************************************
3874  *
3875  * Function Name : Qspi_Ip_ConfigureBasic
3876  * Description   : Builds configuration for octal DDR (DOPI) mode.
3877  */
Qspi_Ip_ConfigureBasic(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)3878 static Qspi_Ip_StatusType Qspi_Ip_ConfigureBasic(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3879                                                  Qspi_Ip_MemoryConfigType *pConfig
3880                                                 )
3881 {
3882     Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
3883 
3884     /* Get size, page size */
3885     Qspi_Ip_SfdpGetSize(sfdpTables, pConfig);
3886     /* Get addres size for read/write commands */
3887     Qspi_Ip_SfdpGetBasicAddrBits(sfdpTables, pConfig);
3888 
3889     /* Configure initial read status register */
3890     Qspi_Ip_SfdpConfigureInitReadStatus(sfdpTables, pConfig, QSPI_IP_CMD_BASIC_READ_SR);
3891 
3892     /* Check QE bit */
3893     Qspi_Ip_SfdpConfigureQE(sfdpTables, pConfig);
3894 
3895     /* Get basic info: read, write, erase, reset, suspend */
3896     Qspi_Ip_SfdpGetBasicInfo(sfdpTables, pConfig);
3897 
3898     /* Configure 0xx capabilities */
3899     Qspi_Ip_SfdpGet0xxInfo(sfdpTables, pConfig);
3900     /* Configure unsupported features */
3901     Qspi_Ip_SfdpConfigureOther(pConfig);
3902 
3903     /* Check for LUT or Init operations overflow */
3904     if (overflow == TRUE)
3905     {
3906         status = STATUS_QSPI_IP_ERROR;
3907     }
3908     return status;
3909 }
3910 
3911 /*FUNCTION**********************************************************************
3912  *
3913  * Function Name : Qspi_Ip_SfdpGetXspi1ResetConfig
3914  * Description   : Builds Xspi1 configure reset settings and initial reset settings.
3915  */
Qspi_Ip_SfdpGetXspi1ResetConfig(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)3916 static void Qspi_Ip_SfdpGetXspi1ResetConfig(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3917                                             Qspi_Ip_MemoryConfigType * pConfig
3918                                            )
3919 {
3920     /* Configure reset settings */
3921     Qspi_Ip_SfdpGetXspi1ResetInfo(sfdpTables, pConfig);
3922     /* Configure initial reset settings */
3923     Qspi_Ip_SfdpGetXspi1InitResetInfo(sfdpTables, pConfig);
3924 }
3925 
3926 
3927 /*FUNCTION**********************************************************************
3928  *
3929  * Function Name : Qspi_Ip_SfdpGetXspi1Info
3930  * Description   : Builds Xspi1 configurations.
3931  */
Qspi_Ip_SfdpGetXspi1Info(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)3932 static inline void Qspi_Ip_SfdpGetXspi1Info(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3933                                             Qspi_Ip_MemoryConfigType * pConfig
3934                                            )
3935 {
3936     /* Configure read command */
3937     Qspi_Ip_SfdpGetXspi1ReadInfo(sfdpTables, pConfig);
3938     /* Configure write command */
3939     Qspi_Ip_SfdpGetXspi1WriteInfo(sfdpTables, pConfig);
3940     /* Configure erase commands */
3941     Qspi_Ip_SfdpGetXspi1EraseInfo(sfdpTables, pConfig);
3942     /* Configure status register */
3943     Qspi_Ip_SfdpGetXspi1StatusInfo(sfdpTables, pConfig);
3944 
3945     /* Configure reset settings and initial reset settings */
3946     Qspi_Ip_SfdpGetXspi1ResetConfig(sfdpTables, pConfig);
3947     /* Configure suspend settings */
3948     Qspi_Ip_SfdpGetXspi1SuspendInfo(sfdpTables, pConfig);
3949     /* Configure initial operations list */
3950     Qspi_Ip_SfdpGetXspi1InitOpInfo(sfdpTables, pConfig);
3951 }
3952 
3953 
3954 /*FUNCTION**********************************************************************
3955  *
3956  * Function Name : Qspi_Ip_ConfigureXspi1
3957  * Description   : Builds octal DDR (DOPI) configuration for xSPI 1.0 devices.
3958  */
Qspi_Ip_ConfigureXspi1(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)3959 static Qspi_Ip_StatusType Qspi_Ip_ConfigureXspi1(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3960                                                  Qspi_Ip_MemoryConfigType *pConfig
3961                                                 )
3962 {
3963     Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
3964 
3965     /* Get size, page size */
3966     Qspi_Ip_SfdpGetSize(sfdpTables, pConfig);
3967 
3968     /* Configure initial read status register */
3969     Qspi_Ip_SfdpConfigureInitReadStatus(sfdpTables, pConfig, QSPI_IP_CMD_XSPI_READ_SR);
3970 
3971     /* Get Xspi1 info: read, write, erase, reset, suspend */
3972     Qspi_Ip_SfdpGetXspi1Info(sfdpTables, pConfig);
3973 
3974     /* Configure 0xx capabilities */
3975     Qspi_Ip_SfdpGet0xxInfo(sfdpTables, pConfig);
3976     /* Configure unsupported features */
3977     Qspi_Ip_SfdpConfigureOther(pConfig);
3978 
3979     /* Check for LUT or Init operations overflow */
3980     if (overflow == TRUE)
3981     {
3982         status = STATUS_QSPI_IP_ERROR;
3983     }
3984     return status;
3985 }
3986 
3987 
3988 /*******************************************************************************
3989  * Code
3990  ******************************************************************************/
3991 
3992 /*FUNCTION**********************************************************************
3993  *
3994  * Function Name : Qspi_Ip_SfdpConfigure
3995  * Description   : Check xSPI 1.0 support
3996  */
Qspi_Ip_SfdpConfigure(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)3997 static Qspi_Ip_StatusType Qspi_Ip_SfdpConfigure(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3998                                                  Qspi_Ip_MemoryConfigType *pConfig
3999                                                 )
4000 {
4001     Qspi_Ip_StatusType status;
4002     if (sfdpTables->paramTableLength_xspi1 > 0U)
4003     {
4004         status = Qspi_Ip_ConfigureXspi1(sfdpTables, pConfig);
4005     }
4006     else
4007     {
4008         status = Qspi_Ip_ConfigureBasic(sfdpTables, pConfig);
4009     }
4010     return status;
4011 }
4012 
4013 /*FUNCTION**********************************************************************
4014  *
4015  * Function Name : Qspi_Ip_ReadSfdp
4016  * Description   : Auto-fills configuration from SFDP information
4017 * @implements      Qspi_Ip_ReadSfdp_Activity */
Qspi_Ip_ReadSfdp(Qspi_Ip_MemoryConfigType * pConfig,const Qspi_Ip_MemoryConnectionType * pConnect)4018 Qspi_Ip_StatusType Qspi_Ip_ReadSfdp(Qspi_Ip_MemoryConfigType * pConfig,
4019                                     const Qspi_Ip_MemoryConnectionType * pConnect
4020                                    )
4021 {
4022     Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
4023     uint32 baseAddress;
4024     /* SFDP Tables */
4025     Qspi_Ip_SfdpTablesContainer sfdpTables;
4026 
4027 #if (QSPI_IP_DEV_ERROR_DETECT == STD_ON)
4028     /* Check for valid parameters */
4029     DEV_ASSERT_QSPI(pConnect != NULL_PTR);
4030     DEV_ASSERT_QSPI(pConfig != NULL_PTR);
4031     DEV_ASSERT_QSPI((pConfig->lutSequences.lutOps != NULL_PTR) && (pConfig->lutSequences.opCount > 0U));
4032 #endif
4033 
4034     /* Get device base address */
4035     baseAddress = Qspi_Ip_GetBaseAdress(pConnect->qspiInstance, pConnect->connectionType);
4036     /* Initiate communication with flash, check SFDP support */
4037     status = Qspi_Ip_SfdpCheck(pConnect->qspiInstance, baseAddress);
4038     if (status != STATUS_QSPI_IP_SUCCESS)
4039     {
4040         /* direct command - nothing to do */
4041     }
4042     else
4043     {
4044         /* Read SFDP tables of interest */
4045         status = Qspi_Ip_SfdpReadTables(pConnect->qspiInstance, baseAddress, &sfdpTables);
4046         if (status != STATUS_QSPI_IP_SUCCESS)
4047         {
4048             /* direct command - nothing to do */
4049         }
4050         else
4051         {
4052             /* Initialize LUT and init operations count */
4053             Qspi_Ip_SfdpLutInit();
4054             /* Build the enter legacy XPI protocol initial operation */
4055             Qspi_Ip_SfdpLutInitEnterLegacySPI(pConfig);
4056             /* Check xSPI 1.0 support */
4057             status = Qspi_Ip_SfdpConfigure(&sfdpTables, pConfig);
4058         }
4059     }
4060 
4061     return status;
4062 }
4063 
4064 
4065 
4066 #define MEM_43_EXFLS_STOP_SEC_CODE
4067 #include "Mem_43_EXFLS_MemMap.h"
4068 
4069 #endif /* (QSPI_IP_MEM_INSTANCE_COUNT > 0) */
4070 
4071 
4072 #ifdef __cplusplus
4073 }
4074 #endif
4075 
4076 /** @} */
4077 
4078