xref: /rk3399_rockchip-uboot/drivers/rtc/mcfrtc.c (revision b73a19e1609d0f705cbab8014ca17aefe89e4c76)
10c698dcaSJean-Christophe PLAGNIOL-VILLARD /*
20c698dcaSJean-Christophe PLAGNIOL-VILLARD  * Copyright (C) 2004-2007 Freescale Semiconductor, Inc.
30c698dcaSJean-Christophe PLAGNIOL-VILLARD  * TsiChung Liew (Tsi-Chung.Liew@freescale.com)
40c698dcaSJean-Christophe PLAGNIOL-VILLARD  *
50c698dcaSJean-Christophe PLAGNIOL-VILLARD  * See file CREDITS for list of people who contributed to this
60c698dcaSJean-Christophe PLAGNIOL-VILLARD  * project.
70c698dcaSJean-Christophe PLAGNIOL-VILLARD  *
80c698dcaSJean-Christophe PLAGNIOL-VILLARD  * This program is free software; you can redistribute it and/or
90c698dcaSJean-Christophe PLAGNIOL-VILLARD  * modify it under the terms of the GNU General Public License as
100c698dcaSJean-Christophe PLAGNIOL-VILLARD  * published by the Free Software Foundation; either version 2 of
110c698dcaSJean-Christophe PLAGNIOL-VILLARD  * the License, or (at your option) any later version.
120c698dcaSJean-Christophe PLAGNIOL-VILLARD  *
130c698dcaSJean-Christophe PLAGNIOL-VILLARD  * This program is distributed in the hope that it will be useful,
140c698dcaSJean-Christophe PLAGNIOL-VILLARD  * but WITHOUT ANY WARRANTY; without even the implied warranty of
150c698dcaSJean-Christophe PLAGNIOL-VILLARD  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
160c698dcaSJean-Christophe PLAGNIOL-VILLARD  * GNU General Public License for more details.
170c698dcaSJean-Christophe PLAGNIOL-VILLARD  *
180c698dcaSJean-Christophe PLAGNIOL-VILLARD  * You should have received a copy of the GNU General Public License
190c698dcaSJean-Christophe PLAGNIOL-VILLARD  * along with this program; if not, write to the Free Software
200c698dcaSJean-Christophe PLAGNIOL-VILLARD  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
210c698dcaSJean-Christophe PLAGNIOL-VILLARD  * MA 02111-1307 USA
220c698dcaSJean-Christophe PLAGNIOL-VILLARD  */
230c698dcaSJean-Christophe PLAGNIOL-VILLARD 
240c698dcaSJean-Christophe PLAGNIOL-VILLARD #include <common.h>
250c698dcaSJean-Christophe PLAGNIOL-VILLARD 
260c698dcaSJean-Christophe PLAGNIOL-VILLARD #if defined(CONFIG_MCFRTC) && defined(CONFIG_CMD_DATE)
270c698dcaSJean-Christophe PLAGNIOL-VILLARD 
280c698dcaSJean-Christophe PLAGNIOL-VILLARD #include <command.h>
290c698dcaSJean-Christophe PLAGNIOL-VILLARD #include <rtc.h>
300c698dcaSJean-Christophe PLAGNIOL-VILLARD #include <asm/immap.h>
310c698dcaSJean-Christophe PLAGNIOL-VILLARD #include <asm/rtc.h>
320c698dcaSJean-Christophe PLAGNIOL-VILLARD 
330c698dcaSJean-Christophe PLAGNIOL-VILLARD #undef RTC_DEBUG
340c698dcaSJean-Christophe PLAGNIOL-VILLARD 
350c698dcaSJean-Christophe PLAGNIOL-VILLARD #ifndef CFG_MCFRTC_BASE
360c698dcaSJean-Christophe PLAGNIOL-VILLARD #error RTC_BASE is not defined!
370c698dcaSJean-Christophe PLAGNIOL-VILLARD #endif
380c698dcaSJean-Christophe PLAGNIOL-VILLARD 
390c698dcaSJean-Christophe PLAGNIOL-VILLARD #define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
400c698dcaSJean-Christophe PLAGNIOL-VILLARD #define	STARTOFTIME		1970
410c698dcaSJean-Christophe PLAGNIOL-VILLARD 
42*b73a19e1SYuri Tikhonov int rtc_get(struct rtc_time *tmp)
430c698dcaSJean-Christophe PLAGNIOL-VILLARD {
440c698dcaSJean-Christophe PLAGNIOL-VILLARD 	volatile rtc_t *rtc = (rtc_t *) (CFG_MCFRTC_BASE);
450c698dcaSJean-Christophe PLAGNIOL-VILLARD 
460c698dcaSJean-Christophe PLAGNIOL-VILLARD 	int rtc_days, rtc_hrs, rtc_mins;
470c698dcaSJean-Christophe PLAGNIOL-VILLARD 	int tim;
480c698dcaSJean-Christophe PLAGNIOL-VILLARD 
490c698dcaSJean-Christophe PLAGNIOL-VILLARD 	rtc_days = rtc->days;
500c698dcaSJean-Christophe PLAGNIOL-VILLARD 	rtc_hrs = rtc->hourmin >> 8;
510c698dcaSJean-Christophe PLAGNIOL-VILLARD 	rtc_mins = RTC_HOURMIN_MINUTES(rtc->hourmin);
520c698dcaSJean-Christophe PLAGNIOL-VILLARD 
530c698dcaSJean-Christophe PLAGNIOL-VILLARD 	tim = (rtc_days * 24) + rtc_hrs;
540c698dcaSJean-Christophe PLAGNIOL-VILLARD 	tim = (tim * 60) + rtc_mins;
550c698dcaSJean-Christophe PLAGNIOL-VILLARD 	tim = (tim * 60) + rtc->seconds;
560c698dcaSJean-Christophe PLAGNIOL-VILLARD 
570c698dcaSJean-Christophe PLAGNIOL-VILLARD 	to_tm(tim, tmp);
580c698dcaSJean-Christophe PLAGNIOL-VILLARD 
590c698dcaSJean-Christophe PLAGNIOL-VILLARD 	tmp->tm_yday = 0;
600c698dcaSJean-Christophe PLAGNIOL-VILLARD 	tmp->tm_isdst = 0;
610c698dcaSJean-Christophe PLAGNIOL-VILLARD 
620c698dcaSJean-Christophe PLAGNIOL-VILLARD #ifdef RTC_DEBUG
630c698dcaSJean-Christophe PLAGNIOL-VILLARD 	printf("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
640c698dcaSJean-Christophe PLAGNIOL-VILLARD 	       tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
650c698dcaSJean-Christophe PLAGNIOL-VILLARD 	       tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
660c698dcaSJean-Christophe PLAGNIOL-VILLARD #endif
67*b73a19e1SYuri Tikhonov 
68*b73a19e1SYuri Tikhonov 	return 0;
690c698dcaSJean-Christophe PLAGNIOL-VILLARD }
700c698dcaSJean-Christophe PLAGNIOL-VILLARD 
710c698dcaSJean-Christophe PLAGNIOL-VILLARD void rtc_set(struct rtc_time *tmp)
720c698dcaSJean-Christophe PLAGNIOL-VILLARD {
730c698dcaSJean-Christophe PLAGNIOL-VILLARD 	volatile rtc_t *rtc = (rtc_t *) (CFG_MCFRTC_BASE);
740c698dcaSJean-Christophe PLAGNIOL-VILLARD 
750c698dcaSJean-Christophe PLAGNIOL-VILLARD 	static int month_days[12] = {
760c698dcaSJean-Christophe PLAGNIOL-VILLARD 		31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
770c698dcaSJean-Christophe PLAGNIOL-VILLARD 	};
780c698dcaSJean-Christophe PLAGNIOL-VILLARD 	int days, i, months;
790c698dcaSJean-Christophe PLAGNIOL-VILLARD 
800c698dcaSJean-Christophe PLAGNIOL-VILLARD 	if (tmp->tm_year > 2037) {
810c698dcaSJean-Christophe PLAGNIOL-VILLARD 		printf("Unable to handle. Exceeding integer limitation!\n");
820c698dcaSJean-Christophe PLAGNIOL-VILLARD 		tmp->tm_year = 2027;
830c698dcaSJean-Christophe PLAGNIOL-VILLARD 	}
840c698dcaSJean-Christophe PLAGNIOL-VILLARD #ifdef RTC_DEBUG
850c698dcaSJean-Christophe PLAGNIOL-VILLARD 	printf("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
860c698dcaSJean-Christophe PLAGNIOL-VILLARD 	       tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
870c698dcaSJean-Christophe PLAGNIOL-VILLARD 	       tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
880c698dcaSJean-Christophe PLAGNIOL-VILLARD #endif
890c698dcaSJean-Christophe PLAGNIOL-VILLARD 
900c698dcaSJean-Christophe PLAGNIOL-VILLARD 	/* calculate days by years */
910c698dcaSJean-Christophe PLAGNIOL-VILLARD 	for (i = STARTOFTIME, days = 0; i < tmp->tm_year; i++) {
920c698dcaSJean-Christophe PLAGNIOL-VILLARD 		days += 365 + isleap(i);
930c698dcaSJean-Christophe PLAGNIOL-VILLARD 	}
940c698dcaSJean-Christophe PLAGNIOL-VILLARD 
950c698dcaSJean-Christophe PLAGNIOL-VILLARD 	/* calculate days by months */
960c698dcaSJean-Christophe PLAGNIOL-VILLARD 	months = tmp->tm_mon - 1;
970c698dcaSJean-Christophe PLAGNIOL-VILLARD 	for (i = 0; i < months; i++) {
980c698dcaSJean-Christophe PLAGNIOL-VILLARD 		days += month_days[i];
990c698dcaSJean-Christophe PLAGNIOL-VILLARD 
1000c698dcaSJean-Christophe PLAGNIOL-VILLARD 		if (i == 1)
1010c698dcaSJean-Christophe PLAGNIOL-VILLARD 			days += isleap(i);
1020c698dcaSJean-Christophe PLAGNIOL-VILLARD 	}
1030c698dcaSJean-Christophe PLAGNIOL-VILLARD 
1040c698dcaSJean-Christophe PLAGNIOL-VILLARD 	days += tmp->tm_mday - 1;
1050c698dcaSJean-Christophe PLAGNIOL-VILLARD 
1060c698dcaSJean-Christophe PLAGNIOL-VILLARD 	rtc->days = days;
1070c698dcaSJean-Christophe PLAGNIOL-VILLARD 	rtc->hourmin = (tmp->tm_hour << 8) | tmp->tm_min;
1080c698dcaSJean-Christophe PLAGNIOL-VILLARD 	rtc->seconds = tmp->tm_sec;
1090c698dcaSJean-Christophe PLAGNIOL-VILLARD }
1100c698dcaSJean-Christophe PLAGNIOL-VILLARD 
1110c698dcaSJean-Christophe PLAGNIOL-VILLARD void rtc_reset(void)
1120c698dcaSJean-Christophe PLAGNIOL-VILLARD {
1130c698dcaSJean-Christophe PLAGNIOL-VILLARD 	volatile rtc_t *rtc = (rtc_t *) (CFG_MCFRTC_BASE);
1140c698dcaSJean-Christophe PLAGNIOL-VILLARD 
1150c698dcaSJean-Christophe PLAGNIOL-VILLARD 	if ((rtc->cr & RTC_CR_EN) == 0) {
1160c698dcaSJean-Christophe PLAGNIOL-VILLARD 		printf("real-time-clock was stopped. Now starting...\n");
1170c698dcaSJean-Christophe PLAGNIOL-VILLARD 		rtc->cr |= RTC_CR_EN;
1180c698dcaSJean-Christophe PLAGNIOL-VILLARD 	}
1190c698dcaSJean-Christophe PLAGNIOL-VILLARD 
1200c698dcaSJean-Christophe PLAGNIOL-VILLARD 	rtc->cr |= RTC_CR_SWR;
1210c698dcaSJean-Christophe PLAGNIOL-VILLARD }
1220c698dcaSJean-Christophe PLAGNIOL-VILLARD 
1230c698dcaSJean-Christophe PLAGNIOL-VILLARD #endif				/* CONFIG_MCFRTC && CONFIG_CMD_DATE */
124