armada38x.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * RTC driver for the Armada 38x Marvell SoCs
  4. *
  5. * Copyright (C) 2021 Marek Behún <kabel@kernel.org>
  6. *
  7. * Based on Linux' driver by Gregory Clement and Marvell
  8. */
  9. #include <asm/io.h>
  10. #include <dm.h>
  11. #include <linux/delay.h>
  12. #include <rtc.h>
  13. #define RTC_STATUS 0x0
  14. #define RTC_TIME 0xC
  15. #define RTC_CONF_TEST 0x1C
  16. /* Armada38x SoC registers */
  17. #define RTC_38X_BRIDGE_TIMING_CTL 0x0
  18. #define RTC_38X_PERIOD_OFFS 0
  19. #define RTC_38X_PERIOD_MASK (0x3FF << RTC_38X_PERIOD_OFFS)
  20. #define RTC_38X_READ_DELAY_OFFS 26
  21. #define RTC_38X_READ_DELAY_MASK (0x1F << RTC_38X_READ_DELAY_OFFS)
  22. #define SAMPLE_NR 100
  23. struct armada38x_rtc {
  24. void __iomem *regs;
  25. void __iomem *regs_soc;
  26. };
  27. /*
  28. * According to Erratum RES-3124064 we have to do some configuration in MBUS.
  29. * To read an RTC register we need to read it 100 times and return the most
  30. * frequent value.
  31. * To write an RTC register we need to write 2x zero into STATUS register,
  32. * followed by the proper write. Linux adds an 5 us delay after this, so we do
  33. * it here as well.
  34. */
  35. static void update_38x_mbus_timing_params(struct armada38x_rtc *rtc)
  36. {
  37. u32 reg;
  38. reg = readl(rtc->regs_soc + RTC_38X_BRIDGE_TIMING_CTL);
  39. reg &= ~RTC_38X_PERIOD_MASK;
  40. reg |= 0x3FF << RTC_38X_PERIOD_OFFS; /* Maximum value */
  41. reg &= ~RTC_38X_READ_DELAY_MASK;
  42. reg |= 0x1F << RTC_38X_READ_DELAY_OFFS; /* Maximum value */
  43. writel(reg, rtc->regs_soc + RTC_38X_BRIDGE_TIMING_CTL);
  44. }
  45. static void armada38x_rtc_write(u32 val, struct armada38x_rtc *rtc, u8 reg)
  46. {
  47. writel(0, rtc->regs + RTC_STATUS);
  48. writel(0, rtc->regs + RTC_STATUS);
  49. writel(val, rtc->regs + reg);
  50. udelay(5);
  51. }
  52. static u32 armada38x_rtc_read(struct armada38x_rtc *rtc, u8 reg)
  53. {
  54. u8 counts[SAMPLE_NR], max_idx;
  55. u32 samples[SAMPLE_NR], max;
  56. int i, j, last;
  57. for (i = 0, last = 0; i < SAMPLE_NR; ++i) {
  58. u32 sample = readl(rtc->regs + reg);
  59. /* find if this value was already read */
  60. for (j = 0; j < last; ++j) {
  61. if (samples[j] == sample)
  62. break;
  63. }
  64. if (j < last) {
  65. /* if yes, increment count */
  66. ++counts[j];
  67. } else {
  68. /* if not, add */
  69. samples[last] = sample;
  70. counts[last] = 1;
  71. ++last;
  72. }
  73. }
  74. /* finally find the sample that was read the most */
  75. max = 0;
  76. max_idx = 0;
  77. for (i = 0; i < last; ++i) {
  78. if (counts[i] > max) {
  79. max = counts[i];
  80. max_idx = i;
  81. }
  82. }
  83. return samples[max_idx];
  84. }
  85. static int armada38x_rtc_get(struct udevice *dev, struct rtc_time *tm)
  86. {
  87. struct armada38x_rtc *rtc = dev_get_priv(dev);
  88. u32 time;
  89. time = armada38x_rtc_read(rtc, RTC_TIME);
  90. rtc_to_tm(time, tm);
  91. return 0;
  92. }
  93. static int armada38x_rtc_reset(struct udevice *dev)
  94. {
  95. struct armada38x_rtc *rtc = dev_get_priv(dev);
  96. u32 reg;
  97. reg = armada38x_rtc_read(rtc, RTC_CONF_TEST);
  98. if (reg & 0xff) {
  99. armada38x_rtc_write(0, rtc, RTC_CONF_TEST);
  100. mdelay(500);
  101. armada38x_rtc_write(0, rtc, RTC_TIME);
  102. armada38x_rtc_write(BIT(0) | BIT(1), rtc, RTC_STATUS);
  103. }
  104. return 0;
  105. }
  106. static int armada38x_rtc_set(struct udevice *dev, const struct rtc_time *tm)
  107. {
  108. struct armada38x_rtc *rtc = dev_get_priv(dev);
  109. unsigned long time;
  110. time = rtc_mktime(tm);
  111. if (time > U32_MAX)
  112. printf("%s: requested time to set will overflow\n", dev->name);
  113. armada38x_rtc_reset(dev);
  114. armada38x_rtc_write(time, rtc, RTC_TIME);
  115. return 0;
  116. }
  117. static int armada38x_probe(struct udevice *dev)
  118. {
  119. struct armada38x_rtc *rtc = dev_get_priv(dev);
  120. rtc->regs = dev_remap_addr_name(dev, "rtc");
  121. if (!rtc->regs)
  122. goto err;
  123. rtc->regs_soc = dev_remap_addr_name(dev, "rtc-soc");
  124. if (!rtc->regs_soc)
  125. goto err;
  126. update_38x_mbus_timing_params(rtc);
  127. return 0;
  128. err:
  129. printf("%s: io address missing\n", dev->name);
  130. return -ENODEV;
  131. }
  132. static const struct rtc_ops armada38x_rtc_ops = {
  133. .get = armada38x_rtc_get,
  134. .set = armada38x_rtc_set,
  135. .reset = armada38x_rtc_reset,
  136. };
  137. static const struct udevice_id armada38x_rtc_ids[] = {
  138. { .compatible = "marvell,armada-380-rtc", .data = 0 },
  139. { }
  140. };
  141. U_BOOT_DRIVER(rtc_armada38x) = {
  142. .name = "rtc-armada38x",
  143. .id = UCLASS_RTC,
  144. .of_match = armada38x_rtc_ids,
  145. .probe = armada38x_probe,
  146. .priv_auto = sizeof(struct armada38x_rtc),
  147. .ops = &armada38x_rtc_ops,
  148. };