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