1 /* 2 * Freescale i.MX28 RTC Driver 3 * 4 * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com> 5 * on behalf of DENX Software Engineering GmbH 6 * 7 * SPDX-License-Identifier: GPL-2.0+ 8 */ 9 10 #include <common.h> 11 #include <rtc.h> 12 #include <asm/io.h> 13 #include <asm/arch/imx-regs.h> 14 #include <asm/arch/sys_proto.h> 15 16 #define MXS_RTC_MAX_TIMEOUT 1000000 17 18 /* Set time in seconds since 1970-01-01 */ 19 int mxs_rtc_set_time(uint32_t secs) 20 { 21 struct mxs_rtc_regs *rtc_regs = (struct mxs_rtc_regs *)MXS_RTC_BASE; 22 int ret; 23 24 writel(secs, &rtc_regs->hw_rtc_seconds); 25 26 /* 27 * The 0x80 here means seconds were copied to analog. This information 28 * is taken from the linux kernel driver for the STMP37xx RTC since 29 * documentation doesn't mention it. 30 */ 31 ret = mxs_wait_mask_clr(&rtc_regs->hw_rtc_stat_reg, 32 0x80 << RTC_STAT_STALE_REGS_OFFSET, MXS_RTC_MAX_TIMEOUT); 33 34 if (ret) 35 printf("MXS RTC: Timeout waiting for update\n"); 36 37 return ret; 38 } 39 40 int rtc_get(struct rtc_time *time) 41 { 42 struct mxs_rtc_regs *rtc_regs = (struct mxs_rtc_regs *)MXS_RTC_BASE; 43 uint32_t secs; 44 45 secs = readl(&rtc_regs->hw_rtc_seconds); 46 to_tm(secs, time); 47 48 return 0; 49 } 50 51 int rtc_set(struct rtc_time *time) 52 { 53 uint32_t secs; 54 55 secs = mktime(time->tm_year, time->tm_mon, time->tm_mday, 56 time->tm_hour, time->tm_min, time->tm_sec); 57 58 return mxs_rtc_set_time(secs); 59 } 60 61 void rtc_reset(void) 62 { 63 struct mxs_rtc_regs *rtc_regs = (struct mxs_rtc_regs *)MXS_RTC_BASE; 64 int ret; 65 66 /* Set time to 1970-01-01 */ 67 mxs_rtc_set_time(0); 68 69 /* Reset the RTC block */ 70 ret = mxs_reset_block(&rtc_regs->hw_rtc_ctrl_reg); 71 if (ret) 72 printf("MXS RTC: Block reset timeout\n"); 73 } 74