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