1 /* 2 * (C) Copyright 2002 3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 4 * 5 * See file CREDITS for list of people who contributed to this 6 * project. 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License as 10 * published by the Free Software Foundation; either version 2 of 11 * the License, or (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 21 * MA 02111-1307 USA 22 */ 23 24 #include <common.h> 25 26 /* 27 * RTC test 28 * 29 * The Real Time Clock (RTC) operation is verified by this test. 30 * The following features are verified: 31 * o) Time uniformity 32 * This is verified by reading RTC in polling within 33 * a short period of time. 34 * o) Passing month boundaries 35 * This is checked by setting RTC to a second before 36 * a month boundary and reading it after its passing the 37 * boundary. The test is performed for both leap- and 38 * nonleap-years. 39 */ 40 41 #ifdef CONFIG_POST 42 43 #include <post.h> 44 #include <rtc.h> 45 46 #if CONFIG_POST & CFG_POST_RTC 47 48 static 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 76 static 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 87 int 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 100 /* Time uniformity */ 101 if (rtc_post_skip (&diff) != 0) { 102 post_log ("Timeout while waiting for a new second !\n"); 103 104 return -1; 105 } 106 107 for (i = 0; i < 5; i++) { 108 if (rtc_post_skip (&diff) != 0) { 109 post_log ("Timeout while waiting for a new second !\n"); 110 111 return -1; 112 } 113 114 if (diff < 950 || diff > 1050) { 115 post_log ("Invalid second duration !\n"); 116 117 return -1; 118 } 119 } 120 121 /* Passing month boundaries */ 122 123 if (rtc_post_skip (&diff) != 0) { 124 post_log ("Timeout while waiting for a new second !\n"); 125 126 return -1; 127 } 128 rtc_get (&svtm); 129 130 for (i = 0; i < 12; i++) { 131 time_t t = mktime (ynl, i + 1, daysnl[i], 23, 59, 59); 132 struct rtc_time tm; 133 134 to_tm (t, &tm); 135 rtc_set (&tm); 136 137 skipped++; 138 if (rtc_post_skip (&diff) != 0) { 139 rtc_post_restore (&svtm, skipped); 140 post_log ("Timeout while waiting for a new second !\n"); 141 142 return -1; 143 } 144 145 rtc_get (&tm); 146 if (tm.tm_mon == i + 1) { 147 rtc_post_restore (&svtm, skipped); 148 post_log ("Month %d boundary is not passed !\n", i + 1); 149 150 return -1; 151 } 152 } 153 154 for (i = 0; i < 12; i++) { 155 time_t t = mktime (yl, i + 1, daysl[i], 23, 59, 59); 156 struct rtc_time tm; 157 158 to_tm (t, &tm); 159 rtc_set (&tm); 160 161 skipped++; 162 if (rtc_post_skip (&diff) != 0) { 163 rtc_post_restore (&svtm, skipped); 164 post_log ("Timeout while waiting for a new second !\n"); 165 166 return -1; 167 } 168 169 rtc_get (&tm); 170 if (tm.tm_mon == i + 1) { 171 rtc_post_restore (&svtm, skipped); 172 post_log ("Month %d boundary is not passed !\n", i + 1); 173 174 return -1; 175 } 176 } 177 rtc_post_restore (&svtm, skipped); 178 179 return 0; 180 } 181 182 #endif /* CONFIG_POST & CFG_POST_RTC */ 183 #endif /* CONFIG_POST */ 184