1535cfa4fSGururaja Hebbar K R /*
2535cfa4fSGururaja Hebbar K R * (C) Copyright 2008
3535cfa4fSGururaja Hebbar K R * Gururaja Hebbar gururajakr@sanyo.co.in
4535cfa4fSGururaja Hebbar K R *
5535cfa4fSGururaja Hebbar K R * reference linux-2.6.20.6/drivers/rtc/rtc-pl031.c
6535cfa4fSGururaja Hebbar K R *
71a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+
8535cfa4fSGururaja Hebbar K R */
9535cfa4fSGururaja Hebbar K R
10535cfa4fSGururaja Hebbar K R #include <common.h>
11535cfa4fSGururaja Hebbar K R #include <command.h>
12535cfa4fSGururaja Hebbar K R #include <rtc.h>
13535cfa4fSGururaja Hebbar K R
14535cfa4fSGururaja Hebbar K R #if defined(CONFIG_CMD_DATE)
15535cfa4fSGururaja Hebbar K R
166d0f6bcfSJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_SYS_RTC_PL031_BASE
176d0f6bcfSJean-Christophe PLAGNIOL-VILLARD #error CONFIG_SYS_RTC_PL031_BASE is not defined!
18535cfa4fSGururaja Hebbar K R #endif
19535cfa4fSGururaja Hebbar K R
20535cfa4fSGururaja Hebbar K R /*
21535cfa4fSGururaja Hebbar K R * Register definitions
22535cfa4fSGururaja Hebbar K R */
23535cfa4fSGururaja Hebbar K R #define RTC_DR 0x00 /* Data read register */
24535cfa4fSGururaja Hebbar K R #define RTC_MR 0x04 /* Match register */
25535cfa4fSGururaja Hebbar K R #define RTC_LR 0x08 /* Data load register */
26535cfa4fSGururaja Hebbar K R #define RTC_CR 0x0c /* Control register */
27535cfa4fSGururaja Hebbar K R #define RTC_IMSC 0x10 /* Interrupt mask and set register */
28535cfa4fSGururaja Hebbar K R #define RTC_RIS 0x14 /* Raw interrupt status register */
29535cfa4fSGururaja Hebbar K R #define RTC_MIS 0x18 /* Masked interrupt status register */
30535cfa4fSGururaja Hebbar K R #define RTC_ICR 0x1c /* Interrupt clear register */
31535cfa4fSGururaja Hebbar K R
32535cfa4fSGururaja Hebbar K R #define RTC_CR_START (1 << 0)
33535cfa4fSGururaja Hebbar K R
34535cfa4fSGururaja Hebbar K R #define RTC_WRITE_REG(addr, val) \
356d0f6bcfSJean-Christophe PLAGNIOL-VILLARD (*(volatile unsigned int *)(CONFIG_SYS_RTC_PL031_BASE + (addr)) = (val))
36535cfa4fSGururaja Hebbar K R #define RTC_READ_REG(addr) \
376d0f6bcfSJean-Christophe PLAGNIOL-VILLARD (*(volatile unsigned int *)(CONFIG_SYS_RTC_PL031_BASE + (addr)))
38535cfa4fSGururaja Hebbar K R
39535cfa4fSGururaja Hebbar K R static int pl031_initted = 0;
40535cfa4fSGururaja Hebbar K R
41535cfa4fSGururaja Hebbar K R /* Enable RTC Start in Control register*/
rtc_init(void)42535cfa4fSGururaja Hebbar K R void rtc_init(void)
43535cfa4fSGururaja Hebbar K R {
44535cfa4fSGururaja Hebbar K R RTC_WRITE_REG(RTC_CR, RTC_CR_START);
45535cfa4fSGururaja Hebbar K R
46535cfa4fSGururaja Hebbar K R pl031_initted = 1;
47535cfa4fSGururaja Hebbar K R }
48535cfa4fSGururaja Hebbar K R
49535cfa4fSGururaja Hebbar K R /*
50535cfa4fSGururaja Hebbar K R * Reset the RTC. We set the date back to 1970-01-01.
51535cfa4fSGururaja Hebbar K R */
rtc_reset(void)52535cfa4fSGururaja Hebbar K R void rtc_reset(void)
53535cfa4fSGururaja Hebbar K R {
54535cfa4fSGururaja Hebbar K R RTC_WRITE_REG(RTC_LR, 0x00);
55535cfa4fSGururaja Hebbar K R if(!pl031_initted)
56535cfa4fSGururaja Hebbar K R rtc_init();
57535cfa4fSGururaja Hebbar K R }
58535cfa4fSGururaja Hebbar K R
59535cfa4fSGururaja Hebbar K R /*
60535cfa4fSGururaja Hebbar K R * Set the RTC
61535cfa4fSGururaja Hebbar K R */
rtc_set(struct rtc_time * tmp)62d1e23194SJean-Christophe PLAGNIOL-VILLARD int rtc_set(struct rtc_time *tmp)
63535cfa4fSGururaja Hebbar K R {
64535cfa4fSGururaja Hebbar K R unsigned long tim;
65535cfa4fSGururaja Hebbar K R
66535cfa4fSGururaja Hebbar K R if(!pl031_initted)
67535cfa4fSGururaja Hebbar K R rtc_init();
68535cfa4fSGururaja Hebbar K R
69535cfa4fSGururaja Hebbar K R if (tmp == NULL) {
70535cfa4fSGururaja Hebbar K R puts("Error setting the date/time\n");
71d1e23194SJean-Christophe PLAGNIOL-VILLARD return -1;
72535cfa4fSGururaja Hebbar K R }
73535cfa4fSGururaja Hebbar K R
74535cfa4fSGururaja Hebbar K R /* Calculate number of seconds this incoming time represents */
75*71420983SSimon Glass tim = rtc_mktime(tmp);
76535cfa4fSGururaja Hebbar K R
77535cfa4fSGururaja Hebbar K R RTC_WRITE_REG(RTC_LR, tim);
78d1e23194SJean-Christophe PLAGNIOL-VILLARD
79d1e23194SJean-Christophe PLAGNIOL-VILLARD return -1;
80535cfa4fSGururaja Hebbar K R }
81535cfa4fSGururaja Hebbar K R
82535cfa4fSGururaja Hebbar K R /*
83535cfa4fSGururaja Hebbar K R * Get the current time from the RTC
84535cfa4fSGururaja Hebbar K R */
rtc_get(struct rtc_time * tmp)85535cfa4fSGururaja Hebbar K R int rtc_get(struct rtc_time *tmp)
86535cfa4fSGururaja Hebbar K R {
87535cfa4fSGururaja Hebbar K R ulong tim;
88535cfa4fSGururaja Hebbar K R
89535cfa4fSGururaja Hebbar K R if(!pl031_initted)
90535cfa4fSGururaja Hebbar K R rtc_init();
91535cfa4fSGururaja Hebbar K R
92535cfa4fSGururaja Hebbar K R if (tmp == NULL) {
93535cfa4fSGururaja Hebbar K R puts("Error getting the date/time\n");
94535cfa4fSGururaja Hebbar K R return -1;
95535cfa4fSGururaja Hebbar K R }
96535cfa4fSGururaja Hebbar K R
97535cfa4fSGururaja Hebbar K R tim = RTC_READ_REG(RTC_DR);
98535cfa4fSGururaja Hebbar K R
999f9276c3SSimon Glass rtc_to_tm(tim, tmp);
100535cfa4fSGururaja Hebbar K R
101535cfa4fSGururaja Hebbar K R debug ( "Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
102535cfa4fSGururaja Hebbar K R tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
103535cfa4fSGururaja Hebbar K R tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
104535cfa4fSGururaja Hebbar K R
105535cfa4fSGururaja Hebbar K R return 0;
106535cfa4fSGururaja Hebbar K R }
107535cfa4fSGururaja Hebbar K R
108535cfa4fSGururaja Hebbar K R #endif
109