xref: /rk3399_rockchip-uboot/drivers/rtc/mxsrtc.c (revision 02ffb580e6ab7aaa7f6703ed35f489e97439cb65)
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  *
71a459660SWolfgang Denk  * SPDX-License-Identifier:	GPL-2.0+
8aa711b11SMarek Vasut  */
9aa711b11SMarek Vasut 
10aa711b11SMarek Vasut #include <common.h>
11aa711b11SMarek Vasut #include <rtc.h>
12aa711b11SMarek Vasut #include <asm/io.h>
13aa711b11SMarek Vasut #include <asm/arch/imx-regs.h>
14aa711b11SMarek Vasut #include <asm/arch/sys_proto.h>
15aa711b11SMarek Vasut 
16aa711b11SMarek Vasut #define	MXS_RTC_MAX_TIMEOUT	1000000
17aa711b11SMarek Vasut 
18aa711b11SMarek Vasut /* Set time in seconds since 1970-01-01 */
mxs_rtc_set_time(uint32_t secs)19aa711b11SMarek Vasut int mxs_rtc_set_time(uint32_t secs)
20aa711b11SMarek Vasut {
219c471142SOtavio Salvador 	struct mxs_rtc_regs *rtc_regs = (struct mxs_rtc_regs *)MXS_RTC_BASE;
22aa711b11SMarek Vasut 	int ret;
23aa711b11SMarek Vasut 
24aa711b11SMarek Vasut 	writel(secs, &rtc_regs->hw_rtc_seconds);
25aa711b11SMarek Vasut 
26aa711b11SMarek Vasut 	/*
27aa711b11SMarek Vasut 	 * The 0x80 here means seconds were copied to analog. This information
28aa711b11SMarek Vasut 	 * is taken from the linux kernel driver for the STMP37xx RTC since
29aa711b11SMarek Vasut 	 * documentation doesn't mention it.
30aa711b11SMarek Vasut 	 */
31fa7a51cbSOtavio Salvador 	ret = mxs_wait_mask_clr(&rtc_regs->hw_rtc_stat_reg,
32aa711b11SMarek Vasut 		0x80 << RTC_STAT_STALE_REGS_OFFSET, MXS_RTC_MAX_TIMEOUT);
33aa711b11SMarek Vasut 
34aa711b11SMarek Vasut 	if (ret)
35aa711b11SMarek Vasut 		printf("MXS RTC: Timeout waiting for update\n");
36aa711b11SMarek Vasut 
37aa711b11SMarek Vasut 	return ret;
38aa711b11SMarek Vasut }
39aa711b11SMarek Vasut 
rtc_get(struct rtc_time * time)40aa711b11SMarek Vasut int rtc_get(struct rtc_time *time)
41aa711b11SMarek Vasut {
429c471142SOtavio Salvador 	struct mxs_rtc_regs *rtc_regs = (struct mxs_rtc_regs *)MXS_RTC_BASE;
43aa711b11SMarek Vasut 	uint32_t secs;
44aa711b11SMarek Vasut 
45aa711b11SMarek Vasut 	secs = readl(&rtc_regs->hw_rtc_seconds);
469f9276c3SSimon Glass 	rtc_to_tm(secs, time);
47aa711b11SMarek Vasut 
48aa711b11SMarek Vasut 	return 0;
49aa711b11SMarek Vasut }
50aa711b11SMarek Vasut 
rtc_set(struct rtc_time * time)51aa711b11SMarek Vasut int rtc_set(struct rtc_time *time)
52aa711b11SMarek Vasut {
53aa711b11SMarek Vasut 	uint32_t secs;
54aa711b11SMarek Vasut 
55*71420983SSimon Glass 	secs = rtc_mktime(time);
56aa711b11SMarek Vasut 
57aa711b11SMarek Vasut 	return mxs_rtc_set_time(secs);
58aa711b11SMarek Vasut }
59aa711b11SMarek Vasut 
rtc_reset(void)60aa711b11SMarek Vasut void rtc_reset(void)
61aa711b11SMarek Vasut {
629c471142SOtavio Salvador 	struct mxs_rtc_regs *rtc_regs = (struct mxs_rtc_regs *)MXS_RTC_BASE;
63aa711b11SMarek Vasut 	int ret;
64aa711b11SMarek Vasut 
65aa711b11SMarek Vasut 	/* Set time to 1970-01-01 */
66aa711b11SMarek Vasut 	mxs_rtc_set_time(0);
67aa711b11SMarek Vasut 
68aa711b11SMarek Vasut 	/* Reset the RTC block */
69fa7a51cbSOtavio Salvador 	ret = mxs_reset_block(&rtc_regs->hw_rtc_ctrl_reg);
70aa711b11SMarek Vasut 	if (ret)
71aa711b11SMarek Vasut 		printf("MXS RTC: Block reset timeout\n");
72aa711b11SMarek Vasut }
73