blob: d000706ed3a974089da3866b6403cd69e7b94401 [file] [log] [blame]
Xiaohu.Huang60950452022-03-12 22:51:01 +08001/*
2 * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
3 *
4 * SPDX-License-Identifier: MIT
5 */
6
7#include <stdio.h>
8#include <string.h>
9#include <unistd.h>
10#include "common.h"
11#include "rtc.h"
12#include "register.h"
13#include "FreeRTOS.h"
14#include "mailbox-api.h"
15#include "soc.h"
16#include "string.h"
17#include "interrupt.h"
18#include "suspend.h"
19
20#undef TAG
21#define TAG "AOCPU RTC"
22
23static void vRTCInterruptHandler(void)
24{
25 uint32_t buf[4] = {0};
26 uint32_t alarm0_int_status;
27 uint32_t reg_val;
28
29 /* Mask alarm0 irq */
30 reg_val = REG32(RTC_INT_MASK);
31 reg_val |= 0x1;
32 REG32(RTC_INT_MASK) = reg_val;
33
34 /* Clear alarm0 */
35 REG32(RTC_ALARM0_REG) = 0;
36
37 alarm0_int_status = REG32(RTC_INT_STATUS) & (1 << RTC_INT_ALM0_IRQ);
38 /* Clear alarm0 int status */
39 if (alarm0_int_status)
40 REG32(RTC_INT_CLR) |= (1 << RTC_INT_CLR_ALM0_IRQ);
41
42 printf("[%s]: rtc alarm fired\n", TAG);
43
44 buf[0] = RTC_WAKEUP;
45 STR_Wakeup_src_Queue_Send_FromISR(buf);
46}
47
48static uint32_t get_reboot_mode(void)
49{
50 uint32_t reg_val;
51 uint32_t reboot_mode;
52
53 reg_val = REG32(SYSCTRL_SEC_STATUS_REG31);
54 reboot_mode = ((reg_val >> 12) & 0xf);
55
56 return reboot_mode;
57}
58
59static void reset_rtc(void)
60{
61 uint32_t reg_val;
62
63 printf("[%s]: reset rtc\n", TAG);
64 /* Reset RTC */
65 reg_val = (1 << 0);
66 REG32(RESETCTRL_RESET4) = reg_val;
67 /* Mask RTC reset to prevent RTC being reset in the next reboot */
68 reg_val = REG32(RESETCTRL_RESET4_MASK);
69 reg_val |= (1 << 0);
70 REG32(RESETCTRL_RESET4_MASK) = reg_val;
71}
72
73static int get_rtc(uint32_t *val)
74{
75 if (!REG32(VRTC_STICKY_REG))
76 return -1;
77 else
78 *(val) = REG32(VRTC_STICKY_REG);
79
80 return 0;
81}
82
83static void set_rtc(uint32_t val)
84{
85 REG32(VRTC_STICKY_REG) = val;
86}
87
88void store_rtc(void)
89{
90 uint32_t reg_val;
91
92 reg_val = REG32(RTC_REAL_TIME);
93 REG32(VRTC_STICKY_REG) = reg_val;
94}
95
96void *MboxSetRTC(void *msg)
97{
98 unsigned int val = *(uint32_t *)msg;
99 printf("[%s]: MboxSetRTC val=0x%x \n", TAG, val);
100 set_rtc(val);
101
102 return NULL;
103}
104
105void *MboxGetRTC(void *msg)
106{
107 uint32_t val = 0;
108
109 get_rtc(&val);
110 memset(msg, 0, MBOX_BUF_LEN);
111 *(uint32_t *)msg = val;
112
113 printf("[%s]: MboxGetRTC val=0x%x\n", TAG, val);
114
115 return NULL;
116}
117
118void rtc_init(void)
119{
120 int ret;
121 uint32_t reboot_mode;
122
123 printf("[%s]: init rtc\n", TAG);
124 ret = RegisterIrq(RTC_IRQ, 6, vRTCInterruptHandler);
125 if (ret)
126 printf("[%s]: RegisterIrq error, ret = %d\n", TAG, ret);
127 EnableIrq(RTC_IRQ);
128
129 ret = xInstallRemoteMessageCallbackFeedBack(AOREE_CHANNEL, MBX_CMD_SET_RTC,
130 MboxSetRTC, 0);
131 if (ret == MBOX_CALL_MAX)
132 printf("[%s]: mbox cmd 0x%x register fail\n", TAG, MBX_CMD_SET_RTC);
133
134 ret = xInstallRemoteMessageCallbackFeedBack(AOREE_CHANNEL, MBX_CMD_GET_RTC,
135 MboxGetRTC, 1);
136 if (ret == MBOX_CALL_MAX)
137 printf("[%s]: mbox cmd 0x%x register fail\n", TAG, MBX_CMD_GET_RTC);
138
139 reboot_mode = get_reboot_mode();
140 if (reboot_mode == COLD_REBOOT)
141 reset_rtc();
142}
143