1 /*
2  * Copyright 2020-2023 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #ifndef _FSL_POWER_H_
9 #define _FSL_POWER_H_
10 
11 #include "fsl_common.h"
12 
13 /*!
14  * @addtogroup power
15  * @{
16  */
17 
18 /*! @file */
19 
20 /*******************************************************************************
21  * Definitions
22  ******************************************************************************/
23 
24 /*! @name Driver version */
25 /*@{*/
26 /*! @brief POWER driver version 2.5.0. */
27 #define FSL_POWER_DRIVER_VERSION (MAKE_VERSION(2, 5, 0))
28 /*@}*/
29 
30 /*!
31  * @brief Pin edge for wakeup.
32  */
33 typedef enum _power_wakeup_edge
34 {
35     kPOWER_WakeupEdgeLow  = 0U, /*!< Wakeup on pin low level. */
36     kPOWER_WakeupEdgeHigh = 1U, /*!< Wakeup on pin high level. */
37 } power_wakeup_edge_t;
38 
39 /*!
40  * @brief Wakeup pin.
41  */
42 typedef enum _power_wakeup_pin
43 {
44     kPOWER_WakeupPin0 = 0U, /*!< Wakeup0 pin. */
45     kPOWER_WakeupPin1 = 1U, /*!< Wakeup1 pin. */
46 } power_wakeup_pin_t;
47 
48 /*!
49  * @brief Reset cause.
50  */
51 typedef enum _power_reset_cause
52 {
53     kPOWER_ResetCauseSysResetReq = 1U << 0U, /*!< CM33 system soft reset request. */
54     kPOWER_ResetCauseLockup      = 1U << 1U, /*!< CM33 locked up. */
55     kPOWER_ResetCauseWdt         = 1U << 2U, /*!< Watchdog timer. */
56     kPOWER_ResetCauseApResetReq  = 1U << 3U, /*!< Debug mailbox reset. */
57     kPOWER_ResetCauseCodeWdt     = 1U << 4U, /*!< Code watchdog timer. */
58     kPOWER_ResetCauseItrc        = 1U << 5U, /*!< ITRC_CHIP reset. */
59     kPOWER_ResetCauseResetB      = 1U << 6U, /*!< sw_resetb_scantest reset. */
60     kPOWER_ResetCauseAll         = 0x7FU,    /*!< All reset causes. Used in POWER_ClearResetCause(). */
61 } power_reset_cause_t;
62 
63 /*!
64  * @brief Reset source.
65  */
66 typedef enum _power_reset_source
67 {
68     kPOWER_ResetSourceSysResetReq = 1U << 0U, /*!< CM33 system soft reset request. */
69     kPOWER_ResetSourceLockup      = 1U << 1U, /*!< CM33 locked up. */
70     kPOWER_ResetSourceWdt         = 1U << 2U, /*!< Watchdog timer. */
71     kPOWER_ResetSourceApResetReq  = 1U << 3U, /*!< Debug mailbox reset. */
72     kPOWER_ResetSourceCodeWdt     = 1U << 4U, /*!< Code watchdog timer. */
73     kPOWER_ResetSourceItrc        = 1U << 5U, /*!< ITRC_CHIP reset. */
74     kPOWER_ResetSourceAll         = 0x3FU,    /*!< All reset sources. */
75 } power_reset_source_t;
76 
77 /*!
78  * @brief PM2 mem power up bits definition
79  */
80 enum _pm2_mem_pu_bits
81 {
82     kPOWER_Pm2MemPuEnet    = (1UL << 28),
83     kPOWER_Pm2MemPuSdio    = (1UL << 27),
84     kPOWER_Pm2MemPuOtp     = (1UL << 26),
85     kPOWER_Pm2MemPuRom     = (1UL << 25),
86     kPOWER_Pm2MemPuFlexspi = (1UL << 24),
87     kPOWER_Pm2MemPuPq      = (1UL << 23),
88     kPOWER_Pm2MemPuPkc     = (1UL << 22),
89     kPOWER_Pm2MemPuEls     = (1UL << 21),
90     kPOWER_Pm2MemPuAon1    = (1UL << 20),
91     kPOWER_Pm2MemPuAon0    = (1UL << 19),
92     kPOWER_Pm2MemPuSram18  = (1UL << 18),
93     kPOWER_Pm2MemPuSram17  = (1UL << 17),
94     kPOWER_Pm2MemPuSram16  = (1UL << 16),
95     kPOWER_Pm2MemPuSram15  = (1UL << 15),
96     kPOWER_Pm2MemPuSram14  = (1UL << 14),
97     kPOWER_Pm2MemPuSram13  = (1UL << 13),
98     kPOWER_Pm2MemPuSram12  = (1UL << 12),
99     kPOWER_Pm2MemPuSram11  = (1UL << 11),
100     kPOWER_Pm2MemPuSram10  = (1UL << 10),
101     kPOWER_Pm2MemPuSram9   = (1UL << 9),
102     kPOWER_Pm2MemPuSram8   = (1UL << 8),
103     kPOWER_Pm2MemPuSram7   = (1UL << 7),
104     kPOWER_Pm2MemPuSram6   = (1UL << 6),
105     kPOWER_Pm2MemPuSram5   = (1UL << 5),
106     kPOWER_Pm2MemPuSram4   = (1UL << 4),
107     kPOWER_Pm2MemPuSram3   = (1UL << 3),
108     kPOWER_Pm2MemPuSram2   = (1UL << 2),
109     kPOWER_Pm2MemPuSram1   = (1UL << 1),
110     kPOWER_Pm2MemPuSram0   = (1UL << 0),
111     kPOWER_Pm2MemPuAll     = (0x1FFFFFFFUL),
112 };
113 
114 /*!
115  * @brief PM2 ana power up bits definition
116  */
117 enum _pm2_ana_pu_bits
118 {
119     kPOWER_Pm2AnaPuT3      = (1UL << 6),
120     kPOWER_Pm2AnaPuTcpuTop = (1UL << 5),
121     kPOWER_Pm2AnaPuTddrTop = (1UL << 4),
122     kPOWER_Pm2AnaPuAnaTop  = (1UL << 3),
123     kPOWER_Pm2AnaPuGau     = (1UL << 2),
124     kPOWER_Pm2AnaPuUsb     = (1UL << 1),
125     kPOWER_Pm2AnaPuAvpll   = (1UL << 0),
126     kPOWER_Pm2AnaPuAll     = (0x7FUL),
127 };
128 
129 /*!
130  * @brief clock gate bits definition
131  */
132 enum _clk_gate_bits
133 {
134     /* Only bit 2 is configuable, others contrlled by HW */
135     kPOWER_ClkGateTddrMciEnet = (1UL << 2),
136     kPOWER_ClkGateAll         = (1UL << 2),
137 };
138 
139 /*!
140  * @brief PM3 buck control bits definition
141  */
142 enum _clk_pm3_buck_bits
143 {
144     kPOWER_Pm3Buck18  = (1UL << 7), /*!< 1: Use normal buck18 level in PM3. 0: Use sleep buck18 level in PM3 */
145     kPOWER_Pm3Buck11  = (1UL << 6), /*!< 1: Use normal buck11 level in PM3. 0: Use sleep buck11 level in PM3 */
146     kPOWER_Pm3BuckAll = (0xC0UL),
147 };
148 
149 /*!
150  * @brief Capture slow pulse width
151  */
152 typedef enum _capt_slow_pulse_width
153 {
154     kPOWER_CaptSlowPulseWidth1 = 0U,
155     kPOWER_CaptSlowPulseWidth2 = 1U,
156     kPOWER_CaptSlowPulseWidth3 = 2U,
157     kPOWER_CaptSlowPulseWidth4 = 3U,
158     kPOWER_CaptSlowPulseWidth5 = 4U,
159     kPOWER_CaptSlowPulseWidth6 = 5U,
160     kPOWER_CaptSlowPulseWidth7 = 6U,
161 } capt_slow_pulse_width_t;
162 
163 /*!
164  * @brief Capture slow pulse edge
165  */
166 typedef enum _capt_slow_pulse_edge
167 {
168     kPOWER_CaptSlowPulseEdgeRising  = 0U,
169     kPOWER_CaptSlowPulseEdgeFalling = 1U,
170     kPOWER_CaptSlowPulseEdgeAny     = 2U,
171 } capt_slow_pulse_edge_t;
172 
173 /*!
174  * @brief Capture timer callback function
175  * @param param : User parameter for callback.
176  */
177 typedef void (*capt_pulse_timer_callback_t)(void *param);
178 
179 /*!
180  * @brief Power mode switch callback function
181  * @param mode : Power mode to switch.
182  * @param param : User parameter for callback.
183  */
184 typedef void (*power_switch_callback_t)(uint32_t mode, void *param);
185 
186 /*!
187  * @brief Init configuration.
188  */
189 typedef struct _power_init_config
190 {
191     bool iBuck;         /*!< true: VCORE and AVDD18 supplied from iBuck; false: supplied from external DCDC. */
192     bool gateCauRefClk; /*!< true: CAU_SOC_SLP_REF_GEN_CLK gated; false: CAU_SOC_SLP_REF_GEN_CLK on. */
193 } power_init_config_t;
194 
195 /*!
196  * @brief Sleep configuration.
197  */
198 typedef struct _power_sleep_config
199 {
200     uint32_t
201         pm2MemPuCfg; /*!< Modules to keep powered on in PM2 mode. Logical OR of the enums in @ref _pm2_mem_pu_bits. */
202     uint32_t pm2AnaPuCfg; /*!< Ana to keep powered on in PM2 mode. Logical OR of the enums in @ref _pm2_ana_pu_bits. */
203     uint32_t clkGate;     /*!< Source clock gate control. Logical OR of the enums in @ref _clk_gate_bits. */
204     uint32_t memPdCfg;    /*!< PMU MEM_CFG: Power Down memory configuration. Bit0-5 for PM3, bit8 for PM4.
205                                             bit0: ram0-5 384KB
206                                             bit1: ram6 64KB
207                                             bit2: ram7 64KB
208                                             bit3: ram8-9 128KB
209                                             bit4: ram10-13 256KB
210                                             bit5: ram14-18 320KB.
211                                             bit8: aon mem higher 8KB */
212     uint32_t pm3BuckCfg;  /*!< PMIP BUCK control in PM3 mode. Logical OR of the enums in @ref _clk_pm3_buck_bits. */
213 } power_sleep_config_t;
214 
215 /*!
216  * @brief Glitch detector configuration.
217  */
218 typedef struct _power_gdet_data
219 {
220     uint32_t CFG[6];
221     uint32_t TRIM0;
222 } power_gdet_data_t;
223 
224 /*!
225  * @brief Glitch detector configuration load function.
226  */
227 typedef bool (*power_load_gdet_cfg)(power_gdet_data_t *data);
228 
229 #if defined(__cplusplus)
230 extern "C" {
231 #endif
232 
233 /**
234  * @brief   Enable system reset source
235  * @param   source   : A bitmask of of @ref power_reset_source_t
236  */
POWER_EnableResetSource(uint32_t source)237 __STATIC_INLINE void POWER_EnableResetSource(uint32_t source)
238 {
239     assert((source & ~(uint32_t)kPOWER_ResetSourceAll) == 0U);
240 
241     PMU->SYS_RST_EN |= source;
242 }
243 
244 /**
245  * @brief   Disable system reset source
246  * @param   source   : A bitmask of of @ref power_reset_source_t
247  */
POWER_DisableResetSource(uint32_t source)248 __STATIC_INLINE void POWER_DisableResetSource(uint32_t source)
249 {
250     assert((source & ~(uint32_t)kPOWER_ResetSourceAll) == 0U);
251 
252     PMU->SYS_RST_EN &= ~source;
253 }
254 
255 /**
256  * @brief   Get last reset cause
257  * @return  Or'ed cause of @ref power_reset_cause_t
258  */
POWER_GetResetCause(void)259 __STATIC_INLINE uint32_t POWER_GetResetCause(void)
260 {
261     /* On reset, PMU->SYS_RST_STATUS is backed up in RF_SYSCON->WO_SCRATCH_REG[3]
262        and cleared by ROM */
263     return RF_SYSCON->WO_SCRATCH_REG[3] & (uint32_t)kPOWER_ResetCauseAll;
264 }
265 
266 /**
267  * @brief   Clear last reset cause
268  * @param   cause   : A bitmask of of @ref power_reset_cause_t
269  */
POWER_ClearResetCause(uint32_t cause)270 __STATIC_INLINE void POWER_ClearResetCause(uint32_t cause)
271 {
272     assert((cause & ~(uint32_t)kPOWER_ResetCauseAll) == 0U);
273 
274     PMU->SYS_RST_CLR = cause;
275 }
276 
277 /**
278  * @brief   Configure pin edge for wakeup
279  * @param   pin     : Wakeup pin
280  * @param   edge    : Pin level for wakeup
281  */
POWER_ConfigWakeupPin(power_wakeup_pin_t pin,power_wakeup_edge_t edge)282 __STATIC_INLINE void POWER_ConfigWakeupPin(power_wakeup_pin_t pin, power_wakeup_edge_t edge)
283 {
284     PMU->WAKEUP_LEVEL = (PMU->WAKEUP_LEVEL & ~(1UL << (uint8_t)pin)) | ((uint32_t)edge << (uint8_t)pin);
285 }
286 
287 /**
288  * @brief   Check if IRQ is the wakeup source
289  * @param   irq   : IRQ number
290  * @return  true if IRQ is the wakeup source, false otherwise.
291  */
292 bool POWER_GetWakeupStatus(IRQn_Type irq);
293 
294 /**
295  * @brief   Clear wakeup status
296  * @param   irq   : IRQ number
297  */
298 void POWER_ClearWakeupStatus(IRQn_Type irq);
299 
300 /**
301  * @brief   Enable the Wakeup interrupt.
302  * @param   irq   : IRQ number
303  */
304 void POWER_EnableWakeup(IRQn_Type irq);
305 
306 /**
307  * @brief   Disable the Wakeup interrupts.
308  * @param   irq   : IRQ number
309  */
310 void POWER_DisableWakeup(IRQn_Type irq);
311 
312 /**
313  * @brief   Set power mode on idle.
314  * @param   mode : 0 ~ 4 stands for PM0 ~ PM4.
315  */
316 AT_QUICKACCESS_SECTION_CODE(void POWER_SetSleepMode(uint32_t mode));
317 
318 /**
319  * @brief   Get power mode waken up from.
320  * @return  Power mode.
321  */
POWER_GetWakenMode(void)322 __STATIC_INLINE uint32_t POWER_GetWakenMode(void)
323 {
324     return (PMU->PWR_MODE_STATUS & PMU_PWR_MODE_STATUS_PWR_MODE_STATUS_MASK) + 1U;
325 }
326 
327 /**
328  * @brief   Get current sleep configuration.
329  * @param   config : Pointer to config structure to save current config.
330  */
331 void POWER_GetCurrentSleepConfig(power_sleep_config_t *config);
332 
333 /**
334  * @brief   Initialize power configuration.
335  * @param   config : Pointer to init config structure.
336  */
337 void POWER_InitPowerConfig(const power_init_config_t *config);
338 
339 /**
340  * @brief   Configure CAU_SOC_SLP_REF_GEN_CLK on/off status in SoC sleep mode.
341  * @param   pdCau : true for clock off; false for clock on.
342  */
343 void POWER_ConfigCauInSleep(bool pdCau);
344 
345 /**
346  * @brief   Set power mode switch callback. The callbacks are called with interrupt disabled.
347  * @param   pre : Function called before power mode switch
348  * @param   preParam : User parameter for pre callback
349  * @param   post : Function called after power mode switch
350  * @param   postParam : User parameter for post callback
351  */
352 void POWER_SetPowerSwitchCallback(power_switch_callback_t pre,
353                                   void *preParam,
354                                   power_switch_callback_t post,
355                                   void *postParam);
356 
357 /**
358  * @brief   Switch system into certain power mode.
359  * @param   mode : 0 ~ 4 stands for PM0 ~ PM4.
360  * @param   config : Sleep configuration on PM2-PM4.
361  * @return  True for success, else failure.
362  */
363 AT_QUICKACCESS_SECTION_CODE(bool POWER_EnterPowerMode(uint32_t mode, const power_sleep_config_t *config));
364 
365 /**
366  * @brief   Power on WLAN.
367  */
368 void POWER_PowerOnWlan(void);
369 
370 /**
371  * @brief   Power off WLAN.
372  */
373 void POWER_PowerOffWlan(void);
374 
375 /**
376  * @brief   Enable MCI wakeup WLAN
377  * @param   wlWakeup : 8 bits wakeup mask
378  */
PMU_EnableWlanWakeup(uint8_t wlWakeup)379 __STATIC_INLINE void PMU_EnableWlanWakeup(uint8_t wlWakeup)
380 {
381     PMU->WLAN_CTRL |= PMU_WLAN_CTRL_WL_WAKEUP(wlWakeup);
382 }
383 
384 /**
385  * @brief   Disable MCI wakeup WLAN
386  * @param   wlWakeup : 8 bits wakeup mask
387  */
PMU_DisableWlanWakeup(uint8_t wlWakeup)388 __STATIC_INLINE void PMU_DisableWlanWakeup(uint8_t wlWakeup)
389 {
390     PMU->WLAN_CTRL &= ~PMU_WLAN_CTRL_WL_WAKEUP(wlWakeup);
391 }
392 
393 /**
394  * @brief   Power on BLE.
395  */
396 void POWER_PowerOnBle(void);
397 
398 /**
399  * @brief   Power off BLE.
400  */
401 void POWER_PowerOffBle(void);
402 
403 /**
404  * @brief   Enable MCI wakeup BLE
405  * @param   bleWakeup : 8 bits wakeup mask
406  */
PMU_EnableBleWakeup(uint8_t bleWakeup)407 __STATIC_INLINE void PMU_EnableBleWakeup(uint8_t bleWakeup)
408 {
409     PMU->BLE_CTRL |= PMU_BLE_CTRL_BLE_WAKEUP(bleWakeup);
410 }
411 
412 /**
413  * @brief   Disable MCI wakeup BLE
414  * @param   bleWakeup : 8 bits wakeup mask
415  */
PMU_DisableBleWakeup(uint8_t bleWakeup)416 __STATIC_INLINE void PMU_DisableBleWakeup(uint8_t bleWakeup)
417 {
418     PMU->BLE_CTRL &= ~PMU_BLE_CTRL_BLE_WAKEUP(bleWakeup);
419 }
420 
421 /**
422  * @brief   Power on GAU.
423  */
424 void POWER_PowerOnGau(void);
425 
426 /**
427  * @brief   Power off GAU.
428  */
429 void POWER_PowerOffGau(void);
430 
431 /**
432  * @brief   Enable capture slow pulse timer with 32768Hz clock source
433  * @param   width    : input capture filter width in cycles
434  * @param   edge     : trigger condition of counter
435  * @param   timeout  : timer expire counter which will trigger callback
436  * @param   callback : callback function on timer expire
437  * @param   param    : callback parameter
438  */
439 void POWER_EnableCaptSlowPulseTimer(capt_slow_pulse_width_t width,
440                                     capt_slow_pulse_edge_t edge,
441                                     uint32_t timeout,
442                                     capt_pulse_timer_callback_t cb,
443                                     void *param);
444 
445 /**
446  * @brief   Enable capture fast pulse timer with 3.84/4MHz clock source
447  * @param   timeout  : timer expire counter which will trigger callback
448  * @param   callback : callback function on timer expire
449  * @param   param    : callback parameter
450  */
451 void POWER_EnableCaptFastPulseTimer(uint32_t timeout, capt_pulse_timer_callback_t cb, void *param);
452 
453 /**
454  * @brief   Disable capture pulse timer
455  */
456 void POWER_DisableCaptPulseTimer(void);
457 
458 /**
459  * @brief   Configure power rail voltage and LVD/HVD threshold.
460  * @param   dro  : trim value from fuse.
461  * @param   pack : Device package type: 0 - QFN, 1 - CSP, 2 - BGA
462  */
463 void POWER_InitVoltage(uint32_t dro, uint32_t pack);
464 
465 /**
466  * @brief   Initialize glitch detector configuration.
467  * @param   loadFunc : function pointer to the GDET load configuration.
468  * @param   data     : GDET config data loaded from fuse.
469  * @param   pack     : Device package type: 0 - QFN, 1 - CSP, 2 - BGA
470  */
471 void Power_InitLoadGdetCfg(power_load_gdet_cfg loadFunc, const power_gdet_data_t *data, uint32_t pack);
472 
473 /**
474  * @brief   Disable GDET and VSensors
475  */
476 AT_QUICKACCESS_SECTION_CODE(void POWER_DisableGDetVSensors(void));
477 
478 /**
479  * @brief   Enable GDET and VSensors
480  * @return  True for success, else failure.
481  */
482 AT_QUICKACCESS_SECTION_CODE(bool POWER_EnableGDetVSensors(void));
483 
484 /**
485  * @brief   Apply SVC GDC equation and get the SVC trim configuration
486  * @param   gdetTrim : GDET trim value from fuse.
487  * @param   pack     : Device package type: 0 - QFN, 1 - CSP, 2 - BGA
488  */
489 uint32_t POWER_TrimSvc(uint32_t gdetTrim, uint32_t pack);
490 
491 #if defined(__cplusplus)
492 }
493 #endif /*_cplusplus */
494 
495 /*! @}*/
496 
497 #endif /* _FSL_POWER_H_ */
498