xref: /rk3399_rockchip-uboot/drivers/rtc/mxsrtc.c (revision fa7a51cb8272bd6076ea4701fd6bdc65a68703ba)
1aa711b11SMarek Vasut /*
2aa711b11SMarek Vasut  * Freescale i.MX28 RTC Driver
3aa711b11SMarek Vasut  *
4aa711b11SMarek Vasut  * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
5aa711b11SMarek Vasut  * on behalf of DENX Software Engineering GmbH
6aa711b11SMarek Vasut  *
7aa711b11SMarek Vasut  * This program is free software; you can redistribute it and/or modify
8aa711b11SMarek Vasut  * it under the terms of the GNU General Public License as published by
9aa711b11SMarek Vasut  * the Free Software Foundation; either version 2 of the License, or
10aa711b11SMarek Vasut  * (at your option) any later version.
11aa711b11SMarek Vasut  *
12aa711b11SMarek Vasut  * This program is distributed in the hope that it will be useful,
13aa711b11SMarek Vasut  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14aa711b11SMarek Vasut  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15aa711b11SMarek Vasut  * GNU General Public License for more details.
16aa711b11SMarek Vasut  *
17aa711b11SMarek Vasut  * You should have received a copy of the GNU General Public License
18aa711b11SMarek Vasut  * along with this program; if not, write to the Free Software
19aa711b11SMarek Vasut  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
20aa711b11SMarek Vasut  *
21aa711b11SMarek Vasut  */
22aa711b11SMarek Vasut 
23aa711b11SMarek Vasut #include <common.h>
24aa711b11SMarek Vasut #include <rtc.h>
25aa711b11SMarek Vasut #include <asm/io.h>
26aa711b11SMarek Vasut #include <asm/arch/imx-regs.h>
27aa711b11SMarek Vasut #include <asm/arch/sys_proto.h>
28aa711b11SMarek Vasut 
29aa711b11SMarek Vasut #define	MXS_RTC_MAX_TIMEOUT	1000000
30aa711b11SMarek Vasut 
31aa711b11SMarek Vasut /* Set time in seconds since 1970-01-01 */
32aa711b11SMarek Vasut int mxs_rtc_set_time(uint32_t secs)
33aa711b11SMarek Vasut {
349c471142SOtavio Salvador 	struct mxs_rtc_regs *rtc_regs = (struct mxs_rtc_regs *)MXS_RTC_BASE;
35aa711b11SMarek Vasut 	int ret;
36aa711b11SMarek Vasut 
37aa711b11SMarek Vasut 	writel(secs, &rtc_regs->hw_rtc_seconds);
38aa711b11SMarek Vasut 
39aa711b11SMarek Vasut 	/*
40aa711b11SMarek Vasut 	 * The 0x80 here means seconds were copied to analog. This information
41aa711b11SMarek Vasut 	 * is taken from the linux kernel driver for the STMP37xx RTC since
42aa711b11SMarek Vasut 	 * documentation doesn't mention it.
43aa711b11SMarek Vasut 	 */
44*fa7a51cbSOtavio Salvador 	ret = mxs_wait_mask_clr(&rtc_regs->hw_rtc_stat_reg,
45aa711b11SMarek Vasut 		0x80 << RTC_STAT_STALE_REGS_OFFSET, MXS_RTC_MAX_TIMEOUT);
46aa711b11SMarek Vasut 
47aa711b11SMarek Vasut 	if (ret)
48aa711b11SMarek Vasut 		printf("MXS RTC: Timeout waiting for update\n");
49aa711b11SMarek Vasut 
50aa711b11SMarek Vasut 	return ret;
51aa711b11SMarek Vasut }
52aa711b11SMarek Vasut 
53aa711b11SMarek Vasut int rtc_get(struct rtc_time *time)
54aa711b11SMarek Vasut {
559c471142SOtavio Salvador 	struct mxs_rtc_regs *rtc_regs = (struct mxs_rtc_regs *)MXS_RTC_BASE;
56aa711b11SMarek Vasut 	uint32_t secs;
57aa711b11SMarek Vasut 
58aa711b11SMarek Vasut 	secs = readl(&rtc_regs->hw_rtc_seconds);
59aa711b11SMarek Vasut 	to_tm(secs, time);
60aa711b11SMarek Vasut 
61aa711b11SMarek Vasut 	return 0;
62aa711b11SMarek Vasut }
63aa711b11SMarek Vasut 
64aa711b11SMarek Vasut int rtc_set(struct rtc_time *time)
65aa711b11SMarek Vasut {
66aa711b11SMarek Vasut 	uint32_t secs;
67aa711b11SMarek Vasut 
68aa711b11SMarek Vasut 	secs = mktime(time->tm_year, time->tm_mon, time->tm_mday,
69aa711b11SMarek Vasut 		time->tm_hour, time->tm_min, time->tm_sec);
70aa711b11SMarek Vasut 
71aa711b11SMarek Vasut 	return mxs_rtc_set_time(secs);
72aa711b11SMarek Vasut }
73aa711b11SMarek Vasut 
74aa711b11SMarek Vasut void rtc_reset(void)
75aa711b11SMarek Vasut {
769c471142SOtavio Salvador 	struct mxs_rtc_regs *rtc_regs = (struct mxs_rtc_regs *)MXS_RTC_BASE;
77aa711b11SMarek Vasut 	int ret;
78aa711b11SMarek Vasut 
79aa711b11SMarek Vasut 	/* Set time to 1970-01-01 */
80aa711b11SMarek Vasut 	mxs_rtc_set_time(0);
81aa711b11SMarek Vasut 
82aa711b11SMarek Vasut 	/* Reset the RTC block */
83*fa7a51cbSOtavio Salvador 	ret = mxs_reset_block(&rtc_regs->hw_rtc_ctrl_reg);
84aa711b11SMarek Vasut 	if (ret)
85aa711b11SMarek Vasut 		printf("MXS RTC: Block reset timeout\n");
86aa711b11SMarek Vasut }
87