1 /***************************************************************************//**
2 * \file cybsp_pm_callbacks.c
3 *
4 * Description:
5 * Provides initialization code for starting up the hardware contained on the
6 * Infineon board.
7 *
8 ********************************************************************************
9 * \copyright
10 * Copyright 2018-2022 Cypress Semiconductor Corporation (an Infineon company) or
11 * an affiliate of Cypress Semiconductor Corporation
12 *
13 * SPDX-License-Identifier: Apache-2.0
14 *
15 * Licensed under the Apache License, Version 2.0 (the "License");
16 * you may not use this file except in compliance with the License.
17 * You may obtain a copy of the License at
18 *
19 *     http://www.apache.org/licenses/LICENSE-2.0
20 *
21 * Unless required by applicable law or agreed to in writing, software
22 * distributed under the License is distributed on an "AS IS" BASIS,
23 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24 * See the License for the specific language governing permissions and
25 * limitations under the License.
26 *******************************************************************************/
27 
28 #include <stdlib.h>
29 #include "cybsp_pm_callbacks.h"
30 #include "cycfg_qspi_memslot.h"
31 #include "cy_sysclk.h"
32 #include "cybsp_dsram.h"
33 #include "cybsp_smif_init.h"
34 
35 // Must be defined in file for RAM functions to utilize during Deep Sleep callback to wake
36 // up external flash memory. Needs reference here when external flash is powered down in DS.
37 #if CY_PDL_FLASH_BOOT
38 cy_stc_smif_mem_config_t** smifConfigLocal = smifMemConfigs;
39 #endif
40 
41 #if defined(__cplusplus)
42 extern "C" {
43 #endif
44 
45 #if (CY_PDL_FLASH_BOOT && (defined(CY_DEVICE_CYW20829) && \
46     (CY_SYSLIB_GET_SILICON_REV_ID != CY_SYSLIB_20829A0_SILICON_REV)))
47 #define CY_EXT_MEM_POWER_DOWN_SUPPORTED
48 #endif
49 ////////////////////////////////////////////////////////////////////////////////////////////////
50 /////////////////////////// BSP PM callbacks order values //////////////////////////////////////
51 
52 // CAT1B device QSPI memory power-down / power-up PM callback order.
53 #ifndef CYBSP_EXT_MEMORY_PM_CALLBACK_ORDER
54     #define CYBSP_EXT_MEMORY_PM_CALLBACK_ORDER  (254u)
55 #endif
56 // The sysclk deep sleep callback is recommended to be the last callback that is executed before
57 // entry into deep sleep mode and the first one upon exit the deep sleep mode.
58 // Doing so minimizes the time spent on low power mode entry and exit.
59 #ifndef CYBSP_SYSCLK_PM_CALLBACK_ORDER
60     #define CYBSP_SYSCLK_PM_CALLBACK_ORDER      (255u)
61 #endif
62 
63 ////////////////////////////////////////////////////////////////////////////////////////////////
64 /////////////////////////// BSP PM callbacks ///////////////////////////////////////////////////
65 
66 // CAT1B device QSPI memory power-down / power-up PM callback.
67 // Intended to put external QSPI memory in low power state
68 // upon device transition to Deepsleep power mode and to wake up
69 // external QSPI device from low power mode upon device wakeup
70 #if defined(CY_EXT_MEM_POWER_DOWN_SUPPORTED)
71 CY_RAMFUNC_BEGIN
cybsp_smif_power_up_callback(cy_stc_syspm_callback_params_t * callbackParams,cy_en_syspm_callback_mode_t mode)72 cy_en_syspm_status_t cybsp_smif_power_up_callback(cy_stc_syspm_callback_params_t* callbackParams,
73                                                   cy_en_syspm_callback_mode_t mode)
74 {
75     cy_en_syspm_status_t retVal = CY_SYSPM_FAIL;
76     CY_UNUSED_PARAMETER(callbackParams);
77     extern cy_stc_smif_context_t cybsp_smif_context;
78 
79     switch (mode)
80     {
81         case CY_SYSPM_CHECK_READY:
82             retVal = CY_SYSPM_SUCCESS;
83             break;
84 
85         case CY_SYSPM_CHECK_FAIL:
86             break;
87 
88         case CY_SYSPM_BEFORE_TRANSITION:
89         {
90             // Put external memory to low power mode
91             // SMIF IOs aren't disabled here as the device enters into DSRAM then the IOs will be
92             // disabled automatically
93             retVal = (cy_en_syspm_status_t)Cy_SMIF_MemCmdPowerDown(SMIF0, smifConfigLocal[0],
94                                                                    &cybsp_smif_context);
95             cybsp_smif_disable();
96             break;
97         }
98 
99         case CY_SYSPM_AFTER_DS_WFI_TRANSITION:
100         {
101             cybsp_smif_enable();
102             // Return external memory to normal operation from low power modes
103             cy_en_smif_status_t smif_functions_status = Cy_SMIF_MemCmdReleasePowerDown(SMIF0,
104                                                                                        smifConfigLocal[
105                                                                                            0],
106                                                                                        &cybsp_smif_context);
107 
108             if (CY_SMIF_SUCCESS == smif_functions_status)
109             {
110                 smif_functions_status = cybsp_is_memory_ready(smifConfigLocal[0]);
111                 if (CY_SMIF_SUCCESS == smif_functions_status)
112                 {
113                     retVal = CY_SYSPM_SUCCESS;
114                 }
115             }
116             break;
117         }
118 
119         case CY_SYSPM_AFTER_TRANSITION:
120         {
121             retVal = CY_SYSPM_SUCCESS;
122             break;
123         }
124 
125         default:
126             break;
127     }
128 
129     return retVal;
130 }
131 
132 
133 CY_RAMFUNC_END
134 #endif // defined(CY_EXT_MEM_POWER_DOWN_SUPPORTED)
135 
136 // CAT1B device QSPI memory power-down / power-up PM callback.
137 // Intended to put external QSPI memory in low power state
138 // upon device transition to DeepsleepRam power mode and to wake up
139 // external QSPI device from low power mode upon device wakeup
140 #if defined(CY_EXT_MEM_POWER_DOWN_SUPPORTED)
141 CY_RAMFUNC_BEGIN
cybsp_dsram_smif_power_up_callback(cy_stc_syspm_callback_params_t * callbackParams,cy_en_syspm_callback_mode_t mode)142 cy_en_syspm_status_t cybsp_dsram_smif_power_up_callback(
143     cy_stc_syspm_callback_params_t* callbackParams,
144     cy_en_syspm_callback_mode_t mode)
145 {
146     cy_en_syspm_status_t retVal = CY_SYSPM_FAIL;
147     CY_UNUSED_PARAMETER(callbackParams);
148     extern cy_stc_smif_context_t cybsp_smif_context;
149 
150     switch (mode)
151     {
152         case CY_SYSPM_CHECK_READY:
153             retVal = CY_SYSPM_SUCCESS;
154             break;
155 
156         case CY_SYSPM_CHECK_FAIL:
157             break;
158 
159         case CY_SYSPM_BEFORE_TRANSITION:
160         {
161             // Put external memory to low power mode
162             retVal = (cy_en_syspm_status_t)Cy_SMIF_MemCmdPowerDown(SMIF0, smifConfigLocal[0],
163                                                                    &cybsp_smif_context);
164             cybsp_smif_disable();
165             break;
166         }
167 
168         case CY_SYSPM_AFTER_DS_WFI_TRANSITION:
169         {
170             if (!Cy_SysLib_IsDSRAMWarmBootEntry())
171             {
172                 cybsp_smif_enable();
173                 // Return external memory to normal operation from low power modes
174                 cy_en_smif_status_t smif_functions_status = Cy_SMIF_MemCmdReleasePowerDown(SMIF0,
175                                                                                            smifConfigLocal[
176                                                                                                0],
177                                                                                            &cybsp_smif_context);
178 
179                 if (CY_SMIF_SUCCESS == smif_functions_status)
180                 {
181                     smif_functions_status = cybsp_is_memory_ready(smifConfigLocal[0]);
182                     if (CY_SMIF_SUCCESS == smif_functions_status)
183                     {
184                         retVal = CY_SYSPM_SUCCESS;
185                     }
186                 }
187             }
188             break;
189         }
190 
191         case CY_SYSPM_AFTER_TRANSITION:
192         {
193             retVal = CY_SYSPM_SUCCESS;
194             break;
195         }
196 
197         default:
198             break;
199     }
200 
201     return retVal;
202 }
203 
204 
205 CY_RAMFUNC_END
206 #endif // defined(CY_EXT_MEM_POWER_DOWN_SUPPORTED)
207 
208 //--------------------------------------------------------------------------------------------------
209 // cybsp_deepsleep_ram_callback
210 //--------------------------------------------------------------------------------------------------
cybsp_deepsleep_ram_callback(cy_stc_syspm_callback_params_t * callbackParams,cy_en_syspm_callback_mode_t mode)211 cy_en_syspm_status_t cybsp_deepsleep_ram_callback(cy_stc_syspm_callback_params_t* callbackParams,
212                                                   cy_en_syspm_callback_mode_t mode)
213 {
214     cy_en_syspm_status_t retVal = CY_SYSPM_FAIL;
215 
216     CY_UNUSED_PARAMETER(callbackParams);
217 
218     switch (mode)
219     {
220         case CY_SYSPM_CHECK_READY:
221         case CY_SYSPM_CHECK_FAIL:
222         case CY_SYSPM_BEFORE_TRANSITION:
223         {
224             retVal = CY_SYSPM_SUCCESS;
225             break;
226         }
227 
228         case CY_SYSPM_AFTER_TRANSITION:
229         {
230             /* Currently GCC and ARMCC supported */
231             #if defined(__GNUC__) || defined(__ARMCC_VERSION)
232             Cy_Syslib_SetWarmBootEntryPoint((uint32_t*)&syspmBspDeepSleepEntryPoint, true);
233             #endif
234 
235             retVal = CY_SYSPM_SUCCESS;
236             break;
237         }
238 
239         default:
240             break;
241     }
242 
243     return retVal;
244 }
245 
246 
247 //--------------------------------------------------------------------------------------------------
248 // cybsp_hibernate_callback
249 //--------------------------------------------------------------------------------------------------
250 #if defined(CY_EXT_MEM_POWER_DOWN_SUPPORTED)
251 CY_SECTION_RAMFUNC_BEGIN
cybsp_hibernate_callback(cy_stc_syspm_callback_params_t * callbackParams,cy_en_syspm_callback_mode_t mode)252 cy_en_syspm_status_t cybsp_hibernate_callback(cy_stc_syspm_callback_params_t* callbackParams,
253                                               cy_en_syspm_callback_mode_t mode)
254 {
255     cy_en_syspm_status_t retVal = CY_SYSPM_FAIL;
256     CY_UNUSED_PARAMETER(callbackParams);
257     extern cy_stc_smif_context_t cybsp_smif_context;
258 
259     switch (mode)
260     {
261         case CY_SYSPM_CHECK_READY:
262         {
263             retVal = CY_SYSPM_SUCCESS;
264             break;
265         }
266 
267         case CY_SYSPM_CHECK_FAIL:
268         {
269             retVal = CY_SYSPM_SUCCESS;
270             break;
271         }
272 
273         case CY_SYSPM_BEFORE_TRANSITION:
274         {
275             // Put external memory to low power mode
276             retVal = (cy_en_syspm_status_t)Cy_SMIF_MemCmdPowerDown(SMIF0, smifConfigLocal[0],
277                                                                    &cybsp_smif_context);
278             break;
279         }
280 
281         case CY_SYSPM_AFTER_TRANSITION:
282         {
283             // Return external memory to normal operation from low power modes
284             cy_en_smif_status_t smif_functions_status = Cy_SMIF_MemCmdReleasePowerDown(SMIF0,
285                                                                                        smifConfigLocal[
286                                                                                            0],
287                                                                                        &cybsp_smif_context);
288             if (CY_SMIF_SUCCESS == smif_functions_status)
289             {
290                 smif_functions_status = cybsp_is_memory_ready(smifConfigLocal[0]);
291                 if (CY_SMIF_SUCCESS == smif_functions_status)
292                 {
293                     retVal = CY_SYSPM_SUCCESS;
294                 }
295             }
296             break;
297         }
298 
299         default:
300             break;
301     }
302 
303     return retVal;
304 }
305 
306 
307 CY_SECTION_RAMFUNC_END
308 #endif // defined(CY_EXT_MEM_POWER_DOWN_SUPPORTED)
309 
310 ////////////////////////////////////////////////////////////////////////////////////////////////
311 //////////////////////// BSP PM callbacks config structures ////////////////////////////////////
312 
313 #if !defined(CYBSP_CUSTOM_SYSCLK_PM_CALLBACK)
314 static cy_stc_syspm_callback_params_t cybsp_sysclk_pm_callback_param = { NULL, NULL };
315 static cy_stc_syspm_callback_t        cybsp_sysclk_pm_callback       =
316 {
317     .callback       = &Cy_SysClk_DeepSleepCallback,
318     #if (CY_CFG_PWR_SYS_IDLE_MODE == CY_CFG_PWR_MODE_DEEPSLEEP_RAM)
319     .type           = (cy_en_syspm_callback_type_t)CY_SYSPM_MODE_DEEPSLEEP_RAM,
320     #else
321     .type           = (cy_en_syspm_callback_type_t)CY_SYSPM_MODE_DEEPSLEEP,
322     #endif
323     .callbackParams = &cybsp_sysclk_pm_callback_param,
324     .order          = CYBSP_SYSCLK_PM_CALLBACK_ORDER
325 };
326 #endif // if !defined(CYBSP_CUSTOM_SYSCLK_PM_CALLBACK)
327 
328 #if defined(CY_EXT_MEM_POWER_DOWN_SUPPORTED)
329 static cy_stc_syspm_callback_params_t cybsp_smif_pu_callback_param = { NULL, NULL };
330 static cy_stc_syspm_callback_t        cybsp_smif_pu_callback       =
331 {
332     .callback       = &cybsp_smif_power_up_callback,
333     .type           = CY_SYSPM_DEEPSLEEP,
334     .callbackParams = &cybsp_smif_pu_callback_param,
335     .order          = CYBSP_EXT_MEMORY_PM_CALLBACK_ORDER
336 };
337 
338 static cy_stc_syspm_callback_params_t cybsp_dsram_smif_pu_callback_param = { NULL, NULL };
339 static cy_stc_syspm_callback_t        cybsp_dsram_smif_pu_callback       =
340 {
341     .callback       = &cybsp_dsram_smif_power_up_callback,
342     .type           = CY_SYSPM_DEEPSLEEP_RAM,
343     .callbackParams = &cybsp_dsram_smif_pu_callback_param,
344     .order          = CYBSP_EXT_MEMORY_PM_CALLBACK_ORDER
345 };
346 
347 static cy_stc_syspm_callback_params_t cybsp_hibernate_pm_callback_param = { NULL, NULL };
348 static cy_stc_syspm_callback_t        cybsp_hibernate_pm_callback       =
349 {
350     .callback       = &cybsp_hibernate_callback,
351     .type           = CY_SYSPM_HIBERNATE,
352     .callbackParams = &cybsp_hibernate_pm_callback_param,
353     .order          = CYBSP_EXT_MEMORY_PM_CALLBACK_ORDER
354 };
355 #endif // defined(CY_EXT_MEM_POWER_DOWN_SUPPORTED)
356 
357 static cy_stc_syspm_callback_params_t cybsp_ds_ram_pm_callback_param = { NULL, NULL };
358 static cy_stc_syspm_callback_t        cybsp_ds_ram_pm_callback       =
359 {
360     .callback       = &cybsp_deepsleep_ram_callback,
361     .type           = CY_SYSPM_DEEPSLEEP_RAM,
362     .callbackParams = &cybsp_ds_ram_pm_callback_param,
363     .order          = 0u
364 };
365 
366 ////////////////////////////////////////////////////////////////////////////////////////////////
367 //////////////////////// BSP PM callbacks array ////////////////////////////////////////////////
368 
369 cy_stc_syspm_callback_t* _cybsp_callbacks_array[] =
370 {
371     #if !defined(CYBSP_CUSTOM_SYSCLK_PM_CALLBACK)
372     &cybsp_sysclk_pm_callback,
373     #endif // if !defined(CYBSP_CUSTOM_SYSCLK_PM_CALLBACK)
374     #if defined(CY_EXT_MEM_POWER_DOWN_SUPPORTED)
375     &cybsp_smif_pu_callback,
376     &cybsp_dsram_smif_pu_callback,
377     &cybsp_hibernate_pm_callback,
378     #endif // defined(CY_EXT_MEM_POWER_DOWN_SUPPORTED)
379     &cybsp_ds_ram_pm_callback
380 };
381 
382 ////////////////////////////////////////////////////////////////////////////////////////////////
383 //////////////////////// BSP PM callbacks array helper function ////////////////////////////////
384 
_cybsp_pm_callbacks_get_ptr_and_number(cy_stc_syspm_callback_t *** arr_ptr,size_t * number_of_elements)385 void _cybsp_pm_callbacks_get_ptr_and_number(cy_stc_syspm_callback_t*** arr_ptr,
386                                             size_t* number_of_elements)
387 {
388     *number_of_elements = 0;
389     if (sizeof(_cybsp_callbacks_array) != 0)
390     {
391         *arr_ptr = _cybsp_callbacks_array;
392         *number_of_elements = sizeof(_cybsp_callbacks_array) / sizeof(_cybsp_callbacks_array[0]);
393     }
394 }
395 
396 
397 #if defined(__cplusplus)
398 }
399 #endif
400