at91sam9_rtt.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2010
  4. * Reinhard Meyer, reinhard.meyer@emk-elektronik.de
  5. */
  6. /*
  7. * Date & Time support for the internal Real-time Timer
  8. * of AT91SAM9260 and compatibles.
  9. * Compatible with the LinuX rtc driver workaround:
  10. * The RTT cannot be written to, but only reset.
  11. * The actual time is the sum of RTT and one of
  12. * the four GPBR registers.
  13. *
  14. * The at91sam9260 has 4 GPBR (0-3).
  15. * For their typical use see at91_gpbr.h !
  16. *
  17. * make sure u-boot and kernel use the same GPBR !
  18. */
  19. #include <common.h>
  20. #include <command.h>
  21. #include <rtc.h>
  22. #include <asm/io.h>
  23. #include <linux/errno.h>
  24. #include <asm/arch/hardware.h>
  25. #include <asm/arch/at91_rtt.h>
  26. #include <asm/arch/at91_gpbr.h>
  27. int rtc_get (struct rtc_time *tmp)
  28. {
  29. at91_rtt_t *rtt = (at91_rtt_t *) ATMEL_BASE_RTT;
  30. at91_gpbr_t *gpbr = (at91_gpbr_t *) ATMEL_BASE_GPBR;
  31. ulong tim;
  32. ulong tim2;
  33. ulong off;
  34. do {
  35. tim = readl(&rtt->vr);
  36. tim2 = readl(&rtt->vr);
  37. } while (tim!=tim2);
  38. off = readl(&gpbr->reg[AT91_GPBR_INDEX_TIMEOFF]);
  39. /* off==0 means time is invalid, but we ignore that */
  40. rtc_to_tm(tim+off, tmp);
  41. return 0;
  42. }
  43. int rtc_set (struct rtc_time *tmp)
  44. {
  45. at91_rtt_t *rtt = (at91_rtt_t *) ATMEL_BASE_RTT;
  46. at91_gpbr_t *gpbr = (at91_gpbr_t *) ATMEL_BASE_GPBR;
  47. ulong tim;
  48. tim = rtc_mktime(tmp);
  49. /* clear alarm, set prescaler to 32768, clear counter */
  50. writel(32768+AT91_RTT_RTTRST, &rtt->mr);
  51. writel(~0, &rtt->ar);
  52. writel(tim, &gpbr->reg[AT91_GPBR_INDEX_TIMEOFF]);
  53. /* wait for counter clear to happen, takes less than a 1/32768th second */
  54. while (readl(&rtt->vr) != 0)
  55. ;
  56. return 0;
  57. }
  58. void rtc_reset (void)
  59. {
  60. at91_rtt_t *rtt = (at91_rtt_t *) ATMEL_BASE_RTT;
  61. at91_gpbr_t *gpbr = (at91_gpbr_t *) ATMEL_BASE_GPBR;
  62. /* clear alarm, set prescaler to 32768, clear counter */
  63. writel(32768+AT91_RTT_RTTRST, &rtt->mr);
  64. writel(~0, &rtt->ar);
  65. writel(0, &gpbr->reg[AT91_GPBR_INDEX_TIMEOFF]);
  66. /* wait for counter clear to happen, takes less than a 1/32768th second */
  67. while (readl(&rtt->vr) != 0)
  68. ;
  69. }