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