blob: 69d22a4bdcb6b6019d9ea4e9448bcdb1fdc4f4ca [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Marek Vasut86487262011-11-08 23:18:17 +00002/*
3 * Freescale i.MX28 RTC Driver
4 *
5 * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
6 * on behalf of DENX Software Engineering GmbH
Marek Vasut86487262011-11-08 23:18:17 +00007 */
8
Marek Vasut86487262011-11-08 23:18:17 +00009#include <rtc.h>
10#include <asm/io.h>
11#include <asm/arch/imx-regs.h>
12#include <asm/arch/sys_proto.h>
13
14#define MXS_RTC_MAX_TIMEOUT 1000000
15
16/* Set time in seconds since 1970-01-01 */
17int mxs_rtc_set_time(uint32_t secs)
18{
Otavio Salvador22f4ff92012-08-05 09:05:31 +000019 struct mxs_rtc_regs *rtc_regs = (struct mxs_rtc_regs *)MXS_RTC_BASE;
Marek Vasut86487262011-11-08 23:18:17 +000020 int ret;
21
22 writel(secs, &rtc_regs->hw_rtc_seconds);
23
24 /*
25 * The 0x80 here means seconds were copied to analog. This information
26 * is taken from the linux kernel driver for the STMP37xx RTC since
27 * documentation doesn't mention it.
28 */
Otavio Salvadorcbf0bf22012-08-13 09:53:12 +000029 ret = mxs_wait_mask_clr(&rtc_regs->hw_rtc_stat_reg,
Marek Vasut86487262011-11-08 23:18:17 +000030 0x80 << RTC_STAT_STALE_REGS_OFFSET, MXS_RTC_MAX_TIMEOUT);
31
32 if (ret)
33 printf("MXS RTC: Timeout waiting for update\n");
34
35 return ret;
36}
37
38int rtc_get(struct rtc_time *time)
39{
Otavio Salvador22f4ff92012-08-05 09:05:31 +000040 struct mxs_rtc_regs *rtc_regs = (struct mxs_rtc_regs *)MXS_RTC_BASE;
Marek Vasut86487262011-11-08 23:18:17 +000041 uint32_t secs;
42
43 secs = readl(&rtc_regs->hw_rtc_seconds);
Simon Glass12994662015-04-20 12:37:18 -060044 rtc_to_tm(secs, time);
Marek Vasut86487262011-11-08 23:18:17 +000045
46 return 0;
47}
48
49int rtc_set(struct rtc_time *time)
50{
51 uint32_t secs;
52
Simon Glass4283e842015-04-20 12:37:19 -060053 secs = rtc_mktime(time);
Marek Vasut86487262011-11-08 23:18:17 +000054
55 return mxs_rtc_set_time(secs);
56}
57
58void rtc_reset(void)
59{
Otavio Salvador22f4ff92012-08-05 09:05:31 +000060 struct mxs_rtc_regs *rtc_regs = (struct mxs_rtc_regs *)MXS_RTC_BASE;
Marek Vasut86487262011-11-08 23:18:17 +000061 int ret;
62
63 /* Set time to 1970-01-01 */
64 mxs_rtc_set_time(0);
65
66 /* Reset the RTC block */
Otavio Salvadorcbf0bf22012-08-13 09:53:12 +000067 ret = mxs_reset_block(&rtc_regs->hw_rtc_ctrl_reg);
Marek Vasut86487262011-11-08 23:18:17 +000068 if (ret)
69 printf("MXS RTC: Block reset timeout\n");
70}