1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include <common.h>
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43#include <post.h>
44#include <rtc.h>
45
46#if CONFIG_POST & CONFIG_SYS_POST_RTC
47
48static int rtc_post_skip (ulong * diff)
49{
50 struct rtc_time tm1;
51 struct rtc_time tm2;
52 ulong start1;
53 ulong start2;
54
55 rtc_get (&tm1);
56 start1 = get_timer (0);
57
58 while (1) {
59 rtc_get (&tm2);
60 start2 = get_timer (0);
61 if (tm1.tm_sec != tm2.tm_sec)
62 break;
63 if (start2 - start1 > 1500)
64 break;
65 }
66
67 if (tm1.tm_sec != tm2.tm_sec) {
68 *diff = start2 - start1;
69
70 return 0;
71 } else {
72 return -1;
73 }
74}
75
76static void rtc_post_restore (struct rtc_time *tm, unsigned int sec)
77{
78 time_t t = mktime (tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour,
79 tm->tm_min, tm->tm_sec) + sec;
80 struct rtc_time ntm;
81
82 to_tm (t, &ntm);
83
84 rtc_set (&ntm);
85}
86
87int rtc_post_test (int flags)
88{
89 ulong diff;
90 unsigned int i;
91 struct rtc_time svtm;
92 static unsigned int daysnl[] =
93 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
94 static unsigned int daysl[] =
95 { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
96 unsigned int ynl = 1999;
97 unsigned int yl = 2000;
98 unsigned int skipped = 0;
99 int reliable;
100
101
102 reliable = rtc_get (&svtm);
103
104
105 if (rtc_post_skip (&diff) != 0) {
106 post_log ("Timeout while waiting for a new second !\n");
107
108 return -1;
109 }
110
111 for (i = 0; i < 5; i++) {
112 if (rtc_post_skip (&diff) != 0) {
113 post_log ("Timeout while waiting for a new second !\n");
114
115 return -1;
116 }
117
118 if (diff < 950 || diff > 1050) {
119 post_log ("Invalid second duration !\n");
120
121 return -1;
122 }
123 }
124
125
126
127 if (rtc_post_skip (&diff) != 0) {
128 post_log ("Timeout while waiting for a new second !\n");
129
130 return -1;
131 }
132 rtc_get (&svtm);
133
134 for (i = 0; i < 12; i++) {
135 time_t t = mktime (ynl, i + 1, daysnl[i], 23, 59, 59);
136 struct rtc_time tm;
137
138 to_tm (t, &tm);
139 rtc_set (&tm);
140
141 skipped++;
142 if (rtc_post_skip (&diff) != 0) {
143 rtc_post_restore (&svtm, skipped);
144 post_log ("Timeout while waiting for a new second !\n");
145
146 return -1;
147 }
148
149 rtc_get (&tm);
150 if (tm.tm_mon == i + 1) {
151 rtc_post_restore (&svtm, skipped);
152 post_log ("Month %d boundary is not passed !\n", i + 1);
153
154 return -1;
155 }
156 }
157
158 for (i = 0; i < 12; i++) {
159 time_t t = mktime (yl, i + 1, daysl[i], 23, 59, 59);
160 struct rtc_time tm;
161
162 to_tm (t, &tm);
163 rtc_set (&tm);
164
165 skipped++;
166 if (rtc_post_skip (&diff) != 0) {
167 rtc_post_restore (&svtm, skipped);
168 post_log ("Timeout while waiting for a new second !\n");
169
170 return -1;
171 }
172
173 rtc_get (&tm);
174 if (tm.tm_mon == i + 1) {
175 rtc_post_restore (&svtm, skipped);
176 post_log ("Month %d boundary is not passed !\n", i + 1);
177
178 return -1;
179 }
180 }
181 rtc_post_restore (&svtm, skipped);
182
183
184
185
186 if (reliable < 0) {
187 post_log ("RTC Time is not reliable! Power fault? \n");
188
189 return -1;
190 }
191
192 return 0;
193}
194
195#endif
196