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