1 /***************************************************************************//**
2 * \file cybsp_smif_init.c
3 *
4 * Description:
5 * Provides initialization code for SMIF.
6 *
7 ********************************************************************************
8 * \copyright
9 * Copyright 2018-2022 Cypress Semiconductor Corporation (an Infineon company) or
10 * an affiliate of Cypress Semiconductor Corporation
11 *
12 * SPDX-License-Identifier: Apache-2.0
13 *
14 * Licensed under the Apache License, Version 2.0 (the "License");
15 * you may not use this file except in compliance with the License.
16 * You may obtain a copy of the License at
17 *
18 * http://www.apache.org/licenses/LICENSE-2.0
19 *
20 * Unless required by applicable law or agreed to in writing, software
21 * distributed under the License is distributed on an "AS IS" BASIS,
22 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23 * See the License for the specific language governing permissions and
24 * limitations under the License.
25 *******************************************************************************/
26 #if CY_PDL_FLASH_BOOT
27 #include "cybsp_smif_init.h"
28 #include "cycfg_pins.h"
29 #include "cyhal_pin_package.h"
30
31 cy_stc_smif_context_t cybsp_smif_context;
32
33 static uint32_t SMIF_PORT_SEL0;
34 static uint32_t SMIF_PORT_SEL1;
35 static uint32_t SMIF_CFG;
36 static uint32_t SMIF_OUT;
37
38 /*******************************************************************************
39 * Function Name: smif_disable
40 ****************************************************************************//**
41 *
42 * it disable the the SMIF.
43 *
44 * \return NULL.
45 *
46 *******************************************************************************/
47 CY_RAMFUNC_BEGIN
cybsp_smif_disable()48 void cybsp_smif_disable()
49 {
50 // to minimize DeepSleep latency this code assumes that all of the SMIF pins are on the same
51 // port
52 int port_number= CYHAL_GET_PORT(CYBSP_QSPI_SS);
53 SMIF0->CTL = SMIF0->CTL & ~SMIF_CTL_ENABLED_Msk;
54 SMIF_PORT_SEL0 = ((HSIOM_PRT_Type*)&HSIOM->PRT[port_number])->PORT_SEL0;
55 SMIF_PORT_SEL1 = ((HSIOM_PRT_Type*)&HSIOM->PRT[port_number])->PORT_SEL1;
56 SMIF_CFG = ((GPIO_PRT_Type*)&GPIO->PRT[port_number])->CFG;
57 SMIF_OUT = ((GPIO_PRT_Type*)&GPIO->PRT[port_number])->OUT;
58 ((HSIOM_PRT_Type*)&HSIOM->PRT[port_number])->PORT_SEL0 = 0x00;
59 ((HSIOM_PRT_Type*)&HSIOM->PRT[port_number])->PORT_SEL1 = 0x00;
60 ((GPIO_PRT_Type*)&GPIO->PRT[port_number])->CFG = 0x600006;
61 ((GPIO_PRT_Type*)&GPIO->PRT[port_number])->OUT = 0x1;
62 }
63
64
65 CY_RAMFUNC_END
66
67 /*******************************************************************************
68 * Function Name: smif_enable
69 ****************************************************************************//**
70 *
71 * it enable the the SMIF.
72 *
73 * \return NULL.
74 *
75 *******************************************************************************/
76 CY_RAMFUNC_BEGIN
cybsp_smif_enable()77 void cybsp_smif_enable()
78 {
79 int port_number= CYHAL_GET_PORT(CYBSP_QSPI_SS);
80 SMIF0->CTL = SMIF0->CTL | SMIF_CTL_ENABLED_Msk;
81 ((HSIOM_PRT_Type*)&HSIOM->PRT[port_number])->PORT_SEL0 = SMIF_PORT_SEL0;
82 ((HSIOM_PRT_Type*)&HSIOM->PRT[port_number])->PORT_SEL1 = SMIF_PORT_SEL1;
83 ((GPIO_PRT_Type*)&GPIO->PRT[port_number])->CFG = SMIF_CFG;
84 ((GPIO_PRT_Type*)&GPIO->PRT[port_number])->OUT = SMIF_OUT;
85 }
86
87
88 CY_RAMFUNC_END
89
90 /*******************************************************************************
91 * Function Name: cybsp_is_memory_ready
92 ****************************************************************************//**
93 *
94 * Polls the memory device to check whether it is ready to accept new commands or
95 * not until either it is ready or the retries have exceeded the limit.
96 *
97 * \param memConfig
98 * memory device configuration
99 *
100 * \return Status of the operation.
101 * CY_SMIF_SUCCESS - Memory is ready to accept new commands.
102 * CY_SMIF_EXCEED_TIMEOUT - Memory is busy.
103 *
104 *******************************************************************************/
105 #if defined (__ICCARM__)
106 /* Suppress warnings originating from configurator */
107 /* Ta022 : "Call to a non __ramfunc function from within a __ramfunc function" */
108 CY_PRAGMA(diag_suppress = Ta022)
109 #endif
110 //--------------------------------------------------------------------------------------------------
111 // cybsp_is_memory_ready
112 //--------------------------------------------------------------------------------------------------
113 CY_RAMFUNC_BEGIN
114
cybsp_is_memory_ready(cy_stc_smif_mem_config_t const * memConfig)115 cy_en_smif_status_t cybsp_is_memory_ready(cy_stc_smif_mem_config_t const* memConfig)
116 {
117 uint32_t retries = 0;
118 bool isBusy;
119
120 do
121 {
122 isBusy =
123 Cy_SMIF_Memslot_IsBusy(SMIF_HW, (cy_stc_smif_mem_config_t*)memConfig,
124 &cybsp_smif_context);
125 Cy_SysLib_DelayUs(15);
126 retries++;
127 } while(isBusy && (retries < MEMORY_BUSY_CHECK_RETRIES));
128
129 return (isBusy ? CY_SMIF_EXCEED_TIMEOUT : CY_SMIF_SUCCESS);
130 }
131
132
133 CY_RAMFUNC_END
134 #if defined (__ICCARM__)
135 CY_PRAGMA(diag_default = Ta022)
136 #endif
137
138 /*******************************************************************************
139 * Function Name: cybsp_enable_quad_mode
140 ****************************************************************************//*
141 *
142 * This function sets the QE (QUAD Enable) bit in the external memory
143 * configuration register to enable Quad SPI mode.
144 *
145 * \param memConfig
146 * Memory device configuration
147 *
148 * \return Status of the operation. See cy_en_smif_status_t.
149 *
150 *******************************************************************************/
151 #if defined (__ICCARM__)
152 /* Suppress warnings originating from configurator */
153 /* Ta022 : "Call to a non __ramfunc function from within a __ramfunc function" */
154 CY_PRAGMA(diag_suppress = Ta022)
155 #endif
156 //--------------------------------------------------------------------------------------------------
157 // cybsp_enable_quad_mode
158 //--------------------------------------------------------------------------------------------------
159 CY_RAMFUNC_BEGIN
160
cybsp_enable_quad_mode(cy_stc_smif_mem_config_t const * memConfig)161 cy_en_smif_status_t cybsp_enable_quad_mode(cy_stc_smif_mem_config_t const* memConfig)
162 {
163 cy_en_smif_status_t status;
164
165 /* Send Write Enable to external memory */
166 status = Cy_SMIF_Memslot_CmdWriteEnable(SMIF_HW, smifMemConfigs[0], &cybsp_smif_context);
167
168 if (CY_SMIF_SUCCESS == status)
169 {
170 status = Cy_SMIF_Memslot_QuadEnable(SMIF_HW, (cy_stc_smif_mem_config_t*)memConfig,
171 &cybsp_smif_context);
172
173 if (CY_SMIF_SUCCESS == status)
174 {
175 /* Poll memory for the completion of operation */
176 status = cybsp_is_memory_ready(memConfig);
177 }
178 }
179
180 return status;
181 }
182
183
184 CY_RAMFUNC_END
185 #if defined (__ICCARM__)
186 CY_PRAGMA(diag_default = Ta022)
187 #endif
188
189
190 /*******************************************************************************
191 * Function Name: cybsp_is_quad_enabled
192 ****************************************************************************//**
193 *
194 * Checks whether QE (Quad Enable) bit is set or not in the configuration
195 * register of the memory.
196 *
197 * \param memConfig
198 * Memory device configuration
199 *
200 * \param isQuadEnabled
201 * This parameter is updated to indicate whether Quad mode is enabled (true) or
202 * not (false). The value is valid only when the function returns
203 * CY_SMIF_SUCCESS.
204 *
205 * \return Status of the operation. See cy_en_smif_status_t.
206 *
207 *******************************************************************************/
208 #if defined (__ICCARM__)
209 /* Suppress warnings originating from configurator */
210 /* Ta022 : "Call to a non __ramfunc function from within a __ramfunc function" */
211 CY_PRAGMA(diag_suppress = Ta022)
212 #endif
213 //--------------------------------------------------------------------------------------------------
214 // cybsp_is_quad_enabled
215 //--------------------------------------------------------------------------------------------------
216 CY_RAMFUNC_BEGIN
217
cybsp_is_quad_enabled(cy_stc_smif_mem_config_t const * memConfig,bool * isQuadEnabled)218 cy_en_smif_status_t cybsp_is_quad_enabled(cy_stc_smif_mem_config_t const* memConfig,
219 bool* isQuadEnabled)
220 {
221 cy_en_smif_status_t status;
222 uint8_t readStatus = 0;
223 uint32_t statusCmd = memConfig->deviceCfg->readStsRegQeCmd->command;
224 uint8_t maskQE = (uint8_t)memConfig->deviceCfg->stsRegQuadEnableMask;
225
226 status = Cy_SMIF_Memslot_CmdReadSts(SMIF_HW, memConfig, &readStatus, statusCmd,
227 &cybsp_smif_context);
228
229 *isQuadEnabled = false;
230 if (CY_SMIF_SUCCESS == status)
231 {
232 /* Check whether Quad mode is already enabled or not */
233 *isQuadEnabled = (maskQE == (readStatus & maskQE));
234 }
235
236 return status;
237 }
238
239
240 CY_RAMFUNC_END
241 #if defined (__ICCARM__)
242 CY_PRAGMA(diag_default = Ta022)
243 #endif
244
245
246 cy_stc_smif_config_t cybsp_smif_config =
247 {
248 .mode = (uint32_t)CY_SMIF_NORMAL,
249 .deselectDelay = 7,
250 .rxClockSel = (uint32_t)CY_SMIF_SEL_INVERTED_FEEDBACK_CLK,
251 .blockEvent = (uint32_t)CY_SMIF_BUS_ERROR,
252 };
253
254 /********************************************************
255 * cybsp_smif_start
256 *********************************************************
257 * Initializes the SMIF hardware, sets the slave select
258 * and enables the SMIF block.
259 *
260 * returns: the status of the block during initialization
261 *
262 ********************************************************/
263 #if defined (__ICCARM__)
264 /* Suppress warnings originating from configurator */
265 /* Ta022 : "Call to a non __ramfunc function from within a __ramfunc function" */
266 CY_PRAGMA(diag_suppress = Ta022)
267 #endif
268 //--------------------------------------------------------------------------------------------------
269 // cybsp_smif_start
270 //--------------------------------------------------------------------------------------------------
271 CY_RAMFUNC_BEGIN
272
cybsp_smif_start(void)273 cy_en_smif_status_t cybsp_smif_start(void)
274 {
275 cy_en_smif_status_t cybsp_smif_status = CY_SMIF_BAD_PARAM;
276
277 cybsp_smif_status =
278 Cy_SMIF_Init(SMIF_HW, &cybsp_smif_config, TIMEOUT_1_MS, &cybsp_smif_context);
279
280 if (cybsp_smif_status == CY_SMIF_SUCCESS)
281 {
282 Cy_SMIF_SetDataSelect(SMIF_HW, smifMemConfigs[0]->slaveSelect,
283 smifMemConfigs[0]->dataSelect);
284 Cy_SMIF_Enable(SMIF_HW, &cybsp_smif_context);
285 }
286
287 return cybsp_smif_status;
288 }
289
290
291 CY_RAMFUNC_END
292 #if defined (__ICCARM__)
293 CY_PRAGMA(diag_default = Ta022)
294 #endif
295
296
297 /********************************************************
298 * cybsp_smif_init
299 *********************************************************
300 * Configures the SMIF hardware
301 ********************************************************/
302 #if defined (__ICCARM__)
303 /* Suppress warnings originating from configurator */
304 /* Ta022 : "Call to a non __ramfunc function from within a __ramfunc function" */
305 CY_PRAGMA(diag_suppress = Ta022)
306 #endif
307 //--------------------------------------------------------------------------------------------------
308 // cybsp_smif_init
309 //--------------------------------------------------------------------------------------------------
310 CY_RAMFUNC_BEGIN
311
cybsp_smif_init(void)312 cy_en_smif_status_t cybsp_smif_init(void)
313 {
314 /* Initalization Status Holders */
315 cy_en_smif_status_t cybsp_smif_status = CY_SMIF_BAD_PARAM;
316 bool QE_status = false;
317
318 cybsp_smif_status = cybsp_smif_start();
319
320 if (cybsp_smif_status == CY_SMIF_SUCCESS)
321 {
322 cybsp_smif_status = Cy_SMIF_MemCmdReleasePowerDown(SMIF0,
323 smifMemConfigs[0],
324 &cybsp_smif_context);
325
326 if (CY_SMIF_SUCCESS == cybsp_smif_status)
327 {
328 cybsp_smif_status = cybsp_is_memory_ready(smifMemConfigs[0]);
329 if (CY_SMIF_SUCCESS == cybsp_smif_status)
330 {
331 /* Map memory device to memory map */
332 cybsp_smif_status = Cy_SMIF_Memslot_Init(SMIF_HW,
333 (cy_stc_smif_block_config_t*)&smifBlockConfig,
334 &cybsp_smif_context);
335 if (cybsp_smif_status == CY_SMIF_SUCCESS)
336 {
337 /* Even after SFDP enumeration QE command is not initialised */
338 /* So, it should be 1.0 device */
339 if ((smifMemConfigs[0]->deviceCfg->readStsRegQeCmd->command ==
340 CY_SMIF_NO_COMMAND_OR_MODE) ||
341 (smifMemConfigs[0]->deviceCfg->readStsRegQeCmd->command == 0))
342 {
343 cybsp_smif_status = Cy_SMIF_MemInitSfdpMode(SMIF_HW,
344 smifMemConfigs[0],
345 CY_SMIF_WIDTH_QUAD,
346 CY_SMIF_SFDP_QER_1,
347 &cybsp_smif_context);
348 }
349
350 if (cybsp_smif_status == CY_SMIF_SUCCESS)
351 {
352 /* Check if Quad mode is already enabled */
353 cybsp_is_quad_enabled(smifMemConfigs[0], &QE_status);
354
355 /* If not enabled, enable quad mode */
356 if (!QE_status)
357 {
358 /* Enable Quad mode */
359 cybsp_smif_status = cybsp_enable_quad_mode(smifMemConfigs[0]);
360 }
361 if (cybsp_smif_status == CY_SMIF_SUCCESS)
362 {
363 /* Put the device in XIP mode */
364 Cy_SMIF_SetMode(SMIF_HW, CY_SMIF_MEMORY);
365 }
366 }
367 }
368 }
369 }
370 }
371
372 return cybsp_smif_status;
373 }
374
375
376 CY_RAMFUNC_END
377 #if defined (__ICCARM__)
378 CY_PRAGMA(diag_default = Ta022)
379 #endif
380
381 #endif // if CY_PDL_FLASH_BOOT
382