1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2011 DENX Software Engineering GmbH
4  * Heiko Schocher <hs@denx.de>
5  * Copyright (C) 2021 Dario Binacchi <dariobin@libero.it>
6  */
7 #include <command.h>
8 #include <dm.h>
9 #include <clk.h>
10 #include <log.h>
11 #include <rtc.h>
12 #include <asm/io.h>
13 #include <dm/device_compat.h>
14 #include <linux/delay.h>
15 
16 /* RTC registers */
17 #define OMAP_RTC_SECONDS_REG		0x00
18 #define OMAP_RTC_MINUTES_REG		0x04
19 #define OMAP_RTC_HOURS_REG		0x08
20 #define OMAP_RTC_DAYS_REG		0x0C
21 #define OMAP_RTC_MONTHS_REG		0x10
22 #define OMAP_RTC_YEARS_REG		0x14
23 #define OMAP_RTC_WEEKS_REG		0x18
24 
25 #define OMAP_RTC_CTRL_REG		0x40
26 #define OMAP_RTC_STATUS_REG		0x44
27 #define OMAP_RTC_INTERRUPTS_REG		0x48
28 
29 #define OMAP_RTC_OSC_REG		0x54
30 
31 #define OMAP_RTC_SCRATCH0_REG		0x60
32 #define OMAP_RTC_SCRATCH1_REG		0x64
33 #define OMAP_RTC_SCRATCH2_REG		0x68
34 
35 #define OMAP_RTC_KICK0_REG		0x6c
36 #define OMAP_RTC_KICK1_REG		0x70
37 
38 #define OMAP_RTC_PMIC_REG		0x98
39 
40 /* OMAP_RTC_CTRL_REG bit fields: */
41 #define OMAP_RTC_CTRL_SPLIT		BIT(7)
42 #define OMAP_RTC_CTRL_DISABLE		BIT(6)
43 #define OMAP_RTC_CTRL_SET_32_COUNTER	BIT(5)
44 #define OMAP_RTC_CTRL_TEST		BIT(4)
45 #define OMAP_RTC_CTRL_MODE_12_24	BIT(3)
46 #define OMAP_RTC_CTRL_AUTO_COMP		BIT(2)
47 #define OMAP_RTC_CTRL_ROUND_30S		BIT(1)
48 #define OMAP_RTC_CTRL_STOP		BIT(0)
49 
50 /* OMAP_RTC_STATUS_REG bit fields */
51 #define OMAP_RTC_STATUS_POWER_UP	BIT(7)
52 #define OMAP_RTC_STATUS_ALARM2		BIT(7)
53 #define OMAP_RTC_STATUS_ALARM		BIT(6)
54 #define OMAP_RTC_STATUS_1D_EVENT	BIT(5)
55 #define OMAP_RTC_STATUS_1H_EVENT	BIT(4)
56 #define OMAP_RTC_STATUS_1M_EVENT	BIT(3)
57 #define OMAP_RTC_STATUS_1S_EVENT	BIT(2)
58 #define OMAP_RTC_STATUS_RUN		BIT(1)
59 #define OMAP_RTC_STATUS_BUSY		BIT(0)
60 
61 /* OMAP_RTC_OSC_REG bit fields */
62 #define OMAP_RTC_OSC_32KCLK_EN		BIT(6)
63 #define OMAP_RTC_OSC_SEL_32KCLK_SRC	BIT(3)
64 #define OMAP_RTC_OSC_OSC32K_GZ_DISABLE	BIT(4)
65 
66 /* OMAP_RTC_KICKER values */
67 #define	OMAP_RTC_KICK0_VALUE		0x83e70b13
68 #define	OMAP_RTC_KICK1_VALUE		0x95a4f1e0
69 
70 struct omap_rtc_device_type {
71 	bool has_32kclk_en;
72 	bool has_irqwakeen;
73 	bool has_pmic_mode;
74 	bool has_power_up_reset;
75 };
76 
77 struct omap_rtc_priv {
78 	fdt_addr_t base;
79 	u8 max_reg;
80 	struct udevice *dev;
81 	struct clk clk;
82 	bool has_ext_clk;
83 	const struct omap_rtc_device_type *type;
84 };
85 
omap_rtc_readb(struct omap_rtc_priv * priv,unsigned int reg)86 static inline u8 omap_rtc_readb(struct omap_rtc_priv *priv, unsigned int reg)
87 {
88 	return readb(priv->base + reg);
89 }
90 
omap_rtc_readl(struct omap_rtc_priv * priv,unsigned int reg)91 static inline u32 omap_rtc_readl(struct omap_rtc_priv *priv, unsigned int reg)
92 {
93 	return readl(priv->base + reg);
94 }
95 
omap_rtc_writeb(struct omap_rtc_priv * priv,unsigned int reg,u8 val)96 static inline void omap_rtc_writeb(struct omap_rtc_priv *priv, unsigned int reg,
97 				   u8 val)
98 {
99 	writeb(val, priv->base + reg);
100 }
101 
omap_rtc_writel(struct omap_rtc_priv * priv,unsigned int reg,u32 val)102 static inline void omap_rtc_writel(struct omap_rtc_priv *priv, unsigned int reg,
103 				   u32 val)
104 {
105 	writel(val, priv->base + reg);
106 }
107 
omap_rtc_unlock(struct omap_rtc_priv * priv)108 static inline void omap_rtc_unlock(struct omap_rtc_priv *priv)
109 {
110 	omap_rtc_writel(priv, OMAP_RTC_KICK0_REG, OMAP_RTC_KICK0_VALUE);
111 	omap_rtc_writel(priv, OMAP_RTC_KICK1_REG, OMAP_RTC_KICK1_VALUE);
112 }
113 
omap_rtc_lock(struct omap_rtc_priv * priv)114 static inline void omap_rtc_lock(struct omap_rtc_priv *priv)
115 {
116 	omap_rtc_writel(priv, OMAP_RTC_KICK0_REG, 0);
117 	omap_rtc_writel(priv, OMAP_RTC_KICK1_REG, 0);
118 }
119 
omap_rtc_wait_not_busy(struct omap_rtc_priv * priv)120 static int omap_rtc_wait_not_busy(struct omap_rtc_priv *priv)
121 {
122 	int count;
123 	u8 status;
124 
125 	status = omap_rtc_readb(priv, OMAP_RTC_STATUS_REG);
126 	if ((status & OMAP_RTC_STATUS_RUN) != OMAP_RTC_STATUS_RUN) {
127 		printf("RTC doesn't run\n");
128 		return -1;
129 	}
130 
131 	/* BUSY may stay active for 1/32768 second (~30 usec) */
132 	for (count = 0; count < 50; count++) {
133 		if (!(status & OMAP_RTC_STATUS_BUSY))
134 			break;
135 
136 		udelay(1);
137 		status = omap_rtc_readb(priv, OMAP_RTC_STATUS_REG);
138 	}
139 
140 	/* now we have ~15 usec to read/write various registers */
141 	return 0;
142 }
143 
omap_rtc_reset(struct udevice * dev)144 static int omap_rtc_reset(struct udevice *dev)
145 {
146 	struct omap_rtc_priv *priv = dev_get_priv(dev);
147 
148 	/* run RTC counter */
149 	omap_rtc_writeb(priv, OMAP_RTC_CTRL_REG, 0x01);
150 	return 0;
151 }
152 
omap_rtc_set(struct udevice * dev,const struct rtc_time * tm)153 static int omap_rtc_set(struct udevice *dev, const struct rtc_time *tm)
154 {
155 	struct omap_rtc_priv *priv = dev_get_priv(dev);
156 	int ret;
157 
158 	ret = omap_rtc_wait_not_busy(priv);
159 	if (ret)
160 		return ret;
161 
162 	omap_rtc_unlock(priv);
163 	omap_rtc_writeb(priv, OMAP_RTC_YEARS_REG, bin2bcd(tm->tm_year % 100));
164 	omap_rtc_writeb(priv, OMAP_RTC_MONTHS_REG, bin2bcd(tm->tm_mon));
165 	omap_rtc_writeb(priv, OMAP_RTC_WEEKS_REG, bin2bcd(tm->tm_wday));
166 	omap_rtc_writeb(priv, OMAP_RTC_DAYS_REG, bin2bcd(tm->tm_mday));
167 	omap_rtc_writeb(priv, OMAP_RTC_HOURS_REG, bin2bcd(tm->tm_hour));
168 	omap_rtc_writeb(priv, OMAP_RTC_MINUTES_REG, bin2bcd(tm->tm_min));
169 	omap_rtc_writeb(priv, OMAP_RTC_SECONDS_REG, bin2bcd(tm->tm_sec));
170 	omap_rtc_lock(priv);
171 
172 	dev_dbg(dev, "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
173 		tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday, tm->tm_hour,
174 		tm->tm_min, tm->tm_sec);
175 
176 	return 0;
177 }
178 
omap_rtc_get(struct udevice * dev,struct rtc_time * tm)179 static int omap_rtc_get(struct udevice *dev, struct rtc_time *tm)
180 {
181 	struct omap_rtc_priv *priv = dev_get_priv(dev);
182 	unsigned long sec, min, hour, mday, wday, mon_cent, year;
183 	int ret;
184 
185 	ret = omap_rtc_wait_not_busy(priv);
186 	if (ret)
187 		return ret;
188 
189 	sec = omap_rtc_readb(priv, OMAP_RTC_SECONDS_REG);
190 	min = omap_rtc_readb(priv, OMAP_RTC_MINUTES_REG);
191 	hour = omap_rtc_readb(priv, OMAP_RTC_HOURS_REG);
192 	mday = omap_rtc_readb(priv, OMAP_RTC_DAYS_REG);
193 	wday = omap_rtc_readb(priv, OMAP_RTC_WEEKS_REG);
194 	mon_cent = omap_rtc_readb(priv, OMAP_RTC_MONTHS_REG);
195 	year = omap_rtc_readb(priv, OMAP_RTC_YEARS_REG);
196 
197 	dev_dbg(dev,
198 		"Get RTC year: %02lx mon/cent: %02lx mday: %02lx wday: %02lx "
199 		"hr: %02lx min: %02lx sec: %02lx\n",
200 		year, mon_cent, mday, wday,
201 		hour, min, sec);
202 
203 	tm->tm_sec  = bcd2bin(sec  & 0x7F);
204 	tm->tm_min  = bcd2bin(min  & 0x7F);
205 	tm->tm_hour = bcd2bin(hour & 0x3F);
206 	tm->tm_mday = bcd2bin(mday & 0x3F);
207 	tm->tm_mon  = bcd2bin(mon_cent & 0x1F);
208 	tm->tm_year = bcd2bin(year) + 2000;
209 	tm->tm_wday = bcd2bin(wday & 0x07);
210 	tm->tm_yday = 0;
211 	tm->tm_isdst = 0;
212 
213 	dev_dbg(dev, "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
214 		tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday, tm->tm_hour,
215 		tm->tm_min, tm->tm_sec);
216 
217 	return 0;
218 }
219 
omap_rtc_scratch_read(struct udevice * dev,uint offset,u8 * buffer,uint len)220 static int omap_rtc_scratch_read(struct udevice *dev, uint offset,
221 				 u8 *buffer, uint len)
222 {
223 	struct omap_rtc_priv *priv = dev_get_priv(dev);
224 	u32 *val = (u32 *)buffer;
225 	unsigned int reg;
226 	int i;
227 
228 	if (len & 3)
229 		return -EFAULT;
230 
231 	for (i = 0; i < len / 4; i++) {
232 		reg = OMAP_RTC_SCRATCH0_REG + offset + (i * 4);
233 		if (reg >= OMAP_RTC_KICK0_REG)
234 			return -EFAULT;
235 
236 		val[i] = omap_rtc_readl(priv, reg);
237 	}
238 
239 	return 0;
240 }
241 
omap_rtc_scratch_write(struct udevice * dev,uint offset,const u8 * buffer,uint len)242 static int omap_rtc_scratch_write(struct udevice *dev, uint offset,
243 				  const u8 *buffer, uint len)
244 {
245 	struct omap_rtc_priv *priv = dev_get_priv(dev);
246 	u32 *val = (u32 *)buffer;
247 	unsigned int reg;
248 	int i;
249 
250 	if (len & 3)
251 		return -EFAULT;
252 
253 	omap_rtc_unlock(priv);
254 	for (i = 0; i < len / 4; i++) {
255 		reg = OMAP_RTC_SCRATCH0_REG + offset + (i * 4);
256 		if (reg >= OMAP_RTC_KICK0_REG)
257 			return -EFAULT;
258 
259 		omap_rtc_writel(priv, reg, val[i]);
260 	}
261 	omap_rtc_lock(priv);
262 
263 	return 0;
264 }
265 
omap_rtc_remove(struct udevice * dev)266 static int omap_rtc_remove(struct udevice *dev)
267 {
268 	struct omap_rtc_priv *priv = dev_get_priv(dev);
269 	u8 reg;
270 
271 	if (priv->clk.dev)
272 		clk_disable(&priv->clk);
273 
274 	omap_rtc_unlock(priv);
275 
276 	/* leave rtc running, but disable irqs */
277 	omap_rtc_writeb(priv, OMAP_RTC_INTERRUPTS_REG, 0);
278 
279 	if (priv->has_ext_clk) {
280 		reg = omap_rtc_readb(priv, OMAP_RTC_OSC_REG);
281 		reg &= ~OMAP_RTC_OSC_SEL_32KCLK_SRC;
282 		omap_rtc_writeb(priv, OMAP_RTC_OSC_REG, reg);
283 	}
284 
285 	omap_rtc_lock(priv);
286 	return 0;
287 }
288 
omap_rtc_probe(struct udevice * dev)289 static int omap_rtc_probe(struct udevice *dev)
290 {
291 	struct omap_rtc_priv *priv = dev_get_priv(dev);
292 	struct rtc_time tm;
293 	u8 reg, mask, new_ctrl;
294 
295 	priv->dev = dev;
296 	priv->type = (struct omap_rtc_device_type *)dev_get_driver_data(dev);
297 	priv->max_reg = OMAP_RTC_PMIC_REG;
298 
299 	if (!clk_get_by_name(dev, "ext-clk", &priv->clk))
300 		priv->has_ext_clk = true;
301 	else
302 		clk_get_by_name(dev, "int-clk", &priv->clk);
303 
304 	if (priv->clk.dev)
305 		clk_enable(&priv->clk);
306 	else
307 		dev_warn(dev, "missing clock\n");
308 
309 	omap_rtc_unlock(priv);
310 
311 	/*
312 	 * disable interrupts
313 	 *
314 	 * NOTE: ALARM2 is not cleared on AM3352 if rtc_write (writeb) is used
315 	 */
316 	omap_rtc_writel(priv, OMAP_RTC_INTERRUPTS_REG, 0);
317 
318 	if (priv->type->has_32kclk_en) {
319 		reg = omap_rtc_readb(priv, OMAP_RTC_OSC_REG);
320 		omap_rtc_writeb(priv, OMAP_RTC_OSC_REG,
321 				reg | OMAP_RTC_OSC_32KCLK_EN);
322 	}
323 
324 	/* clear old status */
325 	reg = omap_rtc_readb(priv, OMAP_RTC_STATUS_REG);
326 
327 	mask = OMAP_RTC_STATUS_ALARM;
328 
329 	if (priv->type->has_pmic_mode)
330 		mask |= OMAP_RTC_STATUS_ALARM2;
331 
332 	if (priv->type->has_power_up_reset) {
333 		mask |= OMAP_RTC_STATUS_POWER_UP;
334 		if (reg & OMAP_RTC_STATUS_POWER_UP)
335 			dev_info(dev, "RTC power up reset detected\n");
336 	}
337 
338 	if (reg & mask)
339 		omap_rtc_writeb(priv, OMAP_RTC_STATUS_REG, reg & mask);
340 
341 	/* On boards with split power, RTC_ON_NOFF won't reset the RTC */
342 	reg = omap_rtc_readb(priv, OMAP_RTC_CTRL_REG);
343 	if (reg & OMAP_RTC_CTRL_STOP)
344 		dev_info(dev, "already running\n");
345 
346 	/* force to 24 hour mode */
347 	new_ctrl = reg & (OMAP_RTC_CTRL_SPLIT | OMAP_RTC_CTRL_AUTO_COMP);
348 	new_ctrl |= OMAP_RTC_CTRL_STOP;
349 
350 	/*
351 	 * BOARD-SPECIFIC CUSTOMIZATION CAN GO HERE:
352 	 *
353 	 *  - Device wake-up capability setting should come through chip
354 	 *    init logic. OMAP1 boards should initialize the "wakeup capable"
355 	 *    flag in the platform device if the board is wired right for
356 	 *    being woken up by RTC alarm. For OMAP-L138, this capability
357 	 *    is built into the SoC by the "Deep Sleep" capability.
358 	 *
359 	 *  - Boards wired so RTC_ON_nOFF is used as the reset signal,
360 	 *    rather than nPWRON_RESET, should forcibly enable split
361 	 *    power mode.  (Some chip errata report that RTC_CTRL_SPLIT
362 	 *    is write-only, and always reads as zero...)
363 	 */
364 
365 	if (new_ctrl & OMAP_RTC_CTRL_SPLIT)
366 		dev_info(dev, "split power mode\n");
367 
368 	if (reg != new_ctrl)
369 		omap_rtc_writeb(priv, OMAP_RTC_CTRL_REG, new_ctrl);
370 
371 	/*
372 	 * If we have the external clock then switch to it so we can keep
373 	 * ticking across suspend.
374 	 */
375 	if (priv->has_ext_clk) {
376 		reg = omap_rtc_readb(priv, OMAP_RTC_OSC_REG);
377 		reg &= ~OMAP_RTC_OSC_OSC32K_GZ_DISABLE;
378 		reg |= OMAP_RTC_OSC_32KCLK_EN | OMAP_RTC_OSC_SEL_32KCLK_SRC;
379 		omap_rtc_writeb(priv, OMAP_RTC_OSC_REG, reg);
380 	}
381 
382 	omap_rtc_lock(priv);
383 
384 	if (omap_rtc_get(dev, &tm)) {
385 		dev_err(dev, "failed to get datetime\n");
386 	} else if (tm.tm_year == 2000 && tm.tm_mon == 1 && tm.tm_mday == 1 &&
387 		   tm.tm_wday == 0) {
388 		tm.tm_wday = 6;
389 		omap_rtc_set(dev, &tm);
390 	}
391 
392 	return 0;
393 }
394 
omap_rtc_of_to_plat(struct udevice * dev)395 static int omap_rtc_of_to_plat(struct udevice *dev)
396 {
397 	struct omap_rtc_priv *priv = dev_get_priv(dev);
398 
399 	priv->base = dev_read_addr(dev);
400 	if (priv->base == FDT_ADDR_T_NONE) {
401 		dev_err(dev, "invalid address\n");
402 		return -EINVAL;
403 	}
404 
405 	dev_dbg(dev, "base=%pa\n", &priv->base);
406 	return 0;
407 }
408 
409 static const struct rtc_ops omap_rtc_ops = {
410 	.get = omap_rtc_get,
411 	.set = omap_rtc_set,
412 	.reset = omap_rtc_reset,
413 	.read = omap_rtc_scratch_read,
414 	.write = omap_rtc_scratch_write,
415 };
416 
417 static const struct omap_rtc_device_type omap_rtc_am3352_type = {
418 	.has_32kclk_en	= true,
419 	.has_irqwakeen	= true,
420 	.has_pmic_mode	= true,
421 };
422 
423 static const struct omap_rtc_device_type omap_rtc_da830_type = {
424 	.has_32kclk_en	= false,
425 	.has_irqwakeen	= false,
426 	.has_pmic_mode	= false,
427 };
428 
429 static const struct udevice_id omap_rtc_ids[] = {
430 	{.compatible = "ti,am3352-rtc", .data = (ulong)&omap_rtc_am3352_type},
431 	{.compatible = "ti,da830-rtc", .data = (ulong)&omap_rtc_da830_type }
432 };
433 
434 U_BOOT_DRIVER(omap_rtc) = {
435 	.name = "omap_rtc",
436 	.id = UCLASS_RTC,
437 	.of_match = omap_rtc_ids,
438 	.ops = &omap_rtc_ops,
439 	.of_to_plat = omap_rtc_of_to_plat,
440 	.probe = omap_rtc_probe,
441 	.remove = omap_rtc_remove,
442 	.priv_auto = sizeof(struct omap_rtc_priv),
443 };
444