xref: /rk3399_rockchip-uboot/drivers/rtc/pl031.c (revision 02ffb580e6ab7aaa7f6703ed35f489e97439cb65)
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