xref: /rk3399_rockchip-uboot/drivers/rtc/ftrtc010.c (revision 39ba774f9b02c44b8fd4df44afac932800c18662)
1*39ba774fSPo-Yu Chuang /*
2*39ba774fSPo-Yu Chuang  * Faraday FTRTC010 Real Time Clock
3*39ba774fSPo-Yu Chuang  *
4*39ba774fSPo-Yu Chuang  * (C) Copyright 2009 Faraday Technology
5*39ba774fSPo-Yu Chuang  * Po-Yu Chuang <ratbert@faraday-tech.com>
6*39ba774fSPo-Yu Chuang  *
7*39ba774fSPo-Yu Chuang  * This program is free software; you can redistribute it and/or modify
8*39ba774fSPo-Yu Chuang  * it under the terms of the GNU General Public License as published by
9*39ba774fSPo-Yu Chuang  * the Free Software Foundation; either version 2 of the License, or
10*39ba774fSPo-Yu Chuang  * (at your option) any later version.
11*39ba774fSPo-Yu Chuang  *
12*39ba774fSPo-Yu Chuang  * This program is distributed in the hope that it will be useful,
13*39ba774fSPo-Yu Chuang  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14*39ba774fSPo-Yu Chuang  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*39ba774fSPo-Yu Chuang  * GNU General Public License for more details.
16*39ba774fSPo-Yu Chuang  *
17*39ba774fSPo-Yu Chuang  * You should have received a copy of the GNU General Public License
18*39ba774fSPo-Yu Chuang  * along with this program; if not, write to the Free Software
19*39ba774fSPo-Yu Chuang  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*39ba774fSPo-Yu Chuang  */
21*39ba774fSPo-Yu Chuang 
22*39ba774fSPo-Yu Chuang #include <config.h>
23*39ba774fSPo-Yu Chuang #include <common.h>
24*39ba774fSPo-Yu Chuang #include <rtc.h>
25*39ba774fSPo-Yu Chuang #include <asm/io.h>
26*39ba774fSPo-Yu Chuang 
27*39ba774fSPo-Yu Chuang struct ftrtc010 {
28*39ba774fSPo-Yu Chuang 	unsigned int sec;		/* 0x00 */
29*39ba774fSPo-Yu Chuang 	unsigned int min;		/* 0x04 */
30*39ba774fSPo-Yu Chuang 	unsigned int hour;		/* 0x08 */
31*39ba774fSPo-Yu Chuang 	unsigned int day;		/* 0x0c */
32*39ba774fSPo-Yu Chuang 	unsigned int alarm_sec;		/* 0x10 */
33*39ba774fSPo-Yu Chuang 	unsigned int alarm_min;		/* 0x14 */
34*39ba774fSPo-Yu Chuang 	unsigned int alarm_hour;	/* 0x18 */
35*39ba774fSPo-Yu Chuang 	unsigned int record;		/* 0x1c */
36*39ba774fSPo-Yu Chuang 	unsigned int cr;		/* 0x20 */
37*39ba774fSPo-Yu Chuang };
38*39ba774fSPo-Yu Chuang 
39*39ba774fSPo-Yu Chuang /*
40*39ba774fSPo-Yu Chuang  * RTC Control Register
41*39ba774fSPo-Yu Chuang  */
42*39ba774fSPo-Yu Chuang #define FTRTC010_CR_ENABLE		(1 << 0)
43*39ba774fSPo-Yu Chuang #define FTRTC010_CR_INTERRUPT_SEC	(1 << 1)	/* per second irq */
44*39ba774fSPo-Yu Chuang #define FTRTC010_CR_INTERRUPT_MIN	(1 << 2)	/* per minute irq */
45*39ba774fSPo-Yu Chuang #define FTRTC010_CR_INTERRUPT_HR	(1 << 3)	/* per hour   irq */
46*39ba774fSPo-Yu Chuang #define FTRTC010_CR_INTERRUPT_DAY	(1 << 4)	/* per day    irq */
47*39ba774fSPo-Yu Chuang 
48*39ba774fSPo-Yu Chuang static struct ftrtc010 *rtc = (struct ftrtc010 *)CONFIG_FTRTC010_BASE;
49*39ba774fSPo-Yu Chuang 
50*39ba774fSPo-Yu Chuang static void ftrtc010_enable(void)
51*39ba774fSPo-Yu Chuang {
52*39ba774fSPo-Yu Chuang 	writel(FTRTC010_CR_ENABLE, &rtc->cr);
53*39ba774fSPo-Yu Chuang }
54*39ba774fSPo-Yu Chuang 
55*39ba774fSPo-Yu Chuang /*
56*39ba774fSPo-Yu Chuang  * return current time in seconds
57*39ba774fSPo-Yu Chuang  */
58*39ba774fSPo-Yu Chuang static unsigned long ftrtc010_time(void)
59*39ba774fSPo-Yu Chuang {
60*39ba774fSPo-Yu Chuang 	unsigned long day;
61*39ba774fSPo-Yu Chuang 	unsigned long hour;
62*39ba774fSPo-Yu Chuang 	unsigned long minute;
63*39ba774fSPo-Yu Chuang 	unsigned long second;
64*39ba774fSPo-Yu Chuang 	unsigned long second2;
65*39ba774fSPo-Yu Chuang 
66*39ba774fSPo-Yu Chuang 	do {
67*39ba774fSPo-Yu Chuang 		second	= readl(&rtc->sec);
68*39ba774fSPo-Yu Chuang 		day	= readl(&rtc->day);
69*39ba774fSPo-Yu Chuang 		hour	= readl(&rtc->hour);
70*39ba774fSPo-Yu Chuang 		minute	= readl(&rtc->min);
71*39ba774fSPo-Yu Chuang 		second2	= readl(&rtc->sec);
72*39ba774fSPo-Yu Chuang 	} while (second != second2);
73*39ba774fSPo-Yu Chuang 
74*39ba774fSPo-Yu Chuang 	return day * 24 * 60 * 60 + hour * 60 * 60 + minute * 60 + second;
75*39ba774fSPo-Yu Chuang }
76*39ba774fSPo-Yu Chuang 
77*39ba774fSPo-Yu Chuang /*
78*39ba774fSPo-Yu Chuang  * Get the current time from the RTC
79*39ba774fSPo-Yu Chuang  */
80*39ba774fSPo-Yu Chuang 
81*39ba774fSPo-Yu Chuang int rtc_get(struct rtc_time *tmp)
82*39ba774fSPo-Yu Chuang {
83*39ba774fSPo-Yu Chuang 	unsigned long now;
84*39ba774fSPo-Yu Chuang 
85*39ba774fSPo-Yu Chuang 	debug("%s(): record register: %x\n",
86*39ba774fSPo-Yu Chuang 	      __func__, readl(&rtc->record));
87*39ba774fSPo-Yu Chuang 
88*39ba774fSPo-Yu Chuang 	now = ftrtc010_time() + readl(&rtc->record);
89*39ba774fSPo-Yu Chuang 
90*39ba774fSPo-Yu Chuang 	to_tm(now, tmp);
91*39ba774fSPo-Yu Chuang 
92*39ba774fSPo-Yu Chuang 	return 0;
93*39ba774fSPo-Yu Chuang }
94*39ba774fSPo-Yu Chuang 
95*39ba774fSPo-Yu Chuang /*
96*39ba774fSPo-Yu Chuang  * Set the RTC
97*39ba774fSPo-Yu Chuang  */
98*39ba774fSPo-Yu Chuang int rtc_set(struct rtc_time *tmp)
99*39ba774fSPo-Yu Chuang {
100*39ba774fSPo-Yu Chuang 	unsigned long new;
101*39ba774fSPo-Yu Chuang 	unsigned long now;
102*39ba774fSPo-Yu Chuang 
103*39ba774fSPo-Yu Chuang 	debug("%s(): DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
104*39ba774fSPo-Yu Chuang 	      __func__,
105*39ba774fSPo-Yu Chuang 	      tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
106*39ba774fSPo-Yu Chuang 	      tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
107*39ba774fSPo-Yu Chuang 
108*39ba774fSPo-Yu Chuang 	new = mktime(tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_hour,
109*39ba774fSPo-Yu Chuang 		     tmp->tm_min, tmp->tm_sec);
110*39ba774fSPo-Yu Chuang 
111*39ba774fSPo-Yu Chuang 	now = ftrtc010_time();
112*39ba774fSPo-Yu Chuang 
113*39ba774fSPo-Yu Chuang 	debug("%s(): write %lx to record register\n", __func__, new - now);
114*39ba774fSPo-Yu Chuang 
115*39ba774fSPo-Yu Chuang 	writel(new - now, &rtc->record);
116*39ba774fSPo-Yu Chuang 
117*39ba774fSPo-Yu Chuang 	return 0;
118*39ba774fSPo-Yu Chuang }
119*39ba774fSPo-Yu Chuang 
120*39ba774fSPo-Yu Chuang void rtc_reset(void)
121*39ba774fSPo-Yu Chuang {
122*39ba774fSPo-Yu Chuang 	debug("%s()\n", __func__);
123*39ba774fSPo-Yu Chuang 	ftrtc010_enable();
124*39ba774fSPo-Yu Chuang }
125