1 /*
2  * Copyright 2024 NXP
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include "fsl_pm_core.h"
8 #include "fsl_pm_device.h"
9 
10 #include "fsl_clock.h"
11 #include "fsl_power.h"
12 
13 /*******************************************************************************
14  * Macros
15  ******************************************************************************/
16 #if defined(PMC0)
17 #define PMC_PDRCFG_REG(x)    (*((volatile uint32_t *)((uint32_t)(&(PMC0->PDRUNCFG0)) + ((uint32_t)(x) << 2U))))
18 #define SLEEPCON_RCFGSET_REG (SLEEPCON0->RUNCFG_SET)
19 #define SLEEPCON_RCFGCLR_REG (SLEEPCON0->RUNCFG_CLR)
20 #else
21 #define PMC_PDRCFG_REG(x)    (*((volatile uint32_t *)((uint32_t)(&(PMC1->PDRUNCFG0)) + ((uint32_t)(x) << 2U))))
22 #define SLEEPCON_RCFGSET_REG (SLEEPCON1->RUNCFG_SET)
23 #define SLEEPCON_RCFGCLR_REG (SLEEPCON1->RUNCFG_CLR)
24 #endif
25 
26 /*******************************************************************************
27  * Prototypes
28  ******************************************************************************/
29 static void PM_DEV_EnterLowPowerMode(uint8_t stateIndex, pm_resc_mask_t *pSoftRescMask, pm_resc_group_t *pSysRescGroup);
30 static void PM_DEV_CleanExitLowPowerMode(void);
31 static void PM_DEV_EnablePeripheralsDeepSleep(pm_resc_mask_t *pSoftRescMask,
32                                               pm_resc_group_t *pSysRescGroup,
33                                               uint32_t *enabledResources);
34 static void PM_DEV_DisablePeripheralsSleep(pm_resc_mask_t *pSoftRescMask, pm_resc_group_t *pSysRescGroup);
35 
36 #if (defined(FSL_PM_SUPPORT_WAKEUP_SOURCE_MANAGER) && FSL_PM_SUPPORT_WAKEUP_SOURCE_MANAGER)
37 static status_t PM_DEV_ManageWakeupSource(pm_wakeup_source_t *ws, bool enable);
38 #endif /* FSL_PM_SUPPORT_WAKEUP_SOURCE_MANAGER */
39 /*******************************************************************************
40  * Variables
41  ******************************************************************************/
42 /*!
43  *  |  Module         |    Sleep     | Deep Sleep |    Full DSR   | Deep Power Down | Full Deep Power Down |
44  *  | COMP_MAINCLK    |    ON/OFF    |   ON/OFF   |      OFF      |      OFF        |       OFF            |
45  *  | SENSEP_MAINCLK  |    ON/OFF    |   ON/OFF   |      OFF      |      OFF        |       OFF            |
46  *  | SENSES_MAINCLK  |    ON/OFF    |   ON/OFF   |      OFF      |      OFF        |       OFF            |
47  *  | RAM0CLK         |    ON/OFF    |   ON/OFF   |      OFF      |      OFF        |       OFF            |
48  *  | RAM1CLK         |    ON/OFF    |   ON/OFF   |      OFF      |      OFF        |       OFF            |
49  *  | COMN_MAINCLK    |    ON/OFF    |   ON/OFF   |      OFF      |      OFF        |       OFF            |
50  *  | MEDIA_MAINCLK   |    ON/OFF    |   ON/OFF   |      OFF      |      OFF        |       OFF            |
51  *  | XTAL            |    ON/OFF    |   ON/OFF   |      OFF      |      OFF        |       OFF            |
52  *  | FRO0            |    ON/OFF    |   ON/OFF   |      OFF      |      OFF        |       OFF            |
53  *  | FRO1            |    ON/OFF    |   ON/OFF   |      OFF      |      OFF        |       OFF            |
54  *  | FRO2            |    ON/OFF    |   ON/OFF   |      OFF      |      OFF        |       OFF            |
55  *  | LPOSC           |    ON/OFF    |   ON/OFF   |      OFF      |      OFF        |       OFF            |
56  *  | MAIN PLL        |    ON/OFF    |   ON/OFF   |      OFF      |      OFF        |       OFF            |
57  *  | AUDIO PLL       |    ON/OFF    |   ON/OFF   |      OFF      |      OFF        |       OFF            |
58  *  | ADC0            |    ON/OFF    |   ON/OFF   |      OFF      |      OFF        |       OFF            |
59  *  | FRO0_EN         |    EN/GATE   |   EN/GATE  |    EN/GATE    |      OFF        |       OFF            |
60  *  | FRO2_EN         |    EN/GATE   |   EN/GATE  |    EN/GATE    |      OFF        |       OFF            |
61  *  | V2NMED          |    ON/OFF    |   ON/OFF   |      OFF      |      OFF        |       OFF            |
62  *  | VNCOM           |    ON/OFF    |   ON/OFF   |      OFF      |      OFF        |       OFF            |
63  *  | V2DSP           |    ON/OFF    |   ON/OFF   |      OFF      |      OFF        |       OFF            |
64  *  | V2MIPI          |    ON/OFF    |   ON/OFF   |      OFF      |      OFF        |       OFF            |
65  *  | DCDC_HP         |    HP/LP     |   HP/LP    |      OFF      |      OFF        |       OFF            |
66  *  | PMC_TEMP        |    ON/OFF    |   ON/OFF   |      OFF      |      OFF        |       OFF            |
67  *  | PMCREF_HP       |    HP/LP     |   HP/LP    |      OFF      |      OFF        |       OFF            |
68  *  | HVD1V8          |    ON/OFF    |   ON/OFF   |      OFF      |      OFF        |       OFF            |
69  *  | PORVDD1_HP      |    HP/LP     |   HP/LP    |      OFF      |      OFF        |       OFF            |
70  *  | LVDVDD1_HP      |    HP/LP     |   HP/LP    |      OFF      |      OFF        |       OFF            |
71  *  | HVDVDD1         |    ON/OFF    |   ON/OFF   |      OFF      |      OFF        |       OFF            |
72  *  | AGDET1          |    ON/OFF    |   ON/OFF   |      OFF      |      OFF        |       OFF            |
73  *  | PORVDD2_HP      |    HP/LP     |   HP/LP    |      OFF      |      OFF        |       OFF            |
74  *  | LVDVDD2_HP      |    HP/LP     |   HP/LP    |      OFF      |      OFF        |       OFF            |
75  *  | HVDVDD2         |    ON/OFF    |   ON/OFF   |      OFF      |      OFF        |       OFF            |
76  *  | AGDET2          |    ON/OFF    |   ON/OFF   |      OFF      |      OFF        |       OFF            |
77  *  | PORVDDN_HP      |    HP/LP     |   HP/LP    |      OFF      |      OFF        |       OFF            |
78  *  | LVDVDDN_HP      |    HP/LP     |   HP/LP    |      OFF      |      OFF        |       OFF            |
79  *  | HVDVDDN         |    ON/OFF    |   ON/OFF   |      OFF      |      OFF        |       OFF            |
80  *  | OTP             |    ON/OFF    |   ON/OFF   |      OFF      |      OFF        |       OFF            |
81  *  | ROM             |    ON/OFF    |   ON/OFF   |      OFF      |      OFF        |       OFF            |
82  *  | PORVDDN_HP      |    HP/LP     |   HP/LP    |      OFF      |      OFF        |       OFF            |
83  *  | LVDVDDN_HP      |    HP/LP     |   HP/LP    |      OFF      |      OFF        |       OFF            |
84  *  | HVDVDDN         |    ON/OFF    |   ON/OFF   |      OFF      |      OFF        |       OFF            |
85  *  | OTP             |    ON/OFF    |   ON/OFF   |      OFF      |      OFF        |       OFF            |
86  *  | ROM             |    ON/OFF    |   ON/OFF   |      OFF      |      OFF        |       OFF            |
87  *  | SRAM0-29        |   ON/RET/OFF | ON/RET/OFF |    RET/OFF    |      OFF        |       OFF            |
88  *  | USDHC0-1 RAM    |   ON/RET/OFF | ON/RET/OFF |    RET/OFF    |      OFF        |       OFF            |
89  *  | USB0-1 RAM      |   ON/RET/OFF | ON/RET/OFF |      OFF      |      OFF        |       OFF            |
90  *  | JPEGDEC RAM     |   ON/RET/OFF | ON/RET/OFF |      OFF      |      OFF        |       OFF            |
91  *  | PNGDEC RAM      |   ON/RET/OFF | ON/RET/OFF |      OFF      |      OFF        |       OFF            |
92  *  | MIPI-DSI RAM    |   ON/RET/OFF | ON/RET/OFF |    RET/OFF    |      OFF        |       OFF            |
93  *  | GPU RAM         |   ON/RET/OFF | ON/RET/OFF |      OFF      |      OFF        |       OFF            |
94  *  | DMA2-3 RAM      |   ON/RET/OFF | ON/RET/OFF |      OFF      |      OFF        |       OFF            |
95  *  | DMA0-1 RAM      |   ON/RET/OFF | ON/RET/OFF |      OFF      |      OFF        |       OFF            |
96  *  | CPU0 code cache |   ON/RET/OFF | ON/RET/OFF |      OFF      |      OFF        |       OFF            |
97  *  | CPU0 data cache |   ON/RET/OFF | ON/RET/OFF |      OFF      |      OFF        |       OFF            |
98  *  | HiFi4 ICache    |   ON/RET/OFF | ON/RET/OFF |      OFF      |      OFF        |       OFF            |
99  *  | HiFi4 DCache    |   ON/RET/OFF | ON/RET/OFF |      OFF      |      OFF        |       OFF            |
100  *  | HiFi4 ITCM      |   ON/RET/OFF | ON/RET/OFF |      OFF      |      OFF        |       OFF            |
101  *  | HiFi4 DTCM      |   ON/RET/OFF | ON/RET/OFF |      OFF      |      OFF        |       OFF            |
102  *  | EZHV RAM        |   ON/RET/OFF | ON/RET/OFF |      OFF      |      OFF        |       OFF            |
103  *  | NPU             |   ON/RET/OFF | ON/RET/OFF |      OFF      |      OFF        |       OFF            |
104  *  | XSPI0-2         |   ON/RET/OFF | ON/RET/OFF |    RET/OFF    |      OFF        |       OFF            |
105  *  | LCDIF RAM       |   ON/RET/OFF | ON/RET/OFF |    RET/OFF    |      OFF        |       OFF            |
106  *  | OCOTP RAM       |   ON/RET/OFF | ON/RET/OFF |    RET/OFF    |      OFF        |       OFF            |
107  */
108 
109 const pm_device_option_t g_devicePMOption = {
110     .states =
111         {
112             /* Sleep */
113             {
114                 .fixConstraintsMask =
115                     {
116                         .rescMask[0U] = 0x00000000UL,
117                         .rescMask[1U] = 0x00000000UL,
118                         .rescMask[2U] = 0x0UL,
119                     },
120                 .varConstraintsMask =
121                     {
122                         .rescMask[0U] = 0xFFFFFFFFUL,
123                         .rescMask[1U] = 0xFFFFFFFFUL,
124                         .rescMask[2U] = 0xFFFFFFFFUL,
125                     },
126             },
127             /* Deep Sleep */
128             {
129                 .fixConstraintsMask =
130                     {
131                         .rescMask[0U] = 0x00000000UL,
132                         .rescMask[1U] = 0x00000000UL,
133                         .rescMask[2U] = 0x0UL,
134                     },
135                 .varConstraintsMask =
136                     {
137                         .rescMask[0U] = 0xFFFFFFFFUL,
138                         .rescMask[1U] = 0xFFFFFFFFUL,
139                         .rescMask[2U] = 0xFFFFFFFFUL,
140                     },
141             },
142             /* DSR */
143             {
144                 .fixConstraintsMask =
145                     {
146                         .rescMask[0U] = 0x00000000UL,
147                         .rescMask[1U] = 0x00000000UL,
148                         .rescMask[2U] = 0x0UL,
149                     },
150                 .varConstraintsMask =
151                     {
152                         .rescMask[0U] = 0xFFFFFFFFUL,
153                         .rescMask[1U] = 0xFFFFFFFFUL,
154                         .rescMask[2U] = 0xFFFFFFFFUL,
155                     },
156             },
157             /* Deep Power Down */
158             {
159                 .fixConstraintsMask =
160                     {
161                         .rescMask[0U] = 0xFFFFFFFFUL,
162                         .rescMask[1U] = 0xFFFFFFFFUL,
163                         .rescMask[2U] = 0xFFFFFFFFUL,
164                     },
165                 .varConstraintsMask =
166                     {
167                         .rescMask[0U] = 0x0UL,
168                         .rescMask[1U] = 0x0UL,
169                         .rescMask[2U] = 0x0UL,
170                     },
171             },
172             /* Full Deep Power Down */
173             {
174                 .fixConstraintsMask =
175                     {
176                         .rescMask[0U] = 0xFFFFFFFFUL,
177                         .rescMask[1U] = 0xFFFFFFFFUL,
178                         .rescMask[2U] = 0xFFFFFFFFUL,
179                     },
180                 .varConstraintsMask =
181                     {
182                         .rescMask[0U] = 0x0UL,
183                         .rescMask[1U] = 0x0UL,
184                         .rescMask[2U] = 0x0UL,
185                     },
186             },
187         },
188     .stateCount = PM_LP_STATE_COUNT,
189     .enter      = PM_DEV_EnterLowPowerMode,
190     .clean      = PM_DEV_CleanExitLowPowerMode,
191 
192 #if (defined(FSL_PM_SUPPORT_WAKEUP_SOURCE_MANAGER) && FSL_PM_SUPPORT_WAKEUP_SOURCE_MANAGER)
193     .manageWakeupSource = PM_DEV_ManageWakeupSource,
194 #endif /* FSL_PM_SUPPORT_WAKEUP_SOURCE_MANAGER */
195 };
196 
197 /* PDSLEEPCFG masks for each System SRAM resource constraint */
198 static const enabled_resources_t enResSRAMs[RESC_GROUP_SRAMS_SIZE] = {
199     [kResc_SRAM0_32KB - RESC_GROUP_SRAMS_START]   = {3U, PMC_PDSLEEPCFG2_SRAM0_MASK},
200     [kResc_SRAM1_32KB - RESC_GROUP_SRAMS_START]   = {3U, PMC_PDSLEEPCFG2_SRAM1_MASK},
201     [kResc_SRAM2_32KB - RESC_GROUP_SRAMS_START]   = {3U, PMC_PDSLEEPCFG2_SRAM2_MASK},
202     [kResc_SRAM3_32KB - RESC_GROUP_SRAMS_START]   = {3U, PMC_PDSLEEPCFG2_SRAM3_MASK},
203     [kResc_SRAM4_64KB - RESC_GROUP_SRAMS_START]   = {3U, PMC_PDSLEEPCFG2_SRAM4_MASK},
204     [kResc_SRAM5_64KB - RESC_GROUP_SRAMS_START]   = {3U, PMC_PDSLEEPCFG2_SRAM5_MASK},
205     [kResc_SRAM6_128KB - RESC_GROUP_SRAMS_START]  = {3U, PMC_PDSLEEPCFG2_SRAM6_MASK},
206     [kResc_SRAM7_128KB - RESC_GROUP_SRAMS_START]  = {3U, PMC_PDSLEEPCFG2_SRAM7_MASK},
207     [kResc_SRAM8_256KB - RESC_GROUP_SRAMS_START]  = {3U, PMC_PDSLEEPCFG2_SRAM8_MASK},
208     [kResc_SRAM9_256KB - RESC_GROUP_SRAMS_START]  = {3U, PMC_PDSLEEPCFG2_SRAM9_MASK},
209     [kResc_SRAM10_512KB - RESC_GROUP_SRAMS_START] = {3U, PMC_PDSLEEPCFG2_SRAM10_MASK},
210     [kResc_SRAM11_512KB - RESC_GROUP_SRAMS_START] = {3U, PMC_PDSLEEPCFG2_SRAM11_MASK},
211     [kResc_SRAM12_1MB - RESC_GROUP_SRAMS_START]   = {3U, PMC_PDSLEEPCFG2_SRAM12_MASK},
212     [kResc_SRAM13_1MB - RESC_GROUP_SRAMS_START]   = {3U, PMC_PDSLEEPCFG2_SRAM13_MASK},
213     [kResc_SRAM14_512KB - RESC_GROUP_SRAMS_START] = {3U, PMC_PDSLEEPCFG2_SRAM14_MASK},
214     [kResc_SRAM15_512KB - RESC_GROUP_SRAMS_START] = {3U, PMC_PDSLEEPCFG2_SRAM15_MASK},
215     [kResc_SRAM16_256KB - RESC_GROUP_SRAMS_START] = {3U, PMC_PDSLEEPCFG2_SRAM16_MASK},
216     [kResc_SRAM17_256KB - RESC_GROUP_SRAMS_START] = {3U, PMC_PDSLEEPCFG2_SRAM17_MASK},
217     [kResc_SRAM18_32KB - RESC_GROUP_SRAMS_START]  = {3U, PMC_PDSLEEPCFG2_SRAM18_MASK},
218     [kResc_SRAM19_32KB - RESC_GROUP_SRAMS_START]  = {3U, PMC_PDSLEEPCFG2_SRAM19_MASK},
219     [kResc_SRAM20_32KB - RESC_GROUP_SRAMS_START]  = {3U, PMC_PDSLEEPCFG2_SRAM20_MASK},
220     [kResc_SRAM21_32KB - RESC_GROUP_SRAMS_START]  = {3U, PMC_PDSLEEPCFG2_SRAM21_MASK},
221     [kResc_SRAM22_64KB - RESC_GROUP_SRAMS_START]  = {3U, PMC_PDSLEEPCFG2_SRAM22_MASK},
222     [kResc_SRAM23_64KB - RESC_GROUP_SRAMS_START]  = {3U, PMC_PDSLEEPCFG2_SRAM23_MASK},
223     [kResc_SRAM24_128KB - RESC_GROUP_SRAMS_START] = {3U, PMC_PDSLEEPCFG2_SRAM24_MASK},
224     [kResc_SRAM25_128KB - RESC_GROUP_SRAMS_START] = {3U, PMC_PDSLEEPCFG2_SRAM25_MASK},
225     [kResc_SRAM26_512KB - RESC_GROUP_SRAMS_START] = {3U, PMC_PDSLEEPCFG2_SRAM26_MASK},
226     [kResc_SRAM27_512KB - RESC_GROUP_SRAMS_START] = {3U, PMC_PDSLEEPCFG2_SRAM27_MASK},
227     [kResc_SRAM28_256KB - RESC_GROUP_SRAMS_START] = {3U, PMC_PDSLEEPCFG2_SRAM28_MASK},
228     [kResc_SRAM29_256KB - RESC_GROUP_SRAMS_START] = {3U, PMC_PDSLEEPCFG2_SRAM29_MASK},
229 
230     [kResc_SRAM_USDHC0 - RESC_GROUP_SRAMS_START]      = {5U, PMC_PDSLEEPCFG4_SDHC0_SRAM_MASK},
231     [kResc_SRAM_USDHC1 - RESC_GROUP_SRAMS_START]      = {5U, PMC_PDSLEEPCFG4_SDHC1_SRAM_MASK},
232     [kResc_SRAM_USB0 - RESC_GROUP_SRAMS_START]        = {5U, PMC_PDSLEEPCFG4_USB0_SRAM_MASK},
233     [kResc_SRAM_USB1 - RESC_GROUP_SRAMS_START]        = {5U, PMC_PDSLEEPCFG4_USB1_SRAM_MASK},
234     [kResc_SRAM_JPEGDEC - RESC_GROUP_SRAMS_START]     = {5U, PMC_PDSLEEPCFG4_JPEG_MASK},
235     [kResc_SRAM_PNGDEC - RESC_GROUP_SRAMS_START]      = {5U, PMC_PDSLEEPCFG4_PNG_MASK},
236     [kResc_SRAM_MIPI - RESC_GROUP_SRAMS_START]        = {5U, PMC_PDSLEEPCFG4_MIPI_MASK},
237     [kResc_SRAM_GPU - RESC_GROUP_SRAMS_START]         = {5U, PMC_PDSLEEPCFG4_GPU_MASK},
238     [kResc_SRAM_DMA23 - RESC_GROUP_SRAMS_START]       = {5U, PMC_PDSLEEPCFG4_DMA2_3_MASK},
239     [kResc_SRAM_DMA01PE - RESC_GROUP_SRAMS_START]     = {5U, PMC_PDSLEEPCFG4_DMA0_1_P_E_MASK},
240     [kResc_SRAM_CPU0_ICACHE - RESC_GROUP_SRAMS_START] = {5U, PMC_PDSLEEPCFG4_CPU0_CCACHE_MASK},
241     [kResc_SRAM_CPU0_DCACHE - RESC_GROUP_SRAMS_START] = {5U, PMC_PDSLEEPCFG4_CPU0_SCACHE_MASK},
242     [kResc_SRAM_DSP_ICACHE - RESC_GROUP_SRAMS_START]  = {5U, PMC_PDSLEEPCFG4_DSP_ICACHE_MASK},
243     [kResc_SRAM_DSP_DCACHE - RESC_GROUP_SRAMS_START]  = {5U, PMC_PDSLEEPCFG4_DSP_DCACHE_MASK},
244     [kResc_SRAM_DSP_ITCM - RESC_GROUP_SRAMS_START]    = {5U, PMC_PDSLEEPCFG4_DSP_ITCM_MASK},
245     [kResc_SRAM_DSP_DTCM - RESC_GROUP_SRAMS_START]    = {5U, PMC_PDSLEEPCFG4_DSP_DTCM_MASK},
246     [kResc_SRAM_EZHV - RESC_GROUP_SRAMS_START]        = {5U, PMC_PDSLEEPCFG4_EZH_TCM_MASK},
247     [kResc_SRAM_NPU - RESC_GROUP_SRAMS_START]         = {5U, PMC_PDSLEEPCFG4_NPU_MASK},
248     [kResc_SRAM_XSPI0 - RESC_GROUP_SRAMS_START]       = {5U, PMC_PDSLEEPCFG4_XSPI0_MASK},
249     [kResc_SRAM_XSPI1 - RESC_GROUP_SRAMS_START]       = {5U, PMC_PDSLEEPCFG4_XSPI1_MASK},
250     [kResc_SRAM_XSPI2 - RESC_GROUP_SRAMS_START]       = {5U, PMC_PDSLEEPCFG4_XSPI2_MASK},
251     [kResc_SRAM_LCDIF - RESC_GROUP_SRAMS_START]       = {5U, PMC_PDSLEEPCFG4_LCD_MASK},
252     [kResc_SRAM_OCOTP - RESC_GROUP_SRAMS_START]       = {5U, PMC_PDSLEEPCFG4_OCOTP_MASK},
253 };
254 
255 /* Table of PDSLEEPCFG group number and mask for each Peripheral constraint */
256 static const enabled_resources_t enResPeripherals[RESC_GROUP_PERIPHERALS_SIZE] = {
257 #if defined(PMC0)
258     [kResc_COMP_MAINCLK - RESC_GROUP_PERIPHERALS_START]   = {0U, SLEEPCON0_SLEEPCFG_COMP_MAINCLK_SHUTOFF_MASK},
259     [kResc_SENSEP_MAINCLK - RESC_GROUP_PERIPHERALS_START] = {0U, SLEEPCON0_SLEEPCFG_SENSEP_MAINCLK_SHUTOFF_MASK},
260     [kResc_SENSES_MAINCLK - RESC_GROUP_PERIPHERALS_START] = {0U, SLEEPCON0_SLEEPCFG_SENSES_MAINCLK_SHUTOFF_MASK},
261     [kResc_RAM0CLK - RESC_GROUP_PERIPHERALS_START]        = {0U, SLEEPCON0_SLEEPCFG_RAM0_CLK_SHUTOFF_MASK},
262     [kResc_RAM1CLK - RESC_GROUP_PERIPHERALS_START]        = {0U, SLEEPCON0_SLEEPCFG_RAM1_CLK_SHUTOFF_MASK},
263     [kResc_COMN_MAINCLK - RESC_GROUP_PERIPHERALS_START]   = {0U, SLEEPCON0_SLEEPCFG_COMN_MAINCLK_SHUTOFF_MASK},
264     [kResc_MEDIA_MAINCLK - RESC_GROUP_PERIPHERALS_START]  = {0U, SLEEPCON0_SLEEPCFG_MEDIA_MAINCLK_SHUTOFF_MASK},
265     [kResc_XTAL - RESC_GROUP_PERIPHERALS_START]           = {0U, SLEEPCON0_SLEEPCFG_XTAL_PD_MASK},
266     [kResc_FRO0 - RESC_GROUP_PERIPHERALS_START]           = {0U, SLEEPCON0_SLEEPCFG_FRO0_PD_MASK},
267     [kResc_FRO1 - RESC_GROUP_PERIPHERALS_START]           = {0U, SLEEPCON0_SLEEPCFG_FRO1_PD_MASK},
268     [kResc_FRO2 - RESC_GROUP_PERIPHERALS_START]           = {0U, SLEEPCON0_SLEEPCFG_FRO2_PD_MASK},
269     [kResc_LPOSC - RESC_GROUP_PERIPHERALS_START]          = {0U, SLEEPCON0_SLEEPCFG_LPOSC_PD_MASK},
270     [kResc_PLLANA - RESC_GROUP_PERIPHERALS_START]         = {0U, SLEEPCON0_SLEEPCFG_PLLANA_PD_MASK},
271     [kResc_PLLLDO - RESC_GROUP_PERIPHERALS_START]         = {0U, SLEEPCON0_SLEEPCFG_PLLLDO_PD_MASK},
272     [kResc_AUDPLLANA - RESC_GROUP_PERIPHERALS_START]      = {0U, SLEEPCON0_SLEEPCFG_AUDPLLANA_PD_MASK},
273     [kResc_ADC0 - RESC_GROUP_PERIPHERALS_START]           = {0U, SLEEPCON0_SLEEPCFG_ADC0_PD_MASK},
274 #else
275     [kResc_SENSEP_MAINCLK - RESC_GROUP_PERIPHERALS_START] = {0U, SLEEPCON1_SLEEPCFG_SENSEP_MAINCLK_SHUTOFF_MASK},
276     [kResc_SENSES_MAINCLK - RESC_GROUP_PERIPHERALS_START] = {0U, SLEEPCON1_SLEEPCFG_SENSES_MAINCLK_SHUTOFF_MASK},
277     [kResc_RAM0CLK - RESC_GROUP_PERIPHERALS_START]        = {0U, SLEEPCON1_SLEEPCFG_RAM0_CLK_SHUTOFF_MASK},
278     [kResc_RAM1CLK - RESC_GROUP_PERIPHERALS_START]        = {0U, SLEEPCON1_SLEEPCFG_RAM1_CLK_SHUTOFF_MASK},
279     [kResc_COMN_MAINCLK - RESC_GROUP_PERIPHERALS_START]   = {0U, SLEEPCON1_SLEEPCFG_COMN_MAINCLK_SHUTOFF_MASK},
280     [kResc_MEDIA_MAINCLK - RESC_GROUP_PERIPHERALS_START]  = {0U, SLEEPCON1_SLEEPCFG_MEDIA_MAINCLK_SHUTOFF_MASK},
281     [kResc_XTAL - RESC_GROUP_PERIPHERALS_START]           = {0U, SLEEPCON1_SLEEPCFG_XTAL_PD_MASK},
282     [kResc_FRO2 - RESC_GROUP_PERIPHERALS_START]           = {0U, SLEEPCON1_SLEEPCFG_FRO2_PD_MASK},
283     [kResc_LPOSC - RESC_GROUP_PERIPHERALS_START]          = {0U, SLEEPCON1_SLEEPCFG_LPOSC_PD_MASK},
284     [kResc_PLLANA - RESC_GROUP_PERIPHERALS_START]         = {0U, SLEEPCON1_SLEEPCFG_PLLANA_PD_MASK},
285     [kResc_PLLLDO - RESC_GROUP_PERIPHERALS_START]         = {0U, SLEEPCON1_SLEEPCFG_PLLLDO_PD_MASK},
286     [kResc_AUDPLLANA - RESC_GROUP_PERIPHERALS_START]      = {0U, SLEEPCON1_SLEEPCFG_AUDPLLANA_PD_MASK},
287     [kResc_ADC0 - RESC_GROUP_PERIPHERALS_START]           = {0U, SLEEPCON1_SLEEPCFG_ADC0_PD_MASK},
288 #endif
289 
290     [kResc_V2NMED - RESC_GROUP_PERIPHERALS_START]  = {1U, PMC_PDSLEEPCFG0_V2NMED_DSR_MASK},
291     [kResc_VNCOM - RESC_GROUP_PERIPHERALS_START]   = {1U, PMC_PDSLEEPCFG0_VNCOM_DSR_MASK},
292     [kResc_V2DSP - RESC_GROUP_PERIPHERALS_START]   = {1U, PMC_PDSLEEPCFG0_V2DSP_PD_MASK},
293     [kResc_V2MIPI - RESC_GROUP_PERIPHERALS_START]  = {1U, PMC_PDSLEEPCFG0_V2MIPI_PD_MASK},
294     [kResc_DCDC_HP - RESC_GROUP_PERIPHERALS_START] = {1U, PMC_PDSLEEPCFG0_DCDC_LP_MASK},
295 
296     [kResc_PMC_TEMP - RESC_GROUP_PERIPHERALS_START]   = {2U, PMC_PDSLEEPCFG1_TEMP_PD_MASK},
297     [kResc_PMCREF_HP - RESC_GROUP_PERIPHERALS_START]  = {2U, PMC_PDSLEEPCFG1_PMCREF_LP_MASK},
298     [kResc_HVD1V8 - RESC_GROUP_PERIPHERALS_START]     = {2U, PMC_PDSLEEPCFG1_HVD1V8_PD_MASK},
299     [kResc_PORVDD1_HP - RESC_GROUP_PERIPHERALS_START] = {2U, PMC_PDSLEEPCFG1_POR1_LP_MASK},
300     [kResc_LVDVDD1_HP - RESC_GROUP_PERIPHERALS_START] = {2U, PMC_PDSLEEPCFG1_LVD1_LP_MASK},
301     [kResc_HVDVDD1 - RESC_GROUP_PERIPHERALS_START]    = {2U, PMC_PDSLEEPCFG1_HVD1_PD_MASK},
302     [kResc_AGDET1 - RESC_GROUP_PERIPHERALS_START]     = {2U, PMC_PDSLEEPCFG1_AGDET1_PD_MASK},
303     [kResc_PORVDD2_HP - RESC_GROUP_PERIPHERALS_START] = {2U, PMC_PDSLEEPCFG1_POR2_LP_MASK},
304     [kResc_LVDVDD2_HP - RESC_GROUP_PERIPHERALS_START] = {2U, PMC_PDSLEEPCFG1_LVD2_LP_MASK},
305     [kResc_HVDVDD2 - RESC_GROUP_PERIPHERALS_START]    = {2U, PMC_PDSLEEPCFG1_HVD2_PD_MASK},
306     [kResc_AGDET2 - RESC_GROUP_PERIPHERALS_START]     = {2U, PMC_PDSLEEPCFG1_AGDET2_PD_MASK},
307     [kResc_PORVDDN_HP - RESC_GROUP_PERIPHERALS_START] = {2U, PMC_PDSLEEPCFG1_PORN_LP_MASK},
308     [kResc_LVDVDDN_HP - RESC_GROUP_PERIPHERALS_START] = {2U, PMC_PDSLEEPCFG1_LVDN_LP_MASK},
309     [kResc_HVDVDDN - RESC_GROUP_PERIPHERALS_START]    = {2U, PMC_PDSLEEPCFG1_HVDN_PD_MASK},
310     [kResc_OTP - RESC_GROUP_PERIPHERALS_START]        = {2U, PMC_PDSLEEPCFG1_OTP_PD_MASK},
311     [kResc_ROM - RESC_GROUP_PERIPHERALS_START]        = {2U, PMC_PDSLEEPCFG1_ROM_PD_MASK},
312 };
313 
314 /*******************************************************************************
315  * Code
316  ******************************************************************************/
317 
PM_DEV_EnablePeripheralsDeepSleep(pm_resc_mask_t * pSoftRescMask,pm_resc_group_t * pSysRescGroup,uint32_t * enabledResources)318 static void PM_DEV_EnablePeripheralsDeepSleep(pm_resc_mask_t *pSoftRescMask,
319                                               pm_resc_group_t *pSysRescGroup,
320                                               uint32_t *enabledResources)
321 {
322     uint32_t rescMask;
323     uint32_t rescGroup;
324     resc_name_t resc;
325     uint32_t feature;
326 
327     /* Configure System RAMs */
328     for (resc = RESC_GROUP_SRAMS_START; resc <= RESC_GROUP_SRAMS_END; resc++)
329     {
330         rescMask  = PM_RESC_MASK(pSoftRescMask, resc);
331         rescGroup = PM_RESC_GROUP(pSysRescGroup, resc);
332         feature   = (uint32_t)resc - (uint32_t)RESC_GROUP_SRAMS_START;
333 
334         if ((rescMask != 0U) && ((rescGroup & PM_RESOURCE_FULL_ON) != 0U))
335         {
336             /* Exclude APD & PPD bits in PDSLEEPCFG for each enabled SRAM */
337             enabledResources[enResSRAMs[feature].group] |= enResSRAMs[feature].mask;
338             enabledResources[enResSRAMs[feature].group + 1UL] |= enResSRAMs[feature].mask;
339         }
340         else if ((rescMask != 0U) && ((rescGroup & PM_RESOURCE_PARTABLE_ON1) != 0U))
341         {
342             /* Exclude APD bit in PDSLEEPCFG2/4 for each retained SRAM */
343             enabledResources[enResSRAMs[feature].group] |= enResSRAMs[feature].mask;
344         }
345         else
346         {
347             /* Intentional empty. */
348         }
349     }
350 
351     /* Configure remaining peripherals */
352     for (resc = RESC_GROUP_PERIPHERALS_START; resc <= RESC_GROUP_PERIPHERALS_END; resc++)
353     {
354         rescMask  = PM_RESC_MASK(pSoftRescMask, resc);
355         rescGroup = PM_RESC_GROUP(pSysRescGroup, resc);
356         feature   = (uint32_t)resc - (uint32_t)RESC_GROUP_PERIPHERALS_START;
357 
358         if ((rescMask != 0U) && ((rescGroup & PM_RESOURCE_FULL_ON) != 0U))
359         {
360             /* Exclude peripheral bit in corresponding PDSLEECFG group */
361             enabledResources[enResPeripherals[feature].group] |= enResPeripherals[feature].mask;
362         }
363     }
364 }
365 
PM_DEV_DisablePeripheralsSleep(pm_resc_mask_t * pSoftRescMask,pm_resc_group_t * pSysRescGroup)366 static void PM_DEV_DisablePeripheralsSleep(pm_resc_mask_t *pSoftRescMask, pm_resc_group_t *pSysRescGroup)
367 {
368     uint32_t rescMask;
369     uint32_t rescGroup;
370     resc_name_t resc;
371     uint32_t feature;
372 
373     /* Configure System RAMs (SRAMs) */
374     for (resc = RESC_GROUP_SRAMS_START; resc <= RESC_GROUP_SRAMS_END; resc++)
375     {
376         rescMask  = PM_RESC_MASK(pSoftRescMask, resc);
377         rescGroup = PM_RESC_GROUP(pSysRescGroup, resc);
378         feature   = (uint32_t)resc - (uint32_t)RESC_GROUP_SRAMS_START;
379 
380         if (rescMask != 0U)
381         {
382             if ((rescGroup & PM_RESOURCE_FULL_ON) != 0U)
383             {
384                 /* Clear APD bit in PDRUNCFG and PPD bit for each enabled SRAM */
385                 PMC_PDRCFG_REG(enResSRAMs[feature].group - 1UL) &= ~enResSRAMs[feature].mask;
386                 PMC_PDRCFG_REG(enResSRAMs[feature].group) &= ~enResSRAMs[feature].mask;
387             }
388             else if ((rescGroup & PM_RESOURCE_PARTABLE_ON1) != 0U)
389             {
390                 /* Clear APD bit in PDRUNCFG for each retained SRAM */
391                 PMC_PDRCFG_REG(enResSRAMs[feature].group - 1UL) &= ~enResSRAMs[feature].mask;
392                 /* Set PPD bit in PDRUNCFG for each retained SRAM */
393                 PMC_PDRCFG_REG(enResSRAMs[feature].group) |= enResSRAMs[feature].mask;
394             }
395             else
396             {
397                 /* Intentional empty. */
398             }
399         }
400         else
401         {
402             /* Set APD bit and PPD bit in PDRUNCFG for each disabled SRAM */
403             PMC_PDRCFG_REG(enResSRAMs[feature].group - 1UL) |= enResSRAMs[feature].mask;
404             PMC_PDRCFG_REG(enResSRAMs[feature].group) |= enResSRAMs[feature].mask;
405         }
406     }
407 
408     /* Configure remaining peripherals with single PDRUNCFG bit */
409     for (resc = RESC_GROUP_PERIPHERALS_START; resc <= RESC_GROUP_PERIPHERALS_END; resc++)
410     {
411         rescMask  = PM_RESC_MASK(pSoftRescMask, resc);
412         rescGroup = PM_RESC_GROUP(pSysRescGroup, resc);
413         feature   = (uint32_t)resc - (uint32_t)RESC_GROUP_PERIPHERALS_START;
414 
415         if ((rescMask != 0U) && ((rescGroup & PM_RESOURCE_FULL_ON) != 0U))
416         {
417             if (enResPeripherals[feature].group == 0U)
418             {
419                 SLEEPCON_RCFGCLR_REG = enResPeripherals[feature].mask;
420             }
421             else
422             {
423                 /* Clear peripheral bit in corresponding PDRUNCFG register */
424                 PMC_PDRCFG_REG(enResPeripherals[feature].group - 1UL) &= ~enResPeripherals[feature].mask;
425             }
426         }
427         else
428         {
429             /* Set peripheral bit in corresponding PDRUNCFG register */
430             if (enResPeripherals[feature].group == 0U)
431             {
432                 SLEEPCON_RCFGSET_REG = enResPeripherals[feature].mask;
433             }
434             else
435             {
436                 /* Clear peripheral bit in corresponding PDRUNCFG register */
437                 PMC_PDRCFG_REG(enResPeripherals[feature].group - 1UL) |= enResPeripherals[feature].mask;
438             }
439         }
440     }
441 
442     POWER_ApplyPD();
443 }
444 
PM_DEV_EnterLowPowerMode(uint8_t stateIndex,pm_resc_mask_t * pSoftRescMask,pm_resc_group_t * pSysRescGroup)445 static void PM_DEV_EnterLowPowerMode(uint8_t stateIndex, pm_resc_mask_t *pSoftRescMask, pm_resc_group_t *pSysRescGroup)
446 {
447     uint32_t enabledResources[7] = {0U, 0U, 0U, 0U, 0U, 0U, 0U};
448 
449     assert(pSoftRescMask != NULL);
450     assert(pSysRescGroup != NULL);
451 
452     switch (stateIndex)
453     {
454         case PM_LP_STATE_SLEEP:
455             /*
456              * Change PDRUNCFG depending on constraints, POWER_EnablePD then POWER_ApplyPD
457              */
458             PM_DEV_DisablePeripheralsSleep(pSoftRescMask, pSysRescGroup);
459             break;
460         case PM_LP_STATE_DEEP_SLEEP:
461         case PM_LP_STATE_DSR:
462             /*
463              * Change PDSLEEPCFG depending on constraints
464              */
465             PM_DEV_EnablePeripheralsDeepSleep(pSoftRescMask, pSysRescGroup, enabledResources);
466             break;
467         case PM_LP_STATE_DEEP_POWER_DOWN:
468             /*
469              * Do nothing
470              */
471             break;
472         case PM_LP_STATE_FULL_DEEP_POWER_DOWN:
473             /*
474              * Do nothing
475              */
476             break;
477         default:
478             /* Should not goes here. */
479             break;
480     }
481     POWER_EnterPowerMode((power_mode_cfg_t)stateIndex, enabledResources);
482 }
483 
PM_DEV_CleanExitLowPowerMode(void)484 static void PM_DEV_CleanExitLowPowerMode(void)
485 {
486     /* Do nothing. */
487 }
488 
PM_DEV_ManageWakeupSource(pm_wakeup_source_t * ws,bool enable)489 static status_t PM_DEV_ManageWakeupSource(pm_wakeup_source_t *ws, bool enable)
490 {
491     uint32_t irqn;
492     uint32_t misc;
493 
494     (void)(misc);
495 
496     assert(ws != NULL);
497     PM_DECODE_WAKEUP_SOURCE_ID(ws->wsId);
498 
499     if (enable)
500     {
501         EnableDeepSleepIRQ((IRQn_Type)irqn);
502     }
503     else
504     {
505         DisableDeepSleepIRQ((IRQn_Type)irqn);
506     }
507     return kStatus_Success;
508 }
509