mxsrtc.c 1.5 KB

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