1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /*
3 * Copyright (c) 2020-2021 Rockchip Electronics Co., Ltd.
4 */
5
6 #include "hal_base.h"
7
8 #ifdef HAL_PM_RUNTIME_MODULE_ENABLED
9
10 /** @addtogroup RK_HAL_Driver
11 * @{
12 */
13
14 /** @addtogroup PM_CPU
15 * @{
16 */
17
18 /** @defgroup PM_CPU_How_To_Use How To Use
19 * @{
20
21 The PM_CPU_SLEEP driver can be used as follows:
22 - Invoke HAL_NVIC_SuspendSave() when NVIC needs to be save.
23 - Invoke HAL_NVIC_ResumeRestore() when NVIC needs to be resume.
24 - Invoke HAL_CPU_SuspendSave() when cpu may need save some info.
25
26 The PM_Runtime driver can be used as follows:
27 - Invoke HAL_PM_RuntimeRequest() when a device is in runtime.
28 - Invoke HAL_PM_RuntimeRelease() when a device is release runtime.
29 - Invoke HAL_PM_RuntimeGetData() when need get all of device status.
30
31 @} */
32
33 static struct PM_RUNTIME_INFO runtimeStatus;
34
35 /** @defgroup PM_PM_RUNTIME_Exported_Functions_Group5 Other Functions
36 * @{
37 */
38
39 /**
40 * @brief request a runtime status by runtimeId.
41 * @param runtimeId: a runtime request id.
42 * @return HAL_Status
43 */
HAL_PM_RuntimeRequest(ePM_RUNTIME_ID runtimeId)44 HAL_Status HAL_PM_RuntimeRequest(ePM_RUNTIME_ID runtimeId)
45 {
46 uint8_t runtimeType, typeOffset;
47
48 HAL_ASSERT(runtimeId < PM_RUNTIME_ID_END);
49
50 runtimeType = PM_RUNTIME_ID_TO_TYPE(runtimeId);
51 typeOffset = PM_RUNTIME_ID_TO_TYPE_OFFSET(runtimeId);
52 HAL_ASSERT(runtimeType < PM_RUNTIME_TYPE_END);
53 HAL_ASSERT(typeOffset < PM_RUNTIME_PER_TYPE_NUM);
54
55 runtimeStatus.bits[runtimeType] |= HAL_BIT(typeOffset);
56
57 return HAL_OK;
58 }
59
60 /**
61 * @brief release a runtime status by runtimeId.
62 * @param runtimeId: a runtime request id.
63 * @return HAL_Status
64 */
HAL_PM_RuntimeRelease(ePM_RUNTIME_ID runtimeId)65 HAL_Status HAL_PM_RuntimeRelease(ePM_RUNTIME_ID runtimeId)
66 {
67 uint8_t runtimeType, typeOffset;
68
69 HAL_ASSERT(runtimeId < PM_RUNTIME_ID_END);
70
71 runtimeType = PM_RUNTIME_ID_TO_TYPE(runtimeId);
72 typeOffset = PM_RUNTIME_ID_TO_TYPE_OFFSET(runtimeId);
73
74 HAL_ASSERT(runtimeType < PM_RUNTIME_TYPE_END);
75 HAL_ASSERT(typeOffset < PM_RUNTIME_PER_TYPE_NUM);
76
77 runtimeStatus.bits[runtimeType] &= ~HAL_BIT(typeOffset);
78
79 return HAL_OK;
80 }
81
82 /**
83 * @brief get the runitme data poiniter.
84 * @return the runitme data poiniter.
85 */
HAL_PM_RuntimeGetData(void)86 const struct PM_RUNTIME_INFO *HAL_PM_RuntimeGetData(void)
87 {
88 return &runtimeStatus;
89 }
90
91 /** @} */
92
93 #endif
94
95 #ifdef HAL_PM_SLEEP_MODULE_ENABLED
96
97 /** @defgroup PM_Private_Definition Private Definition
98 * @{
99 */
100 /********************* Private Variable Definition ***************************/
101 static struct SLEEP_CONFIG_DATA sleepConfigData;
102
103 /** @} */
104 /********************* Public Function Definition ***************************/
105 /** @defgroup PM_CPU_SLEEP_Exported_Functions_Group5 Other Functions
106 * @{
107 */
108
109 /**
110 * @brief get sleepConfigData.
111 * @return addr of sleepConfigData.
112 */
HAL_SYS_GetSuspendConfig(void)113 struct SLEEP_CONFIG_DATA *HAL_SYS_GetSuspendConfig(void)
114 {
115 return &sleepConfigData;
116 }
117
118 /**
119 * @brief config parameters to control suspend flow.
120 * @param id: select parameters to be config.
121 * @param data: data assigned to parameters.
122 * @return HAL_Status.
123 */
HAL_SYS_SuspendConfig(uint32_t id,uint32_t data)124 HAL_Status HAL_SYS_SuspendConfig(uint32_t id, uint32_t data)
125 {
126 switch (id) {
127 case PM_SLEEP_MODE_CONFIG:
128 sleepConfigData.suspendMode = data;
129 break;
130
131 case PM_SLEEP_WAKEUP_SOURCE:
132 sleepConfigData.suspendWkupSrc = data;
133 break;
134
135 default:
136 break;
137 }
138
139 return HAL_OK;
140 }
141
142 /** @} */
143
144 #endif /* HAL_PM_SLEEP_MODULE_ENABLED */
145
146 #if defined(HAL_PM_CPU_SLEEP_MODULE_ENABLED)
147 #if defined(__CM3_REV) || defined(__CM4_REV)
148
149 /** @defgroup PM_CPU_Private_Definition Private Definition
150 * @{
151 */
152 /********************* Private MACRO Definition ******************************/
153
154 #define NVIC_EXT_ISER_NUM (8)
155 #define NVIC_EXT_IP_NUM (240)
156 #define SHP_NUM (12)
157 /********************* Private Structure Definition **************************/
158
159 struct NVIC_SAVE_S {
160 uint32_t iser[NVIC_EXT_ISER_NUM];/* Interrupt Set Enable Register */
161 uint8_t ip[NVIC_EXT_IP_NUM]; /* Interrupt Priority Register */
162 uint32_t pg; /* Interrupt Priority Group Register */
163 };
164
165 /********************* Private Variable Definition ***************************/
166
167 static struct NVIC_SAVE_S nvicSave;
168 static NVIC_Type *pnvic = NVIC;
169 static SCB_Type scbSave;
170
171 /********************* Private Function Definition ***************************/
172
173 /** @} */
174 /********************* Public Function Definition ***************************/
175 /** @defgroup PM_CPU_SLEEP_Exported_Functions_Group5 Other Functions
176 * @{
177 */
178
179 /**
180 * @brief save nvic registers for resume nvic.
181 */
HAL_NVIC_SuspendSave(void)182 void HAL_NVIC_SuspendSave(void)
183 {
184 int i;
185
186 for (i = 0; i < NVIC_EXT_ISER_NUM; i++) {
187 nvicSave.iser[i] = pnvic->ISER[i];
188 }
189
190 for (i = 0; i < NVIC_EXT_IP_NUM; i++) {
191 nvicSave.ip[i] = pnvic->IP[i];
192 }
193
194 nvicSave.pg = NVIC_GetPriorityGrouping();
195 }
196
197 /**
198 * @brief resume nvic registers.
199 */
HAL_NVIC_ResumeRestore(void)200 void HAL_NVIC_ResumeRestore(void)
201 {
202 int i;
203
204 NVIC_SetPriorityGrouping(nvicSave.pg);
205 for (i = 0; i < NVIC_EXT_IP_NUM; i++) {
206 pnvic->IP[i] = nvicSave.ip[i];
207 }
208
209 for (i = 0; i < NVIC_EXT_ISER_NUM; i++) {
210 pnvic->ICER[i] = 0xffffffff;
211 }
212
213 for (i = 0; i < NVIC_EXT_ISER_NUM; i++) {
214 pnvic->ISER[i] = nvicSave.iser[i];
215 }
216 }
217
218 /**
219 * @brief save scb registers for resume nvic.
220 */
HAL_SCB_SuspendSave(void)221 void HAL_SCB_SuspendSave(void)
222 {
223 int i;
224
225 scbSave.ICSR = SCB->ICSR;
226 scbSave.AIRCR = SCB->AIRCR;
227 scbSave.SCR = SCB->SCR;
228 for (i = 0; i < SHP_NUM; i++) {
229 scbSave.SHP[i] = SCB->SHP[i];
230 }
231 scbSave.SHCSR = SCB->SHCSR;
232 scbSave.CFSR = SCB->CFSR;
233 scbSave.DFSR = SCB->DFSR;
234 scbSave.MMFAR = SCB->MMFAR;
235 scbSave.BFAR = SCB->BFAR;
236 scbSave.AFSR = SCB->AFSR;
237 scbSave.CPACR = SCB->CPACR;
238 }
239
240 /**
241 * @brief resume nvic registers.
242 */
HAL_SCB_ResumeRestore(void)243 void HAL_SCB_ResumeRestore(void)
244 {
245 int i;
246
247 SCB->ICSR = scbSave.ICSR;
248 SCB->AIRCR = scbSave.AIRCR;
249 SCB->SCR = scbSave.SCR;
250 for (i = 0; i < SHP_NUM; i++) {
251 SCB->SHP[i] = scbSave.SHP[i];
252 }
253 SCB->SHCSR = scbSave.SHCSR;
254 SCB->CFSR = scbSave.CFSR;
255 SCB->DFSR = scbSave.DFSR;
256 SCB->MMFAR = scbSave.MMFAR;
257 SCB->BFAR = scbSave.BFAR;
258 SCB->AFSR = scbSave.AFSR;
259 SCB->CPACR = scbSave.CPACR;
260 }
261
262 /**
263 * @brief it is for saving cpu's register.
264 * @param ptr: base addr for saving
265 * @param ptrsz: size of the mem for saving
266 * @param sp: the system stack needed be saved
267 * @param ptrSave: save the param ptr.
268 */
HAL_CPU_SuspendSave(uint32_t * ptr,uint32_t ptrsz,uint32_t sp,uint32_t * ptrSave)269 void HAL_CPU_SuspendSave(uint32_t *ptr, uint32_t ptrsz, uint32_t sp, uint32_t *ptrSave)
270 {
271 *ptrSave = (uint32_t)ptr;
272 *ptr++ = sp;
273 *ptr++ = (uint32_t)HAL_CPU_ArchResume + 1;
274 HAL_CPU_ArchSuspend(ptr);
275 }
276
277 /** @} */
278
279 #endif /* __CM3_REV || __CM4_REV */
280
281 /** @} */
282
283 /** @} */
284
285 #endif /* HAL_PM_CPU_SLEEP_MODULE_ENABLED */
286