mxsrtc.c 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. /*
  2. * Freescale i.MX28 RTC Driver
  3. *
  4. * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
  5. * on behalf of DENX Software Engineering GmbH
  6. *
  7. * SPDX-License-Identifier: GPL-2.0+
  8. */
  9. #include <common.h>
  10. #include <rtc.h>
  11. #include <asm/io.h>
  12. #include <asm/arch/imx-regs.h>
  13. #include <asm/arch/sys_proto.h>
  14. #define MXS_RTC_MAX_TIMEOUT 1000000
  15. /* Set time in seconds since 1970-01-01 */
  16. int mxs_rtc_set_time(uint32_t secs)
  17. {
  18. struct mxs_rtc_regs *rtc_regs = (struct mxs_rtc_regs *)MXS_RTC_BASE;
  19. int ret;
  20. writel(secs, &rtc_regs->hw_rtc_seconds);
  21. /*
  22. * The 0x80 here means seconds were copied to analog. This information
  23. * is taken from the linux kernel driver for the STMP37xx RTC since
  24. * documentation doesn't mention it.
  25. */
  26. ret = mxs_wait_mask_clr(&rtc_regs->hw_rtc_stat_reg,
  27. 0x80 << RTC_STAT_STALE_REGS_OFFSET, MXS_RTC_MAX_TIMEOUT);
  28. if (ret)
  29. printf("MXS RTC: Timeout waiting for update\n");
  30. return ret;
  31. }
  32. int rtc_get(struct rtc_time *time)
  33. {
  34. struct mxs_rtc_regs *rtc_regs = (struct mxs_rtc_regs *)MXS_RTC_BASE;
  35. uint32_t secs;
  36. secs = readl(&rtc_regs->hw_rtc_seconds);
  37. rtc_to_tm(secs, time);
  38. return 0;
  39. }
  40. int rtc_set(struct rtc_time *time)
  41. {
  42. uint32_t secs;
  43. secs = mktime(time->tm_year, time->tm_mon, time->tm_mday,
  44. time->tm_hour, time->tm_min, time->tm_sec);
  45. return mxs_rtc_set_time(secs);
  46. }
  47. void rtc_reset(void)
  48. {
  49. struct mxs_rtc_regs *rtc_regs = (struct mxs_rtc_regs *)MXS_RTC_BASE;
  50. int ret;
  51. /* Set time to 1970-01-01 */
  52. mxs_rtc_set_time(0);
  53. /* Reset the RTC block */
  54. ret = mxs_reset_block(&rtc_regs->hw_rtc_ctrl_reg);
  55. if (ret)
  56. printf("MXS RTC: Block reset timeout\n");
  57. }