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  */
update_38x_mbus_timing_params(struct armada38x_rtc * rtc)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 
armada38x_rtc_write(u32 val,struct armada38x_rtc * rtc,u8 reg)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 
armada38x_rtc_read(struct armada38x_rtc * rtc,u8 reg)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 
armada38x_rtc_get(struct udevice * dev,struct rtc_time * tm)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 
armada38x_rtc_reset(struct udevice * dev)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 
armada38x_rtc_set(struct udevice * dev,const struct rtc_time * tm)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 
armada38x_probe(struct udevice * dev)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 };
185