blob: ca4be5ca524311f18a2766b761ab0564d93162d1 [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. */
xiaohu.huang2beac512022-05-07 15:10:04 +08009#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. */
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +080013
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"
xiaohu.huang2beac512022-05-07 15:10:04 +080020#include "gcc_compiler_attributes.h"
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +080021#include "suspend.h"
22#include "power.h"
23
24#include "hdmi_cec.h"
25#include "vrtc.h"
Xiaohu.Huang60950452022-03-12 22:51:01 +080026#include "rtc.h"
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +080027#include "mailbox-api.h"
28#include "wakeup.h"
29#include "stick_mem.h"
Xiaohu.Huang60950452022-03-12 22:51:01 +080030#include "pm.h"
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +080031
xiaohu.huang2beac512022-05-07 15:10:04 +080032SemaphoreHandle_t xSTRSemaphore;
33QueueHandle_t xSTRQueue;
34SemaphoreHandle_t xSTRFlagSem;
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +080035uint32_t suspend_flag;
36uint32_t power_mode;
37
xiaohu.huang2beac512022-05-07 15:10:04 +080038struct WakeUp_Reason vWakeupReason[] = {
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +080039 [UDEFINED_WAKEUP] = { .name = "undefine" },
40 [CHARGING_WAKEUP] = { .name = "charging" },
41 [REMOTE_WAKEUP] = { .name = "remote" },
42 [RTC_WAKEUP] = { .name = "rtc" },
43 [BT_WAKEUP] = { .name = "bt" },
44 [WIFI_WAKEUP] = { .name = "wifi" },
45 [POWER_KEY_WAKEUP] = { .name = "powerkey" },
46 [AUTO_WAKEUP] = { .name = "auto" },
47 [CEC_WAKEUP] = { .name = "cec" },
48 [REMOTE_CUS_WAKEUP] = { .name = "remote_cus" },
49 [ETH_PMT_WAKEUP] = { .name = "eth" },
50 [CECB_WAKEUP] = { .name = "cecb" },
51 [VAD_WAKEUP] = { .name = "vad" },
52 [HDMI_RX_WAKEUP] = { .name = "hdmirx_plugin" },
53};
54
55void set_suspend_flag(void)
56{
57 taskENTER_CRITICAL();
58 suspend_flag = 1;
59 taskEXIT_CRITICAL();
60}
xiaohu.huang2beac512022-05-07 15:10:04 +080061
62__weak void vDDR_suspend(uint32_t st_f)
Xiaohu.Huang60950452022-03-12 22:51:01 +080063{
xiaohu.huang2beac512022-05-07 15:10:04 +080064 (void)st_f;
Xiaohu.Huang60950452022-03-12 22:51:01 +080065}
66
xiaohu.huang2beac512022-05-07 15:10:04 +080067__weak void vDDR_resume(uint32_t st_f)
Xiaohu.Huang60950452022-03-12 22:51:01 +080068{
xiaohu.huang2beac512022-05-07 15:10:04 +080069 (void)st_f;
Xiaohu.Huang60950452022-03-12 22:51:01 +080070}
71
xiaohu.huang2beac512022-05-07 15:10:04 +080072__weak void alarm_set(void)
Xiaohu.Huang60950452022-03-12 22:51:01 +080073{
74}
75
xiaohu.huang2beac512022-05-07 15:10:04 +080076__weak void alarm_clr(void)
Xiaohu.Huang60950452022-03-12 22:51:01 +080077{
78}
79
xiaohu.huang2beac512022-05-07 15:10:04 +080080__weak void vRTC_update(void)
Xiaohu.Huang60950452022-03-12 22:51:01 +080081{
82}
83
xiaohu.huang2beac512022-05-07 15:10:04 +080084__weak void vCreat_alarm_timer(void)
Xiaohu.Huang60950452022-03-12 22:51:01 +080085{
86}
87
xiaohu.huang2beac512022-05-07 15:10:04 +080088__weak void store_rtc(void)
Xiaohu.Huang60950452022-03-12 22:51:01 +080089{
90}
91
xiaohu.huang2beac512022-05-07 15:10:04 +080092__weak void vCLK_suspend(uint32_t st_f)
Xiaohu.Huang60950452022-03-12 22:51:01 +080093{
xiaohu.huang2beac512022-05-07 15:10:04 +080094 (void)st_f;
Xiaohu.Huang60950452022-03-12 22:51:01 +080095}
96
xiaohu.huang2beac512022-05-07 15:10:04 +080097__weak void vCLK_resume(uint32_t st_f)
Xiaohu.Huang60950452022-03-12 22:51:01 +080098{
xiaohu.huang2beac512022-05-07 15:10:04 +080099 (void)st_f;
Xiaohu.Huang60950452022-03-12 22:51:01 +0800100}
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +0800101
102void system_resume(uint32_t pm)
103{
104 uint32_t shutdown_flag = 0;
105
106 if (pm == 0xf)
107 shutdown_flag = 1;
Xiaohu.Huang60950452022-03-12 22:51:01 +0800108 vCLK_resume(shutdown_flag);
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +0800109 /*Need clr alarm ASAP*/
110 alarm_clr();
111 str_power_on(shutdown_flag);
112 vDDR_resume(shutdown_flag);
113 str_hw_disable();
114 vRTC_update();
115 wakeup_ap();
116 clear_wakeup_trigger();
117 /*Shutdown*/
Xiaohu.Huang60950452022-03-12 22:51:01 +0800118 if (shutdown_flag) {
119 /* Store RTC time for a5 temporarily*/
120 store_rtc();
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +0800121 watchdog_reset_system();
Xiaohu.Huang60950452022-03-12 22:51:01 +0800122 }
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +0800123}
124
125void system_suspend(uint32_t pm)
126{
127 uint32_t shutdown_flag = 0;
128
129 if (pm == 0xf)
130 shutdown_flag = 1;
131
132 /*Need set alarm ASAP*/
133 alarm_set();
134 str_hw_init();
135 /*Set flag befor delay. It can be wakeup during delay*/
136 set_suspend_flag();
137 /*Delay 500ms for FSM switch to off*/
138 vTaskDelay(pdMS_TO_TICKS(500));
139 vDDR_suspend(shutdown_flag);
140 str_power_off(shutdown_flag);
Xiaohu.Huang60950452022-03-12 22:51:01 +0800141 vCLK_suspend(shutdown_flag);
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +0800142}
143
144void set_reason_flag(char exit_reason)
145{
146 REG32(WAKEUP_REASON_STICK_REG) &= ~0xf;
147 REG32(WAKEUP_REASON_STICK_REG) |= exit_reason;
148}
149
150uint32_t get_reason_flag(void)
151{
152 return REG32(WAKEUP_REASON_STICK_REG) & 0xf;
153}
154
155uint32_t get_stick_reboot_flag(void)
156{
157#if (configSUPPORT_STICK_MEM == 1)
158 return last_stick_reboot_flag;
159#else
160 printf("Don't support stick memory!\r\n");
161 return 0;
162#endif
163}
164
165void *xMboxGetWakeupReason(void *msg)
166{
167 *(uint32_t *)msg = get_reason_flag();
168 return NULL;
169}
170
171void *xMboxClrWakeupReason(void *msg)
172{
xiaohu.huang2beac512022-05-07 15:10:04 +0800173 (void)msg;
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +0800174 return NULL;
175}
176
177void *xMboxGetStickRebootFlag(void *msg)
178{
179 *(uint32_t *)msg = get_stick_reboot_flag();
180
181 return NULL;
182}
183
184void STR_Start_Sem_Give_FromISR(void)
185{
186 BaseType_t xHigherPriorityTaskWoken;
xiaohu.huang2beac512022-05-07 15:10:04 +0800187
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +0800188 xSemaphoreGiveFromISR(xSTRSemaphore, &xHigherPriorityTaskWoken);
189}
190
191void STR_Start_Sem_Give(void)
192{
193 xSemaphoreGive(xSTRSemaphore);
194}
195
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +0800196void STR_Wakeup_src_Queue_Send_FromISR(uint32_t *src)
197{
198 BaseType_t xHigherPriorityTaskWoken;
199 uint32_t flag = 0;
200 UBaseType_t uxSavedInterruptStatus;
201
202 uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR();
203 if (suspend_flag) {
204 suspend_flag = 0;
205 flag = 1;
206 }
207 taskEXIT_CRITICAL_FROM_ISR(uxSavedInterruptStatus);
208
209 if (flag)
210 xQueueSendFromISR(xSTRQueue, src, &xHigherPriorityTaskWoken);
211}
212
213void STR_Wakeup_src_Queue_Send(uint32_t *src)
214{
215 uint32_t flag = 0;
216
217 taskENTER_CRITICAL();
218 if (suspend_flag) {
219 suspend_flag = 0;
220 flag = 1;
221 }
222 taskEXIT_CRITICAL();
223
224 if (flag)
225 xQueueSend(xSTRQueue, src, portMAX_DELAY);
226}
227
228void *xMboxSuspend_Sem(void *msg)
229{
230 power_mode = *(uint32_t *)msg;
231
xiaohu.huang2beac512022-05-07 15:10:04 +0800232 printf("power_mode=0x%x\n", power_mode);
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +0800233 STR_Start_Sem_Give();
234
235 return NULL;
236}
237
xiaohu.huang2beac512022-05-07 15:10:04 +0800238#define FREEZE_ENTER 0x01
239#define FREEZE_EXIT 0x02
Xiaohu.Huang60950452022-03-12 22:51:01 +0800240
241void *xMboxpm_sem(void *msg);
242void *xMboxpm_sem(void *msg)
243{
244 uint32_t mode = *(uint32_t *)msg;
245
xiaohu.huang2beac512022-05-07 15:10:04 +0800246 if (mode == FREEZE_ENTER)
Xiaohu.Huang60950452022-03-12 22:51:01 +0800247 pm_enter();
xiaohu.huang2beac512022-05-07 15:10:04 +0800248 else if (mode == FREEZE_EXIT)
Xiaohu.Huang60950452022-03-12 22:51:01 +0800249 wakeup_ap_from_kernel();
Xiaohu.Huang60950452022-03-12 22:51:01 +0800250
251 return NULL;
252}
253
xiaohu.huang2beac512022-05-07 15:10:04 +0800254static void vSTRTask(void *pvParameters)
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +0800255{
256 /*make compiler happy*/
257 uint32_t buffer = UDEFINED_WAKEUP;
258 uint32_t exit_reason = 0;
259
xiaohu.huang2beac512022-05-07 15:10:04 +0800260 (void)pvParameters;
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +0800261 xSTRQueue = xQueueCreate(STR_QUEUE_LENGTH, STR_QUEUE_ITEM_SIZE);
262 configASSERT(xSTRQueue);
263 xSTRSemaphore = xSemaphoreCreateBinary();
264 configASSERT(xSTRSemaphore);
265
266 while (1) {
267 xSemaphoreTake(xSTRSemaphore, portMAX_DELAY);
268 system_suspend(power_mode);
xiaohu.huang2beac512022-05-07 15:10:04 +0800269 while (xQueueReceive(xSTRQueue, &buffer, portMAX_DELAY)) {
270 switch (buffer) {
271 case REMOTE_WAKEUP:
272 exit_reason = REMOTE_WAKEUP;
273 break;
274 case RTC_WAKEUP:
275 exit_reason = RTC_WAKEUP;
276 break;
277 case BT_WAKEUP:
278 exit_reason = BT_WAKEUP;
279 break;
280 case CEC_WAKEUP:
281 exit_reason = CEC_WAKEUP;
282 break;
283 case CECB_WAKEUP:
284 exit_reason = CECB_WAKEUP;
285 break;
286 case REMOTE_CUS_WAKEUP:
287 exit_reason = REMOTE_CUS_WAKEUP;
288 break;
289 case POWER_KEY_WAKEUP:
290 exit_reason = POWER_KEY_WAKEUP;
291 break;
292 case ETH_PMT_WAKEUP:
293 exit_reason = ETH_PMT_WAKEUP;
294 break;
295 case WIFI_WAKEUP:
296 exit_reason = WIFI_WAKEUP;
297 break;
298 case VAD_WAKEUP:
299 exit_reason = VAD_WAKEUP;
300 break;
301 case HDMI_RX_WAKEUP:
302 exit_reason = HDMI_RX_WAKEUP;
303 break;
304 default:
305 break;
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +0800306 }
307 if (exit_reason) {
xiaohu.huang2beac512022-05-07 15:10:04 +0800308 printf("exit_reason=%d, %s\n", exit_reason,
309 vWakeupReason[exit_reason].name);
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +0800310 set_reason_flag((char)exit_reason);
311 exit_reason = 0;
312 system_resume(power_mode);
313 goto loop;
314 }
315 }
xiaohu.huang2beac512022-05-07 15:10:04 +0800316loop:
317 continue;
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +0800318 }
319}
320
321void create_str_task(void)
322{
323 int ret;
324
xiaohu.huang2beac512022-05-07 15:10:04 +0800325 if (xTaskCreate(vSTRTask, "STR_task", configMINIMAL_STACK_SIZE, NULL, 3, NULL) < 0)
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +0800326 printf("STR_task create fail!!\n");
327
328 vCreat_alarm_timer();
329
330 ret = xInstallRemoteMessageCallbackFeedBack(AOTEE_CHANNEL, MBX_CMD_SUSPEND,
xiaohu.huang2beac512022-05-07 15:10:04 +0800331 xMboxSuspend_Sem, 0);
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +0800332 if (ret == MBOX_CALL_MAX)
333 printf("mbox cmd 0x%x register fail\n", MBX_CMD_SUSPEND);
334
335 ret = xInstallRemoteMessageCallbackFeedBack(AOREE_CHANNEL, MBX_CMD_GET_WAKEUP_REASON,
xiaohu.huang2beac512022-05-07 15:10:04 +0800336 xMboxGetWakeupReason, 1);
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +0800337 if (ret == MBOX_CALL_MAX)
338 printf("mbox cmd 0x%x register fail\n", MBX_CMD_GET_WAKEUP_REASON);
339
340 ret = xInstallRemoteMessageCallbackFeedBack(AOREE_CHANNEL, MBX_CMD_CLR_WAKEUP_REASON,
xiaohu.huang2beac512022-05-07 15:10:04 +0800341 xMboxClrWakeupReason, 0);
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +0800342
343 ret = xInstallRemoteMessageCallbackFeedBack(AOREE_CHANNEL, MBX_CMD_GET_STICK_REBOOT_FLAG,
xiaohu.huang2beac512022-05-07 15:10:04 +0800344 xMboxGetStickRebootFlag, 1);
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +0800345 if (ret == MBOX_CALL_MAX)
346 printf("mbox cmd 0x%x register fail\n", MBX_CMD_CLR_WAKEUP_REASON);
Xiaohu.Huang60950452022-03-12 22:51:01 +0800347
xiaohu.huang2beac512022-05-07 15:10:04 +0800348 ret = xInstallRemoteMessageCallbackFeedBack(AOREE_CHANNEL, MBX_CMD_PM_FREEZE, xMboxpm_sem,
349 1);
Xiaohu.Huang60950452022-03-12 22:51:01 +0800350 if (ret == MBOX_CALL_MAX)
351 printf("mbox cmd 0x%x register fail\n", MBX_CMD_PM_FREEZE);
Kelvin Zhangc4c3dd12021-12-24 20:59:18 +0800352}