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