blob: dd04124a356474deb4e6ce72392fb8ce8cb55fb0 [file] [log] [blame]
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +08001/*
yang.li24770372022-01-11 15:21:49 +08002 * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +08003 *
yang.li24770372022-01-11 15:21:49 +08004 * SPDX-License-Identifier: MIT
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +08005 */
6
7#include <stdio.h>
8#include "FreeRTOS.h" /* Must come first. */
9#include "task.h" /* RTOS task related API prototypes. */
10#include "queue.h" /* RTOS queue related API prototypes. */
11#include "timers.h" /* Software timer related API prototypes. */
12#include "semphr.h" /* Semaphore related API prototypes. */
13
14#include <unistd.h>
Xiaohu.Huang60950452022-03-12 22:51:01 +080015#include <string.h>
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +080016
17#include "n200_func.h"
18#include "common.h"
19#include "riscv_encoding.h"
20#include "suspend.h"
21#include "power.h"
22
23#include "hdmi_cec.h"
24#include "vrtc.h"
Xiaohu.Huang60950452022-03-12 22:51:01 +080025#include "rtc.h"
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +080026#include "mailbox-api.h"
27#include "wakeup.h"
28#include "stick_mem.h"
Xiaohu.Huang60950452022-03-12 22:51:01 +080029#include "pm.h"
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +080030
31void system_resume(uint32_t pm);
32void system_suspend(uint32_t pm);
33void set_reason_flag(char exit_reason);
34void create_str_task(void);
35uint32_t get_reason_flag(void);
36uint32_t get_stick_reboot_flag(void);
37void *xMboxGetWakeupReason(void *msg);
38void *xMboxClrWakeupReason(void *msg);
39void *xMboxGetStickRebootFlag(void *msg);
40void set_suspend_flag(void);
41
42SemaphoreHandle_t xSTRSemaphore = NULL;
43QueueHandle_t xSTRQueue = NULL;
44SemaphoreHandle_t xSTRFlagSem = NULL;
45uint32_t suspend_flag;
46uint32_t power_mode;
47
48WakeUp_Reason vWakeupReason[] = {
49 [UDEFINED_WAKEUP] = { .name = "undefine" },
50 [CHARGING_WAKEUP] = { .name = "charging" },
51 [REMOTE_WAKEUP] = { .name = "remote" },
52 [RTC_WAKEUP] = { .name = "rtc" },
53 [BT_WAKEUP] = { .name = "bt" },
54 [WIFI_WAKEUP] = { .name = "wifi" },
55 [POWER_KEY_WAKEUP] = { .name = "powerkey" },
56 [AUTO_WAKEUP] = { .name = "auto" },
57 [CEC_WAKEUP] = { .name = "cec" },
58 [REMOTE_CUS_WAKEUP] = { .name = "remote_cus" },
59 [ETH_PMT_WAKEUP] = { .name = "eth" },
60 [CECB_WAKEUP] = { .name = "cecb" },
61 [VAD_WAKEUP] = { .name = "vad" },
62 [HDMI_RX_WAKEUP] = { .name = "hdmirx_plugin" },
63};
64
65void set_suspend_flag(void)
66{
67 taskENTER_CRITICAL();
68 suspend_flag = 1;
69 taskEXIT_CRITICAL();
70}
Xiaohu.Huang60950452022-03-12 22:51:01 +080071__attribute__((weak)) void vDDR_suspend(uint32_t st_f)
72{
73 st_f = st_f;
74}
75
76__attribute__((weak)) void vDDR_resume(uint32_t st_f)
77{
78 st_f = st_f;
79}
80
81__attribute__((weak)) void alarm_set(void)
82{
83}
84
85__attribute__((weak)) void alarm_clr(void)
86{
87}
88
89__attribute__((weak)) void vRTC_update(void)
90{
91}
92
93__attribute__((weak)) void vCreat_alarm_timer(void)
94{
95}
96
97__attribute__((weak)) void store_rtc(void)
98{
99}
100
101__attribute__((weak)) void vCLK_suspend(uint32_t st_f)
102{
103 st_f = st_f;
104}
105
106__attribute__((weak)) void vCLK_resume(uint32_t st_f)
107{
108 st_f = st_f;
109}
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +0800110
111void system_resume(uint32_t pm)
112{
113 uint32_t shutdown_flag = 0;
114
115 if (pm == 0xf)
116 shutdown_flag = 1;
Xiaohu.Huang60950452022-03-12 22:51:01 +0800117 vCLK_resume(shutdown_flag);
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +0800118 /*Need clr alarm ASAP*/
119 alarm_clr();
120 str_power_on(shutdown_flag);
121 vDDR_resume(shutdown_flag);
122 str_hw_disable();
123 vRTC_update();
124 wakeup_ap();
125 clear_wakeup_trigger();
126 /*Shutdown*/
Xiaohu.Huang60950452022-03-12 22:51:01 +0800127 if (shutdown_flag) {
128 /* Store RTC time for a5 temporarily*/
129 store_rtc();
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +0800130 watchdog_reset_system();
Xiaohu.Huang60950452022-03-12 22:51:01 +0800131 }
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +0800132}
133
134void system_suspend(uint32_t pm)
135{
136 uint32_t shutdown_flag = 0;
137
138 if (pm == 0xf)
139 shutdown_flag = 1;
140
141 /*Need set alarm ASAP*/
142 alarm_set();
143 str_hw_init();
144 /*Set flag befor delay. It can be wakeup during delay*/
145 set_suspend_flag();
146 /*Delay 500ms for FSM switch to off*/
147 vTaskDelay(pdMS_TO_TICKS(500));
148 vDDR_suspend(shutdown_flag);
149 str_power_off(shutdown_flag);
Xiaohu.Huang60950452022-03-12 22:51:01 +0800150 vCLK_suspend(shutdown_flag);
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +0800151}
152
153void set_reason_flag(char exit_reason)
154{
155 REG32(WAKEUP_REASON_STICK_REG) &= ~0xf;
156 REG32(WAKEUP_REASON_STICK_REG) |= exit_reason;
157}
158
159uint32_t get_reason_flag(void)
160{
161 return REG32(WAKEUP_REASON_STICK_REG) & 0xf;
162}
163
164uint32_t get_stick_reboot_flag(void)
165{
166#if (configSUPPORT_STICK_MEM == 1)
167 return last_stick_reboot_flag;
168#else
169 printf("Don't support stick memory!\r\n");
170 return 0;
171#endif
172}
173
174void *xMboxGetWakeupReason(void *msg)
175{
176 *(uint32_t *)msg = get_reason_flag();
177 return NULL;
178}
179
180void *xMboxClrWakeupReason(void *msg)
181{
182 msg = msg;
183 return NULL;
184}
185
186void *xMboxGetStickRebootFlag(void *msg)
187{
188 *(uint32_t *)msg = get_stick_reboot_flag();
189
190 return NULL;
191}
192
193void STR_Start_Sem_Give_FromISR(void)
194{
195 BaseType_t xHigherPriorityTaskWoken;
196 xSemaphoreGiveFromISR(xSTRSemaphore, &xHigherPriorityTaskWoken);
197}
198
199void STR_Start_Sem_Give(void)
200{
201 xSemaphoreGive(xSTRSemaphore);
202}
203
204
205void STR_Wakeup_src_Queue_Send_FromISR(uint32_t *src)
206{
207 BaseType_t xHigherPriorityTaskWoken;
208 uint32_t flag = 0;
209 UBaseType_t uxSavedInterruptStatus;
210
211 uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR();
212 if (suspend_flag) {
213 suspend_flag = 0;
214 flag = 1;
215 }
216 taskEXIT_CRITICAL_FROM_ISR(uxSavedInterruptStatus);
217
218 if (flag)
219 xQueueSendFromISR(xSTRQueue, src, &xHigherPriorityTaskWoken);
220}
221
222void STR_Wakeup_src_Queue_Send(uint32_t *src)
223{
224 uint32_t flag = 0;
225
226 taskENTER_CRITICAL();
227 if (suspend_flag) {
228 suspend_flag = 0;
229 flag = 1;
230 }
231 taskEXIT_CRITICAL();
232
233 if (flag)
234 xQueueSend(xSTRQueue, src, portMAX_DELAY);
235}
236
237void *xMboxSuspend_Sem(void *msg)
238{
239 power_mode = *(uint32_t *)msg;
240
241 printf("power_mode=0x%x\n",power_mode);
242 STR_Start_Sem_Give();
243
244 return NULL;
245}
246
Xiaohu.Huang60950452022-03-12 22:51:01 +0800247#define FREEZE_ENTER 0x01
248#define FREEZE_EXIT 0x02
249
250void *xMboxpm_sem(void *msg);
251void *xMboxpm_sem(void *msg)
252{
253 uint32_t mode = *(uint32_t *)msg;
254
255 if (mode == FREEZE_ENTER) {
256 pm_enter();
257 } else if (mode == FREEZE_EXIT) {
258 wakeup_ap_from_kernel();
259 }
260
261 return NULL;
262}
263
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +0800264static void vSTRTask( void *pvParameters )
265{
266 /*make compiler happy*/
267 uint32_t buffer = UDEFINED_WAKEUP;
268 uint32_t exit_reason = 0;
269
270 pvParameters = pvParameters;
271 xSTRQueue = xQueueCreate(STR_QUEUE_LENGTH, STR_QUEUE_ITEM_SIZE);
272 configASSERT(xSTRQueue);
273 xSTRSemaphore = xSemaphoreCreateBinary();
274 configASSERT(xSTRSemaphore);
275
276 while (1) {
277 xSemaphoreTake(xSTRSemaphore, portMAX_DELAY);
278 system_suspend(power_mode);
279 while (xQueueReceive(xSTRQueue, &buffer, portMAX_DELAY))
280 {
281 switch (buffer)
282 {
283 case REMOTE_WAKEUP:
284 exit_reason = REMOTE_WAKEUP;
285 break;
286 case RTC_WAKEUP:
287 exit_reason = RTC_WAKEUP;
288 break;
289 case BT_WAKEUP:
290 exit_reason = BT_WAKEUP;
291 break;
292 case CEC_WAKEUP:
293 exit_reason = CEC_WAKEUP;
294 break;
295 case CECB_WAKEUP:
296 exit_reason = CECB_WAKEUP;
297 break;
298 case REMOTE_CUS_WAKEUP:
299 exit_reason = REMOTE_CUS_WAKEUP;
300 break;
301 case POWER_KEY_WAKEUP:
302 exit_reason = POWER_KEY_WAKEUP;
303 break;
304 case ETH_PMT_WAKEUP:
305 exit_reason = ETH_PMT_WAKEUP;
306 break;
307 case WIFI_WAKEUP:
308 exit_reason = WIFI_WAKEUP;
309 break;
310 case VAD_WAKEUP:
311 exit_reason = VAD_WAKEUP;
312 break;
313 case HDMI_RX_WAKEUP:
314 exit_reason = HDMI_RX_WAKEUP;
315 break;
316 default:
317 break;
318 }
319 if (exit_reason) {
320 printf("exit_reason=%d, %s\n",exit_reason, vWakeupReason[exit_reason].name);
321 set_reason_flag((char)exit_reason);
322 exit_reason = 0;
323 system_resume(power_mode);
324 goto loop;
325 }
326 }
327 loop: continue;
328 }
329}
330
331void create_str_task(void)
332{
333 int ret;
334
335 if (xTaskCreate( vSTRTask, "STR_task", configMINIMAL_STACK_SIZE, NULL, 3, NULL ) < 0)
336 printf("STR_task create fail!!\n");
337
338 vCreat_alarm_timer();
339
340 ret = xInstallRemoteMessageCallbackFeedBack(AOTEE_CHANNEL, MBX_CMD_SUSPEND,
341 xMboxSuspend_Sem, 0);
342 if (ret == MBOX_CALL_MAX)
343 printf("mbox cmd 0x%x register fail\n", MBX_CMD_SUSPEND);
344
345 ret = xInstallRemoteMessageCallbackFeedBack(AOREE_CHANNEL, MBX_CMD_GET_WAKEUP_REASON,
346 xMboxGetWakeupReason, 1);
347 if (ret == MBOX_CALL_MAX)
348 printf("mbox cmd 0x%x register fail\n", MBX_CMD_GET_WAKEUP_REASON);
349
350 ret = xInstallRemoteMessageCallbackFeedBack(AOREE_CHANNEL, MBX_CMD_CLR_WAKEUP_REASON,
351 xMboxClrWakeupReason, 0);
352
353 ret = xInstallRemoteMessageCallbackFeedBack(AOREE_CHANNEL, MBX_CMD_GET_STICK_REBOOT_FLAG,
354 xMboxGetStickRebootFlag, 1);
355 if (ret == MBOX_CALL_MAX)
356 printf("mbox cmd 0x%x register fail\n", MBX_CMD_CLR_WAKEUP_REASON);
Xiaohu.Huang60950452022-03-12 22:51:01 +0800357
358 ret = xInstallRemoteMessageCallbackFeedBack(AOREE_CHANNEL, MBX_CMD_PM_FREEZE,
359 xMboxpm_sem, 1);
360 if (ret == MBOX_CALL_MAX)
361 printf("mbox cmd 0x%x register fail\n", MBX_CMD_PM_FREEZE);
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +0800362}