xref: /rk3399_rockchip-uboot/drivers/rtc/at91sam9_rtt.c (revision 372f2783a7b111f567ca541194bc7a75a3d5d64a)
1c7260d15SReinhard Meyer /*
2c7260d15SReinhard Meyer  * (C) Copyright 2010
3c7260d15SReinhard Meyer  * Reinhard Meyer, reinhard.meyer@emk-elektronik.de
4c7260d15SReinhard Meyer  *
5c7260d15SReinhard Meyer  * See file CREDITS for list of people who contributed to this
6c7260d15SReinhard Meyer  * project.
7c7260d15SReinhard Meyer  *
8c7260d15SReinhard Meyer  * This program is free software; you can redistribute it and/or
9c7260d15SReinhard Meyer  * modify it under the terms of the GNU General Public License as
10c7260d15SReinhard Meyer  * published by the Free Software Foundation; either version 2 of
11c7260d15SReinhard Meyer  * the License, or (at your option) any later version.
12c7260d15SReinhard Meyer  *
13c7260d15SReinhard Meyer  * This program is distributed in the hope that it will be useful,
14c7260d15SReinhard Meyer  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15c7260d15SReinhard Meyer  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16c7260d15SReinhard Meyer  * GNU General Public License for more details.
17c7260d15SReinhard Meyer  *
18c7260d15SReinhard Meyer  * You should have received a copy of the GNU General Public License
19c7260d15SReinhard Meyer  * along with this program; if not, write to the Free Software
20c7260d15SReinhard Meyer  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21c7260d15SReinhard Meyer  * MA 02111-1307 USA
22c7260d15SReinhard Meyer  */
23c7260d15SReinhard Meyer 
24c7260d15SReinhard Meyer /*
25c7260d15SReinhard Meyer  * Date & Time support for the internal Real-time Timer
26c7260d15SReinhard Meyer  * of AT91SAM9260 and compatibles.
27c7260d15SReinhard Meyer  * Compatible with the LinuX rtc driver workaround:
28c7260d15SReinhard Meyer  * The RTT cannot be written to, but only reset.
29c7260d15SReinhard Meyer  * The actual time is the sum of RTT and one of
30c7260d15SReinhard Meyer  * the four GPBR registers.
31c7260d15SReinhard Meyer  *
32c7260d15SReinhard Meyer  * The at91sam9260 has 4 GPBR (0-3).
33c7260d15SReinhard Meyer  * For their typical use see at91_gpbr.h !
34c7260d15SReinhard Meyer  *
35c7260d15SReinhard Meyer  * make sure u-boot and kernel use the same GPBR !
36c7260d15SReinhard Meyer  */
37c7260d15SReinhard Meyer 
38c7260d15SReinhard Meyer #include <common.h>
39c7260d15SReinhard Meyer #include <command.h>
40c7260d15SReinhard Meyer #include <rtc.h>
41c7260d15SReinhard Meyer #include <asm/errno.h>
42c7260d15SReinhard Meyer #include <asm/arch/hardware.h>
43c7260d15SReinhard Meyer #include <asm/arch/io.h>
44c7260d15SReinhard Meyer #include <asm/arch/at91_rtt.h>
45c7260d15SReinhard Meyer #include <asm/arch/at91_gpbr.h>
46c7260d15SReinhard Meyer 
47c7260d15SReinhard Meyer #if defined(CONFIG_CMD_DATE)
48c7260d15SReinhard Meyer 
49c7260d15SReinhard Meyer int rtc_get (struct rtc_time *tmp)
50c7260d15SReinhard Meyer {
51*372f2783SReinhard Meyer 	at91_rtt_t *rtt = (at91_rtt_t *) ATMEL_BASE_RTT;
52*372f2783SReinhard Meyer 	at91_gpbr_t *gpbr = (at91_gpbr_t *) ATMEL_BASE_GPBR;
53c7260d15SReinhard Meyer 	ulong tim;
54c7260d15SReinhard Meyer 	ulong tim2;
55c7260d15SReinhard Meyer 	ulong off;
56c7260d15SReinhard Meyer 
57c7260d15SReinhard Meyer 	do {
58c7260d15SReinhard Meyer 		tim = readl(&rtt->vr);
59c7260d15SReinhard Meyer 		tim2 = readl(&rtt->vr);
60c7260d15SReinhard Meyer 	} while (tim!=tim2);
61c7260d15SReinhard Meyer 	off = readl(&gpbr->reg[AT91_GPBR_INDEX_TIMEOFF]);
62c7260d15SReinhard Meyer 	/* off==0 means time is invalid, but we ignore that */
63c7260d15SReinhard Meyer 	to_tm (tim+off, tmp);
64c7260d15SReinhard Meyer 	return 0;
65c7260d15SReinhard Meyer }
66c7260d15SReinhard Meyer 
67c7260d15SReinhard Meyer int rtc_set (struct rtc_time *tmp)
68c7260d15SReinhard Meyer {
69*372f2783SReinhard Meyer 	at91_rtt_t *rtt = (at91_rtt_t *) ATMEL_BASE_RTT;
70*372f2783SReinhard Meyer 	at91_gpbr_t *gpbr = (at91_gpbr_t *) ATMEL_BASE_GPBR;
71c7260d15SReinhard Meyer 	ulong tim;
72c7260d15SReinhard Meyer 
73c7260d15SReinhard Meyer 	tim = mktime (tmp->tm_year, tmp->tm_mon, tmp->tm_mday,
74c7260d15SReinhard Meyer 		      tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
75c7260d15SReinhard Meyer 
76c7260d15SReinhard Meyer 	/* clear alarm, set prescaler to 32768, clear counter */
77c7260d15SReinhard Meyer 	writel(32768+AT91_RTT_RTTRST, &rtt->mr);
78c7260d15SReinhard Meyer 	writel(~0, &rtt->ar);
79c7260d15SReinhard Meyer 	writel(tim, &gpbr->reg[AT91_GPBR_INDEX_TIMEOFF]);
80c7260d15SReinhard Meyer 	/* wait for counter clear to happen, takes less than a 1/32768th second */
81c7260d15SReinhard Meyer 	while (readl(&rtt->vr) != 0)
82c7260d15SReinhard Meyer 		;
83c7260d15SReinhard Meyer 	return 0;
84c7260d15SReinhard Meyer }
85c7260d15SReinhard Meyer 
86c7260d15SReinhard Meyer void rtc_reset (void)
87c7260d15SReinhard Meyer {
88*372f2783SReinhard Meyer 	at91_rtt_t *rtt = (at91_rtt_t *) ATMEL_BASE_RTT;
89*372f2783SReinhard Meyer 	at91_gpbr_t *gpbr = (at91_gpbr_t *) ATMEL_BASE_GPBR;
90c7260d15SReinhard Meyer 
91c7260d15SReinhard Meyer 	/* clear alarm, set prescaler to 32768, clear counter */
92c7260d15SReinhard Meyer 	writel(32768+AT91_RTT_RTTRST, &rtt->mr);
93c7260d15SReinhard Meyer 	writel(~0, &rtt->ar);
94c7260d15SReinhard Meyer 	writel(0, &gpbr->reg[AT91_GPBR_INDEX_TIMEOFF]);
95c7260d15SReinhard Meyer 	/* wait for counter clear to happen, takes less than a 1/32768th second */
96c7260d15SReinhard Meyer 	while (readl(&rtt->vr) != 0)
97c7260d15SReinhard Meyer 		;
98c7260d15SReinhard Meyer }
99c7260d15SReinhard Meyer 
100c7260d15SReinhard Meyer #endif
101