1 /*
2  * Copyright 2022 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "fsl_pm_core.h"
9 #include "fsl_pm_device.h"
10 
11 #include "fsl_clock.h"
12 #include "fsl_power.h"
13 
14 /*******************************************************************************
15  * Macros
16  ******************************************************************************/
17 
18  /*******************************************************************************
19  * Prototypes
20  ******************************************************************************/
21 static void IMXRT500_EnterLowPowerMode(uint8_t stateIndex, pm_resc_mask_t *pSoftRescMask, pm_resc_group_t *pSysRescGroup);
22 static void IMXRT500_CleanExitLowPowerMode(void);
23 static void iMXRT500_EnablePeripheralsDeepSleep(pm_resc_mask_t *pSoftRescMask, pm_resc_group_t *pSysRescGroup, uint32_t *enabledResources);
24 static void iMXRT500_DisablePeripheralsSleep(pm_resc_mask_t *pSoftRescMask, pm_resc_group_t *pSysRescGroup);
25 
26 #if (defined(FSL_PM_SUPPORT_WAKEUP_SOURCE_MANAGER) && FSL_PM_SUPPORT_WAKEUP_SOURCE_MANAGER)
27 static status_t IMXRT500_ManageWakeupSource(pm_wakeup_source_t *ws, bool enable);
28 #endif /* FSL_PM_SUPPORT_WAKEUP_SOURCE_MANAGER */
29 /*******************************************************************************
30  * Variables
31  ******************************************************************************/
32 /*!
33  *  |  Module         |    Sleep     | Deep Sleep | Deep Power Down | Full Deep Power Down |
34  *  | MAIN CLK        |    ON/OFF    |   ON/OFF   |      OFF        |       OFF            |
35  *  | VDDCOREREG      |    HP/LP     |   HP/LP    |      OFF        |       OFF            |
36  *  | PMC_REF         |    HP/LP     |   HP/LP    |      OFF        |       OFF            |
37  *  | HVD_1V8         |    ON/OFF    |   ON/OFF   |      OFF        |       OFF            |
38  *  | POR_CORE        |    HP/LP     |   HP/LP    |      OFF        |       OFF            |
39  *  | LVDCORE         |    HP/LP     |   HP/LP    |      OFF        |       OFF            |
40  *  | HVDCORE         |    ON/OFF    |   ON/OFF   |      OFF        |       OFF            |
41  *  | SYSXTAL         |    ON/OFF    |   ON/OFF   |      OFF        |       OFF            |
42  *  | LPOSC           |    ON/OFF    |   ON/OFF   |      OFF        |       OFF            |
43  *  | FRO-192M / 96M  |    ON/OFF    |   ON/OFF   |      OFF        |       OFF            |
44  *  | SYS PLL         |    ON/OFF    |   ON/OFF   |      OFF        |       OFF            |
45  *  | AUDIO PLL       |    ON/OFF    |   ON/OFF   |      OFF        |       OFF            |
46  *  | ADC             |    ON/OFF    |   ON/OFF   |      OFF        |       OFF            |
47  *  | ADC TEMP        |    ON/OFF    |   ON/OFF   |      OFF        |       OFF            |
48  *  | PMC TEMP        |    ON/OFF    |   ON/OFF   |      OFF        |       OFF            |
49  *  | ACMP            |    ON/OFF    |   ON/OFF   |      OFF        |       OFF            |
50  *  | DSP             |    ON/OFF    |   ON/OFF   |      OFF        |       OFF            |
51  *  | MIPI-DSI        |    ON/OFF    |   ON/OFF   |      OFF        |       OFF            |
52  *  | OTP             |    ON/OFF    |   ON/OFF   |      OFF        |       OFF            |
53  *  | ROM             |    ON/OFF    |   ON/OFF   |      OFF        |       OFF            |
54  *  | PowerQuad RAM   |    ON/OFF    |   ON/OFF   |      OFF        |       OFF            |
55  *  | FLEXSPI0 RAM    |   ON/RET/OFF | ON/RET/OFF |      OFF        |       OFF            |
56  *  | FLEXSPI1 RAM    |   ON/RET/OFF | ON/RET/OFF |      OFF        |       OFF            |
57  *  | USB RAM         |   ON/RET/OFF | ON/RET/OFF |      OFF        |       OFF            |
58  *  | USDHC0 RAM      |   ON/RET/OFF | ON/RET/OFF |      OFF        |       OFF            |
59  *  | USDHC1 RAM      |   ON/RET/OFF | ON/RET/OFF |      OFF        |       OFF            |
60  *  | CASPER RAM      |    ON/OFF    |   ON/OFF   |      OFF        |       OFF            |
61  *  | GPU RAM         |   ON/RET/OFF | ON/RET/OFF |      OFF        |       OFF            |
62  *  | SmartDMA RAM    |   ON/RET/OFF | ON/RET/OFF |      OFF        |       OFF            |
63  *  | MIPI-DSI RAM    |   ON/RET/OFF | ON/RET/OFF |      OFF        |       OFF            |
64  *  | LCDIF RAM       |   ON/RET/OFF | ON/RET/OFF |      OFF        |       OFF            |
65  *  | SRAM0-7 32KB    |   ON/RET/OFF | ON/RET/OFF |      OFF        |       OFF            |
66  *  | SRAM8-11 64KB   |   ON/RET/OFF | ON/RET/OFF |      OFF        |       OFF            |
67  *  | SRAM12-15 128KB |   ON/RET/OFF | ON/RET/OFF |      OFF        |       OFF            |
68  *  | SRAM16-31 256KB |   ON/RET/OFF | ON/RET/OFF |      OFF        |       OFF            |
69  */
70 
71 const pm_device_option_t g_devicePMOption = {
72     .states =
73         {
74             /* Sleep */
75             {
76                 .fixConstraintsMask =
77                     {
78                         .rescMask[0U] = 0x00000000UL,
79                         .rescMask[1U] = 0x00000000UL,
80                         .rescMask[2U] = 0x0UL,
81                     },
82                 .varConstraintsMask =
83                     {
84                         .rescMask[0U] = 0xFFFFFFFFUL,
85                         .rescMask[1U] = 0xFFFFFFFFUL,
86                         .rescMask[2U] = 0x3UL,
87                     },
88             },
89             /* Deep Sleep */
90             {
91                 .fixConstraintsMask =
92                     {
93                         .rescMask[0U] = 0x00000000UL,
94                         .rescMask[1U] = 0x00000000UL,
95                         .rescMask[2U] = 0x0UL,
96                     },
97                 .varConstraintsMask =
98                     {
99                         .rescMask[0U] = 0xFFFFFFFFUL,
100                         .rescMask[1U] = 0xFFFFFFFFUL,
101                         .rescMask[2U] = 0x3UL,
102                     },
103             },
104             /* Deep Power Down */
105             {
106                 .fixConstraintsMask =
107                     {
108                         .rescMask[0U] = 0xFFFFFFFFUL,
109                         .rescMask[1U] = 0xFFFFFFFFUL,
110                         .rescMask[2U] = 0x3UL,
111                     },
112                 .varConstraintsMask =
113                     {
114                         .rescMask[0U] = 0x0UL,
115                         .rescMask[1U] = 0x0UL,
116                         .rescMask[2U] = 0x0UL,
117                     },
118             },
119             /* Full Deep Power Down */
120             {
121                 .fixConstraintsMask =
122                     {
123                         .rescMask[0U] = 0xFFFFFFFFUL,
124                         .rescMask[1U] = 0xFFFFFFFFUL,
125                         .rescMask[2U] = 0x3UL,
126                     },
127                 .varConstraintsMask =
128                     {
129                         .rescMask[0U] = 0x0UL,
130                         .rescMask[1U] = 0x0UL,
131                         .rescMask[2U] = 0x0UL,
132                     },
133             },
134         },
135     .stateCount = PM_LP_STATE_COUNT,
136     .enter      = IMXRT500_EnterLowPowerMode,
137     .clean      = IMXRT500_CleanExitLowPowerMode,
138 
139 #if (defined(FSL_PM_SUPPORT_WAKEUP_SOURCE_MANAGER) && FSL_PM_SUPPORT_WAKEUP_SOURCE_MANAGER)
140     .manageWakeupSource = IMXRT500_ManageWakeupSource,
141 #endif /* FSL_PM_SUPPORT_WAKEUP_SOURCE_MANAGER */
142 };
143 
144 /* Table of PDSLEEPCFG1 masks for each dedicated Peripheral RAM (PRAM) constraint */
145 static const enabled_resources_prams_t enResPRAMs[RESC_GROUP_PRAMS_SIZE] =
146 {
147   [kResc_SRAM_FLEXSPI0  - RESC_GROUP_PRAMS_START] =
148       {SYSCTL0_PDSLEEPCFG1_FLEXSPI0_SRAM_APD_MASK, SYSCTL0_PDSLEEPCFG1_FLEXSPI0_SRAM_PPD_MASK},
149   [kResc_SRAM_FLEXSPI1  - RESC_GROUP_PRAMS_START] =
150       {SYSCTL0_PDSLEEPCFG1_FLEXSPI1_SRAM_APD_MASK, SYSCTL0_PDSLEEPCFG1_FLEXSPI1_SRAM_PPD_MASK},
151   [kResc_SRAM_USB       - RESC_GROUP_PRAMS_START] =
152       {SYSCTL0_PDSLEEPCFG1_USBHS_SRAM_APD_MASK, SYSCTL0_PDSLEEPCFG1_USBHS_SRAM_PPD_MASK},
153   [kResc_SRAM_USDHC0    - RESC_GROUP_PRAMS_START] =
154       {SYSCTL0_PDSLEEPCFG1_USDHC0_SRAM_APD_MASK, SYSCTL0_PDSLEEPCFG1_USDHC0_SRAM_PPD_MASK},
155   [kResc_SRAM_USDHC1    - RESC_GROUP_PRAMS_START] =
156       {SYSCTL0_PDSLEEPCFG1_USDHC1_SRAM_APD_MASK, SYSCTL0_PDSLEEPCFG1_USDHC1_SRAM_PPD_MASK},
157   [kResc_SRAM_GPU       - RESC_GROUP_PRAMS_START] =
158       {SYSCTL0_PDSLEEPCFG1_GPU_SRAM_APD_MASK, SYSCTL0_PDSLEEPCFG1_GPU_SRAM_PPD_MASK},
159   [kResc_SRAM_SMARTDMA  - RESC_GROUP_PRAMS_START] =
160       {SYSCTL0_PDSLEEPCFG1_SMARTDMA_SRAM_APD_MASK, SYSCTL0_PDSLEEPCFG1_SMARTDMA_SRAM_PPD_MASK},
161   [kResc_SRAM_MIPIDSI   - RESC_GROUP_PRAMS_START] =
162       {SYSCTL0_PDSLEEPCFG1_MIPIDSI_SRAM_APD_MASK, SYSCTL0_PDSLEEPCFG1_MIPIDSI_SRAM_PPD_MASK},
163   [kResc_SRAM_LCDIF     - RESC_GROUP_PRAMS_START] =
164       {SYSCTL0_PDSLEEPCFG1_LCDIF_SRAM_APD_MASK, SYSCTL0_PDSLEEPCFG1_LCDIF_SRAM_PPD_MASK},
165 };
166 
167 /* PDSLEEPCFG masks for each System SRAM resource constraint */
168 static const uint32_t enResSRAMs[RESC_GROUP_SRAMS_SIZE] =
169 {
170   [kResc_SRAM0_32KB   - RESC_GROUP_SRAMS_START] = SYSCTL0_PDSLEEPCFG2_SRAM_IF0_APD_MASK,
171   [kResc_SRAM1_32KB   - RESC_GROUP_SRAMS_START] = SYSCTL0_PDSLEEPCFG2_SRAM_IF1_APD_MASK,
172   [kResc_SRAM2_32KB   - RESC_GROUP_SRAMS_START] = SYSCTL0_PDSLEEPCFG2_SRAM_IF2_APD_MASK,
173   [kResc_SRAM3_32KB   - RESC_GROUP_SRAMS_START] = SYSCTL0_PDSLEEPCFG2_SRAM_IF3_APD_MASK,
174   [kResc_SRAM4_32KB   - RESC_GROUP_SRAMS_START] = SYSCTL0_PDSLEEPCFG2_SRAM_IF4_APD_MASK,
175   [kResc_SRAM5_32KB   - RESC_GROUP_SRAMS_START] = SYSCTL0_PDSLEEPCFG2_SRAM_IF5_APD_MASK,
176   [kResc_SRAM6_32KB   - RESC_GROUP_SRAMS_START] = SYSCTL0_PDSLEEPCFG2_SRAM_IF6_APD_MASK,
177   [kResc_SRAM7_32KB   - RESC_GROUP_SRAMS_START] = SYSCTL0_PDSLEEPCFG2_SRAM_IF7_APD_MASK,
178   [kResc_SRAM8_64KB   - RESC_GROUP_SRAMS_START] = SYSCTL0_PDSLEEPCFG2_SRAM_IF8_APD_MASK,
179   [kResc_SRAM9_64KB   - RESC_GROUP_SRAMS_START] = SYSCTL0_PDSLEEPCFG2_SRAM_IF9_APD_MASK,
180   [kResc_SRAM10_64KB  - RESC_GROUP_SRAMS_START] = SYSCTL0_PDSLEEPCFG2_SRAM_IF10_APD_MASK,
181   [kResc_SRAM11_64KB  - RESC_GROUP_SRAMS_START] = SYSCTL0_PDSLEEPCFG2_SRAM_IF11_APD_MASK,
182   [kResc_SRAM12_128KB - RESC_GROUP_SRAMS_START] = SYSCTL0_PDSLEEPCFG2_SRAM_IF12_APD_MASK,
183   [kResc_SRAM13_128KB - RESC_GROUP_SRAMS_START] = SYSCTL0_PDSLEEPCFG2_SRAM_IF13_APD_MASK,
184   [kResc_SRAM14_128KB - RESC_GROUP_SRAMS_START] = SYSCTL0_PDSLEEPCFG2_SRAM_IF14_APD_MASK,
185   [kResc_SRAM15_128KB - RESC_GROUP_SRAMS_START] = SYSCTL0_PDSLEEPCFG2_SRAM_IF15_APD_MASK,
186   [kResc_SRAM16_256KB - RESC_GROUP_SRAMS_START] = SYSCTL0_PDSLEEPCFG2_SRAM_IF16_APD_MASK,
187   [kResc_SRAM17_256KB - RESC_GROUP_SRAMS_START] = SYSCTL0_PDSLEEPCFG2_SRAM_IF17_APD_MASK,
188   [kResc_SRAM18_256KB - RESC_GROUP_SRAMS_START] = SYSCTL0_PDSLEEPCFG2_SRAM_IF18_APD_MASK,
189   [kResc_SRAM19_256KB - RESC_GROUP_SRAMS_START] = SYSCTL0_PDSLEEPCFG2_SRAM_IF19_APD_MASK,
190   [kResc_SRAM20_256KB - RESC_GROUP_SRAMS_START] = SYSCTL0_PDSLEEPCFG2_SRAM_IF20_APD_MASK,
191   [kResc_SRAM21_256KB - RESC_GROUP_SRAMS_START] = SYSCTL0_PDSLEEPCFG2_SRAM_IF21_APD_MASK,
192   [kResc_SRAM22_256KB - RESC_GROUP_SRAMS_START] = SYSCTL0_PDSLEEPCFG2_SRAM_IF22_APD_MASK,
193   [kResc_SRAM23_256KB - RESC_GROUP_SRAMS_START] = SYSCTL0_PDSLEEPCFG2_SRAM_IF23_APD_MASK,
194   [kResc_SRAM24_256KB - RESC_GROUP_SRAMS_START] = SYSCTL0_PDSLEEPCFG2_SRAM_IF24_APD_MASK,
195   [kResc_SRAM25_256KB - RESC_GROUP_SRAMS_START] = SYSCTL0_PDSLEEPCFG2_SRAM_IF25_APD_MASK,
196   [kResc_SRAM26_256KB - RESC_GROUP_SRAMS_START] = SYSCTL0_PDSLEEPCFG2_SRAM_IF26_APD_MASK,
197   [kResc_SRAM27_256KB - RESC_GROUP_SRAMS_START] = SYSCTL0_PDSLEEPCFG2_SRAM_IF27_APD_MASK,
198   [kResc_SRAM28_256KB - RESC_GROUP_SRAMS_START] = SYSCTL0_PDSLEEPCFG2_SRAM_IF28_APD_MASK,
199   [kResc_SRAM29_256KB - RESC_GROUP_SRAMS_START] = SYSCTL0_PDSLEEPCFG2_SRAM_IF29_APD_MASK,
200   [kResc_SRAM30_256KB - RESC_GROUP_SRAMS_START] = SYSCTL0_PDSLEEPCFG2_SRAM_IF30_APD_MASK,
201   [kResc_SRAM31_256KB - RESC_GROUP_SRAMS_START] = SYSCTL0_PDSLEEPCFG2_SRAM_IF31_APD_MASK,
202 };
203 
204 /* Table of PDSLEEPCFG group number and mask for each Peripheral constraint */
205 static const enabled_resources_peripherals_t enResPeripherals[RESC_GROUP_PERIPHERALS_SIZE] =
206 {
207   [kResc_MAIN_CLK      - RESC_GROUP_PERIPHERALS_START] = {0, SYSCTL0_PDSLEEPCFG0_MAINCLK_SHUTOFF_MASK},
208   [kResc_VDDCOREREG_HP - RESC_GROUP_PERIPHERALS_START] = {0, SYSCTL0_PDSLEEPCFG0_VDDCOREREG_LP_MASK  },
209   [kResc_PMCREF_HP     - RESC_GROUP_PERIPHERALS_START] = {0, SYSCTL0_PDSLEEPCFG0_PMCREF_LP_MASK      },
210   [kResc_HVD1V8        - RESC_GROUP_PERIPHERALS_START] = {0, SYSCTL0_PDSLEEPCFG0_HVD1V8_PD_MASK      },
211   [kResc_PORCORE_HP    - RESC_GROUP_PERIPHERALS_START] = {0, SYSCTL0_PDSLEEPCFG0_PORCORE_LP_MASK     },
212   [kResc_LVDCORE_HP    - RESC_GROUP_PERIPHERALS_START] = {0, SYSCTL0_PDSLEEPCFG0_LVDCORE_LP_MASK     },
213   [kResc_HVDCORE       - RESC_GROUP_PERIPHERALS_START] = {0, SYSCTL0_PDSLEEPCFG0_HVDCORE_PD_MASK     },
214   [kResc_SYSXTAL       - RESC_GROUP_PERIPHERALS_START] = {0, SYSCTL0_PDSLEEPCFG0_SYSXTAL_PD_MASK     },
215   [kResc_LPOSC         - RESC_GROUP_PERIPHERALS_START] = {0, SYSCTL0_PDSLEEPCFG0_LPOSC_PD_MASK       },
216   [kResc_FRO           - RESC_GROUP_PERIPHERALS_START] = {0, SYSCTL0_PDSLEEPCFG0_FFRO_PD_MASK        },
217   [kResc_SYSPLLLDO     - RESC_GROUP_PERIPHERALS_START] = {0, SYSCTL0_PDSLEEPCFG0_SYSPLLLDO_PD_MASK   },
218   [kResc_SYSPLLANA     - RESC_GROUP_PERIPHERALS_START] = {0, SYSCTL0_PDSLEEPCFG0_SYSPLLANA_PD_MASK   },
219   [kResc_AUDIOPLLLDO   - RESC_GROUP_PERIPHERALS_START] = {0, SYSCTL0_PDSLEEPCFG0_AUDPLLLDO_PD_MASK   },
220   [kResc_AUDIOPLLANA   - RESC_GROUP_PERIPHERALS_START] = {0, SYSCTL0_PDSLEEPCFG0_AUDPLLANA_PD_MASK   },
221   [kResc_ADC_ACTIVE    - RESC_GROUP_PERIPHERALS_START] = {0, SYSCTL0_PDSLEEPCFG0_ADC_PD_MASK         },
222   [kResc_ADC_TEMP      - RESC_GROUP_PERIPHERALS_START] = {0, SYSCTL0_PDSLEEPCFG0_ADC_TEMPSNS_PD_MASK },
223   [kResc_PMC_TEMP      - RESC_GROUP_PERIPHERALS_START] = {0, SYSCTL0_PDSLEEPCFG0_PMC_TEMPSNS_PD_MASK },
224   [kResc_ACMP          - RESC_GROUP_PERIPHERALS_START] = {0, SYSCTL0_PDSLEEPCFG0_ACMP_PD_MASK        },
225 
226   [kResc_SRAM_PQ       - RESC_GROUP_PERIPHERALS_START] = {1, SYSCTL0_PDSLEEPCFG1_PQ_SRAM_PPD_MASK    },
227   [kResc_SRAM_CASPER   - RESC_GROUP_PERIPHERALS_START] = {1, SYSCTL0_PDSLEEPCFG1_CASPER_SRAM_PPD_MASK},
228   [kResc_DSP           - RESC_GROUP_PERIPHERALS_START] = {1, SYSCTL0_PDSLEEPCFG1_DSP_PD_MASK         },
229   [kResc_MIPIDSI       - RESC_GROUP_PERIPHERALS_START] = {1, SYSCTL0_PDSLEEPCFG1_MIPIDSI_PD_MASK     },
230   [kResc_OTP           - RESC_GROUP_PERIPHERALS_START] = {1, SYSCTL0_PDSLEEPCFG1_OTP_PD_MASK         },
231   [kResc_ROM           - RESC_GROUP_PERIPHERALS_START] = {1, SYSCTL0_PDSLEEPCFG1_ROM_PD_MASK         },
232 };
233 
234 /*******************************************************************************
235  * Code
236  ******************************************************************************/
237 
iMXRT500_EnablePeripheralsDeepSleep(pm_resc_mask_t * pSoftRescMask,pm_resc_group_t * pSysRescGroup,uint32_t * enabledResources)238 static void iMXRT500_EnablePeripheralsDeepSleep(pm_resc_mask_t *pSoftRescMask, pm_resc_group_t *pSysRescGroup, uint32_t *enabledResources)
239 {
240     uint32_t rescMask;
241     uint32_t rescGroup;
242     resc_name_t resc;
243     uint32_t feature;
244 
245     /* Configure Dedicated Peripheral RAMs (PRAMs) */
246     for (resc = RESC_GROUP_PRAMS_START; resc <= RESC_GROUP_PRAMS_END; resc++)
247     {
248         rescMask  = PM_RESC_MASK(pSoftRescMask,  resc);
249         rescGroup = PM_RESC_GROUP(pSysRescGroup, resc);
250         feature = resc - RESC_GROUP_PRAMS_START;
251 
252         if (rescMask && ((rescGroup & PM_RESOURCE_FULL_ON) != 0U))
253         {
254             /* Exclude APD & PPD bits in PDSLEEPCFG1 for each enabled PRAM */
255             enabledResources[1] |= enResPRAMs[feature].apd_mask | enResPRAMs[feature].ppd_mask;
256         }
257         else if (rescMask && ((rescGroup & PM_RESOURCE_PARTABLE_ON1) != 0U))
258         {
259             /* Exclude APD bit in PDSLEEPCFG1 for each retained PRAM */
260             enabledResources[1] |= enResPRAMs[feature].apd_mask;
261         }
262     }
263 
264     /* Configure System RAMs (SRAMs) */
265     for (resc = RESC_GROUP_SRAMS_START; resc <= RESC_GROUP_SRAMS_END; resc++)
266     {
267         rescMask  = PM_RESC_MASK(pSoftRescMask,  resc);
268         rescGroup = PM_RESC_GROUP(pSysRescGroup, resc);
269         feature = resc - RESC_GROUP_SRAMS_START;
270 
271         if (rescMask && ((rescGroup & PM_RESOURCE_FULL_ON) != 0U))
272         {
273             /* Exclude APD bit in PDSLEEPCFG2 & PPD bit in PDSLEEPCFG3 */
274             enabledResources[2] |= enResSRAMs[feature];
275             enabledResources[3] |= enResSRAMs[feature];
276         }
277         else if (rescMask && ((rescGroup & PM_RESOURCE_PARTABLE_ON1) != 0U))
278         {
279             /* Exclude APD bit in PDSLEEPCFG2 */
280             enabledResources[2] |= enResSRAMs[feature];
281         }
282     }
283 
284     /* Configure remaining peripherals with single PDSLEEPCFG bit */
285     for (resc = RESC_GROUP_PERIPHERALS_START; resc <= RESC_GROUP_PERIPHERALS_END; resc++)
286     {
287         rescMask  = PM_RESC_MASK(pSoftRescMask,  resc);
288         rescGroup = PM_RESC_GROUP(pSysRescGroup, resc);
289         feature = resc - RESC_GROUP_PERIPHERALS_START;
290 
291         if (rescMask && ((rescGroup & PM_RESOURCE_FULL_ON) != 0U))
292         {
293             /* Exclude peripheral bit in corresponding PDSLEECFG group */
294             enabledResources[enResPeripherals[feature].group] |= enResPeripherals[feature].mask;
295         }
296     }
297 
298     /* Enable SRAM RBBs */
299     enabledResources[0] |= SYSCTL0_PDSLEEPCFG0_RBB_PD_MASK | SYSCTL0_PDSLEEPCFG0_RBBSRAM_PD_MASK;
300 }
301 
iMXRT500_DisablePeripheralsSleep(pm_resc_mask_t * pSoftRescMask,pm_resc_group_t * pSysRescGroup)302 static void iMXRT500_DisablePeripheralsSleep(pm_resc_mask_t *pSoftRescMask, pm_resc_group_t *pSysRescGroup)
303 {
304     uint32_t rescMask;
305     uint32_t rescGroup;
306     resc_name_t resc;
307     uint32_t feature;
308 
309     /* Configure Dedicated Peripheral RAMs (PRAMs) */
310     for (resc = RESC_GROUP_PRAMS_START; resc <= RESC_GROUP_PRAMS_END; resc++)
311     {
312         rescMask  = PM_RESC_MASK(pSoftRescMask,  resc);
313         rescGroup = PM_RESC_GROUP(pSysRescGroup, resc);
314         feature = resc - RESC_GROUP_PRAMS_START;
315 
316         if(rescMask)
317         {
318             if ((rescGroup & PM_RESOURCE_FULL_ON) != 0U)
319             {
320                 /* Clear APD and PPD bits in PDRUNCFG1 for each enabled PSRAM */
321                 SYSCTL0_PDRCFGCLR_REG(1) = enResPRAMs[feature].apd_mask | enResPRAMs[feature].ppd_mask;
322             }
323             else if ((rescGroup & PM_RESOURCE_PARTABLE_ON1) != 0U)
324             {
325                 /* Clear APD bit in PDRUNCFG1 for each retained PSRAM */
326                 SYSCTL0_PDRCFGCLR_REG(1) = enResPRAMs[feature].apd_mask;
327                 /* Set   PPD bit in PDRUNCFG1 for each retained PSRAM */
328                 SYSCTL0_PDRCFGSET_REG(1) = enResPRAMs[feature].ppd_mask;
329             }
330         }
331         else
332         {
333             /* Set APD and PPD bits in PDRUNCFG1 for each disabled PSRAM */
334             SYSCTL0_PDRCFGSET_REG(1) = enResPRAMs[feature].apd_mask | enResPRAMs[feature].ppd_mask;
335         }
336     }
337 
338     /* Configure System RAMs (SRAMs) */
339     for (resc = RESC_GROUP_SRAMS_START; resc <= RESC_GROUP_SRAMS_END; resc++)
340     {
341         rescMask  = PM_RESC_MASK(pSoftRescMask,  resc);
342         rescGroup = PM_RESC_GROUP(pSysRescGroup, resc);
343         feature = resc - RESC_GROUP_SRAMS_START;
344 
345         if (rescMask)
346         {
347 			if ((rescGroup & PM_RESOURCE_FULL_ON) != 0U)
348             {
349                 /* Clear APD bit in PDRUNCFG2 and PPD bit in PDRUNCFG3 for each enabled SRAM */
350                 SYSCTL0_PDRCFGCLR_REG(2) = enResSRAMs[feature];
351                 SYSCTL0_PDRCFGCLR_REG(3) = enResSRAMs[feature];
352             }
353             else if ((rescGroup & PM_RESOURCE_PARTABLE_ON1) != 0U)
354             {
355                 /* Clear APD bit in PDRUNCFG2 for each retained SRAM */
356                 SYSCTL0_PDRCFGCLR_REG(2) = enResSRAMs[feature];
357                 /* Set   PPD bit in PDRUNCFG3 for each retained SRAM */
358                 SYSCTL0_PDRCFGSET_REG(3) = enResSRAMs[feature];
359             }
360         }
361         else
362         {
363             /* Set APD bit in PDRUNCFG2 and PPD bit in PDRUNCFG3 for each disabled SRAM */
364             SYSCTL0_PDRCFGSET_REG(2) = enResSRAMs[feature];
365             SYSCTL0_PDRCFGSET_REG(3) = enResSRAMs[feature];
366         }
367     }
368 
369     /* Configure remaining peripherals with single PDRUNCFG bit */
370     for (resc = RESC_GROUP_PERIPHERALS_START; resc <= RESC_GROUP_PERIPHERALS_END; resc++)
371     {
372         rescMask  = PM_RESC_MASK(pSoftRescMask,  resc);
373         rescGroup = PM_RESC_GROUP(pSysRescGroup, resc);
374         feature = resc - RESC_GROUP_PERIPHERALS_START;
375 
376         if (rescMask && ((rescGroup & PM_RESOURCE_FULL_ON) != 0U))
377         {
378             /* Clear peripheral bit in corresponding PDRUNCFG register */
379             SYSCTL0_PDRCFGCLR_REG(enResPeripherals[feature].group) = enResPeripherals[feature].mask;
380         }
381         else
382         {
383             /* Set peripheral bit in corresponding PDRUNCFG register */
384             SYSCTL0_PDRCFGSET_REG(enResPeripherals[feature].group) = enResPeripherals[feature].mask;
385         }
386     }
387 
388     /* Configure OTP Switch RBB, since not calling POWER_EnablePD/POWER_DisablePD() */
389     rescMask  = PM_RESC_MASK(pSoftRescMask,  kResc_OTP);
390     rescGroup = PM_RESC_GROUP(pSysRescGroup, kResc_OTP);
391 
392     if (rescMask && ((rescGroup & PM_RESOURCE_FULL_ON) != 0U))
393     {
394         PMC->CTRL &= ~PMC_CTRL_OTPSWREN_MASK; /* Disable RBB for OTP switch */
395     }
396     else
397     {
398         PMC->CTRL |= PMC_CTRL_OTPSWREN_MASK; /* Enable RBB for OTP switch */
399     }
400 
401 	POWER_ApplyPD();
402 }
403 
IMXRT500_EnterLowPowerMode(uint8_t stateIndex,pm_resc_mask_t * pSoftRescMask,pm_resc_group_t * pSysRescGroup)404 static void IMXRT500_EnterLowPowerMode(uint8_t stateIndex, pm_resc_mask_t *pSoftRescMask, pm_resc_group_t *pSysRescGroup)
405 {
406 	uint32_t enabledResources[4] = {0, 0, 0, 0}; /* SYSPDSLEEPCFG0-3 */
407 
408 	assert(pSoftRescMask != NULL);
409     assert(pSysRescGroup != NULL);
410 
411     switch (stateIndex)
412     {
413         case PM_LP_STATE_SLEEP:
414         /*
415          * Change SYSPDRUNCFG depending on constraints, POWER_EnablePD then POWER_ApplyPD
416          */
417 			iMXRT500_DisablePeripheralsSleep(pSoftRescMask, pSysRescGroup);
418 			break;
419         case PM_LP_STATE_DEEP_SLEEP:
420         /*
421          * Change SYSPDSLEEPCFG depending on constraints
422          */
423 			iMXRT500_EnablePeripheralsDeepSleep(pSoftRescMask, pSysRescGroup, enabledResources);
424 			break;
425         case PM_LP_STATE_DEEP_POWER_DOWN:
426         /*
427          * Do nothing
428          */
429 			break;
430         case PM_LP_STATE_FULL_DEEP_POWER_DOWN:
431         /*
432          * Do nothing
433          */
434 			break;
435         default:
436             return;
437     }
438     POWER_EnterPowerMode((power_mode_cfg_t)stateIndex, enabledResources);
439 }
440 
IMXRT500_CleanExitLowPowerMode(void)441 static void IMXRT500_CleanExitLowPowerMode(void)
442 {
443 	/* Do nothing. */
444 }
445 
IMXRT500_ManageWakeupSource(pm_wakeup_source_t * ws,bool enable)446 static status_t IMXRT500_ManageWakeupSource(pm_wakeup_source_t *ws, bool enable)
447 {
448 	uint32_t irqn;
449     uint32_t misc;
450 
451     (void)(misc);
452 
453     assert(ws != NULL);
454     PM_DECODE_WAKEUP_SOURCE_ID(ws->wsId);
455 
456     if (enable)
457     {
458 		EnableDeepSleepIRQ((IRQn_Type)irqn);
459     }
460     else
461     {
462 		DisableDeepSleepIRQ((IRQn_Type)irqn);
463     }
464     return kStatus_Success;
465 }
466