[U-Boot] [PATCH v2] AT91: add RTT and GPBR based RTC

adds kernel compatible RTC handling to u-boot using the RTT and one GPBRegister
Signed-off-by: Reinhard Meyer reinhard.meyer@emk-elektronik.de --- This patch replaces the wrongly split and outdated patch from 05.07.2010 arch/arm/include/asm/arch-at91/at91_gpbr.h | 45 +++++++++++++ arch/arm/include/asm/arch-at91/at91_rtt.h | 36 ++++++++++ drivers/rtc/Makefile | 1 + drivers/rtc/at91sam9.c | 100 ++++++++++++++++++++++++++++ 4 files changed, 182 insertions(+), 0 deletions(-) create mode 100644 arch/arm/include/asm/arch-at91/at91_gpbr.h create mode 100644 arch/arm/include/asm/arch-at91/at91_rtt.h create mode 100644 drivers/rtc/at91sam9.c
diff --git a/arch/arm/include/asm/arch-at91/at91_gpbr.h b/arch/arm/include/asm/arch-at91/at91_gpbr.h new file mode 100644 index 0000000..cf1d790 --- /dev/null +++ b/arch/arm/include/asm/arch-at91/at91_gpbr.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2010 + * Reinhard Meyer, reinhard.meyer@emk-elektronik.de + * + * General Purpose Backup Registers + * Based on AT91SAM9XE datasheet + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef AT91_GPBR_H +#define AT91_GPBR_H + +/* + * The Atmel AT91SAM9 series has a small resource of 4 nonvolatile + * 32 Bit registers (buffered by the Vbu power). + * + * Please consider carefully before using this resource for tasks + * that do not really need nonvolatile registers. Maybe you can + * store information in EEPROM or FLASH instead. + * + * However, if you use a GPBR please document its use here and + * reference the define in your code! + * + * known typical uses of the GPBRs: + * GPBR[0]: offset for RTT timekeeping (u-boot, kernel) + * GPBR[1]: unused + * GPBR[2]: unused + * GPBR[3]: bootcount (u-boot) + */ +#define AT91_GPBR_INDEX_TIMEOFF 0 +#define AT91_GPBR_INDEX_BOOTCOUNT 3 + +#ifndef __ASSEMBLY__ + +typedef struct at91_gpbr { + u32 reg[4]; +} at91_gpbr_t; + +#endif /* __ASSEMBLY__ */ + +#endif diff --git a/arch/arm/include/asm/arch-at91/at91_rtt.h b/arch/arm/include/asm/arch-at91/at91_rtt.h new file mode 100644 index 0000000..e0253ef --- /dev/null +++ b/arch/arm/include/asm/arch-at91/at91_rtt.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2010 + * Reinhard Meyer, reinhard.meyer@emk-elektronik.de + * + * Real-time Timer + * Based on AT91SAM9XE datasheet + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef AT91_RTT_H +#define AT91_RTT_H + +#ifndef __ASSEMBLY__ + +typedef struct at91_rtt { + u32 mr; /* Mode Register RW 0x00008000 */ + u32 ar; /* Alarm Register RW 0xFFFFFFFF */ + u32 vr; /* Value Register RO 0x00000000 */ + u32 sr; /* Status Register RO 0x00000000 */ +} at91_rtt_t; + +#endif /* __ASSEMBLY__ */ + +#define AT91_RTT_MR_RTPRES 0x0000ffff +#define AT91_RTT_MR_ALMIEN 0x00010000 +#define AT91_RTT_RTTINCIEN 0x00020000 +#define AT91_RTT_RTTRST 0x00040000 + +#define AT91_RTT_SR_ALMS 0x00000001 +#define AT91_RTT_SR_RTTINC 0x00000002 + +#endif diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 772a49a..a8ff908 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -27,6 +27,7 @@ include $(TOPDIR)/config.mk
LIB = $(obj)librtc.a
+COBJS-$(CONFIG_RTC_AT91SAM9) += at91sam9.o COBJS-$(CONFIG_RTC_BFIN) += bfin_rtc.o COBJS-y += date.o COBJS-$(CONFIG_RTC_DS12887) += ds12887.o diff --git a/drivers/rtc/at91sam9.c b/drivers/rtc/at91sam9.c new file mode 100644 index 0000000..de8e30d --- /dev/null +++ b/drivers/rtc/at91sam9.c @@ -0,0 +1,100 @@ +/* + * (C) Copyright 2010 + * Reinhard Meyer, reinhard.meyer@emk-elektronik.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * Date & Time support for the internal Real-time Timer + * of AT91SAM9260 and compatibles. + * Compatible with the LinuX rtc driver workaround: + * The RTT cannot be written to, but only reset. + * The actual time is the sum of RTT and one of + * the four GPBR registers. + * + * The at91sam9260 has 4 GPBR (0-3). + * For their typical use see at91_gpbr.h ! + * + * make sure u-boot and kernel use the same GPBR ! + */ + +#include <common.h> +#include <command.h> +#include <rtc.h> +#include <asm/errno.h> +#include <asm/arch/hardware.h> +#include <asm/arch/io.h> +#include <asm/arch/at91_rtt.h> +#include <asm/arch/at91_gpbr.h> + +#if defined(CONFIG_CMD_DATE) + +int rtc_get (struct rtc_time *tmp) +{ + at91_rtt_t *rtt = (at91_rtt_t *) AT91_RTT_BASE; + at91_gpbr_t *gpbr = (at91_gpbr_t *) AT91_GPR_BASE; + ulong tim; + ulong tim2; + ulong off; + + do { + tim = readl(&rtt->vr); + tim2 = readl(&rtt->vr); + } while (tim!=tim2); + off = readl(&gpbr->reg[AT91_GPBR_INDEX_TIMEOFF]); + /* off==0 means time is invalid, but we ignore that */ + to_tm (tim+off, tmp); + return 0; +} + +int rtc_set (struct rtc_time *tmp) +{ + at91_rtt_t *rtt = (at91_rtt_t *) AT91_RTT_BASE; + at91_gpbr_t *gpbr = (at91_gpbr_t *) AT91_GPR_BASE; + ulong tim; + + tim = mktime (tmp->tm_year, tmp->tm_mon, tmp->tm_mday, + tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + + /* clear alarm, set prescaler to 32768, clear counter */ + writel(32768+AT91_RTT_RTTRST, &rtt->mr); + writel(~0, &rtt->ar); + writel(tim, &gpbr->reg[AT91_GPBR_INDEX_TIMEOFF]); + /* wait for counter clear to happen, takes less than a 1/32768th second */ + while (readl(&rtt->vr) != 0) + ; + return 0; +} + +void rtc_reset (void) +{ + at91_rtt_t *rtt = (at91_rtt_t *) AT91_RTT_BASE; + at91_gpbr_t *gpbr = (at91_gpbr_t *) AT91_GPR_BASE; + + /* clear alarm, set prescaler to 32768, clear counter */ + writel(32768+AT91_RTT_RTTRST, &rtt->mr); + writel(~0, &rtt->ar); + writel(0, &gpbr->reg[AT91_GPBR_INDEX_TIMEOFF]); + /* wait for counter clear to happen, takes less than a 1/32768th second */ + while (readl(&rtt->vr) != 0) + ; +} + +#endif

