421-rtc-armada38x-reset-after-rtc-power-loss.patch 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. From 1a990fefb641398fb580a0ea0be99b0ff27cbb9b Mon Sep 17 00:00:00 2001
  2. From: Baruch Siach <baruch@tkos.co.il>
  3. Date: Thu, 21 Jun 2018 20:40:23 +0300
  4. Subject: [PATCH] rtc: armada38x: reset after rtc power loss
  5. When the RTC block looses power it needs a reset sequence to make it
  6. usable again. Otherwise, writes to the time register have no effect.
  7. This reset sequence combines information from the mvebu_rtc driver in
  8. the Marvell provided U-Boot, and the SolidRun provided U-Boot repo.
  9. Tested on the Armada 388 based SolidRun Clearfog Base.
  10. Signed-off-by: Baruch Siach <baruch@tkos.co.il>
  11. Acked-by: Gregory CLEMENT <gregory.clement@bootlin.com>
  12. Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
  13. ---
  14. drivers/rtc/rtc-armada38x.c | 23 +++++++++++++++++++++++
  15. 1 file changed, 23 insertions(+)
  16. --- a/drivers/rtc/rtc-armada38x.c
  17. +++ b/drivers/rtc/rtc-armada38x.c
  18. @@ -30,6 +30,8 @@
  19. #define RTC_IRQ_FREQ_1HZ BIT(2)
  20. #define RTC_CCR 0x18
  21. #define RTC_CCR_MODE BIT(15)
  22. +#define RTC_CONF_TEST 0x1C
  23. +#define RTC_NOMINAL_TIMING BIT(13)
  24. #define RTC_TIME 0xC
  25. #define RTC_ALARM1 0x10
  26. @@ -75,6 +77,7 @@ struct armada38x_rtc {
  27. void __iomem *regs_soc;
  28. spinlock_t lock;
  29. int irq;
  30. + bool initialized;
  31. struct value_to_freq *val_to_freq;
  32. struct armada38x_rtc_data *data;
  33. };
  34. @@ -226,6 +229,23 @@ static int armada38x_rtc_read_time(struc
  35. return 0;
  36. }
  37. +static void armada38x_rtc_reset(struct armada38x_rtc *rtc)
  38. +{
  39. + u32 reg;
  40. +
  41. + reg = rtc->data->read_rtc_reg(rtc, RTC_CONF_TEST);
  42. + /* If bits [7:0] are non-zero, assume RTC was uninitialized */
  43. + if (reg & 0xff) {
  44. + rtc_delayed_write(0, rtc, RTC_CONF_TEST);
  45. + msleep(500); /* Oscillator startup time */
  46. + rtc_delayed_write(0, rtc, RTC_TIME);
  47. + rtc_delayed_write(SOC_RTC_ALARM1 | SOC_RTC_ALARM2, rtc,
  48. + RTC_STATUS);
  49. + rtc_delayed_write(RTC_NOMINAL_TIMING, rtc, RTC_CCR);
  50. + }
  51. + rtc->initialized = true;
  52. +}
  53. +
  54. static int armada38x_rtc_set_time(struct device *dev, struct rtc_time *tm)
  55. {
  56. struct armada38x_rtc *rtc = dev_get_drvdata(dev);
  57. @@ -237,6 +257,9 @@ static int armada38x_rtc_set_time(struct
  58. if (ret)
  59. goto out;
  60. + if (!rtc->initialized)
  61. + armada38x_rtc_reset(rtc);
  62. +
  63. spin_lock_irqsave(&rtc->lock, flags);
  64. rtc_delayed_write(time, rtc, RTC_TIME);
  65. spin_unlock_irqrestore(&rtc->lock, flags);