blob: a991597bc760de1b293e0455d7ad8e792fb0eae0 [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{
xiaohu.huang2beac512022-05-07 15:10:04 +080025 uint32_t buf[4] = { 0 };
Xiaohu.Huang60950452022-03-12 22:51:01 +080026 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;
Xiaohu.Huang60950452022-03-12 22:51:01 +080077
xiaohu.huang2beac512022-05-07 15:10:04 +080078 *(val) = REG32(VRTC_STICKY_REG);
Xiaohu.Huang60950452022-03-12 22:51:01 +080079 return 0;
80}
81
82static void set_rtc(uint32_t val)
83{
84 REG32(VRTC_STICKY_REG) = val;
85}
86
87void store_rtc(void)
88{
89 uint32_t reg_val;
90
91 reg_val = REG32(RTC_REAL_TIME);
92 REG32(VRTC_STICKY_REG) = reg_val;
93}
94
95void *MboxSetRTC(void *msg)
96{
97 unsigned int val = *(uint32_t *)msg;
xiaohu.huang2beac512022-05-07 15:10:04 +080098
99 printf("[%s]: %s val=0x%x\n", TAG, __func__, val);
Xiaohu.Huang60950452022-03-12 22:51:01 +0800100 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
xiaohu.huang2beac512022-05-07 15:10:04 +0800113 printf("[%s]: %s val=0x%x\n", TAG, __func__, val);
Xiaohu.Huang60950452022-03-12 22:51:01 +0800114
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
xiaohu.huang2beac512022-05-07 15:10:04 +0800129 ret = xInstallRemoteMessageCallbackFeedBack(AOREE_CHANNEL, MBX_CMD_SET_RTC, MboxSetRTC, 0);
Xiaohu.Huang60950452022-03-12 22:51:01 +0800130 if (ret == MBOX_CALL_MAX)
131 printf("[%s]: mbox cmd 0x%x register fail\n", TAG, MBX_CMD_SET_RTC);
132
xiaohu.huang2beac512022-05-07 15:10:04 +0800133 ret = xInstallRemoteMessageCallbackFeedBack(AOREE_CHANNEL, MBX_CMD_GET_RTC, MboxGetRTC, 1);
Xiaohu.Huang60950452022-03-12 22:51:01 +0800134 if (ret == MBOX_CALL_MAX)
135 printf("[%s]: mbox cmd 0x%x register fail\n", TAG, MBX_CMD_GET_RTC);
136
137 reboot_mode = get_reboot_mode();
138 if (reboot_mode == COLD_REBOOT)
139 reset_rtc();
140}