Hi Reinhard,
-----Original Message----- From: u-boot-bounces@lists.denx.de [mailto:u-boot-bounces@lists.denx.de] On Behalf Of Reinhard Meyer Sent: Friday, August 20, 2010 10:00 PM To: u-boot Subject: [U-Boot] [PATCH v2] AT91: add RTT and GPBR based RTC
adds kernel compatible RTC handling to u-boot using the RTT and one GPBRegister
Signed-off-by: Reinhard Meyer reinhard.meyer@emk-elektronik.de
This patch replaces the wrongly split and outdated patch from 05.07.2010 arch/arm/include/asm/arch-at91/at91_gpbr.h | 45 +++++++++++++ arch/arm/include/asm/arch-at91/at91_rtt.h | 36 ++++++++++ drivers/rtc/Makefile | 1 + drivers/rtc/at91sam9.c | 100
Some of Atmel's ARM926EJS chips have builtin RTC, for example, SAM9G45 SAM9M10 SAM9RL and new X5 serials. May we take this into account at this stage?
We can use big #ifdef to add real RTC support in drivers/rtc/at91sam9.c
- or -
We can rename drivers/rtc/at91sam9.c to , for example, drivers/rtc/at91sam9_rtt.c, and let drivers/rtc/at91sam9.c for the real RTC support.
What's your opinion?
Thanks.
BR, Eric
[...]

