1 /*
2  * Copyright 2023-2024 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 #include "fsl_common.h"
8 #include "fsl_power.h"
9 
10 /*******************************************************************************
11  * Variables
12  ******************************************************************************/
13 #if defined(PMC0)                               /* Only PMC0 can power down DCDC, LDO. */
14 static power_vdd_src_t s_vddnSrc = kVddSrc_PMC; /* VDDN supply source, DCDC or PMIC. */
15 static power_vdd_src_t s_vdd1Src = kVddSrc_PMC;
16 static power_vdd_src_t s_vdd2Src = kVddSrc_PMC;
17 
18 AT_QUICKACCESS_SECTION_DATA(static uint32_t lpReqConfig[5]);
19 AT_QUICKACCESS_SECTION_DATA(static bool xspiCacheEnabled);
20 #else
21 AT_QUICKACCESS_SECTION_DATA(static uint32_t lpReqConfig[4]);
22 #endif /* PMC0 */
23 /*******************************************************************************
24  * Definitions
25  ******************************************************************************/
26 /* Component ID definition, used by tools. */
27 #ifndef FSL_COMPONENT_ID
28 #define FSL_COMPONENT_ID "platform.drivers.power"
29 #endif
30 #define MEGA (1000000U)
31 
32 #if defined(PMC0)
33 #define PMC      PMC0
34 #define SLEEPCON SLEEPCON0
35 #elif defined(PMC1)
36 #define PMC      PMC1
37 #define SLEEPCON SLEEPCON1
38 #else
39 #error "Unsupported header file"
40 #endif
41 
42 #define PMC_PDRCFG_REG(x)         (*((volatile uint32_t *)((uint32_t)(&(PMC->PDRUNCFG0)) + ((x - 1U) << 2U))))
43 #define SLEEPCON_PDRCFGSET_REG(x) (*((volatile uint32_t *)((uint32_t)(&(SLEEPCON->RUNCFG_SET)) + ((x) << 2U))))
44 #define SLEEPCON_PDRCFGCLR_REG(x) (*((volatile uint32_t *)((uint32_t)(&(SLEEPCON->RUNCFG_CLR)) + ((x) << 2U))))
45 
46 #define PMC_REG(off) (*((volatile uint32_t *)(void *)PMC + (off) / 4U))
47 
48 #define LP_CTRL_REG(offset)        (*((volatile uint32_t *)((uint32_t)(&(SLEEPCON->SHA_MED_CCTRL0)) + ((offset) << 2U))))
49 #define LP_STATE_REG(offset)       (*((volatile uint32_t *)((uint32_t)(&(SLEEPCON->SHA_MED_CSTAT0)) + ((offset) << 2U))))
50 #define POWER_LP_REQ_TIMEOUT_COUNT (400U)
51 
52 /* Get AFBB bits mask from body bias domain _body_bias_domain */
53 #define POWER_AFBB_BITS_MASK(x) (((x)&0x20000000u) << 2U | (((x)&0x05400000u) << 1U))
54 
55 /* Each loop has 4 instructions.*/
56 #define US2LOOP(clk, x) ((clk / MEGA * x) >> 2U)
57 
58 /* Calcuate the voltage in uV for given LVD register value. */
59 #define POWER_CALCULATE_LVD_VOLT_FROM_VALUE(x) (500000U + 10000U * (x))
60 
61 #if defined(PMC0)
62 /* SLEEPCON SLEEPCFG0 */
63 #define SCFG0_DEEP_SLEEP                                                                                             \
64     (SLEEPCON0_SLEEPCFG_COMP_MAINCLK_SHUTOFF_MASK | SLEEPCON0_SLEEPCFG_SENSEP_MAINCLK_SHUTOFF_MASK |                 \
65      SLEEPCON0_SLEEPCFG_SENSES_MAINCLK_SHUTOFF_MASK | SLEEPCON0_SLEEPCFG_RAM0_CLK_SHUTOFF_MASK |                     \
66      SLEEPCON0_SLEEPCFG_RAM1_CLK_SHUTOFF_MASK | SLEEPCON0_SLEEPCFG_COMN_MAINCLK_SHUTOFF_MASK |                       \
67      SLEEPCON0_SLEEPCFG_MEDIA_MAINCLK_SHUTOFF_MASK | SLEEPCON0_SLEEPCFG_XTAL_PD_MASK |                               \
68      SLEEPCON0_SLEEPCFG_FRO0_PD_MASK | SLEEPCON0_SLEEPCFG_FRO1_PD_MASK | SLEEPCON0_SLEEPCFG_FRO2_PD_MASK |           \
69      SLEEPCON0_SLEEPCFG_LPOSC_PD_MASK | SLEEPCON0_SLEEPCFG_PLLANA_PD_MASK | SLEEPCON0_SLEEPCFG_PLLLDO_PD_MASK |      \
70      SLEEPCON0_SLEEPCFG_AUDPLLANA_PD_MASK | SLEEPCON0_SLEEPCFG_AUDPLLLDO_PD_MASK | SLEEPCON0_SLEEPCFG_ADC0_PD_MASK | \
71      SLEEPCON0_SLEEPCFG_FRO0_GATE_MASK | SLEEPCON0_SLEEPCFG_FRO2_GATE_MASK)
72 
73 #define POWER_IS_XIP_XSPI0()                                                                  \
74     ((((uint32_t)POWER_ApplyPD >= 0x28000000U) && ((uint32_t)POWER_ApplyPD < 0x30000000U)) || \
75      (((uint32_t)POWER_ApplyPD >= 0x38000000U) && ((uint32_t)POWER_ApplyPD < 0x40000000U)))
76 #define POWER_IS_XIP_XSPI1()                                                                  \
77     ((((uint32_t)POWER_ApplyPD >= 0x08000000U) && ((uint32_t)POWER_ApplyPD < 0x10000000U)) || \
78      (((uint32_t)POWER_ApplyPD >= 0x18000000U) && ((uint32_t)POWER_ApplyPD < 0x20000000U)))
79 
80 /* Mask used for low power request - ack handshake for modules with DMA HWWake function. */
81 #define PRIVATE_TCTRL_HWWAKE_MODULE_MASK0 (0x3FFFU) /* LP_FLEXCOMM0-13 Bus Low power request. */
82 #define PRIVATE_TSTAT_HWWAKE_MODULE_MASK0 (0x3FFFU)
83 #define PRIVATE_TCTRL_HWWAKE_MODULE_MASK1                                                  \
84     (SLEEPCON0_PRIVATE_TCTRL2_SAI0_LPREQ_MASK | SLEEPCON0_PRIVATE_TCTRL2_SAI1_LPREQ_MASK | \
85      SLEEPCON0_PRIVATE_TCTRL2_SAI2_LPREQ_MASK) /* SAI0-2 */
86 #define PRIVATE_TSTAT_HWWAKE_MODULE_MASK1                                                        \
87     (SLEEPCON0_PRIVATE_TSTAT1_SAI0_LPACCEPT_MASK | SLEEPCON0_PRIVATE_TSTAT1_SAI1_LPACCEPT_MASK | \
88      SLEEPCON0_PRIVATE_TSTAT1_SAI2_LPACCEPT_MASK)
89 #define PRIVATE_CONTROLLER_HWWAKE_MODULE_MASK \
90     (SLEEPCON0_PRIVATE_CCTRL0_EDMA0_STOP_MASK | SLEEPCON0_PRIVATE_CCTRL0_EDMA1_STOP_MASK) /* DMA1, DMA0 */
91 #define SHA_MEDSEN_TSTAT_HWWAKE_MODULE_MASK                                                                 \
92     (SLEEPCON0_SHA_MEDSEN_TSTAT0_FLEXIO_B_LPACCEPT_MASK | SLEEPCON0_SHA_MEDSEN_TSTAT0_MICFIL_STOPPED_MASK | \
93      SLEEPCON0_SHA_MEDSEN_TSTAT0_LPSPI14_B_LPACCEPT_MASK | SLEEPCON0_SHA_MEDSEN_TSTAT0_LPSPI16_B_LPACCEPT_MASK)
94 #else
95 
96 #define SCFG0_DEEP_SLEEP                                                                                            \
97     (SLEEPCON1_SLEEPCFG_SENSEP_MAINCLK_SHUTOFF_MASK | SLEEPCON1_SLEEPCFG_SENSES_MAINCLK_SHUTOFF_MASK |              \
98      SLEEPCON1_SLEEPCFG_RAM0_CLK_SHUTOFF_MASK | SLEEPCON1_SLEEPCFG_RAM1_CLK_SHUTOFF_MASK |                          \
99      SLEEPCON1_SLEEPCFG_COMN_MAINCLK_SHUTOFF_MASK | SLEEPCON1_SLEEPCFG_MEDIA_MAINCLK_SHUTOFF_MASK |                 \
100      SLEEPCON1_SLEEPCFG_XTAL_PD_MASK | SLEEPCON1_SLEEPCFG_FRO2_PD_MASK | SLEEPCON1_SLEEPCFG_LPOSC_PD_MASK |         \
101      SLEEPCON1_SLEEPCFG_PLLANA_PD_MASK | SLEEPCON1_SLEEPCFG_PLLLDO_PD_MASK | SLEEPCON1_SLEEPCFG_AUDPLLANA_PD_MASK | \
102      SLEEPCON1_SLEEPCFG_AUDPLLLDO_PD_MASK | SLEEPCON1_SLEEPCFG_ADC0_PD_MASK | SLEEPCON1_SLEEPCFG_FRO2_GATE_MASK)
103 
104 /* Mask used for low power request - ack handshake for modules with DMA HWWake function. */
105 #define PRIVATE_TCTRL_HWWAKE_MODULE_MASK0                                                                          \
106     (SLEEPCON1_PRIVATE_TCTRL0_LP_FLEXCOMM17__B_LPREQ_MASK | SLEEPCON1_PRIVATE_TCTRL0_LP_FLEXCOMM18__B_LPREQ_MASK | \
107      SLEEPCON1_PRIVATE_TCTRL0_LP_FLEXCOMM19__B_LPREQ_MASK | SLEEPCON1_PRIVATE_TCTRL0_LP_FLEXCOMM20__B_LPREQ_MASK | \
108      SLEEPCON1_PRIVATE_TCTRL0_SAI3_LPREQ_MASK)
109 #define PRIVATE_TSTAT_HWWAKE_MODULE_MASK0                                                                              \
110     (SLEEPCON1_PRIVATE_TSTAT0_LP_FLEXCOMM17_B_LPACCEPT_MASK | SLEEPCON1_PRIVATE_TSTAT0_LP_FLEXCOMM18_B_LPACCEPT_MASK | \
111      SLEEPCON1_PRIVATE_TSTAT0_LP_FLEXCOMM19_B_LPACCEPT_MASK | SLEEPCON1_PRIVATE_TSTAT0_LP_FLEXCOMM20_B_LPACCEPT_MASK | \
112      SLEEPCON1_PRIVATE_TSTAT0_SAI3_LPACCEPT_MASK)
113 #define PRIVATE_CONTROLLER_HWWAKE_MODULE_MASK \
114     (SLEEPCON1_PRIVATE_CCTRL0_EDMA3_STOP_MASK | SLEEPCON1_PRIVATE_CCTRL0_EDMA2_STOP_MASK) /* DMA3, DMA2 */
115 #define SHA_MEDSEN_TSTAT_HWWAKE_MODULE_MASK \
116     (SLEEPCON1_SHA_MEDSEN_TSTAT0_FLEXIO_B_LPACCEPT_MASK | SLEEPCON1_SHA_MEDSEN_TSTAT0_MICFIL_STOP_MASK)
117 #endif
118 /* PMC PDSLEEPCFG0. Note, when V2COM_DSR other VDD2 and VDDN switches should be off.   */
119 #define PCFG0_DEEP_SLEEP                                                                             \
120     (PMC_PDSLEEPCFG0_V2DSP_PD_MASK | PMC_PDSLEEPCFG0_V2MIPI_PD_MASK | PMC_PDSLEEPCFG0_DCDC_LP_MASK | \
121      PMC_PDSLEEPCFG0_V2NMED_DSR_MASK | PMC_PDSLEEPCFG0_VNCOM_DSR_MASK)
122 #define PCFG0_DSR                                                                                         \
123     (PMC_PDSLEEPCFG0_V2COMP_DSR_MASK | PMC_PDSLEEPCFG0_V2NMED_DSR_MASK | PMC_PDSLEEPCFG0_V2COM_DSR_MASK | \
124      PMC_PDSLEEPCFG0_VNCOM_DSR_MASK)
125 #define PCFG1_DEEP_SLEEP                                                                              \
126     (PMC_PDSLEEPCFG1_TEMP_PD_MASK | PMC_PDSLEEPCFG1_PMCREF_LP_MASK | PMC_PDSLEEPCFG1_HVD1V8_PD_MASK | \
127      PMC_PDSLEEPCFG1_POR1_LP_MASK | PMC_PDSLEEPCFG1_LVD1_LP_MASK | PMC_PDSLEEPCFG1_HVD1_PD_MASK |     \
128      PMC_PDSLEEPCFG1_AGDET1_PD_MASK | PMC_PDSLEEPCFG1_POR2_LP_MASK | PMC_PDSLEEPCFG1_LVD2_LP_MASK |   \
129      PMC_PDSLEEPCFG1_HVD2_PD_MASK | PMC_PDSLEEPCFG1_AGDET2_PD_MASK | PMC_PDSLEEPCFG1_PORN_LP_MASK |   \
130      PMC_PDSLEEPCFG1_LVDN_LP_MASK | PMC_PDSLEEPCFG1_HVDN_PD_MASK | PMC_PDSLEEPCFG1_OTP_PD_MASK |      \
131      PMC_PDSLEEPCFG1_ROM_PD_MASK | PMC_PDSLEEPCFG1_SRAMSLEEP_MASK)
132 #define PCFG2_DEEP_SLEEP (0xFFFFFFFFU)
133 #define PCFG3_DEEP_SLEEP (0xFFFFFFFFU)
134 #define PCFG4_DEEP_SLEEP (0xFFFFFFFFU)
135 #define PCFG5_DEEP_SLEEP (0xFFFFFFFFU)
136 
137 /*******************************************************************************
138  * Code
139  ******************************************************************************/
140 
141 /*!
142  * @brief API to enable PDRUNCFG bit in the SLEEPCON and PMC. Note that enabling the bit powers down the peripheral
143  *
144  * @param en    peripheral for which to enable the PDRUNCFG bit
145  * @return none
146  */
POWER_EnablePD(pd_bit_t en)147 void POWER_EnablePD(pd_bit_t en)
148 {
149     assert(en != kPDRUNCFG_ForceUnsigned);
150 
151     if (GET_PD_REG_FROM_BITS(en) != 0U) /* PMC PDRUNCFG */
152     {
153         PMC_PDRCFG_REG(GET_PD_REG_FROM_BITS(en)) |= (1UL << (((uint32_t)en) & 0xFFU));
154     }
155     else /* SLEEPCON_RUNCFG */
156     {
157         SLEEPCON_PDRCFGSET_REG(GET_PD_REG_FROM_BITS(en)) = (1UL << (((uint32_t)en) & 0xFFU));
158     }
159 }
160 
161 /*!
162  * @brief API to disable PDRUNCFG bit in the Sysctl0. Note that disabling the bit powers up the peripheral
163  *
164  * @param en    peripheral for which to disable the PDRUNCFG bit
165  * @return none
166  */
POWER_DisablePD(pd_bit_t en)167 void POWER_DisablePD(pd_bit_t en)
168 {
169     assert(en != kPDRUNCFG_ForceUnsigned);
170 
171     if (GET_PD_REG_FROM_BITS(en) != 0U) /* PMC PDRUNCFG */
172     {
173         PMC_PDRCFG_REG(GET_PD_REG_FROM_BITS(en)) &= ~(1UL << (((uint32_t)en) & 0xFFU));
174     }
175     else /* SLEEPCON_RUNCFG */
176     {
177         SLEEPCON_PDRCFGCLR_REG(GET_PD_REG_FROM_BITS(en)) = (1UL << (((uint32_t)en) & 0xFFU));
178     }
179 }
180 
181 /* Low power request and wait ACK. */
POWER_ModuleEnterLPRequest(lp_bit_t en)182 status_t POWER_ModuleEnterLPRequest(lp_bit_t en)
183 {
184     uint32_t timeout = POWER_LP_REQ_TIMEOUT_COUNT;
185     /* Assert low power request. */
186     LP_CTRL_REG(GET_LP_CTRL_REG_FROM_BITS(en)) |= 1UL << (GET_LP_CTRL_BIT_FROM_BITS(en));
187 
188     /* Wait ACK. */
189     while ((LP_STATE_REG(GET_LP_STATE_REG_FROM_BITS(en)) & (1UL << (GET_LP_STATE_BIT_FROM_BITS(en)))) == 0U)
190     {
191         timeout--;
192 
193         if (timeout == 0U)
194         {
195             return kStatus_Timeout;
196         }
197     }
198 
199     return kStatus_Success;
200 }
201 
POWER_ModuleExitLPRequest(lp_bit_t en)202 void POWER_ModuleExitLPRequest(lp_bit_t en)
203 {
204     /* Clear low power request. */
205     LP_CTRL_REG(GET_LP_CTRL_REG_FROM_BITS(en)) &= ~(1UL << (GET_LP_CTRL_BIT_FROM_BITS(en)));
206 }
207 
208 /**
209  * @brief  API to apply updated PMC PDRUNCFG bits in the Sysctl0.
210  */
POWER_ApplyPD(void)211 void POWER_ApplyPD(void)
212 {
213     /* Cannot set APPLYCFG when BUSY is 1 */
214     while ((PMC->STATUS & PMC_STATUS_BUSY_MASK) != 0U)
215     {
216     }
217     PMC->CTRL |= PMC_CTRL_APPLYCFG_MASK;
218     /* Wait all PMC finite state machines finished. */
219     while ((PMC->STATUS & PMC_STATUS_BUSY_MASK) != 0U)
220     {
221     }
222 }
223 
POWER_SetPmicMode(uint32_t mode,pmic_mode_reg_t reg)224 void POWER_SetPmicMode(uint32_t mode, pmic_mode_reg_t reg)
225 {
226     __disable_irq();
227 
228     PMC_REG((uint32_t)reg) =
229         (PMC_REG((uint32_t)reg) & ~PMC_PDSLEEPCFG0_PMICMODE_MASK) | (mode << PMC_PDSLEEPCFG0_PMICMODE_SHIFT);
230 
231     __enable_irq();
232 }
233 
POWER_GetPmicMode(pmic_mode_reg_t reg)234 uint32_t POWER_GetPmicMode(pmic_mode_reg_t reg)
235 {
236     uint32_t mode = (uint32_t)reg;
237 
238     return ((PMC_REG(mode) & PMC_PDSLEEPCFG0_PMICMODE_MASK) >> PMC_PDSLEEPCFG0_PMICMODE_SHIFT);
239 }
240 
241 /**
242  * @brief   Clears the PMC event flags state.
243  * @param   statusMask : A bitmask of event flags that are to be cleared.
244  */
POWER_ClearEventFlags(uint32_t statusMask)245 void POWER_ClearEventFlags(uint32_t statusMask)
246 {
247     PMC->FLAGS = statusMask;
248 }
249 
250 /**
251  * @brief   Get the PMC event flags state.
252  * @return  PMC FLAGS register value
253  */
POWER_GetEventFlags(void)254 uint32_t POWER_GetEventFlags(void)
255 {
256     return PMC->FLAGS;
257 }
258 
259 /**
260  * @brief   Enable the PMC reset requests.
261  * @param   resetMask : A bitmask of of resets to enable.
262  */
POWER_EnableResets(uint32_t resetMask)263 void POWER_EnableResets(uint32_t resetMask)
264 {
265     PMC->CTRL |= resetMask;
266 }
267 
268 /**
269  * @brief   Disable the PMC reset requests.
270  * @param   resetMask : A bitmask of of resets to disable.
271  */
POWER_DisableResets(uint32_t resetMask)272 void POWER_DisableResets(uint32_t resetMask)
273 {
274     PMC->CTRL &= ~resetMask;
275 }
276 
277 /**
278  * @brief   Enable the PMC interrupt requests.
279  * @param   interruptMask : A bitmask of of interrupts to enable.
280  */
POWER_EnableInterrupts(uint32_t interruptMask)281 void POWER_EnableInterrupts(uint32_t interruptMask)
282 {
283     PMC->INTRCTRL |= interruptMask;
284 }
285 
POWER_EnableDMAHWWake(uint32_t sources)286 void POWER_EnableDMAHWWake(uint32_t sources)
287 {
288     SLEEPCON->HW_WAKE_SET = sources;
289 }
290 
POWER_DisableDMAHWWake(uint32_t sources)291 void POWER_DisableDMAHWWake(uint32_t sources)
292 {
293     SLEEPCON->HW_WAKE_CLR = sources;
294 }
295 
296 /**
297  * @brief   Disable the PMC interrupt requests.
298  * @param   interruptMask : A bitmask of of interrupts to disable.
299  */
POWER_DisableInterrupts(uint32_t interruptMask)300 void POWER_DisableInterrupts(uint32_t interruptMask)
301 {
302     PMC->INTRCTRL &= ~interruptMask;
303 }
304 
EnableDeepSleepIRQ(IRQn_Type interrupt)305 void EnableDeepSleepIRQ(IRQn_Type interrupt)
306 {
307     uint32_t intNumber = (uint32_t)interrupt;
308 
309 #if defined(PMC0)
310     if (intNumber >= 128U)
311     {
312         /* enable interrupt wake up in the WAKEUPEN4 register */
313         SLEEPCON->WAKEUPEN4_SET = 1UL << (intNumber - 128U);
314     }
315     else if (intNumber >= 96U)
316     {
317         SLEEPCON->WAKEUPEN3_SET = 1UL << (intNumber - 96U);
318     }
319     else if (intNumber >= 64U)
320 #else  /* For sense domain */
321     if (intNumber >= 64U)
322 #endif /* PMC0 */
323     {
324         SLEEPCON->WAKEUPEN2_SET = 1UL << (intNumber - 64U);
325     }
326     else if (intNumber >= 32U)
327     {
328         SLEEPCON->WAKEUPEN1_SET = 1UL << (intNumber - 32U);
329     }
330     else
331     {
332         SLEEPCON->WAKEUPEN0_SET = 1UL << intNumber;
333     }
334     /* also enable interrupt at NVIC */
335     (void)EnableIRQ(interrupt);
336 }
337 
DisableDeepSleepIRQ(IRQn_Type interrupt)338 void DisableDeepSleepIRQ(IRQn_Type interrupt)
339 {
340     uint32_t intNumber = (uint32_t)interrupt;
341 
342     /* also disable interrupt at NVIC */
343     (void)DisableIRQ(interrupt);
344 
345 #if defined(PMC0)
346     if (intNumber >= 128U)
347     {
348         /* enable interrupt wake up in the WAKEUPEN4 register */
349         SLEEPCON->WAKEUPEN4_CLR = 1UL << (intNumber - 128U);
350     }
351     else if (intNumber >= 96U)
352     {
353         SLEEPCON->WAKEUPEN3_CLR = 1UL << (intNumber - 96U);
354     }
355     else if (intNumber >= 64U)
356 #else
357     if (intNumber >= 64U)
358 #endif /* PMC0 */
359     {
360         SLEEPCON->WAKEUPEN2_CLR = 1UL << (intNumber - 64U);
361     }
362     else if (intNumber >= 32U)
363     {
364         SLEEPCON->WAKEUPEN1_CLR = 1UL << (intNumber - 32U);
365     }
366     else
367     {
368         SLEEPCON->WAKEUPEN0_CLR = 1UL << intNumber;
369     }
370 }
371 
POWER_EnableLPRequestMask(uint32_t mask)372 void POWER_EnableLPRequestMask(uint32_t mask)
373 {
374     SLEEPCON->SHARED_MASK0_SET |= mask;
375 }
376 
POWER_DisableLPRequestMask(uint32_t mask)377 void POWER_DisableLPRequestMask(uint32_t mask)
378 {
379     SLEEPCON->SHARED_MASK0_CLR |= mask;
380 }
381 
POWER_EnterSleep(void)382 void POWER_EnterSleep(void)
383 {
384     uint32_t pmsk;
385     pmsk = __get_PRIMASK();
386     __disable_irq();
387     SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
388     __WFI();
389     __set_PRIMASK(pmsk);
390 }
391 
POWER_EnableAutoWake(uint16_t ticks)392 void POWER_EnableAutoWake(uint16_t ticks)
393 {
394     PMC->WAKEUP = (PMC->WAKEUP & 0x3F000000U) | PMC_WAKEUP_WAKETIME(ticks); /* Don't clear the [WKSRCF] W1C bits! */
395     PMC->INTRCTRL |= PMC_INTRCTRL_AUTOWKIE_MASK;
396     EnableDeepSleepIRQ(PMC_IRQn);
397 }
398 
POWER_EnableRunAFBB(uint32_t mask)399 void POWER_EnableRunAFBB(uint32_t mask)
400 {
401     /* clear AFBBxxx_PD, set RBBxxx_PD. No AFBBSRAM1 bit. */
402     PMC->PDRUNCFG0 &= ~POWER_AFBB_BITS_MASK(mask);
403     PMC->PDRUNCFG0 |= mask;
404 }
405 
POWER_EnableRunRBB(uint32_t mask)406 void POWER_EnableRunRBB(uint32_t mask)
407 {
408     PMC->PDRUNCFG0 &= ~mask; /* Clear RBB* bits, set AFBB* bits */
409     PMC->PDRUNCFG0 |= POWER_AFBB_BITS_MASK(mask);
410 }
411 
POWER_EnableSleepRBB(uint32_t mask)412 void POWER_EnableSleepRBB(uint32_t mask)
413 {
414     /* Set AFBB bits, clear RBB bits. */
415     PMC->PDSLEEPCFG0 &= ~mask;
416     PMC->PDSLEEPCFG0 |= POWER_AFBB_BITS_MASK(mask);
417 }
418 
POWER_EnableRunNBB(uint32_t mask)419 void POWER_EnableRunNBB(uint32_t mask)
420 {
421     /* Set AFBB and RBB bits. */
422     PMC->PDRUNCFG0 |= mask | POWER_AFBB_BITS_MASK(mask);
423 }
424 
POWER_EnableSleepNBB(uint32_t mask)425 void POWER_EnableSleepNBB(uint32_t mask)
426 {
427     /* Set AFBB bits and RBB bits. */
428     PMC->PDSLEEPCFG0 |= mask | POWER_AFBB_BITS_MASK(mask);
429 }
430 
POWER_CalRegValueFromVolt(uint32_t volt,uint32_t base,uint32_t slope)431 static uint32_t POWER_CalRegValueFromVolt(uint32_t volt, uint32_t base, uint32_t slope)
432 {
433     uint32_t temp = 0U;
434     temp          = volt - base - 1U; /* Rounding up.*/
435     return (uint32_t)((temp + slope) / slope);
436 }
437 
POWER_ConfigRegulatorSetpoints(power_regulator_t regulator,const power_regulator_voltage_t * volt,const power_lvd_voltage_t * lvd)438 status_t POWER_ConfigRegulatorSetpoints(power_regulator_t regulator,
439                                         const power_regulator_voltage_t *volt,
440                                         const power_lvd_voltage_t *lvd)
441 {
442     status_t ret = kStatus_Success;
443 
444 #if defined(PMC0)
445     if (regulator == kRegulator_DCDC) /* DCDC with 2 setpoints. */
446     {
447         if ((volt->DCDC.vsel1 < volt->DCDC.vsel0) || (lvd->VDDN.lvl1 < lvd->VDDN.lvl0) ||
448             (volt->DCDC.vsel1 > 1150000U) || (volt->DCDC.vsel0 < 500000U))
449         {
450             ret = kStatus_InvalidArgument;
451         }
452         else
453         {
454             PMC->DCDCVSEL = PMC_DCDCVSEL_VSEL0(POWER_CalRegValueFromVolt(volt->DCDC.vsel0, 500000U, 6250U)) |
455                             PMC_DCDCVSEL_VSEL1(POWER_CalRegValueFromVolt(volt->DCDC.vsel1, 500000U, 6250U));
456             PMC->LVDVDDNCTRL = PMC_LVDVDDNCTRL_LVL0(POWER_CalRegValueFromVolt(lvd->VDDN.lvl0, 500000U, 10000U)) |
457                                PMC_LVDVDDNCTRL_LVL1(POWER_CalRegValueFromVolt(lvd->VDDN.lvl1, 500000U, 10000U));
458         }
459     }
460 #else
461     if (regulator != kRegulator_Vdd1LDO) /* Only VDD1 LDO configurable from Sense side. */
462     {
463         ret = kStatus_InvalidArgument;
464     }
465 #endif   /* PMC0, only compute domain support DCDC, LDO VDD2 control. */
466     else /* LDO with 4 setpoints. */
467     {
468         if ((volt->LDO.vsel3 < volt->LDO.vsel2) || (volt->LDO.vsel2 < volt->LDO.vsel1) ||
469             (volt->LDO.vsel1 < volt->LDO.vsel0) || (lvd->VDD12.lvl3 < lvd->VDD12.lvl2) ||
470             (lvd->VDD12.lvl2 < lvd->VDD12.lvl1) || (lvd->VDD12.lvl1 < lvd->VDD12.lvl0) ||
471             (volt->LDO.vsel3 > 1150000U) || (volt->LDO.vsel0 < 450000U))
472         {
473             ret = kStatus_InvalidArgument;
474         }
475         else
476         {
477             PMC_REG(0x24U + 4U * ((uint32_t)regulator - 1U)) =
478                 PMC_LDOVDD1VSEL_VSEL0(POWER_CalRegValueFromVolt(volt->LDO.vsel0, 450000U, 12500U)) |
479                 PMC_LDOVDD1VSEL_VSEL1(POWER_CalRegValueFromVolt(volt->LDO.vsel1, 450000U, 12500U)) |
480                 PMC_LDOVDD1VSEL_VSEL2(POWER_CalRegValueFromVolt(volt->LDO.vsel2, 450000U, 12500U)) |
481                 PMC_LDOVDD1VSEL_VSEL3(POWER_CalRegValueFromVolt(volt->LDO.vsel3, 450000U, 12500U)); /* LDOVDDxVSEL */
482             PMC_REG(0x30U + 4U * ((uint32_t)regulator - 1U)) =
483                 PMC_LVDVDD1CTRL_LVL0(POWER_CalRegValueFromVolt(lvd->VDD12.lvl0, 500000U, 10000U)) |
484                 PMC_LVDVDD1CTRL_LVL1(POWER_CalRegValueFromVolt(lvd->VDD12.lvl1, 500000U, 10000U)) |
485                 PMC_LVDVDD1CTRL_LVL2(POWER_CalRegValueFromVolt(lvd->VDD12.lvl2, 500000U, 10000U)) |
486                 PMC_LVDVDD1CTRL_LVL3(POWER_CalRegValueFromVolt(lvd->VDD12.lvl3, 500000U, 10000U)); /* LVDVDDxCTRL */
487         }
488     }
489 
490     return ret;
491 }
492 
POWER_ConfigLvdSetpoints(power_regulator_t regulator,const power_lvd_voltage_t * lvd)493 status_t POWER_ConfigLvdSetpoints(power_regulator_t regulator, const power_lvd_voltage_t *lvd)
494 {
495     status_t ret = kStatus_Success;
496 
497 #if defined(PMC0)
498     if (regulator == kRegulator_DCDC) /* DCDC with 2 setpoints. */
499     {
500         if ((lvd->VDDN.lvl1 < lvd->VDDN.lvl0) || (lvd->VDDN.lvl0 < 500000U))
501         {
502             ret = kStatus_InvalidArgument;
503         }
504         else
505         {
506             PMC->LVDVDDNCTRL = PMC_LVDVDDNCTRL_LVL0(POWER_CalRegValueFromVolt(lvd->VDDN.lvl0, 500000U, 10000U)) |
507                                PMC_LVDVDDNCTRL_LVL1(POWER_CalRegValueFromVolt(lvd->VDDN.lvl1, 500000U, 10000U));
508         }
509     }
510 #else
511     if (regulator != kRegulator_Vdd1LDO) /* Only VDD1 LDO configurable from Sense side. */
512     {
513         ret = kStatus_InvalidArgument;
514     }
515 #endif   /* PMC0, only compute domain support DCDC, LDO VDD2 control. */
516     else /* LDO with 4 setpoints. */
517     {
518         if ((lvd->VDD12.lvl3 < lvd->VDD12.lvl2) || (lvd->VDD12.lvl2 < lvd->VDD12.lvl1) ||
519             (lvd->VDD12.lvl1 < lvd->VDD12.lvl0) || (lvd->VDD12.lvl0 < 500000U))
520         {
521             ret = kStatus_InvalidArgument;
522         }
523         else
524         {
525             PMC_REG(0x30U + 4U * ((uint32_t)regulator - 1U)) =
526                 PMC_LVDVDD1CTRL_LVL0(POWER_CalRegValueFromVolt(lvd->VDD12.lvl0, 500000U, 10000U)) |
527                 PMC_LVDVDD1CTRL_LVL1(POWER_CalRegValueFromVolt(lvd->VDD12.lvl1, 500000U, 10000U)) |
528                 PMC_LVDVDD1CTRL_LVL2(POWER_CalRegValueFromVolt(lvd->VDD12.lvl2, 500000U, 10000U)) |
529                 PMC_LVDVDD1CTRL_LVL3(POWER_CalRegValueFromVolt(lvd->VDD12.lvl3, 500000U, 10000U)); /* LVDVDDxCTRL */
530         }
531     }
532 
533     return ret;
534 }
535 
POWER_GetLvdSetpoints(power_regulator_t regulator,power_lvd_voltage_t * lvd)536 void POWER_GetLvdSetpoints(power_regulator_t regulator, power_lvd_voltage_t *lvd)
537 {
538     uint32_t reg = 0U;
539 
540     (void)memset(lvd, 0, sizeof(power_lvd_voltage_t));
541 
542     if (regulator == kRegulator_DCDC) /* DCDC with 2 setpoints. */
543     {
544         reg = PMC->LVDVDDNCTRL;
545         lvd->lvl[0] =
546             POWER_CALCULATE_LVD_VOLT_FROM_VALUE((reg & PMC_LVDVDDNCTRL_LVL0_MASK) >> PMC_LVDVDDNCTRL_LVL0_SHIFT);
547         lvd->lvl[1] =
548             POWER_CALCULATE_LVD_VOLT_FROM_VALUE((reg & PMC_LVDVDDNCTRL_LVL1_MASK) >> PMC_LVDVDDNCTRL_LVL1_SHIFT);
549     }
550     else /* LDO with 4 setpoints. */
551     {
552         reg = PMC_REG(0x30U + 4U * ((uint32_t)regulator - 1U));
553 
554         lvd->VDD12.lvl0 =
555             POWER_CALCULATE_LVD_VOLT_FROM_VALUE((reg & PMC_LVDVDD2CTRL_LVL0_MASK) >> PMC_LVDVDD2CTRL_LVL0_SHIFT);
556         lvd->VDD12.lvl1 =
557             POWER_CALCULATE_LVD_VOLT_FROM_VALUE((reg & PMC_LVDVDD2CTRL_LVL1_MASK) >> PMC_LVDVDD2CTRL_LVL1_SHIFT);
558         lvd->VDD12.lvl2 =
559             POWER_CALCULATE_LVD_VOLT_FROM_VALUE((reg & PMC_LVDVDD2CTRL_LVL2_MASK) >> PMC_LVDVDD2CTRL_LVL2_SHIFT);
560         lvd->VDD12.lvl3 =
561             POWER_CALCULATE_LVD_VOLT_FROM_VALUE((reg & PMC_LVDVDD2CTRL_LVL3_MASK) >> PMC_LVDVDD2CTRL_LVL3_SHIFT);
562     }
563 }
564 
POWER_SelectRunSetpoint(power_regulator_t regulator,uint32_t setpoint)565 void POWER_SelectRunSetpoint(power_regulator_t regulator, uint32_t setpoint)
566 {
567     if (regulator == kRegulator_DCDC)
568     {
569         assert(setpoint < 2U);
570         PMC->PDRUNCFG0 &= ~PMC_PDRUNCFG0_DCDC_VSEL_MASK;
571         PMC->PDRUNCFG0 |= PMC_PDRUNCFG0_DCDC_VSEL(setpoint);
572     }
573     else if (regulator == kRegulator_Vdd2LDO)
574     {
575         assert(setpoint < 4U);
576         PMC->PDRUNCFG0 &= ~PMC_PDRUNCFG0_LDO2_VSEL_MASK;
577         PMC->PDRUNCFG0 |= PMC_PDRUNCFG0_LDO2_VSEL(setpoint);
578     }
579     else
580     {
581         assert(setpoint < 4U);
582         PMC->PDRUNCFG0 &= ~PMC_PDRUNCFG0_LDO1_VSEL_MASK;
583         PMC->PDRUNCFG0 |= PMC_PDRUNCFG0_LDO1_VSEL(setpoint);
584     }
585 }
586 
POWER_SelectSleepSetpoint(power_regulator_t regulator,uint32_t setpoint)587 void POWER_SelectSleepSetpoint(power_regulator_t regulator, uint32_t setpoint)
588 {
589     if (regulator == kRegulator_DCDC)
590     {
591         assert(setpoint < 2U);
592         PMC->PDSLEEPCFG0 &= ~PMC_PDSLEEPCFG0_DCDC_VSEL_MASK;
593         PMC->PDSLEEPCFG0 |= PMC_PDSLEEPCFG0_DCDC_VSEL(setpoint);
594     }
595     else if (regulator == kRegulator_Vdd2LDO)
596     {
597         assert(setpoint < 4U);
598         PMC->PDSLEEPCFG0 &= ~PMC_PDSLEEPCFG0_LDO2_VSEL_MASK;
599         PMC->PDSLEEPCFG0 |= PMC_PDSLEEPCFG0_LDO2_VSEL(setpoint);
600     }
601     else
602     {
603         assert(setpoint < 4U);
604         PMC->PDSLEEPCFG0 &= ~PMC_PDSLEEPCFG0_LDO1_VSEL_MASK;
605         PMC->PDSLEEPCFG0 |= PMC_PDSLEEPCFG0_LDO1_VSEL(setpoint);
606     }
607 }
608 
POWER_SetRunRegulatorMode(power_regulator_t regulator,uint32_t mode)609 void POWER_SetRunRegulatorMode(power_regulator_t regulator, uint32_t mode)
610 {
611     if (regulator == kRegulator_DCDC)
612     {
613         PMC->PDRUNCFG0 &= ~PMC_PDRUNCFG0_DCDC_LP_MASK;
614         PMC->PDRUNCFG0 |= PMC_PDRUNCFG0_DCDC_LP(mode);
615     }
616     else if (regulator == kRegulator_Vdd2LDO)
617     {
618         PMC->PDRUNCFG0 &= ~PMC_PDRUNCFG0_LDO2_MODE_MASK;
619         PMC->PDRUNCFG0 |= PMC_PDRUNCFG0_LDO2_MODE(mode);
620     }
621     else
622     {
623         PMC->PDRUNCFG0 &= ~PMC_PDRUNCFG0_LDO1_MODE_MASK;
624         PMC->PDRUNCFG0 |= PMC_PDRUNCFG0_LDO1_MODE(mode);
625     }
626 }
627 
POWER_SetSleepRegulatorMode(power_regulator_t regulator,uint32_t mode)628 void POWER_SetSleepRegulatorMode(power_regulator_t regulator, uint32_t mode)
629 {
630     if (regulator == kRegulator_DCDC)
631     {
632         PMC->PDSLEEPCFG0 &= ~PMC_PDSLEEPCFG0_DCDC_LP_MASK;
633         PMC->PDSLEEPCFG0 |= PMC_PDSLEEPCFG0_DCDC_LP(mode);
634     }
635     else if (regulator == kRegulator_Vdd2LDO)
636     {
637         PMC->PDSLEEPCFG0 &= ~PMC_PDSLEEPCFG0_LDO2_MODE_MASK;
638         PMC->PDSLEEPCFG0 |= PMC_PDSLEEPCFG0_LDO2_MODE(mode);
639     }
640     else
641     {
642         PMC->PDSLEEPCFG0 &= ~PMC_PDSLEEPCFG0_LDO1_MODE_MASK;
643         PMC->PDSLEEPCFG0 |= PMC_PDSLEEPCFG0_LDO1_MODE(mode);
644     }
645 }
646 
POWER_ResetIOBank(uint32_t mask)647 void POWER_ResetIOBank(uint32_t mask)
648 {
649     uint32_t cfg = 0U;
650     cfg          = PMC->PADCFG;
651 
652     cfg &= ~(PMC_PADCFG_ISOCTRL_MASK | PMC_PADCFG_RSTCTRL_MASK); /* Clear W1C bits. */
653     PMC->PADCFG = cfg | (mask << PMC_PADCFG_RSTCTRL_SHIFT);
654 }
655 
POWER_IOBankIsolationHold(uint32_t mask)656 void POWER_IOBankIsolationHold(uint32_t mask)
657 {
658     uint32_t cfg = 0U;
659     cfg          = PMC->PADCFG;
660 
661     cfg &= ~(PMC_PADCFG_ISOCTRL_MASK | PMC_PADCFG_RSTCTRL_MASK); /* Clear W1C bits. */
662 
663     PMC->PADCFG = cfg | (mask << PMC_PADCFG_ISOHOLD_SHIFT);
664 }
665 
POWER_IOBankClearIsolationHold(uint32_t mask)666 void POWER_IOBankClearIsolationHold(uint32_t mask)
667 {
668     PMC->PADCFG |= mask << PMC_PADCFG_ISOCTRL_SHIFT; /* W1C. */
669 }
670 
671 #if defined(PMC0)
POWER_ConfigRBBVolt(const power_rbb_voltage_t * config)672 void POWER_ConfigRBBVolt(const power_rbb_voltage_t *config)
673 {
674     PMC->BBCTRL = (*((const uint32_t *)(const void *)config)) &
675                   (PMC_BBCTRL_RBB1LVL_MASK | PMC_BBCTRL_RBB2LVL_MASK | PMC_BBCTRL_RBBNLVL_MASK);
676 }
677 
POWER_SetVddnSupplySrc(power_vdd_src_t src)678 void POWER_SetVddnSupplySrc(power_vdd_src_t src)
679 {
680     assert(src == kVddSrc_PMIC); /* The VDDN can't be supplied by DCDC due to ERRATA. */
681 
682     s_vddnSrc = src;
683     if (s_vddnSrc == kVddSrc_PMIC) /* If powered by external PMIC, power down DCDC. */
684     {
685         PMC->POWERCFG |= PMC_POWERCFG_DCDCPD_MASK;
686     }
687 }
688 
POWER_SetVdd1SupplySrc(power_vdd_src_t src)689 void POWER_SetVdd1SupplySrc(power_vdd_src_t src)
690 {
691     s_vdd1Src = src;
692     if (src == kVddSrc_PMIC) /* If powered by external PMIC, power down LDO1. */
693     {
694         PMC->POWERCFG |= PMC_POWERCFG_LDO1PD_MASK;
695     }
696 }
697 
POWER_SetVdd2SupplySrc(power_vdd_src_t src)698 void POWER_SetVdd2SupplySrc(power_vdd_src_t src)
699 {
700     s_vdd2Src = src;
701     if (src == kVddSrc_PMIC) /* If powered by external PMIC, power down LDO2. */
702     {
703         PMC->POWERCFG |= PMC_POWERCFG_LDO2PD_MASK;
704     }
705 }
706 
POWER_DisableRegulators(uint32_t mask)707 void POWER_DisableRegulators(uint32_t mask)
708 {
709     PMC->POWERCFG |= mask & 0xFF80U; /* Ignore FDSR related bits. */
710 }
711 
POWER_EnableSleepRegulators(uint32_t mask)712 void POWER_EnableSleepRegulators(uint32_t mask)
713 {
714     PMC->POWERCFG |= mask & 0x7FU; /* Ignore all mode control bits. */
715 }
716 
POWER_DisableSleepRegulators(uint32_t mask)717 void POWER_DisableSleepRegulators(uint32_t mask)
718 {
719     PMC->POWERCFG &= ~(mask & 0x7FU); /* Ignore all mode control bits. */
720 }
721 
POWER_SetPMICModeDelay(uint8_t value)722 void POWER_SetPMICModeDelay(uint8_t value)
723 {
724     PMC->POWERCFG &= ~PMC_POWERCFG_MODEDLY_MASK;
725     PMC->POWERCFG |= PMC_POWERCFG_MODEDLY(value);
726 }
727 
POWER_SetPORVoltage(const power_por_voltage_t * porVolt)728 void POWER_SetPORVoltage(const power_por_voltage_t *porVolt)
729 {
730     PMC->PORCTRL = (*((const uint32_t *)(const void *)porVolt));
731 }
732 #endif
733 
734 #if defined(PMC0) /* Compute domain request enter deep sleep mode. */
AT_QUICKACCESS_SECTION_CODE(static void POWER_EnableXspiCache (CACHE64_CTRL_Type * cache))735 AT_QUICKACCESS_SECTION_CODE(static void POWER_EnableXspiCache(CACHE64_CTRL_Type *cache))
736 {
737     /* First, invalidate the entire cache. */
738     cache->CCR |= CACHE64_CTRL_CCR_INVW0_MASK | CACHE64_CTRL_CCR_INVW1_MASK | CACHE64_CTRL_CCR_GO_MASK;
739     while ((cache->CCR & CACHE64_CTRL_CCR_GO_MASK) != 0x00U)
740     {
741     }
742     /* As a precaution clear the bits to avoid inadvertently re-running this command. */
743     cache->CCR &= ~(CACHE64_CTRL_CCR_INVW0_MASK | CACHE64_CTRL_CCR_INVW1_MASK);
744     /* Now enable the cache. */
745     cache->CCR |= CACHE64_CTRL_CCR_ENCACHE_MASK;
746 }
747 
AT_QUICKACCESS_SECTION_CODE(static void POWER_DisableXspiCache (CACHE64_CTRL_Type * cache))748 AT_QUICKACCESS_SECTION_CODE(static void POWER_DisableXspiCache(CACHE64_CTRL_Type *cache))
749 {
750     /* First, clean XSPI cache. */
751     cache->CCR |= CACHE64_CTRL_CCR_PUSHW0_MASK | CACHE64_CTRL_CCR_PUSHW1_MASK | CACHE64_CTRL_CCR_GO_MASK;
752     while ((cache->CCR & CACHE64_CTRL_CCR_GO_MASK) != 0x00U)
753     {
754     }
755     /* As a precaution clear the bits to avoid inadvertently re-running this command. */
756     cache->CCR &= ~(CACHE64_CTRL_CCR_PUSHW0_MASK | CACHE64_CTRL_CCR_PUSHW1_MASK);
757 
758     /* Now disable XSPI cache. */
759     cache->CCR &= ~CACHE64_CTRL_CCR_ENCACHE_MASK;
760 }
761 
AT_QUICKACCESS_SECTION_CODE(static void deinitXSPI (XSPI_Type * base,CACHE64_CTRL_Type * cache))762 AT_QUICKACCESS_SECTION_CODE(static void deinitXSPI(XSPI_Type *base, CACHE64_CTRL_Type *cache))
763 {
764     xspiCacheEnabled = false;
765     base->MCR &= ~XSPI_MCR_MDIS_MASK;
766 
767     /* Wait until XSPI is not busy */
768     while ((base->SR & XSPI_SR_BUSY_MASK) != 0U)
769     {
770     }
771 
772     if ((cache->CCR & CACHE64_CTRL_CCR_ENCACHE_MASK) != 0x00U)
773     {
774         xspiCacheEnabled = true;
775         POWER_DisableXspiCache(cache);
776     }
777 
778     /* Disable module. */
779     base->MCR |= XSPI_MCR_MDIS_MASK;
780 }
781 
AT_QUICKACCESS_SECTION_CODE(static void initXSPI (XSPI_Type * base,CACHE64_CTRL_Type * cache))782 AT_QUICKACCESS_SECTION_CODE(static void initXSPI(XSPI_Type *base, CACHE64_CTRL_Type *cache))
783 {
784     /* Disable XSPI module */
785     base->MCR |= XSPI_MCR_MDIS_MASK;
786     base->MCR |= XSPI_MCR_IPS_TG_RST_MASK;
787 
788     base->MCR &= ~XSPI_MCR_MDIS_MASK;
789 
790     base->MCR |= XSPI_MCR_SWRSTSD_MASK | XSPI_MCR_SWRSTHD_MASK;
791     for (uint32_t i = 0U; i < 6U; i++)
792     {
793         __NOP();
794     }
795     base->MCR |= XSPI_MCR_MDIS_MASK;
796     base->MCR &= ~(XSPI_MCR_SWRSTSD_MASK | XSPI_MCR_SWRSTHD_MASK);
797     for (uint32_t i = 0U; i < 6U; i++)
798     {
799         __NOP();
800     }
801     base->MCR &= ~XSPI_MCR_MDIS_MASK;
802 
803     base->MCR |= XSPI_MCR_MDIS_MASK;
804 
805     /* Clear AHB buffer. */
806     base->SPTRCLR |= XSPI_SPTRCLR_ABRT_CLR_MASK;
807     while ((base->SPTRCLR & XSPI_SPTRCLR_ABRT_CLR_MASK) != 0UL)
808     {
809     }
810 
811     /* Clear AHB access sequence pointer. */
812     base->SPTRCLR |= XSPI_SPTRCLR_BFPTRC_MASK;
813 
814     /* Enable XSPI module */
815     base->MCR &= ~XSPI_MCR_MDIS_MASK;
816 
817     if (xspiCacheEnabled)
818     {
819         POWER_EnableXspiCache(cache);
820     }
821 
822     __DSB();
823     __ISB();
824 }
825 
AT_QUICKACCESS_SECTION_CODE(static void deinitXip (void))826 AT_QUICKACCESS_SECTION_CODE(static void deinitXip(void))
827 {
828     if (POWER_IS_XIP_XSPI0())
829     {
830         /* Enable XSPI clock again */
831         CLKCTL0->PSCCTL1_SET = CLKCTL0_PSCCTL1_SET_XSPI0_MASK;
832         /* Disable XSPI module */
833         deinitXSPI(XSPI0, CACHE64_CTRL0);
834         CLKCTL0->PSCCTL1_CLR = CLKCTL0_PSCCTL1_SET_XSPI0_MASK;
835     }
836     else if (POWER_IS_XIP_XSPI1())
837     {
838         /* Enable XSPI clock again */
839         CLKCTL0->PSCCTL1_SET = CLKCTL0_PSCCTL1_SET_XSPI1_MASK;
840         /* Disable XSPI module */
841         deinitXSPI(XSPI1, CACHE64_CTRL1);
842         CLKCTL0->PSCCTL1_CLR = CLKCTL0_PSCCTL1_SET_XSPI1_MASK;
843     }
844     else
845     {
846         /* Do nothing */
847     }
848 }
849 
AT_QUICKACCESS_SECTION_CODE(static void initXip (void))850 AT_QUICKACCESS_SECTION_CODE(static void initXip(void))
851 {
852     if (POWER_IS_XIP_XSPI0())
853     {
854         /* Enable XSPI clock again */
855         CLKCTL0->PSCCTL1_SET = CLKCTL0_PSCCTL1_SET_XSPI0_MASK;
856         /* Re-enable XSPI module */
857         initXSPI(XSPI0, CACHE64_CTRL0);
858     }
859     else if (POWER_IS_XIP_XSPI1())
860     {
861         /* Enable XSPI clock again */
862         CLKCTL0->PSCCTL1_SET = CLKCTL0_PSCCTL1_SET_XSPI1_MASK;
863         /* Re-enable XSPI module */
864         initXSPI(XSPI1, CACHE64_CTRL1);
865     }
866     else
867     {
868         /* Do nothing */
869     }
870 }
871 
872 /* Need do low power request-ack for all the modules capable of DMA HW Wake function if the DMA_HWWake is used. */
AT_QUICKACCESS_SECTION_CODE(static void POWER_DMA_HWWake_LPRequest (void))873 AT_QUICKACCESS_SECTION_CODE(static void POWER_DMA_HWWake_LPRequest(void))
874 {
875     uint32_t lpReqClockCfg, lpReqResetCfg;
876 
877     if (SLEEPCON0->HW_WAKE != 0U) /* Only assert the LP Requet when DMA HW_WAKE enabled. */
878     {
879         lpReqClockCfg  = CLKCTL0->PSCCTL1;
880         lpReqResetCfg  = RSTCTL0->PRSTCTL2;
881         lpReqConfig[0] = SLEEPCON0->PRIVATE_CCTRL0;
882         lpReqConfig[1] = SLEEPCON0->SHA_MED_TCTRL0;
883         lpReqConfig[2] = SLEEPCON0->SHA_SEN_TCTRL0;
884         lpReqConfig[3] = SLEEPCON0->PRIVATE_TCTRL0;
885         lpReqConfig[4] = SLEEPCON0->PRIVATE_TCTRL2;
886 
887         CLKCTL0->PSCCTL1_SET =
888             CLKCTL0_PSCCTL1_EDMA0_MASK |
889             CLKCTL0_PSCCTL1_EDMA1_MASK; /* DMA clock need to be enabled to finishe low power handshake. */
890         RSTCTL0->PRSTCTL2_CLR =
891             RSTCTL0_PRSTCTL2_EDMA0_MASK |
892             RSTCTL0_PRSTCTL2_EDMA1_MASK; /* DMA reset need to be cleared to finishe low power handshake. */
893 
894         SLEEPCON0->PRIVATE_CCTRL0 |= PRIVATE_CONTROLLER_HWWAKE_MODULE_MASK;
895         SLEEPCON0->SHA_MED_TCTRL0 |= SLEEPCON0_SHA_MED_TCTRL0_FLEXIO_B_LPREQ_MASK |
896                                      SLEEPCON0_SHA_MED_TCTRL0_LPSPI16_B_LPREQ_MASK |
897                                      SLEEPCON0_SHA_MED_TCTRL0_LPSPI14_B_LPREQ_MASK; /* FLEXIO, LPSPI Bus*/
898         SLEEPCON0->SHA_SEN_TCTRL0 |= SLEEPCON0_SHA_SEN_TCTRL0_MICFIL_STOP_MASK;     /* MICFIL */
899         SLEEPCON0->PRIVATE_TCTRL0 |= PRIVATE_TCTRL_HWWAKE_MODULE_MASK0;             /* LP_FLEXCOMM */
900         SLEEPCON0->PRIVATE_TCTRL2 |= PRIVATE_TCTRL_HWWAKE_MODULE_MASK1;             /* SAI */
901 
902         while ((SLEEPCON0->PRIVATE_CSTAT0 & PRIVATE_CONTROLLER_HWWAKE_MODULE_MASK) !=
903                PRIVATE_CONTROLLER_HWWAKE_MODULE_MASK)
904         {
905         }
906         while ((SLEEPCON0->SHA_MEDSEN_TSTAT0 & SHA_MEDSEN_TSTAT_HWWAKE_MODULE_MASK) !=
907                SHA_MEDSEN_TSTAT_HWWAKE_MODULE_MASK)
908         {
909         }
910         while ((SLEEPCON0->PRIVATE_TSTAT0 & PRIVATE_TSTAT_HWWAKE_MODULE_MASK0) != PRIVATE_TSTAT_HWWAKE_MODULE_MASK0)
911         {
912         }
913         while ((SLEEPCON0->PRIVATE_TSTAT1 & PRIVATE_TSTAT_HWWAKE_MODULE_MASK1) != PRIVATE_TSTAT_HWWAKE_MODULE_MASK1)
914         {
915         }
916 
917         CLKCTL0->PSCCTL1  = lpReqClockCfg;
918         RSTCTL0->PRSTCTL2 = lpReqResetCfg;
919     }
920 }
921 
AT_QUICKACCESS_SECTION_CODE(static void POWER_DMA_HWWake_LPRestore (void))922 AT_QUICKACCESS_SECTION_CODE(static void POWER_DMA_HWWake_LPRestore(void))
923 {
924     if (SLEEPCON0->HW_WAKE != 0U) /* DMA HW_WAKE enabled. */
925     {
926         /* restore the configuration */
927         SLEEPCON0->PRIVATE_CCTRL0 = lpReqConfig[0];
928         SLEEPCON0->SHA_MED_TCTRL0 = lpReqConfig[1];
929         SLEEPCON0->SHA_SEN_TCTRL0 = lpReqConfig[2];
930         SLEEPCON0->PRIVATE_TCTRL0 = lpReqConfig[3];
931         SLEEPCON0->PRIVATE_TCTRL2 = lpReqConfig[4];
932     }
933 }
934 
AT_QUICKACCESS_SECTION_CODE(static void POWER_DisableCache (XCACHE_Type * base))935 AT_QUICKACCESS_SECTION_CODE(static void POWER_DisableCache(XCACHE_Type *base))
936 {
937     /* First, push any modified contents. */
938     base->CCR |= XCACHE_CCR_PUSHW0_MASK | XCACHE_CCR_PUSHW1_MASK | XCACHE_CCR_GO_MASK;
939 
940     /* Wait until the cache command completes. */
941     while ((base->CCR & XCACHE_CCR_GO_MASK) != 0x00U)
942     {
943     }
944 
945     /* As a precaution clear the bits to avoid inadvertently re-running this command. */
946     base->CCR &= ~(XCACHE_CCR_PUSHW0_MASK | XCACHE_CCR_PUSHW1_MASK);
947 
948     /* Now disable the cache. */
949     base->CCR &= ~XCACHE_CCR_ENCACHE_MASK;
950 }
951 
AT_QUICKACCESS_SECTION_CODE(static void POWER_EnableCache (XCACHE_Type * base))952 AT_QUICKACCESS_SECTION_CODE(static void POWER_EnableCache(XCACHE_Type *base))
953 {
954     /* Invalidate all lines in both ways and initiate the cache command. */
955     base->CCR |= XCACHE_CCR_INVW0_MASK | XCACHE_CCR_INVW1_MASK | XCACHE_CCR_GO_MASK;
956 
957     /* Wait until the cache command completes. */
958     while ((base->CCR & XCACHE_CCR_GO_MASK) != 0x00U)
959     {
960     }
961 
962     /* Now enable the cache. */
963     base->CCR |= XCACHE_CCR_ENCACHE_MASK;
964     __ISB();
965     __DSB();
966 }
967 
968 /** @brief This API configure the SLEEPCON SLEEPCFG and PMC_PDSLEEPCFG registers.
969  *
970  * @param exclude_from_pd the bits mask need to be cleared for the registers.
971  */
AT_QUICKACCESS_SECTION_CODE(static void POWER_EnterLowPower_FullConfig (const uint32_t exclude_from_pd[7],power_mode_cfg_t mode,uint32_t pmic_mode_pins))972 AT_QUICKACCESS_SECTION_CODE(static void POWER_EnterLowPower_FullConfig(const uint32_t exclude_from_pd[7],
973                                                                        power_mode_cfg_t mode,
974                                                                        uint32_t pmic_mode_pins))
975 {
976     uint32_t pmc_ctrl;
977     uint32_t pmicMode;
978     uint32_t pdsleepcfg0;
979     bool cacheEnabled[2];
980     bool backupCache[2];
981 
982     uint32_t pmsk = __get_PRIMASK();
983 
984     __disable_irq();
985 
986     /* Body bias is configured through other APIs before the API call. */
987 
988     SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
989 
990     if (mode == kPower_DeepSleep)
991     {
992         /* The DMA HWWake function requires all the ACK of modules supporting HWWake, do handshake for those modules. */
993         POWER_DMA_HWWake_LPRequest();
994     }
995 
996     /* Power on mask bit correspond modules during Deep Sleep mode. */
997     SLEEPCON->SLEEPCFG = (SCFG0_DEEP_SLEEP & ~exclude_from_pd[0]) | (SLEEPCON->RUNCFG & ~exclude_from_pd[0]);
998 
999     if ((exclude_from_pd[0] & SLEEPCON0_SLEEPCFG_FRO0_PD_MASK) == 0U) /* Power down FRO0, need wait FRO0 power down. */
1000     {
1001         SLEEPCON->PWRDOWN_WAIT &= ~SLEEPCON0_PWRDOWN_WAIT_IGN_FRO0PDR_MASK;
1002     }
1003     if ((exclude_from_pd[0] & SLEEPCON0_SLEEPCFG_FRO1_PD_MASK) ==
1004         0U) /* When keeping power on, the PWRDOWN_WAIT is not used. */
1005     {
1006         SLEEPCON->PWRDOWN_WAIT &= ~SLEEPCON0_PWRDOWN_WAIT_IGN_FRO1PDR_MASK;
1007     }
1008 
1009     pdsleepcfg0    = PMC->PDSLEEPCFG0 & (~PCFG0_DEEP_SLEEP);
1010     backupCache[0] = false;
1011     backupCache[1] = false;
1012 
1013     switch (mode)
1014     {
1015         case kPower_DeepSleep:
1016             if ((exclude_from_pd[5] & PMC_PDSLEEPCFG4_CPU0_CCACHE_MASK) == 0U)
1017             {
1018                 backupCache[1] = true;
1019             }
1020             if ((exclude_from_pd[5] & PMC_PDSLEEPCFG4_CPU0_SCACHE_MASK) == 0U)
1021             {
1022                 backupCache[0] = true;
1023             }
1024 
1025             /* Keep *BB, LDOVSEL, DCDV VSEL bits not changed. Clear DPD, FDPD, FDSR, V2COMP_DSR, V2COM_DSR(When
1026              * V2COM_DSR set all other VDD2 need to be off), PMICMODE bits. */
1027             pdsleepcfg0 &=
1028                 ~(PMC_PDSLEEPCFG0_FDSR_MASK | PMC_PDSLEEPCFG0_V2COMP_DSR_MASK | PMC_PDSLEEPCFG0_V2COM_DSR_MASK |
1029                   PMC_PDSLEEPCFG0_DPD_MASK | PMC_PDSLEEPCFG0_FDPD_MASK | PMC_PDSLEEPCFG0_PMICMODE_MASK);
1030             PMC->PDSLEEPCFG0 = pdsleepcfg0 | (PCFG0_DEEP_SLEEP & ~exclude_from_pd[1]);
1031             /* V2NMED_DSR should be set if VNCOM_DSR is set. */
1032             if ((PMC->PDSLEEPCFG0 & PMC_PDSLEEPCFG0_VNCOM_DSR_MASK) != 0U)
1033             {
1034                 assert((exclude_from_pd[1] & PMC_PDSLEEPCFG0_V2NMED_DSR_MASK) == 0U);
1035             }
1036             break;
1037 
1038         case kPower_DeepSleepRetention:
1039             backupCache[0] = true;
1040             backupCache[1] = true;
1041             /* Keep *BB, LDOVSEL, DCDV VSEL bits not changed. Clear DPD, FDPD, PMICMODE bits. Always set
1042              * V2COMP_DSR(Compute DSR) and V2DSP_PD(When VDD2_COMP off, VDD2_DSP need to be off).*/
1043             pdsleepcfg0 &= ~(PMC_PDSLEEPCFG0_DPD_MASK | PMC_PDSLEEPCFG0_FDPD_MASK | PMC_PDSLEEPCFG0_PMICMODE_MASK);
1044             PMC->PDSLEEPCFG0 = pdsleepcfg0 |
1045                                ((PCFG0_DEEP_SLEEP | PCFG0_DSR | PMC_PDSLEEPCFG0_FDSR_MASK) & ~exclude_from_pd[1]) |
1046                                PMC_PDSLEEPCFG0_V2COMP_DSR_MASK | PMC_PDSLEEPCFG0_V2DSP_PD_MASK;
1047             /* Check DSR combination. If request V2COM_DSR,all other DSR bits should be set */
1048             if ((PMC->PDSLEEPCFG0 & PMC_PDSLEEPCFG0_V2COM_DSR_MASK) != 0U)
1049             {
1050                 assert((exclude_from_pd[1] & (PMC_PDSLEEPCFG0_V2COMP_DSR_MASK | PMC_PDSLEEPCFG0_V2NMED_DSR_MASK |
1051                                               PMC_PDSLEEPCFG0_VNCOM_DSR_MASK)) == 0U);
1052             }
1053             else if ((PMC->PDSLEEPCFG0 & PMC_PDSLEEPCFG0_VNCOM_DSR_MASK) !=
1054                      0U) /* V2NMED_DSR should be set if VNCOM_DSR is set. */
1055             {
1056                 assert((exclude_from_pd[1] & PMC_PDSLEEPCFG0_V2NMED_DSR_MASK) == 0U);
1057             }
1058             else
1059             {
1060                 /* Empty. */
1061             }
1062             break;
1063 
1064         case kPower_DeepPowerDown:
1065             /* Incase the CPU is in DSR mode. */
1066             backupCache[0] = true;
1067             backupCache[1] = true;
1068             /* Keep *BB, LDOVSEL, DCDV VSEL bits not changed. Clear PMICMODE bits.*/
1069             pdsleepcfg0 &= ~(PMC_PDSLEEPCFG0_PMICMODE_MASK | PMC_PDSLEEPCFG0_FDSR_MASK);
1070             PMC->PDSLEEPCFG0 =
1071                 pdsleepcfg0 | ((PCFG0_DEEP_SLEEP | PCFG0_DSR) & ~exclude_from_pd[1]) | PMC_PDSLEEPCFG0_DPD_MASK;
1072             break;
1073 
1074         case kPower_FullDeepPowerDown:
1075             /* Incase the CPU is in DSR mode. */
1076             backupCache[0] = true;
1077             backupCache[1] = true;
1078             /* Keep *BB, LDOVSEL, DCDV VSEL bits not changed. Clear PMICMODE bits.*/
1079             pdsleepcfg0 &= ~(PMC_PDSLEEPCFG0_PMICMODE_MASK | PMC_PDSLEEPCFG0_FDSR_MASK);
1080             PMC->PDSLEEPCFG0 =
1081                 pdsleepcfg0 | ((PCFG0_DEEP_SLEEP | PCFG0_DSR) & ~exclude_from_pd[1]) | PMC_PDSLEEPCFG0_FDPD_MASK;
1082             break;
1083 
1084         default:
1085             /* Added comments to prevent the violation of MISRA C-2012 rule. */
1086             break;
1087     }
1088 
1089     pmicMode = (exclude_from_pd[1] & PMC_PDSLEEPCFG0_PMICMODE_MASK) >> PMC_PDSLEEPCFG0_PMICMODE_SHIFT;
1090     if (pmicMode == 0U) /* Use default PMIC Mode configuration. */
1091     {
1092         /* Set PMIC mode pin as pre-defined. */
1093         PMC->PDSLEEPCFG0 |= PMC_PDSLEEPCFG0_PMICMODE(pmic_mode_pins);
1094     }
1095     else /* User defined PMIC mode. */
1096     {
1097         PMC->PDSLEEPCFG0 |= pmicMode << PMC_PDSLEEPCFG0_PMICMODE_SHIFT;
1098     }
1099 
1100     /* Regulator related configuration. */
1101     PMC->PDSLEEPCFG0 &= ~PMC_PDSLEEPCFG0_LDO1_VSEL_MASK; /* Select lowest LDOVDD1 voltage for aggregation. */
1102     if (s_vdd1Src == kVddSrc_PMIC)
1103     {
1104         PMC->PDSLEEPCFG0 &= ~PMC_PDSLEEPCFG0_LDO1_MODE_MASK; /* Bypass mode. */
1105     }
1106     else
1107     {
1108         PMC->PDSLEEPCFG0 |= PMC_PDSLEEPCFG0_LDO1_MODE_MASK; /* Low power mode. */
1109     }
1110     if (s_vdd2Src == kVddSrc_PMIC)
1111     {
1112         PMC->PDSLEEPCFG0 &= ~PMC_PDSLEEPCFG0_LDO2_MODE_MASK; /* Bypass mode. */
1113     }
1114     else
1115     {
1116         PMC->PDSLEEPCFG0 |= PMC_PDSLEEPCFG0_LDO2_MODE_MASK; /* Low power mode. */
1117     }
1118 
1119     PMC->PDSLEEPCFG1 = (PCFG1_DEEP_SLEEP & ~exclude_from_pd[2]) | (PMC->PDRUNCFG1 & ~exclude_from_pd[2]);
1120 
1121     /* When either PLL, FRO, TEMPERATURE, POR, LVD, HVD enabled, the PMCREF_LP should be cleared. */
1122     if (((exclude_from_pd[0] &
1123           (SLEEPCON0_SLEEPCFG_FRO0_PD_MASK | SLEEPCON0_SLEEPCFG_FRO1_PD_MASK | SLEEPCON0_SLEEPCFG_FRO2_PD_MASK |
1124            SLEEPCON0_SLEEPCFG_AUDPLLANA_PD_MASK | SLEEPCON0_SLEEPCFG_AUDPLLLDO_PD_MASK |
1125            SLEEPCON0_SLEEPCFG_PLLANA_PD_MASK | SLEEPCON0_SLEEPCFG_PLLLDO_PD_MASK)) != 0U) ||
1126         ((exclude_from_pd[2] &
1127           (PMC_PDSLEEPCFG1_HVDN_PD_MASK | PMC_PDSLEEPCFG1_LVDN_LP_MASK | PMC_PDSLEEPCFG1_PORN_LP_MASK |
1128            PMC_PDSLEEPCFG1_HVD2_PD_MASK | PMC_PDSLEEPCFG1_LVD2_LP_MASK | PMC_PDSLEEPCFG1_POR2_LP_MASK |
1129            PMC_PDSLEEPCFG1_HVD1_PD_MASK | PMC_PDSLEEPCFG1_LVD1_LP_MASK | PMC_PDSLEEPCFG1_POR1_LP_MASK)) != 0U))
1130     {
1131         PMC->PDSLEEPCFG1 &= ~PMC_PDSLEEPCFG1_PMCREF_LP_MASK;
1132     }
1133 
1134     PMC->PDSLEEPCFG2 = (PCFG2_DEEP_SLEEP & ~exclude_from_pd[3]) | (PMC->PDRUNCFG2 & ~exclude_from_pd[3]);
1135     PMC->PDSLEEPCFG3 = (PCFG3_DEEP_SLEEP & ~exclude_from_pd[4]) | (PMC->PDRUNCFG3 & ~exclude_from_pd[4]);
1136     PMC->PDSLEEPCFG4 = (PCFG4_DEEP_SLEEP & ~exclude_from_pd[5]) | (PMC->PDRUNCFG4 & ~exclude_from_pd[5]);
1137     PMC->PDSLEEPCFG5 = (PCFG5_DEEP_SLEEP & ~exclude_from_pd[6]) | (PMC->PDRUNCFG5 & ~exclude_from_pd[6]);
1138 
1139     /* Stall Hifi4 if power down VDD2_DSP*/
1140     if ((PMC->PDSLEEPCFG0 & PMC_PDSLEEPCFG0_V2DSP_PD_MASK) != 0U)
1141     {
1142         SYSCON0->DSPSTALL = SYSCON0_DSPSTALL_DSPSTALL_MASK;
1143     }
1144 
1145     /* Set PMC_CTRL[APPLYCFG]. */
1146     while ((PMC->STATUS & PMC_STATUS_BUSY_MASK) != 0U) /* Cannot set APPLYCFG when ACTIVEFSM is 1 */
1147     {
1148     }
1149     PMC->CTRL |= PMC_CTRL_APPLYCFG_MASK;
1150     while ((PMC->STATUS & PMC_STATUS_BUSY_MASK) != 0U) /* Wait all PMC finite state machines finished. */
1151     {
1152     }
1153 
1154     /* Clear all event flags before enter deep sleep */
1155     PMC->FLAGS    = PMC->FLAGS;
1156     PMC->PWRFLAGS = PMC->PWRFLAGS;
1157 
1158     /* Disable LVD core reset. */
1159     pmc_ctrl  = PMC->CTRL;
1160     PMC->CTRL = pmc_ctrl & ~(PMC_CTRL_LVDNRE_MASK | PMC_CTRL_LVD2RE_MASK | PMC_CTRL_LVD1RE_MASK |
1161                              PMC_CTRL_AGDET2RE_MASK | PMC_CTRL_AGDET1RE_MASK);
1162 
1163     /* Deinit XSPI interface in case XIP */
1164     deinitXip();
1165 
1166     if (backupCache[1]) /* Xcache is not retented in DSR mode. */
1167     {
1168         cacheEnabled[1] = ((XCACHE1->CCR & XCACHE_CCR_ENCACHE_MASK) == 0U) ? false : true;
1169 
1170         if (cacheEnabled[1])
1171         {
1172             POWER_DisableCache(XCACHE1);
1173         }
1174     }
1175     if (backupCache[0]) /* Xcache is not retented in DSR mode. */
1176     {
1177         cacheEnabled[0] = ((XCACHE0->CCR & XCACHE_CCR_ENCACHE_MASK) == 0U) ? false : true;
1178 
1179         if (cacheEnabled[0])
1180         {
1181             POWER_DisableCache(XCACHE0);
1182         }
1183     }
1184 
1185     /* If the first one to Deep Sleep, ignore the Ignores power-down ready signal from LPOSC, FRO2. */
1186     if ((PMC->STATUS & PMC_STATUS_DSSENS_MASK) == 0U)
1187     {
1188         SLEEPCON->PWRDOWN_WAIT |= SLEEPCON0_PWRDOWN_WAIT_IGN_FRO2PDR_MASK | SLEEPCON0_PWRDOWN_WAIT_IGN_LPOSCPDR_MASK;
1189     }
1190 
1191     /* Enter deep sleep mode */
1192     __WFI();
1193 
1194     if (mode == kPower_DeepSleep)
1195     {
1196         POWER_DMA_HWWake_LPRestore();
1197     }
1198 
1199     if (backupCache[1])
1200     {
1201         if (cacheEnabled[1])
1202         {
1203             POWER_EnableCache(XCACHE1);
1204         }
1205     }
1206     if (backupCache[0])
1207     {
1208         if (cacheEnabled[0])
1209         {
1210             POWER_EnableCache(XCACHE0);
1211         }
1212     }
1213 
1214     /* Init XSPI in case XIP */
1215     initXip();
1216 
1217     /* Restore PMC LVD core reset and OTP switch setting */
1218     PMC->CTRL = pmc_ctrl;
1219 
1220     SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
1221     __set_PRIMASK(pmsk);
1222 }
1223 
AT_QUICKACCESS_SECTION_CODE(void POWER_EnterDSR (const uint32_t exclude_from_pd[7]))1224 AT_QUICKACCESS_SECTION_CODE(void POWER_EnterDSR(const uint32_t exclude_from_pd[7]))
1225 {
1226     POWER_EnterLowPower_FullConfig(exclude_from_pd, kPower_DeepSleepRetention, POWER_DEFAULT_PMICMODE_DSR);
1227 }
1228 #else
1229 /* Need do low power request-ack for all the modules capable of DMA HW Wake function if the DMA_HWWake is used. */
AT_QUICKACCESS_SECTION_CODE(static void POWER_DMA_HWWake_LPRequest (void))1230 AT_QUICKACCESS_SECTION_CODE(static void POWER_DMA_HWWake_LPRequest(void))
1231 {
1232     uint32_t lpReqClockCfg, lpReqResetCfg;
1233 
1234     if (SLEEPCON1->HW_WAKE != 0U) /* Only assert the LP Requet when DMA HW_WAKE enabled. */
1235     {
1236         lpReqClockCfg  = CLKCTL1->PSCCTL1;
1237         lpReqResetCfg  = RSTCTL1->PRSTCTL0;
1238         lpReqConfig[0] = SLEEPCON1->PRIVATE_CCTRL0;
1239         lpReqConfig[1] = SLEEPCON1->SHA_MED_TCTRL0;
1240         lpReqConfig[2] = SLEEPCON1->SHA_SEN_TCTRL0;
1241         lpReqConfig[3] = SLEEPCON1->PRIVATE_TCTRL0;
1242 
1243         CLKCTL1->PSCCTL1_SET =
1244             CLKCTL1_PSCCTL1_EDMA2_MASK |
1245             CLKCTL1_PSCCTL1_EDMA3_MASK; /* DMA clock need to be enabled to finishe low power handshake. */
1246         RSTCTL1->PRSTCTL0_CLR =
1247             RSTCTL1_PRSTCTL0_EDMA2_MASK |
1248             RSTCTL1_PRSTCTL0_EDMA3_MASK; /* DMA reset need to be cleared to finishe low power handshake. */
1249 
1250         SLEEPCON1->PRIVATE_CCTRL0 |= PRIVATE_CONTROLLER_HWWAKE_MODULE_MASK;
1251         SLEEPCON1->SHA_MED_TCTRL0 |= SLEEPCON1_SHA_MED_TCTRL0_FLEXIO_B_LPREQ_MASK; /* FLEXIO Bus*/
1252         SLEEPCON1->SHA_SEN_TCTRL0 |= SLEEPCON1_SHA_SEN_TCTRL0_MICFIL_STOP_MASK;    /* MICFIL */
1253         SLEEPCON1->PRIVATE_TCTRL0 |= PRIVATE_TCTRL_HWWAKE_MODULE_MASK0;            /* SAI and LP_FLEXCOMM */
1254 
1255         while ((SLEEPCON1->PRIVATE_CSTAT0 & PRIVATE_CONTROLLER_HWWAKE_MODULE_MASK) !=
1256                PRIVATE_CONTROLLER_HWWAKE_MODULE_MASK)
1257         {
1258         }
1259         while ((SLEEPCON1->SHA_MEDSEN_TSTAT0 & SHA_MEDSEN_TSTAT_HWWAKE_MODULE_MASK) !=
1260                SHA_MEDSEN_TSTAT_HWWAKE_MODULE_MASK)
1261         {
1262         }
1263         while ((SLEEPCON1->PRIVATE_TSTAT0 & PRIVATE_TSTAT_HWWAKE_MODULE_MASK0) != PRIVATE_TSTAT_HWWAKE_MODULE_MASK0)
1264         {
1265         }
1266         CLKCTL1->PSCCTL1  = lpReqClockCfg;
1267         RSTCTL1->PRSTCTL0 = lpReqResetCfg;
1268     }
1269 }
1270 
AT_QUICKACCESS_SECTION_CODE(static void POWER_DMA_HWWake_LPRestore (void))1271 AT_QUICKACCESS_SECTION_CODE(static void POWER_DMA_HWWake_LPRestore(void))
1272 {
1273     if (SLEEPCON1->HW_WAKE != 0U) /* DMA HW_WAKE enabled. */
1274     {
1275         /* restore the configuration */
1276         SLEEPCON1->PRIVATE_CCTRL0 = lpReqConfig[0];
1277         SLEEPCON1->SHA_MED_TCTRL0 = lpReqConfig[1];
1278         SLEEPCON1->SHA_SEN_TCTRL0 = lpReqConfig[2];
1279         SLEEPCON1->PRIVATE_TCTRL0 = lpReqConfig[3];
1280     }
1281 }
1282 
1283 /** @brief This API configure the SLEEPCON SLEEPCFG and PMC_PDSLEEPCFG registers.
1284  *
1285  * @param exclude_from_pd the bits mask need to be cleared for the registers.
1286  */
AT_QUICKACCESS_SECTION_CODE(void static POWER_EnterLowPower_FullConfig (const uint32_t exclude_from_pd[7],power_mode_cfg_t mode,uint32_t pmic_mode_pins))1287 AT_QUICKACCESS_SECTION_CODE(void static POWER_EnterLowPower_FullConfig(const uint32_t exclude_from_pd[7],
1288                                                                        power_mode_cfg_t mode,
1289                                                                        uint32_t pmic_mode_pins))
1290 {
1291     uint32_t pmicMode;
1292     uint32_t pdsleepcfg0;
1293     uint32_t pmc_ctrl;
1294 
1295     uint32_t pmsk = __get_PRIMASK();
1296 
1297     __disable_irq();
1298 
1299     SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
1300 
1301     if (mode == kPower_DeepSleep)
1302     {
1303         /* The DMA HWWake function requires all the ACK of modules supporting HWWake, do handshake for those modules. */
1304         POWER_DMA_HWWake_LPRequest();
1305     }
1306 
1307     /* Power on mask bit correspond modules during Deep Sleep mode. */
1308     SLEEPCON->SLEEPCFG = (SCFG0_DEEP_SLEEP & ~exclude_from_pd[0]) | (SLEEPCON->RUNCFG & ~exclude_from_pd[0]);
1309 
1310     if ((exclude_from_pd[0] & SLEEPCON1_SLEEPCFG_FRO2_PD_MASK) != 0U)
1311     {
1312         SLEEPCON->PWRDOWN_WAIT |= SLEEPCON1_PWRDOWN_WAIT_IGN_FRO2PDR_MASK;
1313     }
1314 
1315     pdsleepcfg0 = PMC->PDSLEEPCFG0 & (~PCFG0_DEEP_SLEEP);
1316     switch (mode)
1317     {
1318         case kPower_DeepSleep:
1319             /* Keep *BB, LDOVSEL, DCDV VSEL bits not changed. Clear DPD, FDPD, FDSR, PMICMODE bits.*/
1320             pdsleepcfg0 &= ~(PMC_PDSLEEPCFG0_FDSR_MASK | PMC_PDSLEEPCFG0_DPD_MASK | PMC_PDSLEEPCFG0_FDPD_MASK |
1321                              PMC_PDSLEEPCFG0_PMICMODE_MASK);
1322             PMC->PDSLEEPCFG0 = pdsleepcfg0 | ((PCFG0_DEEP_SLEEP | PCFG0_DSR) & ~exclude_from_pd[1]);
1323 
1324             break;
1325 
1326         case kPower_DeepSleepRetention:
1327             /* Keep *BB, LDOVSEL, DCDV VSEL bits not changed. Clear DPD, FDPD, *DSR, PMICMODE bits.*/
1328             pdsleepcfg0 &= ~(PMC_PDSLEEPCFG0_DPD_MASK | PMC_PDSLEEPCFG0_FDPD_MASK | PMC_PDSLEEPCFG0_PMICMODE_MASK);
1329             PMC->PDSLEEPCFG0 = pdsleepcfg0 | (PCFG0_DEEP_SLEEP & ~exclude_from_pd[1]) | PCFG0_DSR |
1330                                PMC_PDSLEEPCFG0_FDSR_MASK; /* All domain DSR. */
1331             break;
1332 
1333         case kPower_DeepPowerDown:
1334             /* Keep *BB, LDOVSEL, DCDV VSEL bits not changed. Clear PMICMODE bits.*/
1335             pdsleepcfg0 &= ~(PMC_PDSLEEPCFG0_PMICMODE_MASK | PMC_PDSLEEPCFG0_FDSR_MASK);
1336             PMC->PDSLEEPCFG0 =
1337                 pdsleepcfg0 | ((PCFG0_DEEP_SLEEP | PCFG0_DSR) & ~exclude_from_pd[1]) | PMC_PDSLEEPCFG0_DPD_MASK;
1338             break;
1339 
1340         case kPower_FullDeepPowerDown:
1341             /* Keep *BB, LDOVSEL, DCDV VSEL bits not changed. Clear PMICMODE bits.*/
1342             pdsleepcfg0 &= ~(PMC_PDSLEEPCFG0_PMICMODE_MASK | PMC_PDSLEEPCFG0_FDSR_MASK);
1343             PMC->PDSLEEPCFG0 =
1344                 pdsleepcfg0 | ((PCFG0_DEEP_SLEEP | PCFG0_DSR) & ~exclude_from_pd[1]) | PMC_PDSLEEPCFG0_FDPD_MASK;
1345             break;
1346 
1347         default:
1348             /* Added comments to prevent the violation of MISRA C-2012 rule. */
1349             break;
1350     }
1351 
1352     pmicMode = (exclude_from_pd[1] & PMC_PDSLEEPCFG0_PMICMODE_MASK) >> PMC_PDSLEEPCFG0_PMICMODE_SHIFT;
1353     if (pmicMode == 0U) /* Use default PMIC Mode configuration. */
1354     {
1355         /* Set PMIC mode pin as predefined. */
1356         PMC->PDSLEEPCFG0 |= PMC_PDSLEEPCFG0_PMICMODE(pmic_mode_pins);
1357     }
1358     else /* User defined PMIC mode. */
1359     {
1360         PMC->PDSLEEPCFG0 |= pmicMode << PMC_PDSLEEPCFG0_PMICMODE_SHIFT;
1361     }
1362 
1363     /* Regulator related configuration. */
1364     PMC->PDSLEEPCFG0 &= ~PMC_PDSLEEPCFG0_LDO2_VSEL_MASK;     /* Select lowest LDOVDD2 voltage for aggregation. */
1365     if ((PMC->POWERCFG & PMC_POWERCFG_LDO1PD_MASK) != 0U)    /* PMIC used.*/
1366     {
1367         PMC->PDSLEEPCFG0 &= ~PMC_PDSLEEPCFG0_LDO1_MODE_MASK; /* Bypass mode. */
1368     }
1369     else
1370     {
1371         PMC->PDSLEEPCFG0 |= PMC_PDSLEEPCFG0_LDO1_MODE_MASK; /* Low power mode. */
1372     }
1373     if ((PMC->POWERCFG & PMC_POWERCFG_LDO2PD_MASK) != 0U)
1374     {
1375         PMC->PDSLEEPCFG0 &= ~PMC_PDSLEEPCFG0_LDO2_MODE_MASK; /* Bypass mode. */
1376     }
1377     else
1378     {
1379         PMC->PDSLEEPCFG0 |= PMC_PDSLEEPCFG0_LDO2_MODE_MASK; /* Low power mode. */
1380     }
1381 
1382     PMC->PDSLEEPCFG1 = (PCFG1_DEEP_SLEEP & ~exclude_from_pd[2]) | (PMC->PDRUNCFG1 & ~exclude_from_pd[2]);
1383 
1384     /* When either PLL, FRO, TEMPERATURE, POR, LVD, HVD enabled, the PMCREF_LP should be cleared. */
1385     if (((exclude_from_pd[0] & (SLEEPCON1_SLEEPCFG_FRO2_PD_MASK | SLEEPCON1_SLEEPCFG_AUDPLLANA_PD_MASK |
1386                                 SLEEPCON1_SLEEPCFG_AUDPLLLDO_PD_MASK | SLEEPCON1_SLEEPCFG_PLLANA_PD_MASK |
1387                                 SLEEPCON1_SLEEPCFG_PLLLDO_PD_MASK)) != 0U) ||
1388         ((exclude_from_pd[2] &
1389           (PMC_PDSLEEPCFG1_HVDN_PD_MASK | PMC_PDSLEEPCFG1_LVDN_LP_MASK | PMC_PDSLEEPCFG1_PORN_LP_MASK |
1390            PMC_PDSLEEPCFG1_HVD2_PD_MASK | PMC_PDSLEEPCFG1_LVD2_LP_MASK | PMC_PDSLEEPCFG1_POR2_LP_MASK |
1391            PMC_PDSLEEPCFG1_HVD1_PD_MASK | PMC_PDSLEEPCFG1_LVD1_LP_MASK | PMC_PDSLEEPCFG1_POR1_LP_MASK)) != 0U))
1392     {
1393         PMC->PDSLEEPCFG1 &= ~PMC_PDSLEEPCFG1_PMCREF_LP_MASK;
1394     }
1395 
1396     PMC->PDSLEEPCFG2 = (PCFG2_DEEP_SLEEP & ~exclude_from_pd[3]) | (PMC->PDRUNCFG2 & ~exclude_from_pd[3]);
1397     PMC->PDSLEEPCFG3 = (PCFG3_DEEP_SLEEP & ~exclude_from_pd[4]) | (PMC->PDRUNCFG3 & ~exclude_from_pd[4]);
1398     PMC->PDSLEEPCFG4 = (PCFG4_DEEP_SLEEP & ~exclude_from_pd[5]) | (PMC->PDRUNCFG4 & ~exclude_from_pd[5]);
1399     PMC->PDSLEEPCFG5 = (PCFG5_DEEP_SLEEP & ~exclude_from_pd[6]) | (PMC->PDRUNCFG5 & ~exclude_from_pd[6]);
1400 
1401     /* Set PMC_CTRL[APPLYCFG]. */
1402     while ((PMC->STATUS & PMC_STATUS_BUSY_MASK) != 0U) /* Cannot set APPLYCFG when ACTIVEFSM is 1 */
1403     {
1404     }
1405     PMC->CTRL |= PMC_CTRL_APPLYCFG_MASK;
1406     while ((PMC->STATUS & PMC_STATUS_BUSY_MASK) != 0U) /* Wait all PMC finite state machines finished. */
1407     {
1408     }
1409 
1410     /* Clear all event flags before enter deep sleep */
1411     PMC->FLAGS    = PMC->FLAGS;
1412     PMC->PWRFLAGS = PMC->PWRFLAGS;
1413 
1414     /* Disable LVD core reset. */
1415     pmc_ctrl  = PMC->CTRL;
1416     PMC->CTRL = pmc_ctrl & ~(PMC_CTRL_LVDNRE_MASK | PMC_CTRL_LVD2RE_MASK | PMC_CTRL_LVD1RE_MASK |
1417                              PMC_CTRL_AGDET2RE_MASK | PMC_CTRL_AGDET1RE_MASK);
1418 
1419     /* If the first one to Deep Sleep, ignore the Ignores power-down ready signal from LPOSC, FRO2. */
1420     /* if ((PMC->STATUS & PMC_STATUS_DSCOMP_MASK) == 0U) Ignore FRO2, LPOSC power-down ready signal because sense don't
1421      * know if they are used by compute domain. */
1422     SLEEPCON->PWRDOWN_WAIT |= SLEEPCON1_PWRDOWN_WAIT_IGN_FRO2PDR_MASK | SLEEPCON1_PWRDOWN_WAIT_IGN_LPOSCPDR_MASK;
1423 
1424     /* Enter deep sleep mode */
1425     __WFI();
1426 
1427     if (mode == kPower_DeepSleep)
1428     {
1429         POWER_DMA_HWWake_LPRestore();
1430     }
1431 
1432     /* Restore PMC LVD core reset and OTP switch setting */
1433     PMC->CTRL = pmc_ctrl;
1434 
1435     SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
1436     __set_PRIMASK(pmsk);
1437 }
1438 
AT_QUICKACCESS_SECTION_CODE(void POWER_RequestDSR (const uint32_t exclude_from_pd[7]))1439 AT_QUICKACCESS_SECTION_CODE(void POWER_RequestDSR(const uint32_t exclude_from_pd[7]))
1440 {
1441     POWER_EnterLowPower_FullConfig(exclude_from_pd, kPower_DeepSleepRetention, POWER_DEFAULT_PMICMODE_DSR);
1442 }
1443 #endif
1444 
AT_QUICKACCESS_SECTION_CODE(void POWER_EnterDeepSleep (const uint32_t exclude_from_pd[7]))1445 AT_QUICKACCESS_SECTION_CODE(void POWER_EnterDeepSleep(const uint32_t exclude_from_pd[7]))
1446 {
1447     POWER_EnterLowPower_FullConfig(exclude_from_pd, kPower_DeepSleep, POWER_DEFAULT_PMICMODE_DS);
1448 }
1449 
1450 /**
1451  * @brief    PMC Deep Sleep Power Down function call
1452  * @return   nothing
1453  */
AT_QUICKACCESS_SECTION_CODE(void POWER_RequestDeepPowerDown (const uint32_t exclude_from_pd[7]))1454 AT_QUICKACCESS_SECTION_CODE(void POWER_RequestDeepPowerDown(const uint32_t exclude_from_pd[7]))
1455 {
1456     POWER_EnterLowPower_FullConfig(exclude_from_pd, kPower_DeepPowerDown, POWER_DEFAULT_PMICMODE_DPD);
1457 }
1458 
AT_QUICKACCESS_SECTION_CODE(void POWER_RequestFullDeepPowerDown (const uint32_t exclude_from_pd[7]))1459 AT_QUICKACCESS_SECTION_CODE(void POWER_RequestFullDeepPowerDown(const uint32_t exclude_from_pd[7]))
1460 {
1461     POWER_EnterLowPower_FullConfig(exclude_from_pd, kPower_FullDeepPowerDown, POWER_DEFAULT_PMICMODE_FDPD);
1462 }
1463 
1464 /* Enter Power mode */
POWER_EnterPowerMode(power_mode_cfg_t mode,const uint32_t exclude_from_pd[7])1465 void POWER_EnterPowerMode(power_mode_cfg_t mode, const uint32_t exclude_from_pd[7])
1466 {
1467     switch (mode)
1468     {
1469         case kPower_Sleep:
1470             POWER_EnterSleep();
1471             break;
1472         case kPower_DeepSleep:
1473             POWER_EnterDeepSleep(exclude_from_pd);
1474             break;
1475         case kPower_DeepSleepRetention:
1476 #if defined(PMC0)
1477             POWER_EnterDSR(exclude_from_pd);
1478 #else
1479             POWER_RequestDSR(exclude_from_pd);
1480 #endif
1481             break;
1482         case kPower_DeepPowerDown:
1483             POWER_RequestDeepPowerDown(exclude_from_pd);
1484             break;
1485         case kPower_FullDeepPowerDown:
1486             POWER_RequestFullDeepPowerDown(exclude_from_pd);
1487             break;
1488         default:
1489             /* Invalide mode. */
1490             assert(false);
1491             break;
1492     }
1493 }
1494 
1495 /* Get power lib version */
POWER_GetLibVersion(void)1496 uint32_t POWER_GetLibVersion(void)
1497 {
1498     return (uint32_t)FSL_POWER_DRIVER_VERSION;
1499 }
1500