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