blob: 97dadd068b9d29c9b56071cca02a817d838ff973 [file] [log] [blame]
Jason Cooperb608b952011-08-04 21:26:16 +05301/*
2 * Copyright (C) 2011
3 * Jason Cooper <u-boot@lakedaemon.net>
4 *
Wolfgang Denk1a459662013-07-08 09:37:19 +02005 * SPDX-License-Identifier: GPL-2.0+
Jason Cooperb608b952011-08-04 21:26:16 +05306 */
7
8/*
9 * Date & Time support for Marvell Integrated RTC
10 */
11
12#include <common.h>
13#include <command.h>
14#include <rtc.h>
Anatolij Gustschin0ac16bf2011-10-29 11:19:47 +000015#include <asm/io.h>
Jason Cooperb608b952011-08-04 21:26:16 +053016#include "mvrtc.h"
17
18/* This RTC does not support century, so we assume 20 */
19#define CENTURY 20
20
21int rtc_get(struct rtc_time *t)
22{
23 u32 time;
24 u32 date;
25 struct mvrtc_registers *mvrtc_regs;
26
27 mvrtc_regs = (struct mvrtc_registers *)KW_RTC_BASE;
28
29 /* read the time register */
30 time = readl(&mvrtc_regs->time);
31
32 /* read the date register */
33 date = readl(&mvrtc_regs->date);
34
35 /* test for 12 hour clock (can't tell if it's am/pm) */
36 if (time & MVRTC_HRFMT_MSK) {
37 printf("Error: RTC in 12 hour mode, can't determine AM/PM.\n");
38 return -1;
39 }
40
41 /* time */
42 t->tm_sec = bcd2bin((time >> MVRTC_SEC_SFT) & MVRTC_SEC_MSK);
43 t->tm_min = bcd2bin((time >> MVRTC_MIN_SFT) & MVRTC_MIN_MSK);
44 t->tm_hour = bcd2bin((time >> MVRTC_HOUR_SFT) & MVRTC_HOUR_MSK);
45 t->tm_wday = bcd2bin((time >> MVRTC_DAY_SFT) & MVRTC_DAY_MSK);
46 t->tm_wday--;
47
48 /* date */
49 t->tm_mday = bcd2bin((date >> MVRTC_DATE_SFT) & MVRTC_DATE_MSK);
50 t->tm_mon = bcd2bin((date >> MVRTC_MON_SFT) & MVRTC_MON_MSK);
51 t->tm_year = bcd2bin((date >> MVRTC_YEAR_SFT) & MVRTC_YEAR_MSK);
52 t->tm_year += CENTURY * 100;
53
54 /* not supported in this RTC */
55 t->tm_yday = 0;
56 t->tm_isdst = 0;
57
58 return 0;
59}
60
61int rtc_set(struct rtc_time *t)
62{
63 u32 time = 0; /* sets hour format bit to zero, 24hr format. */
64 u32 date = 0;
65 struct mvrtc_registers *mvrtc_regs;
66
67 mvrtc_regs = (struct mvrtc_registers *)KW_RTC_BASE;
68
69 /* check that this code isn't 80+ years old ;-) */
70 if ((t->tm_year / 100) != CENTURY)
71 printf("Warning: Only century %d supported.\n", CENTURY);
72
73 /* time */
74 time |= (bin2bcd(t->tm_sec) & MVRTC_SEC_MSK) << MVRTC_SEC_SFT;
75 time |= (bin2bcd(t->tm_min) & MVRTC_MIN_MSK) << MVRTC_MIN_SFT;
76 time |= (bin2bcd(t->tm_hour) & MVRTC_HOUR_MSK) << MVRTC_HOUR_SFT;
77 time |= (bin2bcd(t->tm_wday + 1) & MVRTC_DAY_MSK) << MVRTC_DAY_SFT;
78
79 /* date */
80 date |= (bin2bcd(t->tm_mday) & MVRTC_DATE_MSK) << MVRTC_DATE_SFT;
81 date |= (bin2bcd(t->tm_mon) & MVRTC_MON_MSK) << MVRTC_MON_SFT;
82 date |= (bin2bcd(t->tm_year % 100) & MVRTC_YEAR_MSK) << MVRTC_YEAR_SFT;
83
84 /* write the time register */
85 writel(time, &mvrtc_regs->time);
86
87 /* write the date register */
88 writel(date, &mvrtc_regs->date);
89
90 return 0;
91}
92
93void rtc_reset(void)
94{
95 u32 time;
96 u32 sec;
97 struct mvrtc_registers *mvrtc_regs;
98
99 mvrtc_regs = (struct mvrtc_registers *)KW_RTC_BASE;
100
101 /* no init routine for this RTC needed, just check that it's working */
102 time = readl(&mvrtc_regs->time);
103 sec = bcd2bin((time >> MVRTC_SEC_SFT) & MVRTC_SEC_MSK);
104 udelay(1000000);
105 time = readl(&mvrtc_regs->time);
106
107 if (sec == bcd2bin((time >> MVRTC_SEC_SFT) & MVRTC_SEC_MSK))
108 printf("Error: RTC did not increment.\n");
109}