mvebu: Replace RTC initialization patch with upstreamed version

While we're at it, rename the patches to their proper git format-patch
name.

Tested on a Turris Omnia.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
This commit is contained in:
Rosen Penev 2018-09-08 21:23:57 -07:00 committed by John Crispin
parent a9aa25c8b6
commit 6a2ee91267
3 changed files with 78 additions and 74 deletions

View file

@ -0,0 +1,78 @@
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(+)
diff --git a/drivers/rtc/rtc-armada38x.c b/drivers/rtc/rtc-armada38x.c
index 1e4978c..bde53c8c 100644
--- 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(struct device *dev, struct rtc_time *tm)
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 device *dev, struct rtc_time *tm)
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);
--
2.7.4

View file

@ -1,74 +0,0 @@
Some boards like the Turris Omnia have an RTC chip that does not get
initialized. Initializing the RTC at the driver level helps get rid of
bootloader hacks that write special register values.
--- a/drivers/rtc/rtc-armada38x.c
+++ b/drivers/rtc/rtc-armada38x.c
@@ -30,6 +30,9 @@
#define RTC_IRQ_FREQ_1HZ BIT(2)
#define RTC_CCR 0x18
#define RTC_CCR_MODE BIT(15)
+#define RTC_CCR_NORMAL_PPB 0x2000
+#define RTC_TEST_CONF 0x1c
+#define RTC_TEST_CONF_MASK 0xff
#define RTC_TIME 0xC
#define RTC_ALARM1 0x10
@@ -91,6 +94,7 @@ struct armada38x_rtc_data {
void (*clear_isr)(struct armada38x_rtc *rtc);
void (*unmask_interrupt)(struct armada38x_rtc *rtc);
u32 alarm;
+ void (*init_rtc)(struct armada38x_rtc *rtc);
};
/*
@@ -202,6 +206,23 @@ static void armada38x_unmask_interrupt(s
writel(val | SOC_RTC_ALARM1_MASK, rtc->regs_soc + SOC_RTC_INTERRUPT);
}
+static void armada38x_rtc_init(struct armada38x_rtc *rtc)
+{
+ u32 reg;
+
+ /* Test RTC test configuration register bits [7:0] */
+ reg = readl(rtc->regs + RTC_TEST_CONF);
+ /* If bits [7:0] are non-zero, assume RTC was uninitialized */
+ if (reg & RTC_TEST_CONF_MASK) {
+ rtc_delayed_write(0, rtc, RTC_TEST_CONF);
+ rtc_delayed_write(0, rtc, RTC_TIME);
+ rtc_delayed_write((RTC_STATUS_ALARM1 | RTC_STATUS_ALARM2),
+ rtc, RTC_STATUS);
+ rtc_delayed_write(RTC_CCR_NORMAL_PPB, rtc, RTC_CCR);
+ }
+ return;
+}
+
static void armada8k_clear_isr(struct armada38x_rtc *rtc)
{
writel(RTC_8K_ALARM2, rtc->regs_soc + RTC_8K_ISR);
@@ -464,6 +485,7 @@ static const struct armada38x_rtc_data a
.clear_isr = armada38x_clear_isr,
.unmask_interrupt = armada38x_unmask_interrupt,
.alarm = ALARM1,
+ .init_rtc = armada38x_rtc_init,
};
static const struct armada38x_rtc_data armada8k_data = {
@@ -558,6 +580,17 @@ static __init int armada38x_rtc_probe(st
dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
return ret;
}
+
+ /*
+ * Try to detect if RTC is in uninitialized state.
+ * It is not definitive to know if the RTC is in an uninialized state or not,
+ * but the following call will read some bits in the RTC unit and guess if
+ * if it's in that state, and accordingly set it to sane default values.
+ */
+ if (rtc->data->init_rtc) {
+ rtc->data->init_rtc(rtc);
+ }
+
return 0;
}