at91sam9_rtt.c 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  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. #if defined(CONFIG_CMD_DATE)
  28. int rtc_get (struct rtc_time *tmp)
  29. {
  30. at91_rtt_t *rtt = (at91_rtt_t *) ATMEL_BASE_RTT;
  31. at91_gpbr_t *gpbr = (at91_gpbr_t *) ATMEL_BASE_GPBR;
  32. ulong tim;
  33. ulong tim2;
  34. ulong off;
  35. do {
  36. tim = readl(&rtt->vr);
  37. tim2 = readl(&rtt->vr);
  38. } while (tim!=tim2);
  39. off = readl(&gpbr->reg[AT91_GPBR_INDEX_TIMEOFF]);
  40. /* off==0 means time is invalid, but we ignore that */
  41. rtc_to_tm(tim+off, tmp);
  42. return 0;
  43. }
  44. int rtc_set (struct rtc_time *tmp)
  45. {
  46. at91_rtt_t *rtt = (at91_rtt_t *) ATMEL_BASE_RTT;
  47. at91_gpbr_t *gpbr = (at91_gpbr_t *) ATMEL_BASE_GPBR;
  48. ulong tim;
  49. tim = rtc_mktime(tmp);
  50. /* clear alarm, set prescaler to 32768, clear counter */
  51. writel(32768+AT91_RTT_RTTRST, &rtt->mr);
  52. writel(~0, &rtt->ar);
  53. writel(tim, &gpbr->reg[AT91_GPBR_INDEX_TIMEOFF]);
  54. /* wait for counter clear to happen, takes less than a 1/32768th second */
  55. while (readl(&rtt->vr) != 0)
  56. ;
  57. return 0;
  58. }
  59. void rtc_reset (void)
  60. {
  61. at91_rtt_t *rtt = (at91_rtt_t *) ATMEL_BASE_RTT;
  62. at91_gpbr_t *gpbr = (at91_gpbr_t *) ATMEL_BASE_GPBR;
  63. /* clear alarm, set prescaler to 32768, clear counter */
  64. writel(32768+AT91_RTT_RTTRST, &rtt->mr);
  65. writel(~0, &rtt->ar);
  66. writel(0, &gpbr->reg[AT91_GPBR_INDEX_TIMEOFF]);
  67. /* wait for counter clear to happen, takes less than a 1/32768th second */
  68. while (readl(&rtt->vr) != 0)
  69. ;
  70. }
  71. #endif