mvebu: Add Solidrun RTC init patch.
[openwrt/staging/mkresin.git] / target / linux / mvebu / patches-4.14 / 421-rtc-initialize.patch
1 Some boards like the Turris Omnia have an RTC chip that does not get
2 initialized. Initializing the RTC at the driver level helps get rid of
3 bootloader hacks that write special register values.
4
5 --- a/drivers/rtc/rtc-armada38x.c
6 +++ b/drivers/rtc/rtc-armada38x.c
7 @@ -30,6 +30,9 @@
8 #define RTC_IRQ_FREQ_1HZ BIT(2)
9 #define RTC_CCR 0x18
10 #define RTC_CCR_MODE BIT(15)
11 +#define RTC_CCR_NORMAL_PPB 0x2000
12 +#define RTC_TEST_CONF 0x1c
13 +#define RTC_TEST_CONF_MASK 0xff
14
15 #define RTC_TIME 0xC
16 #define RTC_ALARM1 0x10
17 @@ -91,6 +94,7 @@ struct armada38x_rtc_data {
18 void (*clear_isr)(struct armada38x_rtc *rtc);
19 void (*unmask_interrupt)(struct armada38x_rtc *rtc);
20 u32 alarm;
21 + void (*init_rtc)(struct armada38x_rtc *rtc);
22 };
23
24 /*
25 @@ -202,6 +206,23 @@ static void armada38x_unmask_interrupt(s
26 writel(val | SOC_RTC_ALARM1_MASK, rtc->regs_soc + SOC_RTC_INTERRUPT);
27 }
28
29 +static void armada38x_rtc_init(struct armada38x_rtc *rtc)
30 +{
31 + u32 reg;
32 +
33 + /* Test RTC test configuration register bits [7:0] */
34 + reg = readl(rtc->regs + RTC_TEST_CONF);
35 + /* If bits [7:0] are non-zero, assume RTC was uninitialized */
36 + if (reg & RTC_TEST_CONF_MASK) {
37 + rtc_delayed_write(0, rtc, RTC_TEST_CONF);
38 + rtc_delayed_write(0, rtc, RTC_TIME);
39 + rtc_delayed_write((RTC_STATUS_ALARM1 | RTC_STATUS_ALARM2),
40 + rtc, RTC_STATUS);
41 + rtc_delayed_write(RTC_CCR_NORMAL_PPB, rtc, RTC_CCR);
42 + }
43 + return;
44 +}
45 +
46 static void armada8k_clear_isr(struct armada38x_rtc *rtc)
47 {
48 writel(RTC_8K_ALARM2, rtc->regs_soc + RTC_8K_ISR);
49 @@ -464,6 +485,7 @@ static const struct armada38x_rtc_data a
50 .clear_isr = armada38x_clear_isr,
51 .unmask_interrupt = armada38x_unmask_interrupt,
52 .alarm = ALARM1,
53 + .init_rtc = armada38x_rtc_init,
54 };
55
56 static const struct armada38x_rtc_data armada8k_data = {
57 @@ -558,6 +580,17 @@ static __init int armada38x_rtc_probe(st
58 dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
59 return ret;
60 }
61 +
62 + /*
63 + * Try to detect if RTC is in uninitialized state.
64 + * It is not definitive to know if the RTC is in an uninialized state or not,
65 + * but the following call will read some bits in the RTC unit and guess if
66 + * if it's in that state, and accordingly set it to sane default values.
67 + */
68 + if (rtc->data->init_rtc) {
69 + rtc->data->init_rtc(rtc);
70 + }
71 +
72 return 0;
73 }
74