blob: be899a925408c3f6ccfba9c9fab399fb89296926 [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
9#include <common.h>
10#include <rtc.h>
11#include <asm/io.h>
12#include <asm/arch/imx-regs.h>
13#include <asm/arch/sys_proto.h>
14
15#define MXS_RTC_MAX_TIMEOUT 1000000
16
17/* Set time in seconds since 1970-01-01 */
18int mxs_rtc_set_time(uint32_t secs)
19{
Otavio Salvador22f4ff92012-08-05 09:05:31 +000020 struct mxs_rtc_regs *rtc_regs = (struct mxs_rtc_regs *)MXS_RTC_BASE;
Marek Vasut86487262011-11-08 23:18:17 +000021 int ret;
22
23 writel(secs, &rtc_regs->hw_rtc_seconds);
24
25 /*
26 * The 0x80 here means seconds were copied to analog. This information
27 * is taken from the linux kernel driver for the STMP37xx RTC since
28 * documentation doesn't mention it.
29 */
Otavio Salvadorcbf0bf22012-08-13 09:53:12 +000030 ret = mxs_wait_mask_clr(&rtc_regs->hw_rtc_stat_reg,
Marek Vasut86487262011-11-08 23:18:17 +000031 0x80 << RTC_STAT_STALE_REGS_OFFSET, MXS_RTC_MAX_TIMEOUT);
32
33 if (ret)
34 printf("MXS RTC: Timeout waiting for update\n");
35
36 return ret;
37}
38
39int rtc_get(struct rtc_time *time)
40{
Otavio Salvador22f4ff92012-08-05 09:05:31 +000041 struct mxs_rtc_regs *rtc_regs = (struct mxs_rtc_regs *)MXS_RTC_BASE;
Marek Vasut86487262011-11-08 23:18:17 +000042 uint32_t secs;
43
44 secs = readl(&rtc_regs->hw_rtc_seconds);
Simon Glass12994662015-04-20 12:37:18 -060045 rtc_to_tm(secs, time);
Marek Vasut86487262011-11-08 23:18:17 +000046
47 return 0;
48}
49
50int rtc_set(struct rtc_time *time)
51{
52 uint32_t secs;
53
Simon Glass4283e842015-04-20 12:37:19 -060054 secs = rtc_mktime(time);
Marek Vasut86487262011-11-08 23:18:17 +000055
56 return mxs_rtc_set_time(secs);
57}
58
59void rtc_reset(void)
60{
Otavio Salvador22f4ff92012-08-05 09:05:31 +000061 struct mxs_rtc_regs *rtc_regs = (struct mxs_rtc_regs *)MXS_RTC_BASE;
Marek Vasut86487262011-11-08 23:18:17 +000062 int ret;
63
64 /* Set time to 1970-01-01 */
65 mxs_rtc_set_time(0);
66
67 /* Reset the RTC block */
Otavio Salvadorcbf0bf22012-08-13 09:53:12 +000068 ret = mxs_reset_block(&rtc_regs->hw_rtc_ctrl_reg);
Marek Vasut86487262011-11-08 23:18:17 +000069 if (ret)
70 printf("MXS RTC: Block reset timeout\n");
71}