12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 |
- From 1a990fefb641398fb580a0ea0be99b0ff27cbb9b Mon Sep 17 00:00:00 2001
- From: Baruch Siach <baruch@tkos.co.il>
- Date: Thu, 21 Jun 2018 20:40:23 +0300
- Subject: [PATCH] rtc: armada38x: reset after rtc power loss
- When the RTC block looses power it needs a reset sequence to make it
- usable again. Otherwise, writes to the time register have no effect.
- This reset sequence combines information from the mvebu_rtc driver in
- the Marvell provided U-Boot, and the SolidRun provided U-Boot repo.
- Tested on the Armada 388 based SolidRun Clearfog Base.
- Signed-off-by: Baruch Siach <baruch@tkos.co.il>
- Acked-by: Gregory CLEMENT <gregory.clement@bootlin.com>
- Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
- ---
- drivers/rtc/rtc-armada38x.c | 23 +++++++++++++++++++++++
- 1 file changed, 23 insertions(+)
- --- a/drivers/rtc/rtc-armada38x.c
- +++ b/drivers/rtc/rtc-armada38x.c
- @@ -30,6 +30,8 @@
- #define RTC_IRQ_FREQ_1HZ BIT(2)
- #define RTC_CCR 0x18
- #define RTC_CCR_MODE BIT(15)
- +#define RTC_CONF_TEST 0x1C
- +#define RTC_NOMINAL_TIMING BIT(13)
-
- #define RTC_TIME 0xC
- #define RTC_ALARM1 0x10
- @@ -75,6 +77,7 @@ struct armada38x_rtc {
- void __iomem *regs_soc;
- spinlock_t lock;
- int irq;
- + bool initialized;
- struct value_to_freq *val_to_freq;
- struct armada38x_rtc_data *data;
- };
- @@ -226,6 +229,23 @@ static int armada38x_rtc_read_time(struc
- return 0;
- }
-
- +static void armada38x_rtc_reset(struct armada38x_rtc *rtc)
- +{
- + u32 reg;
- +
- + reg = rtc->data->read_rtc_reg(rtc, RTC_CONF_TEST);
- + /* If bits [7:0] are non-zero, assume RTC was uninitialized */
- + if (reg & 0xff) {
- + rtc_delayed_write(0, rtc, RTC_CONF_TEST);
- + msleep(500); /* Oscillator startup time */
- + rtc_delayed_write(0, rtc, RTC_TIME);
- + rtc_delayed_write(SOC_RTC_ALARM1 | SOC_RTC_ALARM2, rtc,
- + RTC_STATUS);
- + rtc_delayed_write(RTC_NOMINAL_TIMING, rtc, RTC_CCR);
- + }
- + rtc->initialized = true;
- +}
- +
- static int armada38x_rtc_set_time(struct device *dev, struct rtc_time *tm)
- {
- struct armada38x_rtc *rtc = dev_get_drvdata(dev);
- @@ -237,6 +257,9 @@ static int armada38x_rtc_set_time(struct
- if (ret)
- goto out;
-
- + if (!rtc->initialized)
- + armada38x_rtc_reset(rtc);
- +
- spin_lock_irqsave(&rtc->lock, flags);
- rtc_delayed_write(time, rtc, RTC_TIME);
- spin_unlock_irqrestore(&rtc->lock, flags);
|