Dear Xu, Hong,
adds kernel compatible RTC handling to u-boot using the RTT and one GPBRegister ... arch/arm/include/asm/arch-at91/at91_gpbr.h | 45 +++++++++++++ arch/arm/include/asm/arch-at91/at91_rtt.h | 36 ++++++++++ drivers/rtc/Makefile | 1 + drivers/rtc/at91sam9.c | 100
Some of Atmel's ARM926EJS chips have builtin RTC, for example, SAM9G45 SAM9M10 SAM9RL and new X5 serials. May we take this into account at this stage?
We can use big #ifdef to add real RTC support in drivers/rtc/at91sam9.c
I don't think that makes sense, assuming the "real rtc" uses registers that count like HHMMSS DDMMYY. It would be completely different code.
- or -
We can rename drivers/rtc/at91sam9.c to , for example, drivers/rtc/at91sam9_rtt.c, and let drivers/rtc/at91sam9.c for the real RTC support.
I'd go with that, and even suggest naming the maybe upcoming "real rtc" driver at91sam9_rtc.c to give a clearer indication of the different approaches.
Besides, for LinuX the rtt makes more sense since it directly counts in seconds since epoch.
Thanks Reinhard

Dear Xu, Hong,
Some of Atmel's ARM926EJS chips have builtin RTC, for example, SAM9G45 SAM9M10 SAM9RL and new X5 serials. May we take this into account at this stage?
Maybe you can help me here: the 9260 and the 9XE-ENG Sample (soldered on my EK) have the GPBRs at 0xfffffd50. Its sold as a feature (but I think its a bug) that the current Mask of the 9XE has the GPBRs at 0xfffffd60 (0xfffffd50 designated "reserved" now). Is there a simple way to distinguish between both masks?
Reinhard

Hi Reinhard,
-----Original Message----- From: Reinhard Meyer [mailto:u-boot@emk-elektronik.de] Sent: Wednesday, August 25, 2010 10:23 AM To: Xu, Hong Cc: u-boot@lists.denx.de Subject: Re: [U-Boot] [PATCH v2] AT91: add RTT and GPBR based RTC
Dear Xu, Hong,
Some of Atmel's ARM926EJS chips have builtin RTC, for
example, SAM9G45 SAM9M10 SAM9RL and new X5 serials.
May we take this into account at this stage?
Maybe you can help me here: the 9260 and the 9XE-ENG Sample (soldered on my EK) have the GPBRs at 0xfffffd50. Its sold as a feature (but I think its a bug) that the current Mask of the 9XE has the GPBRs at 0xfffffd60 (0xfffffd50 designated "reserved" now). Is there a simple way to distinguish between both masks?
Per the latest datasheet from Atmel's official website, 0xFFFFFD60 is GPBR base address for SAM9XE 0xFFFFFD50 is GPBR base address for SAM9260.
We'd use this for official EK board and forget Eng samples.
If you want to distinguish different chip revision, DBGU_CIDR and DBGU_EXID may help.
BR, Eric
Reinhard

Dear Xu, Hong,
Per the latest datasheet from Atmel's official website, 0xFFFFFD60 is GPBR base address for SAM9XE 0xFFFFFD50 is GPBR base address for SAM9260.
True. I still think it was not planned like that. It just makes live more complicated since otherwise, as long as one does not use the internal flash, the code for 9260 and 9XE would be identical...
We'd use this for official EK board and forget Eng samples.
Fine with me. I tried to send a patch for at91sam9260.h this night but it was mangled. I'll try to repost that later.
My way to define for the 9XE is currently as follows:
#define CONFIG_AT91SAM9260 #define CONFIG_AT91SAM9XE
That avoids extra #if added to several files which would be necessary if only CONFIG_AT91SAM9XE were defined.
If you want to distinguish different chip revision, DBGU_CIDR and DBGU_EXID may help.
Provided they are different between ENG and actual masks... I don't have the XE-EK with the ENG sample ready right now to check that.
Regards, Reinhard
participants (2)
-
Reinhard Meyer
-
Xu, Hong