1 /* 2 * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. 3 * TsiChung Liew (Tsi-Chung.Liew@freescale.com) 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <common.h> 9 10 #if defined(CONFIG_CMD_DATE) 11 12 #include <command.h> 13 #include <rtc.h> 14 #include <asm/immap.h> 15 #include <asm/rtc.h> 16 17 #undef RTC_DEBUG 18 19 #ifndef CONFIG_SYS_MCFRTC_BASE 20 #error RTC_BASE is not defined! 21 #endif 22 23 #define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0) 24 #define STARTOFTIME 1970 25 26 int rtc_get(struct rtc_time *tmp) 27 { 28 volatile rtc_t *rtc = (rtc_t *) (CONFIG_SYS_MCFRTC_BASE); 29 30 int rtc_days, rtc_hrs, rtc_mins; 31 int tim; 32 33 rtc_days = rtc->days; 34 rtc_hrs = rtc->hourmin >> 8; 35 rtc_mins = RTC_HOURMIN_MINUTES(rtc->hourmin); 36 37 tim = (rtc_days * 24) + rtc_hrs; 38 tim = (tim * 60) + rtc_mins; 39 tim = (tim * 60) + rtc->seconds; 40 41 to_tm(tim, tmp); 42 43 tmp->tm_yday = 0; 44 tmp->tm_isdst = 0; 45 46 #ifdef RTC_DEBUG 47 printf("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", 48 tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, 49 tmp->tm_hour, tmp->tm_min, tmp->tm_sec); 50 #endif 51 52 return 0; 53 } 54 55 int rtc_set(struct rtc_time *tmp) 56 { 57 volatile rtc_t *rtc = (rtc_t *) (CONFIG_SYS_MCFRTC_BASE); 58 59 static int month_days[12] = { 60 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 61 }; 62 int days, i, months; 63 64 if (tmp->tm_year > 2037) { 65 printf("Unable to handle. Exceeding integer limitation!\n"); 66 tmp->tm_year = 2027; 67 } 68 #ifdef RTC_DEBUG 69 printf("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", 70 tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, 71 tmp->tm_hour, tmp->tm_min, tmp->tm_sec); 72 #endif 73 74 /* calculate days by years */ 75 for (i = STARTOFTIME, days = 0; i < tmp->tm_year; i++) { 76 days += 365 + isleap(i); 77 } 78 79 /* calculate days by months */ 80 months = tmp->tm_mon - 1; 81 for (i = 0; i < months; i++) { 82 days += month_days[i]; 83 84 if (i == 1) 85 days += isleap(i); 86 } 87 88 days += tmp->tm_mday - 1; 89 90 rtc->days = days; 91 rtc->hourmin = (tmp->tm_hour << 8) | tmp->tm_min; 92 rtc->seconds = tmp->tm_sec; 93 94 return 0; 95 } 96 97 void rtc_reset(void) 98 { 99 volatile rtc_t *rtc = (rtc_t *) (CONFIG_SYS_MCFRTC_BASE); 100 101 if ((rtc->cr & RTC_CR_EN) == 0) { 102 printf("real-time-clock was stopped. Now starting...\n"); 103 rtc->cr |= RTC_CR_EN; 104 } 105 106 rtc->cr |= RTC_CR_SWR; 107 } 108 109 #endif /* CONFIG_MCFRTC && CONFIG_CMD_DATE */ 110