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 #include <post.h> 42 #include <rtc.h> 43 44 #if CONFIG_POST & CFG_POST_RTC 45 46 static int rtc_post_skip (ulong * diff) 47 { 48 struct rtc_time tm1; 49 struct rtc_time tm2; 50 ulong start1; 51 ulong start2; 52 53 rtc_get (&tm1); 54 start1 = get_timer (0); 55 56 while (1) { 57 rtc_get (&tm2); 58 start2 = get_timer (0); 59 if (tm1.tm_sec != tm2.tm_sec) 60 break; 61 if (start2 - start1 > 1500) 62 break; 63 } 64 65 if (tm1.tm_sec != tm2.tm_sec) { 66 *diff = start2 - start1; 67 68 return 0; 69 } else { 70 return -1; 71 } 72 } 73 74 static void rtc_post_restore (struct rtc_time *tm, unsigned int sec) 75 { 76 time_t t = mktime (tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, 77 tm->tm_min, tm->tm_sec) + sec; 78 struct rtc_time ntm; 79 80 to_tm (t, &ntm); 81 82 rtc_set (&ntm); 83 } 84 85 int rtc_post_test (int flags) 86 { 87 ulong diff; 88 unsigned int i; 89 struct rtc_time svtm; 90 static unsigned int daysnl[] = 91 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 92 static unsigned int daysl[] = 93 { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 94 unsigned int ynl = 1999; 95 unsigned int yl = 2000; 96 unsigned int skipped = 0; 97 98 /* Time uniformity */ 99 if (rtc_post_skip (&diff) != 0) { 100 post_log ("Timeout while waiting for a new second !\n"); 101 102 return -1; 103 } 104 105 for (i = 0; i < 5; i++) { 106 if (rtc_post_skip (&diff) != 0) { 107 post_log ("Timeout while waiting for a new second !\n"); 108 109 return -1; 110 } 111 112 if (diff < 950 || diff > 1050) { 113 post_log ("Invalid second duration !\n"); 114 115 return -1; 116 } 117 } 118 119 /* Passing month boundaries */ 120 121 if (rtc_post_skip (&diff) != 0) { 122 post_log ("Timeout while waiting for a new second !\n"); 123 124 return -1; 125 } 126 rtc_get (&svtm); 127 128 for (i = 0; i < 12; i++) { 129 time_t t = mktime (ynl, i + 1, daysnl[i], 23, 59, 59); 130 struct rtc_time tm; 131 132 to_tm (t, &tm); 133 rtc_set (&tm); 134 135 skipped++; 136 if (rtc_post_skip (&diff) != 0) { 137 rtc_post_restore (&svtm, skipped); 138 post_log ("Timeout while waiting for a new second !\n"); 139 140 return -1; 141 } 142 143 rtc_get (&tm); 144 if (tm.tm_mon == i + 1) { 145 rtc_post_restore (&svtm, skipped); 146 post_log ("Month %d boundary is not passed !\n", i + 1); 147 148 return -1; 149 } 150 } 151 152 for (i = 0; i < 12; i++) { 153 time_t t = mktime (yl, i + 1, daysl[i], 23, 59, 59); 154 struct rtc_time tm; 155 156 to_tm (t, &tm); 157 rtc_set (&tm); 158 159 skipped++; 160 if (rtc_post_skip (&diff) != 0) { 161 rtc_post_restore (&svtm, skipped); 162 post_log ("Timeout while waiting for a new second !\n"); 163 164 return -1; 165 } 166 167 rtc_get (&tm); 168 if (tm.tm_mon == i + 1) { 169 rtc_post_restore (&svtm, skipped); 170 post_log ("Month %d boundary is not passed !\n", i + 1); 171 172 return -1; 173 } 174 } 175 rtc_post_restore (&svtm, skipped); 176 177 return 0; 178 } 179 180 #endif /* CONFIG_POST & CFG_POST_RTC */ 181