xref: /linux/drivers/rtc/rtc-renesas-rtca3.c (revision 2a9f04bde07a35530d53b71628cdc950dac86eab)
1d4488377SClaudiu Beznea // SPDX-License-Identifier: GPL-2.0
2d4488377SClaudiu Beznea /*
3d4488377SClaudiu Beznea  * On-Chip RTC Support available on RZ/G3S SoC
4d4488377SClaudiu Beznea  *
5d4488377SClaudiu Beznea  * Copyright (C) 2024 Renesas Electronics Corp.
6d4488377SClaudiu Beznea  */
7d4488377SClaudiu Beznea #include <linux/bcd.h>
88f315a5cSClaudiu Beznea #include <linux/bitfield.h>
9d4488377SClaudiu Beznea #include <linux/cleanup.h>
10d4488377SClaudiu Beznea #include <linux/clk.h>
11d4488377SClaudiu Beznea #include <linux/completion.h>
12d4488377SClaudiu Beznea #include <linux/delay.h>
13d4488377SClaudiu Beznea #include <linux/iopoll.h>
14d4488377SClaudiu Beznea #include <linux/interrupt.h>
15d4488377SClaudiu Beznea #include <linux/jiffies.h>
16d4488377SClaudiu Beznea #include <linux/of.h>
17d4488377SClaudiu Beznea #include <linux/platform_device.h>
18d4488377SClaudiu Beznea #include <linux/pm_runtime.h>
19d4488377SClaudiu Beznea #include <linux/reset.h>
20d4488377SClaudiu Beznea #include <linux/rtc.h>
21d4488377SClaudiu Beznea 
22d4488377SClaudiu Beznea /* Counter registers. */
23d4488377SClaudiu Beznea #define RTCA3_RSECCNT			0x2
24d4488377SClaudiu Beznea #define RTCA3_RSECCNT_SEC		GENMASK(6, 0)
25d4488377SClaudiu Beznea #define RTCA3_RMINCNT			0x4
26d4488377SClaudiu Beznea #define RTCA3_RMINCNT_MIN		GENMASK(6, 0)
27d4488377SClaudiu Beznea #define RTCA3_RHRCNT			0x6
28d4488377SClaudiu Beznea #define RTCA3_RHRCNT_HR			GENMASK(5, 0)
29d4488377SClaudiu Beznea #define RTCA3_RHRCNT_PM			BIT(6)
30d4488377SClaudiu Beznea #define RTCA3_RWKCNT			0x8
31d4488377SClaudiu Beznea #define RTCA3_RWKCNT_WK			GENMASK(2, 0)
32d4488377SClaudiu Beznea #define RTCA3_RDAYCNT			0xa
33d4488377SClaudiu Beznea #define RTCA3_RDAYCNT_DAY		GENMASK(5, 0)
34d4488377SClaudiu Beznea #define RTCA3_RMONCNT			0xc
35d4488377SClaudiu Beznea #define RTCA3_RMONCNT_MONTH		GENMASK(4, 0)
36d4488377SClaudiu Beznea #define RTCA3_RYRCNT			0xe
37d4488377SClaudiu Beznea #define RTCA3_RYRCNT_YEAR		GENMASK(7, 0)
38d4488377SClaudiu Beznea 
39d4488377SClaudiu Beznea /* Alarm registers. */
40d4488377SClaudiu Beznea #define RTCA3_RSECAR			0x10
41d4488377SClaudiu Beznea #define RTCA3_RSECAR_SEC		GENMASK(6, 0)
42d4488377SClaudiu Beznea #define RTCA3_RMINAR			0x12
43d4488377SClaudiu Beznea #define RTCA3_RMINAR_MIN		GENMASK(6, 0)
44d4488377SClaudiu Beznea #define RTCA3_RHRAR			0x14
45d4488377SClaudiu Beznea #define RTCA3_RHRAR_HR			GENMASK(5, 0)
46d4488377SClaudiu Beznea #define RTCA3_RHRAR_PM			BIT(6)
47d4488377SClaudiu Beznea #define RTCA3_RWKAR			0x16
48d4488377SClaudiu Beznea #define RTCA3_RWKAR_DAYW		GENMASK(2, 0)
49d4488377SClaudiu Beznea #define RTCA3_RDAYAR			0x18
50d4488377SClaudiu Beznea #define RTCA3_RDAYAR_DATE		GENMASK(5, 0)
51d4488377SClaudiu Beznea #define RTCA3_RMONAR			0x1a
52d4488377SClaudiu Beznea #define RTCA3_RMONAR_MON		GENMASK(4, 0)
53d4488377SClaudiu Beznea #define RTCA3_RYRAR			0x1c
54d4488377SClaudiu Beznea #define RTCA3_RYRAR_YR			GENMASK(7, 0)
55d4488377SClaudiu Beznea #define RTCA3_RYRAREN			0x1e
56d4488377SClaudiu Beznea 
57d4488377SClaudiu Beznea /* Alarm enable bit (for all alarm registers). */
58d4488377SClaudiu Beznea #define RTCA3_AR_ENB			BIT(7)
59d4488377SClaudiu Beznea 
60d4488377SClaudiu Beznea /* Control registers. */
61d4488377SClaudiu Beznea #define RTCA3_RCR1			0x22
62d4488377SClaudiu Beznea #define RTCA3_RCR1_AIE			BIT(0)
63d4488377SClaudiu Beznea #define RTCA3_RCR1_CIE			BIT(1)
64d4488377SClaudiu Beznea #define RTCA3_RCR1_PIE			BIT(2)
65d4488377SClaudiu Beznea #define RTCA3_RCR1_PES			GENMASK(7, 4)
66d4488377SClaudiu Beznea #define RTCA3_RCR1_PES_1_64_SEC		0x8
67d4488377SClaudiu Beznea #define RTCA3_RCR2			0x24
68d4488377SClaudiu Beznea #define RTCA3_RCR2_START		BIT(0)
69d4488377SClaudiu Beznea #define RTCA3_RCR2_RESET		BIT(1)
70d4488377SClaudiu Beznea #define RTCA3_RCR2_AADJE		BIT(4)
71d4488377SClaudiu Beznea #define RTCA3_RCR2_ADJP			BIT(5)
72d4488377SClaudiu Beznea #define RTCA3_RCR2_HR24			BIT(6)
73d4488377SClaudiu Beznea #define RTCA3_RCR2_CNTMD		BIT(7)
74d4488377SClaudiu Beznea #define RTCA3_RSR			0x20
75d4488377SClaudiu Beznea #define RTCA3_RSR_AF			BIT(0)
76d4488377SClaudiu Beznea #define RTCA3_RSR_CF			BIT(1)
77d4488377SClaudiu Beznea #define RTCA3_RSR_PF			BIT(2)
78d4488377SClaudiu Beznea #define RTCA3_RADJ			0x2e
79d4488377SClaudiu Beznea #define RTCA3_RADJ_ADJ			GENMASK(5, 0)
80d4488377SClaudiu Beznea #define RTCA3_RADJ_ADJ_MAX		0x3f
81d4488377SClaudiu Beznea #define RTCA3_RADJ_PMADJ		GENMASK(7, 6)
82d4488377SClaudiu Beznea #define RTCA3_RADJ_PMADJ_NONE		0
83d4488377SClaudiu Beznea #define RTCA3_RADJ_PMADJ_ADD		1
84d4488377SClaudiu Beznea #define RTCA3_RADJ_PMADJ_SUB		2
85d4488377SClaudiu Beznea 
86d4488377SClaudiu Beznea /* Polling operation timeouts. */
87d4488377SClaudiu Beznea #define RTCA3_DEFAULT_TIMEOUT_US	150
88d4488377SClaudiu Beznea #define RTCA3_IRQSET_TIMEOUT_US		5000
89d4488377SClaudiu Beznea #define RTCA3_START_TIMEOUT_US		150000
90d4488377SClaudiu Beznea #define RTCA3_RESET_TIMEOUT_US		200000
91d4488377SClaudiu Beznea 
92d4488377SClaudiu Beznea /**
93d4488377SClaudiu Beznea  * enum rtca3_alrm_set_step - RTCA3 alarm set steps
94d4488377SClaudiu Beznea  * @RTCA3_ALRM_SSTEP_DONE: alarm setup done step
95d4488377SClaudiu Beznea  * @RTCA3_ALRM_SSTEP_IRQ: two 1/64 periodic IRQs were generated step
96d4488377SClaudiu Beznea  * @RTCA3_ALRM_SSTEP_INIT: alarm setup initialization step
97d4488377SClaudiu Beznea  */
98d4488377SClaudiu Beznea enum rtca3_alrm_set_step {
99d4488377SClaudiu Beznea 	RTCA3_ALRM_SSTEP_DONE = 0,
100d4488377SClaudiu Beznea 	RTCA3_ALRM_SSTEP_IRQ = 1,
101d4488377SClaudiu Beznea 	RTCA3_ALRM_SSTEP_INIT = 3,
102d4488377SClaudiu Beznea };
103d4488377SClaudiu Beznea 
104d4488377SClaudiu Beznea /**
105d4488377SClaudiu Beznea  * struct rtca3_ppb_per_cycle - PPB per cycle
106d4488377SClaudiu Beznea  * @ten_sec: PPB per cycle in 10 seconds adjutment mode
107d4488377SClaudiu Beznea  * @sixty_sec: PPB per cycle in 60 seconds adjustment mode
108d4488377SClaudiu Beznea  */
109d4488377SClaudiu Beznea struct rtca3_ppb_per_cycle {
110d4488377SClaudiu Beznea 	int ten_sec;
111d4488377SClaudiu Beznea 	int sixty_sec;
112d4488377SClaudiu Beznea };
113d4488377SClaudiu Beznea 
114d4488377SClaudiu Beznea /**
115d4488377SClaudiu Beznea  * struct rtca3_priv - RTCA3 private data structure
116d4488377SClaudiu Beznea  * @base: base address
117d4488377SClaudiu Beznea  * @rtc_dev: RTC device
118d4488377SClaudiu Beznea  * @rstc: reset control
119d4488377SClaudiu Beznea  * @set_alarm_completion: alarm setup completion
120d4488377SClaudiu Beznea  * @alrm_sstep: alarm setup step (see enum rtca3_alrm_set_step)
121d4488377SClaudiu Beznea  * @lock: device lock
122d4488377SClaudiu Beznea  * @ppb: ppb per cycle for each the available adjustment modes
123d4488377SClaudiu Beznea  * @wakeup_irq: wakeup IRQ
124d4488377SClaudiu Beznea  */
125d4488377SClaudiu Beznea struct rtca3_priv {
126d4488377SClaudiu Beznea 	void __iomem *base;
127d4488377SClaudiu Beznea 	struct rtc_device *rtc_dev;
128d4488377SClaudiu Beznea 	struct reset_control *rstc;
129d4488377SClaudiu Beznea 	struct completion set_alarm_completion;
130d4488377SClaudiu Beznea 	atomic_t alrm_sstep;
131d4488377SClaudiu Beznea 	spinlock_t lock;
132d4488377SClaudiu Beznea 	struct rtca3_ppb_per_cycle ppb;
133d4488377SClaudiu Beznea 	int wakeup_irq;
134d4488377SClaudiu Beznea };
135d4488377SClaudiu Beznea 
rtca3_byte_update_bits(struct rtca3_priv * priv,u8 off,u8 mask,u8 val)136d4488377SClaudiu Beznea static void rtca3_byte_update_bits(struct rtca3_priv *priv, u8 off, u8 mask, u8 val)
137d4488377SClaudiu Beznea {
138d4488377SClaudiu Beznea 	u8 tmp;
139d4488377SClaudiu Beznea 
140d4488377SClaudiu Beznea 	tmp = readb(priv->base + off);
141d4488377SClaudiu Beznea 	tmp &= ~mask;
142d4488377SClaudiu Beznea 	tmp |= (val & mask);
143d4488377SClaudiu Beznea 	writeb(tmp, priv->base + off);
144d4488377SClaudiu Beznea }
145d4488377SClaudiu Beznea 
rtca3_alarm_handler_helper(struct rtca3_priv * priv)146d4488377SClaudiu Beznea static u8 rtca3_alarm_handler_helper(struct rtca3_priv *priv)
147d4488377SClaudiu Beznea {
148d4488377SClaudiu Beznea 	u8 val, pending;
149d4488377SClaudiu Beznea 
150d4488377SClaudiu Beznea 	val = readb(priv->base + RTCA3_RSR);
151d4488377SClaudiu Beznea 	pending = val & RTCA3_RSR_AF;
152d4488377SClaudiu Beznea 	writeb(val & ~pending, priv->base + RTCA3_RSR);
153d4488377SClaudiu Beznea 
154d4488377SClaudiu Beznea 	if (pending)
155d4488377SClaudiu Beznea 		rtc_update_irq(priv->rtc_dev, 1, RTC_AF | RTC_IRQF);
156d4488377SClaudiu Beznea 
157d4488377SClaudiu Beznea 	return pending;
158d4488377SClaudiu Beznea }
159d4488377SClaudiu Beznea 
rtca3_alarm_handler(int irq,void * dev_id)160d4488377SClaudiu Beznea static irqreturn_t rtca3_alarm_handler(int irq, void *dev_id)
161d4488377SClaudiu Beznea {
162d4488377SClaudiu Beznea 	struct rtca3_priv *priv = dev_id;
163d4488377SClaudiu Beznea 	u8 pending;
164d4488377SClaudiu Beznea 
165d4488377SClaudiu Beznea 	guard(spinlock)(&priv->lock);
166d4488377SClaudiu Beznea 
167d4488377SClaudiu Beznea 	pending = rtca3_alarm_handler_helper(priv);
168d4488377SClaudiu Beznea 
169d4488377SClaudiu Beznea 	return IRQ_RETVAL(pending);
170d4488377SClaudiu Beznea }
171d4488377SClaudiu Beznea 
rtca3_periodic_handler(int irq,void * dev_id)172d4488377SClaudiu Beznea static irqreturn_t rtca3_periodic_handler(int irq, void *dev_id)
173d4488377SClaudiu Beznea {
174d4488377SClaudiu Beznea 	struct rtca3_priv *priv = dev_id;
175d4488377SClaudiu Beznea 	u8 val, pending;
176d4488377SClaudiu Beznea 
177d4488377SClaudiu Beznea 	guard(spinlock)(&priv->lock);
178d4488377SClaudiu Beznea 
179d4488377SClaudiu Beznea 	val = readb(priv->base + RTCA3_RSR);
180d4488377SClaudiu Beznea 	pending = val & RTCA3_RSR_PF;
181d4488377SClaudiu Beznea 
182d4488377SClaudiu Beznea 	if (pending) {
183d4488377SClaudiu Beznea 		writeb(val & ~pending, priv->base + RTCA3_RSR);
184d4488377SClaudiu Beznea 
185d4488377SClaudiu Beznea 		if (atomic_read(&priv->alrm_sstep) > RTCA3_ALRM_SSTEP_IRQ) {
186d4488377SClaudiu Beznea 			/* Alarm setup in progress. */
187d4488377SClaudiu Beznea 			atomic_dec(&priv->alrm_sstep);
188d4488377SClaudiu Beznea 
189d4488377SClaudiu Beznea 			if (atomic_read(&priv->alrm_sstep) == RTCA3_ALRM_SSTEP_IRQ) {
190d4488377SClaudiu Beznea 				/*
191d4488377SClaudiu Beznea 				 * We got 2 * 1/64 periodic interrupts. Disable
192d4488377SClaudiu Beznea 				 * interrupt and let alarm setup continue.
193d4488377SClaudiu Beznea 				 */
194d4488377SClaudiu Beznea 				rtca3_byte_update_bits(priv, RTCA3_RCR1,
195d4488377SClaudiu Beznea 						       RTCA3_RCR1_PIE, 0);
196d4488377SClaudiu Beznea 				readb_poll_timeout_atomic(priv->base + RTCA3_RCR1, val,
197d4488377SClaudiu Beznea 							  !(val & RTCA3_RCR1_PIE),
198d4488377SClaudiu Beznea 							  10, RTCA3_DEFAULT_TIMEOUT_US);
199d4488377SClaudiu Beznea 				complete(&priv->set_alarm_completion);
200d4488377SClaudiu Beznea 			}
201d4488377SClaudiu Beznea 		}
202d4488377SClaudiu Beznea 	}
203d4488377SClaudiu Beznea 
204d4488377SClaudiu Beznea 	return IRQ_RETVAL(pending);
205d4488377SClaudiu Beznea }
206d4488377SClaudiu Beznea 
rtca3_prepare_cntalrm_regs_for_read(struct rtca3_priv * priv,bool cnt)207d4488377SClaudiu Beznea static void rtca3_prepare_cntalrm_regs_for_read(struct rtca3_priv *priv, bool cnt)
208d4488377SClaudiu Beznea {
209d4488377SClaudiu Beznea 	/* Offset b/w time and alarm registers. */
210d4488377SClaudiu Beznea 	u8 offset = cnt ? 0 : 0xe;
211d4488377SClaudiu Beznea 
212d4488377SClaudiu Beznea 	/*
213d4488377SClaudiu Beznea 	 * According to HW manual (section 22.6.4. Notes on writing to and
214d4488377SClaudiu Beznea 	 * reading from registers) after writing to count registers, alarm
215d4488377SClaudiu Beznea 	 * registers, year alarm enable register, bits RCR2.AADJE, AADJP,
216d4488377SClaudiu Beznea 	 * and HR24 register, we need to do 3 empty reads before being
217d4488377SClaudiu Beznea 	 * able to fetch the registers content.
218d4488377SClaudiu Beznea 	 */
219d4488377SClaudiu Beznea 	for (u8 i = 0; i < 3; i++) {
220d4488377SClaudiu Beznea 		readb(priv->base + RTCA3_RSECCNT + offset);
221d4488377SClaudiu Beznea 		readb(priv->base + RTCA3_RMINCNT + offset);
222d4488377SClaudiu Beznea 		readb(priv->base + RTCA3_RHRCNT  + offset);
223d4488377SClaudiu Beznea 		readb(priv->base + RTCA3_RWKCNT  + offset);
224d4488377SClaudiu Beznea 		readb(priv->base + RTCA3_RDAYCNT + offset);
225d4488377SClaudiu Beznea 		readw(priv->base + RTCA3_RYRCNT  + offset);
226d4488377SClaudiu Beznea 		if (!cnt)
227d4488377SClaudiu Beznea 			readb(priv->base + RTCA3_RYRAREN);
228d4488377SClaudiu Beznea 	}
229d4488377SClaudiu Beznea }
230d4488377SClaudiu Beznea 
rtca3_read_time(struct device * dev,struct rtc_time * tm)231d4488377SClaudiu Beznea static int rtca3_read_time(struct device *dev, struct rtc_time *tm)
232d4488377SClaudiu Beznea {
233d4488377SClaudiu Beznea 	struct rtca3_priv *priv = dev_get_drvdata(dev);
234d4488377SClaudiu Beznea 	u8 sec, min, hour, wday, mday, month, tmp;
235d4488377SClaudiu Beznea 	u8 trials = 0;
236d4488377SClaudiu Beznea 	u32 year100;
237d4488377SClaudiu Beznea 	u16 year;
238d4488377SClaudiu Beznea 
239d4488377SClaudiu Beznea 	guard(spinlock_irqsave)(&priv->lock);
240d4488377SClaudiu Beznea 
241d4488377SClaudiu Beznea 	tmp = readb(priv->base + RTCA3_RCR2);
242d4488377SClaudiu Beznea 	if (!(tmp & RTCA3_RCR2_START))
243d4488377SClaudiu Beznea 		return -EINVAL;
244d4488377SClaudiu Beznea 
245d4488377SClaudiu Beznea 	do {
246d4488377SClaudiu Beznea 		/* Clear carry interrupt. */
247d4488377SClaudiu Beznea 		rtca3_byte_update_bits(priv, RTCA3_RSR, RTCA3_RSR_CF, 0);
248d4488377SClaudiu Beznea 
249d4488377SClaudiu Beznea 		/* Read counters. */
250d4488377SClaudiu Beznea 		sec = readb(priv->base + RTCA3_RSECCNT);
251d4488377SClaudiu Beznea 		min = readb(priv->base + RTCA3_RMINCNT);
252d4488377SClaudiu Beznea 		hour = readb(priv->base + RTCA3_RHRCNT);
253d4488377SClaudiu Beznea 		wday = readb(priv->base + RTCA3_RWKCNT);
254d4488377SClaudiu Beznea 		mday = readb(priv->base + RTCA3_RDAYCNT);
255d4488377SClaudiu Beznea 		month = readb(priv->base + RTCA3_RMONCNT);
256d4488377SClaudiu Beznea 		year = readw(priv->base + RTCA3_RYRCNT);
257d4488377SClaudiu Beznea 
258d4488377SClaudiu Beznea 		tmp = readb(priv->base + RTCA3_RSR);
259d4488377SClaudiu Beznea 
260d4488377SClaudiu Beznea 		/*
261d4488377SClaudiu Beznea 		 * We cannot generate carries due to reading 64Hz counter as
262d4488377SClaudiu Beznea 		 * the driver doesn't implement carry, thus, carries will be
263d4488377SClaudiu Beznea 		 * generated once per seconds. Add a timeout of 5 trials here
264d4488377SClaudiu Beznea 		 * to avoid infinite loop, if any.
265d4488377SClaudiu Beznea 		 */
266d4488377SClaudiu Beznea 	} while ((tmp & RTCA3_RSR_CF) && ++trials < 5);
267d4488377SClaudiu Beznea 
268d4488377SClaudiu Beznea 	if (trials >= 5)
269d4488377SClaudiu Beznea 		return -ETIMEDOUT;
270d4488377SClaudiu Beznea 
271d4488377SClaudiu Beznea 	tm->tm_sec = bcd2bin(FIELD_GET(RTCA3_RSECCNT_SEC, sec));
272d4488377SClaudiu Beznea 	tm->tm_min = bcd2bin(FIELD_GET(RTCA3_RMINCNT_MIN, min));
273d4488377SClaudiu Beznea 	tm->tm_hour = bcd2bin(FIELD_GET(RTCA3_RHRCNT_HR, hour));
274d4488377SClaudiu Beznea 	tm->tm_wday = bcd2bin(FIELD_GET(RTCA3_RWKCNT_WK, wday));
275d4488377SClaudiu Beznea 	tm->tm_mday = bcd2bin(FIELD_GET(RTCA3_RDAYCNT_DAY, mday));
276d4488377SClaudiu Beznea 	tm->tm_mon = bcd2bin(FIELD_GET(RTCA3_RMONCNT_MONTH, month)) - 1;
277d4488377SClaudiu Beznea 	year = FIELD_GET(RTCA3_RYRCNT_YEAR, year);
278d4488377SClaudiu Beznea 	year100 = bcd2bin((year == 0x99) ? 0x19 : 0x20);
279d4488377SClaudiu Beznea 	tm->tm_year = (year100 * 100 + bcd2bin(year)) - 1900;
280d4488377SClaudiu Beznea 
281d4488377SClaudiu Beznea 	return 0;
282d4488377SClaudiu Beznea }
283d4488377SClaudiu Beznea 
rtca3_set_time(struct device * dev,struct rtc_time * tm)284d4488377SClaudiu Beznea static int rtca3_set_time(struct device *dev, struct rtc_time *tm)
285d4488377SClaudiu Beznea {
286d4488377SClaudiu Beznea 	struct rtca3_priv *priv = dev_get_drvdata(dev);
287d4488377SClaudiu Beznea 	u8 rcr2, tmp;
288d4488377SClaudiu Beznea 	int ret;
289d4488377SClaudiu Beznea 
290d4488377SClaudiu Beznea 	guard(spinlock_irqsave)(&priv->lock);
291d4488377SClaudiu Beznea 
292d4488377SClaudiu Beznea 	/* Stop the RTC. */
293d4488377SClaudiu Beznea 	rcr2 = readb(priv->base + RTCA3_RCR2);
294d4488377SClaudiu Beznea 	writeb(rcr2 & ~RTCA3_RCR2_START, priv->base + RTCA3_RCR2);
295d4488377SClaudiu Beznea 	ret = readb_poll_timeout_atomic(priv->base + RTCA3_RCR2, tmp,
296d4488377SClaudiu Beznea 					!(tmp & RTCA3_RCR2_START),
297d4488377SClaudiu Beznea 					10, RTCA3_DEFAULT_TIMEOUT_US);
298d4488377SClaudiu Beznea 	if (ret)
299d4488377SClaudiu Beznea 		return ret;
300d4488377SClaudiu Beznea 
301d4488377SClaudiu Beznea 	/* Update time. */
302d4488377SClaudiu Beznea 	writeb(bin2bcd(tm->tm_sec), priv->base + RTCA3_RSECCNT);
303d4488377SClaudiu Beznea 	writeb(bin2bcd(tm->tm_min), priv->base + RTCA3_RMINCNT);
304d4488377SClaudiu Beznea 	writeb(bin2bcd(tm->tm_hour), priv->base + RTCA3_RHRCNT);
305d4488377SClaudiu Beznea 	writeb(bin2bcd(tm->tm_wday), priv->base + RTCA3_RWKCNT);
306d4488377SClaudiu Beznea 	writeb(bin2bcd(tm->tm_mday), priv->base + RTCA3_RDAYCNT);
307d4488377SClaudiu Beznea 	writeb(bin2bcd(tm->tm_mon + 1), priv->base + RTCA3_RMONCNT);
308d4488377SClaudiu Beznea 	writew(bin2bcd(tm->tm_year % 100), priv->base + RTCA3_RYRCNT);
309d4488377SClaudiu Beznea 
310d4488377SClaudiu Beznea 	/* Make sure we can read back the counters. */
311d4488377SClaudiu Beznea 	rtca3_prepare_cntalrm_regs_for_read(priv, true);
312d4488377SClaudiu Beznea 
313d4488377SClaudiu Beznea 	/* Start RTC. */
314d4488377SClaudiu Beznea 	writeb(rcr2 | RTCA3_RCR2_START, priv->base + RTCA3_RCR2);
315d4488377SClaudiu Beznea 	return readb_poll_timeout_atomic(priv->base + RTCA3_RCR2, tmp,
316d4488377SClaudiu Beznea 					 (tmp & RTCA3_RCR2_START),
317d4488377SClaudiu Beznea 					 10, RTCA3_DEFAULT_TIMEOUT_US);
318d4488377SClaudiu Beznea }
319d4488377SClaudiu Beznea 
rtca3_alarm_irq_set_helper(struct rtca3_priv * priv,u8 interrupts,unsigned int enabled)320d4488377SClaudiu Beznea static int rtca3_alarm_irq_set_helper(struct rtca3_priv *priv,
321d4488377SClaudiu Beznea 				      u8 interrupts,
322d4488377SClaudiu Beznea 				      unsigned int enabled)
323d4488377SClaudiu Beznea {
324d4488377SClaudiu Beznea 	u8 tmp, val;
325d4488377SClaudiu Beznea 
326d4488377SClaudiu Beznea 	if (enabled) {
327d4488377SClaudiu Beznea 		/*
328d4488377SClaudiu Beznea 		 * AIE, CIE, PIE bit indexes in RSR corresponds with
329d4488377SClaudiu Beznea 		 * those on RCR1. Same interrupts mask can be used.
330d4488377SClaudiu Beznea 		 */
331d4488377SClaudiu Beznea 		rtca3_byte_update_bits(priv, RTCA3_RSR, interrupts, 0);
332d4488377SClaudiu Beznea 		val = interrupts;
333d4488377SClaudiu Beznea 	} else {
334d4488377SClaudiu Beznea 		val = 0;
335d4488377SClaudiu Beznea 	}
336d4488377SClaudiu Beznea 
337d4488377SClaudiu Beznea 	rtca3_byte_update_bits(priv, RTCA3_RCR1, interrupts, val);
338d4488377SClaudiu Beznea 	return readb_poll_timeout_atomic(priv->base + RTCA3_RCR1, tmp,
339d4488377SClaudiu Beznea 					 ((tmp & interrupts) == val),
340d4488377SClaudiu Beznea 					 10, RTCA3_IRQSET_TIMEOUT_US);
341d4488377SClaudiu Beznea }
342d4488377SClaudiu Beznea 
rtca3_alarm_irq_enable(struct device * dev,unsigned int enabled)343d4488377SClaudiu Beznea static int rtca3_alarm_irq_enable(struct device *dev, unsigned int enabled)
344d4488377SClaudiu Beznea {
345d4488377SClaudiu Beznea 	struct rtca3_priv *priv = dev_get_drvdata(dev);
346d4488377SClaudiu Beznea 
347d4488377SClaudiu Beznea 	guard(spinlock_irqsave)(&priv->lock);
348d4488377SClaudiu Beznea 
349d4488377SClaudiu Beznea 	return rtca3_alarm_irq_set_helper(priv, RTCA3_RCR1_AIE, enabled);
350d4488377SClaudiu Beznea }
351d4488377SClaudiu Beznea 
rtca3_read_alarm(struct device * dev,struct rtc_wkalrm * wkalrm)352d4488377SClaudiu Beznea static int rtca3_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
353d4488377SClaudiu Beznea {
354d4488377SClaudiu Beznea 	struct rtca3_priv *priv = dev_get_drvdata(dev);
355d4488377SClaudiu Beznea 	u8 sec, min, hour, wday, mday, month;
356d4488377SClaudiu Beznea 	struct rtc_time *tm = &wkalrm->time;
357d4488377SClaudiu Beznea 	u32 year100;
358d4488377SClaudiu Beznea 	u16 year;
359d4488377SClaudiu Beznea 
360d4488377SClaudiu Beznea 	guard(spinlock_irqsave)(&priv->lock);
361d4488377SClaudiu Beznea 
362d4488377SClaudiu Beznea 	sec = readb(priv->base + RTCA3_RSECAR);
363d4488377SClaudiu Beznea 	min = readb(priv->base + RTCA3_RMINAR);
364d4488377SClaudiu Beznea 	hour = readb(priv->base + RTCA3_RHRAR);
365d4488377SClaudiu Beznea 	wday = readb(priv->base + RTCA3_RWKAR);
366d4488377SClaudiu Beznea 	mday = readb(priv->base + RTCA3_RDAYAR);
367d4488377SClaudiu Beznea 	month = readb(priv->base + RTCA3_RMONAR);
368d4488377SClaudiu Beznea 	year = readw(priv->base + RTCA3_RYRAR);
369d4488377SClaudiu Beznea 
370d4488377SClaudiu Beznea 	tm->tm_sec = bcd2bin(FIELD_GET(RTCA3_RSECAR_SEC, sec));
371d4488377SClaudiu Beznea 	tm->tm_min = bcd2bin(FIELD_GET(RTCA3_RMINAR_MIN, min));
372d4488377SClaudiu Beznea 	tm->tm_hour = bcd2bin(FIELD_GET(RTCA3_RHRAR_HR, hour));
373d4488377SClaudiu Beznea 	tm->tm_wday = bcd2bin(FIELD_GET(RTCA3_RWKAR_DAYW, wday));
374d4488377SClaudiu Beznea 	tm->tm_mday = bcd2bin(FIELD_GET(RTCA3_RDAYAR_DATE, mday));
375d4488377SClaudiu Beznea 	tm->tm_mon = bcd2bin(FIELD_GET(RTCA3_RMONAR_MON, month)) - 1;
376d4488377SClaudiu Beznea 	year = FIELD_GET(RTCA3_RYRAR_YR, year);
377d4488377SClaudiu Beznea 	year100 = bcd2bin((year == 0x99) ? 0x19 : 0x20);
378d4488377SClaudiu Beznea 	tm->tm_year = (year100 * 100 + bcd2bin(year)) - 1900;
379d4488377SClaudiu Beznea 
380d4488377SClaudiu Beznea 	wkalrm->enabled = !!(readb(priv->base + RTCA3_RCR1) & RTCA3_RCR1_AIE);
381d4488377SClaudiu Beznea 
382d4488377SClaudiu Beznea 	return 0;
383d4488377SClaudiu Beznea }
384d4488377SClaudiu Beznea 
rtca3_set_alarm(struct device * dev,struct rtc_wkalrm * wkalrm)385d4488377SClaudiu Beznea static int rtca3_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
386d4488377SClaudiu Beznea {
387d4488377SClaudiu Beznea 	struct rtca3_priv *priv = dev_get_drvdata(dev);
388d4488377SClaudiu Beznea 	struct rtc_time *tm = &wkalrm->time;
389d4488377SClaudiu Beznea 	u8 rcr1, tmp;
390d4488377SClaudiu Beznea 	int ret;
391d4488377SClaudiu Beznea 
392d4488377SClaudiu Beznea 	scoped_guard(spinlock_irqsave, &priv->lock) {
393d4488377SClaudiu Beznea 		tmp = readb(priv->base + RTCA3_RCR2);
394d4488377SClaudiu Beznea 		if (!(tmp & RTCA3_RCR2_START))
395d4488377SClaudiu Beznea 			return -EPERM;
396d4488377SClaudiu Beznea 
397d4488377SClaudiu Beznea 		/* Disable AIE to prevent false interrupts. */
398d4488377SClaudiu Beznea 		rcr1 = readb(priv->base + RTCA3_RCR1);
399d4488377SClaudiu Beznea 		rcr1 &= ~RTCA3_RCR1_AIE;
400d4488377SClaudiu Beznea 		writeb(rcr1, priv->base + RTCA3_RCR1);
401d4488377SClaudiu Beznea 		ret = readb_poll_timeout_atomic(priv->base + RTCA3_RCR1, tmp,
402d4488377SClaudiu Beznea 						!(tmp & RTCA3_RCR1_AIE),
403d4488377SClaudiu Beznea 						10, RTCA3_DEFAULT_TIMEOUT_US);
404d4488377SClaudiu Beznea 		if (ret)
405d4488377SClaudiu Beznea 			return ret;
406d4488377SClaudiu Beznea 
407d4488377SClaudiu Beznea 		/* Set the time and enable the alarm. */
408d4488377SClaudiu Beznea 		writeb(RTCA3_AR_ENB | bin2bcd(tm->tm_sec), priv->base + RTCA3_RSECAR);
409d4488377SClaudiu Beznea 		writeb(RTCA3_AR_ENB | bin2bcd(tm->tm_min), priv->base + RTCA3_RMINAR);
410d4488377SClaudiu Beznea 		writeb(RTCA3_AR_ENB | bin2bcd(tm->tm_hour), priv->base + RTCA3_RHRAR);
411d4488377SClaudiu Beznea 		writeb(RTCA3_AR_ENB | bin2bcd(tm->tm_wday), priv->base + RTCA3_RWKAR);
412d4488377SClaudiu Beznea 		writeb(RTCA3_AR_ENB | bin2bcd(tm->tm_mday), priv->base + RTCA3_RDAYAR);
413d4488377SClaudiu Beznea 		writeb(RTCA3_AR_ENB | bin2bcd(tm->tm_mon + 1), priv->base + RTCA3_RMONAR);
414d4488377SClaudiu Beznea 
415d4488377SClaudiu Beznea 		writew(bin2bcd(tm->tm_year % 100), priv->base + RTCA3_RYRAR);
416d4488377SClaudiu Beznea 		writeb(RTCA3_AR_ENB, priv->base + RTCA3_RYRAREN);
417d4488377SClaudiu Beznea 
418d4488377SClaudiu Beznea 		/* Make sure we can read back the counters. */
419d4488377SClaudiu Beznea 		rtca3_prepare_cntalrm_regs_for_read(priv, false);
420d4488377SClaudiu Beznea 
421d4488377SClaudiu Beznea 		/* Need to wait for 2 * 1/64 periodic interrupts to be generated. */
422d4488377SClaudiu Beznea 		atomic_set(&priv->alrm_sstep, RTCA3_ALRM_SSTEP_INIT);
423d4488377SClaudiu Beznea 		reinit_completion(&priv->set_alarm_completion);
424d4488377SClaudiu Beznea 
425d4488377SClaudiu Beznea 		/* Enable periodic interrupt. */
426d4488377SClaudiu Beznea 		rcr1 |= RTCA3_RCR1_PIE;
427d4488377SClaudiu Beznea 		writeb(rcr1, priv->base + RTCA3_RCR1);
428d4488377SClaudiu Beznea 		ret = readb_poll_timeout_atomic(priv->base + RTCA3_RCR1, tmp,
429d4488377SClaudiu Beznea 						(tmp & RTCA3_RCR1_PIE),
430d4488377SClaudiu Beznea 						10, RTCA3_IRQSET_TIMEOUT_US);
431d4488377SClaudiu Beznea 	}
432d4488377SClaudiu Beznea 
433d4488377SClaudiu Beznea 	if (ret)
434d4488377SClaudiu Beznea 		goto setup_failed;
435d4488377SClaudiu Beznea 
436d4488377SClaudiu Beznea 	/* Wait for the 2 * 1/64 periodic interrupts. */
437d4488377SClaudiu Beznea 	ret = wait_for_completion_interruptible_timeout(&priv->set_alarm_completion,
438d4488377SClaudiu Beznea 							msecs_to_jiffies(500));
439d4488377SClaudiu Beznea 	if (ret <= 0) {
440d4488377SClaudiu Beznea 		ret = -ETIMEDOUT;
441d4488377SClaudiu Beznea 		goto setup_failed;
442d4488377SClaudiu Beznea 	}
443d4488377SClaudiu Beznea 
444d4488377SClaudiu Beznea 	scoped_guard(spinlock_irqsave, &priv->lock) {
445d4488377SClaudiu Beznea 		ret = rtca3_alarm_irq_set_helper(priv, RTCA3_RCR1_AIE, wkalrm->enabled);
446d4488377SClaudiu Beznea 		atomic_set(&priv->alrm_sstep, RTCA3_ALRM_SSTEP_DONE);
447d4488377SClaudiu Beznea 	}
448d4488377SClaudiu Beznea 
449d4488377SClaudiu Beznea 	return ret;
450d4488377SClaudiu Beznea 
451d4488377SClaudiu Beznea setup_failed:
452d4488377SClaudiu Beznea 	scoped_guard(spinlock_irqsave, &priv->lock) {
453d4488377SClaudiu Beznea 		/*
454d4488377SClaudiu Beznea 		 * Disable PIE to avoid interrupt storm in case HW needed more than
455d4488377SClaudiu Beznea 		 * specified timeout for setup.
456d4488377SClaudiu Beznea 		 */
457d4488377SClaudiu Beznea 		writeb(rcr1 & ~RTCA3_RCR1_PIE, priv->base + RTCA3_RCR1);
458d4488377SClaudiu Beznea 		readb_poll_timeout_atomic(priv->base + RTCA3_RCR1, tmp, !(tmp & ~RTCA3_RCR1_PIE),
459d4488377SClaudiu Beznea 					  10, RTCA3_DEFAULT_TIMEOUT_US);
460d4488377SClaudiu Beznea 		atomic_set(&priv->alrm_sstep, RTCA3_ALRM_SSTEP_DONE);
461d4488377SClaudiu Beznea 	}
462d4488377SClaudiu Beznea 
463d4488377SClaudiu Beznea 	return ret;
464d4488377SClaudiu Beznea }
465d4488377SClaudiu Beznea 
rtca3_read_offset(struct device * dev,long * offset)466d4488377SClaudiu Beznea static int rtca3_read_offset(struct device *dev, long *offset)
467d4488377SClaudiu Beznea {
468d4488377SClaudiu Beznea 	struct rtca3_priv *priv = dev_get_drvdata(dev);
469d4488377SClaudiu Beznea 	u8 val, radj, cycles;
470d4488377SClaudiu Beznea 	u32 ppb_per_cycle;
471d4488377SClaudiu Beznea 
472d4488377SClaudiu Beznea 	scoped_guard(spinlock_irqsave, &priv->lock) {
473d4488377SClaudiu Beznea 		radj = readb(priv->base + RTCA3_RADJ);
474d4488377SClaudiu Beznea 		val = readb(priv->base + RTCA3_RCR2);
475d4488377SClaudiu Beznea 	}
476d4488377SClaudiu Beznea 
477d4488377SClaudiu Beznea 	cycles = FIELD_GET(RTCA3_RADJ_ADJ, radj);
478d4488377SClaudiu Beznea 
479d4488377SClaudiu Beznea 	if (!cycles) {
480d4488377SClaudiu Beznea 		*offset = 0;
481d4488377SClaudiu Beznea 		return 0;
482d4488377SClaudiu Beznea 	}
483d4488377SClaudiu Beznea 
484d4488377SClaudiu Beznea 	if (val & RTCA3_RCR2_ADJP)
485d4488377SClaudiu Beznea 		ppb_per_cycle = priv->ppb.ten_sec;
486d4488377SClaudiu Beznea 	else
487d4488377SClaudiu Beznea 		ppb_per_cycle = priv->ppb.sixty_sec;
488d4488377SClaudiu Beznea 
489d4488377SClaudiu Beznea 	*offset = cycles * ppb_per_cycle;
490d4488377SClaudiu Beznea 	val = FIELD_GET(RTCA3_RADJ_PMADJ, radj);
491d4488377SClaudiu Beznea 	if (val == RTCA3_RADJ_PMADJ_SUB)
492d4488377SClaudiu Beznea 		*offset = -(*offset);
493d4488377SClaudiu Beznea 
494d4488377SClaudiu Beznea 	return 0;
495d4488377SClaudiu Beznea }
496d4488377SClaudiu Beznea 
rtca3_set_offset(struct device * dev,long offset)497d4488377SClaudiu Beznea static int rtca3_set_offset(struct device *dev, long offset)
498d4488377SClaudiu Beznea {
499d4488377SClaudiu Beznea 	struct rtca3_priv *priv = dev_get_drvdata(dev);
500d4488377SClaudiu Beznea 	int cycles, cycles10, cycles60;
501d4488377SClaudiu Beznea 	u8 radj, adjp, tmp;
502d4488377SClaudiu Beznea 	int ret;
503d4488377SClaudiu Beznea 
504d4488377SClaudiu Beznea 	/*
505d4488377SClaudiu Beznea 	 * Automatic time error adjustment could be set at intervals of 10
506d4488377SClaudiu Beznea 	 * or 60 seconds.
507d4488377SClaudiu Beznea 	 */
508d4488377SClaudiu Beznea 	cycles10 = DIV_ROUND_CLOSEST(offset, priv->ppb.ten_sec);
509d4488377SClaudiu Beznea 	cycles60 = DIV_ROUND_CLOSEST(offset, priv->ppb.sixty_sec);
510d4488377SClaudiu Beznea 
511d4488377SClaudiu Beznea 	/* We can set b/w 1 and 63 clock cycles. */
512d4488377SClaudiu Beznea 	if (cycles60 >= -RTCA3_RADJ_ADJ_MAX &&
513d4488377SClaudiu Beznea 	    cycles60 <= RTCA3_RADJ_ADJ_MAX) {
514d4488377SClaudiu Beznea 		cycles = cycles60;
515d4488377SClaudiu Beznea 		adjp = 0;
516d4488377SClaudiu Beznea 	} else if (cycles10 >= -RTCA3_RADJ_ADJ_MAX &&
517d4488377SClaudiu Beznea 		   cycles10 <= RTCA3_RADJ_ADJ_MAX) {
518d4488377SClaudiu Beznea 		cycles = cycles10;
519d4488377SClaudiu Beznea 		adjp = RTCA3_RCR2_ADJP;
520d4488377SClaudiu Beznea 	} else {
521d4488377SClaudiu Beznea 		return -ERANGE;
522d4488377SClaudiu Beznea 	}
523d4488377SClaudiu Beznea 
524d4488377SClaudiu Beznea 	radj = FIELD_PREP(RTCA3_RADJ_ADJ, abs(cycles));
525d4488377SClaudiu Beznea 	if (!cycles)
526d4488377SClaudiu Beznea 		radj |= FIELD_PREP(RTCA3_RADJ_PMADJ, RTCA3_RADJ_PMADJ_NONE);
527d4488377SClaudiu Beznea 	else if (cycles > 0)
528d4488377SClaudiu Beznea 		radj |= FIELD_PREP(RTCA3_RADJ_PMADJ, RTCA3_RADJ_PMADJ_ADD);
529d4488377SClaudiu Beznea 	else
530d4488377SClaudiu Beznea 		radj |= FIELD_PREP(RTCA3_RADJ_PMADJ, RTCA3_RADJ_PMADJ_SUB);
531d4488377SClaudiu Beznea 
532d4488377SClaudiu Beznea 	guard(spinlock_irqsave)(&priv->lock);
533d4488377SClaudiu Beznea 
534d4488377SClaudiu Beznea 	tmp = readb(priv->base + RTCA3_RCR2);
535d4488377SClaudiu Beznea 
536d4488377SClaudiu Beznea 	if ((tmp & RTCA3_RCR2_ADJP) != adjp) {
537d4488377SClaudiu Beznea 		/* RADJ.PMADJ need to be set to zero before setting RCR2.ADJP. */
538d4488377SClaudiu Beznea 		writeb(0, priv->base + RTCA3_RADJ);
539d4488377SClaudiu Beznea 		ret = readb_poll_timeout_atomic(priv->base + RTCA3_RADJ, tmp, !tmp,
540d4488377SClaudiu Beznea 						10, RTCA3_DEFAULT_TIMEOUT_US);
541d4488377SClaudiu Beznea 		if (ret)
542d4488377SClaudiu Beznea 			return ret;
543d4488377SClaudiu Beznea 
544d4488377SClaudiu Beznea 		rtca3_byte_update_bits(priv, RTCA3_RCR2, RTCA3_RCR2_ADJP, adjp);
545d4488377SClaudiu Beznea 		ret = readb_poll_timeout_atomic(priv->base + RTCA3_RCR2, tmp,
546d4488377SClaudiu Beznea 						((tmp & RTCA3_RCR2_ADJP) == adjp),
547d4488377SClaudiu Beznea 						10, RTCA3_DEFAULT_TIMEOUT_US);
548d4488377SClaudiu Beznea 		if (ret)
549d4488377SClaudiu Beznea 			return ret;
550d4488377SClaudiu Beznea 	}
551d4488377SClaudiu Beznea 
552d4488377SClaudiu Beznea 	writeb(radj, priv->base + RTCA3_RADJ);
553d4488377SClaudiu Beznea 	return readb_poll_timeout_atomic(priv->base + RTCA3_RADJ, tmp, (tmp == radj),
554d4488377SClaudiu Beznea 					 10, RTCA3_DEFAULT_TIMEOUT_US);
555d4488377SClaudiu Beznea }
556d4488377SClaudiu Beznea 
557d4488377SClaudiu Beznea static const struct rtc_class_ops rtca3_ops = {
558d4488377SClaudiu Beznea 	.read_time = rtca3_read_time,
559d4488377SClaudiu Beznea 	.set_time = rtca3_set_time,
560d4488377SClaudiu Beznea 	.read_alarm = rtca3_read_alarm,
561d4488377SClaudiu Beznea 	.set_alarm = rtca3_set_alarm,
562d4488377SClaudiu Beznea 	.alarm_irq_enable = rtca3_alarm_irq_enable,
563d4488377SClaudiu Beznea 	.set_offset = rtca3_set_offset,
564d4488377SClaudiu Beznea 	.read_offset = rtca3_read_offset,
565d4488377SClaudiu Beznea };
566d4488377SClaudiu Beznea 
rtca3_initial_setup(struct clk * clk,struct rtca3_priv * priv)567d4488377SClaudiu Beznea static int rtca3_initial_setup(struct clk *clk, struct rtca3_priv *priv)
568d4488377SClaudiu Beznea {
569d4488377SClaudiu Beznea 	unsigned long osc32k_rate;
570d4488377SClaudiu Beznea 	u8 val, tmp, mask;
571d4488377SClaudiu Beznea 	u32 sleep_us;
572d4488377SClaudiu Beznea 	int ret;
573d4488377SClaudiu Beznea 
574d4488377SClaudiu Beznea 	osc32k_rate = clk_get_rate(clk);
575d4488377SClaudiu Beznea 	if (!osc32k_rate)
576d4488377SClaudiu Beznea 		return -EINVAL;
577d4488377SClaudiu Beznea 
578d4488377SClaudiu Beznea 	sleep_us = DIV_ROUND_UP_ULL(1000000ULL, osc32k_rate) * 6;
579d4488377SClaudiu Beznea 
580d4488377SClaudiu Beznea 	priv->ppb.ten_sec = DIV_ROUND_CLOSEST_ULL(1000000000ULL, (osc32k_rate * 10));
581d4488377SClaudiu Beznea 	priv->ppb.sixty_sec = DIV_ROUND_CLOSEST_ULL(1000000000ULL, (osc32k_rate * 60));
582d4488377SClaudiu Beznea 
583d4488377SClaudiu Beznea 	/*
584d4488377SClaudiu Beznea 	 * According to HW manual (section 22.4.2. Clock and count mode setting procedure)
585d4488377SClaudiu Beznea 	 * we need to wait at least 6 cycles of the 32KHz clock after clock was enabled.
586d4488377SClaudiu Beznea 	 */
587d4488377SClaudiu Beznea 	usleep_range(sleep_us, sleep_us + 10);
588d4488377SClaudiu Beznea 
589d4488377SClaudiu Beznea 	/* Disable all interrupts. */
590d4488377SClaudiu Beznea 	mask = RTCA3_RCR1_AIE | RTCA3_RCR1_CIE | RTCA3_RCR1_PIE;
591d4488377SClaudiu Beznea 	ret = rtca3_alarm_irq_set_helper(priv, mask, 0);
592d4488377SClaudiu Beznea 	if (ret)
593d4488377SClaudiu Beznea 		return ret;
594d4488377SClaudiu Beznea 
595d4488377SClaudiu Beznea 	mask = RTCA3_RCR2_START | RTCA3_RCR2_HR24;
596d4488377SClaudiu Beznea 	val = readb(priv->base + RTCA3_RCR2);
597d4488377SClaudiu Beznea 	/* Nothing to do if already started in 24 hours and calendar count mode. */
598d4488377SClaudiu Beznea 	if ((val & mask) == mask)
599d4488377SClaudiu Beznea 		return 0;
600d4488377SClaudiu Beznea 
601d4488377SClaudiu Beznea 	/* Reconfigure the RTC in 24 hours and calendar count mode. */
602d4488377SClaudiu Beznea 	mask = RTCA3_RCR2_START | RTCA3_RCR2_CNTMD;
603d4488377SClaudiu Beznea 	writeb(0, priv->base + RTCA3_RCR2);
604d4488377SClaudiu Beznea 	ret = readb_poll_timeout(priv->base + RTCA3_RCR2, tmp, !(tmp & mask),
605d4488377SClaudiu Beznea 				 10, RTCA3_DEFAULT_TIMEOUT_US);
606d4488377SClaudiu Beznea 	if (ret)
607d4488377SClaudiu Beznea 		return ret;
608d4488377SClaudiu Beznea 
609d4488377SClaudiu Beznea 	/*
610d4488377SClaudiu Beznea 	 * Set 24 hours mode. According to HW manual (section 22.3.19. RTC Control
611d4488377SClaudiu Beznea 	 * Register 2) this needs to be done separate from stop operation.
612d4488377SClaudiu Beznea 	 */
613d4488377SClaudiu Beznea 	mask = RTCA3_RCR2_HR24;
614d4488377SClaudiu Beznea 	val = RTCA3_RCR2_HR24;
615d4488377SClaudiu Beznea 	writeb(val, priv->base + RTCA3_RCR2);
616d4488377SClaudiu Beznea 	ret = readb_poll_timeout(priv->base + RTCA3_RCR2, tmp, (tmp & mask),
617d4488377SClaudiu Beznea 				 10, RTCA3_DEFAULT_TIMEOUT_US);
618d4488377SClaudiu Beznea 	if (ret)
619d4488377SClaudiu Beznea 		return ret;
620d4488377SClaudiu Beznea 
621d4488377SClaudiu Beznea 	/* Execute reset. */
622d4488377SClaudiu Beznea 	mask = RTCA3_RCR2_RESET;
623d4488377SClaudiu Beznea 	writeb(val | RTCA3_RCR2_RESET, priv->base + RTCA3_RCR2);
624d4488377SClaudiu Beznea 	ret = readb_poll_timeout(priv->base + RTCA3_RCR2, tmp, !(tmp & mask),
625d4488377SClaudiu Beznea 				 10, RTCA3_RESET_TIMEOUT_US);
626d4488377SClaudiu Beznea 	if (ret)
627d4488377SClaudiu Beznea 		return ret;
628d4488377SClaudiu Beznea 
629d4488377SClaudiu Beznea 	/*
630d4488377SClaudiu Beznea 	 * According to HW manual (section 22.6.3. Notes on writing to and reading
631d4488377SClaudiu Beznea 	 * from registers) after reset we need to wait 6 clock cycles before
632d4488377SClaudiu Beznea 	 * writing to RTC registers.
633d4488377SClaudiu Beznea 	 */
634d4488377SClaudiu Beznea 	usleep_range(sleep_us, sleep_us + 10);
635d4488377SClaudiu Beznea 
636d4488377SClaudiu Beznea 	/* Set no adjustment. */
637d4488377SClaudiu Beznea 	writeb(0, priv->base + RTCA3_RADJ);
638d4488377SClaudiu Beznea 	ret = readb_poll_timeout(priv->base + RTCA3_RADJ, tmp, !tmp, 10,
639d4488377SClaudiu Beznea 				 RTCA3_DEFAULT_TIMEOUT_US);
640d4488377SClaudiu Beznea 
641d4488377SClaudiu Beznea 	/* Start the RTC and enable automatic time error adjustment. */
642d4488377SClaudiu Beznea 	mask = RTCA3_RCR2_START | RTCA3_RCR2_AADJE;
643d4488377SClaudiu Beznea 	val |= RTCA3_RCR2_START | RTCA3_RCR2_AADJE;
644d4488377SClaudiu Beznea 	writeb(val, priv->base + RTCA3_RCR2);
645d4488377SClaudiu Beznea 	ret = readb_poll_timeout(priv->base + RTCA3_RCR2, tmp, ((tmp & mask) == mask),
646d4488377SClaudiu Beznea 				 10, RTCA3_START_TIMEOUT_US);
647d4488377SClaudiu Beznea 	if (ret)
648d4488377SClaudiu Beznea 		return ret;
649d4488377SClaudiu Beznea 
650d4488377SClaudiu Beznea 	/*
651d4488377SClaudiu Beznea 	 * According to HW manual (section 22.6.4. Notes on writing to and reading
652d4488377SClaudiu Beznea 	 * from registers) we need to wait 1/128 seconds while the clock is operating
653d4488377SClaudiu Beznea 	 * (RCR2.START bit = 1) to be able to read the counters after a return from
654d4488377SClaudiu Beznea 	 * reset.
655d4488377SClaudiu Beznea 	 */
656d4488377SClaudiu Beznea 	usleep_range(8000, 9000);
657d4488377SClaudiu Beznea 
658d4488377SClaudiu Beznea 	/* Set period interrupt to 1/64 seconds. It is necessary for alarm setup. */
659d4488377SClaudiu Beznea 	val = FIELD_PREP(RTCA3_RCR1_PES, RTCA3_RCR1_PES_1_64_SEC);
660d4488377SClaudiu Beznea 	rtca3_byte_update_bits(priv, RTCA3_RCR1, RTCA3_RCR1_PES, val);
661d4488377SClaudiu Beznea 	return readb_poll_timeout(priv->base + RTCA3_RCR1, tmp, ((tmp & RTCA3_RCR1_PES) == val),
662d4488377SClaudiu Beznea 				  10, RTCA3_DEFAULT_TIMEOUT_US);
663d4488377SClaudiu Beznea }
664d4488377SClaudiu Beznea 
rtca3_request_irqs(struct platform_device * pdev,struct rtca3_priv * priv)665d4488377SClaudiu Beznea static int rtca3_request_irqs(struct platform_device *pdev, struct rtca3_priv *priv)
666d4488377SClaudiu Beznea {
667d4488377SClaudiu Beznea 	struct device *dev = &pdev->dev;
668d4488377SClaudiu Beznea 	int ret, irq;
669d4488377SClaudiu Beznea 
670d4488377SClaudiu Beznea 	irq = platform_get_irq_byname(pdev, "alarm");
671d4488377SClaudiu Beznea 	if (irq < 0)
672d4488377SClaudiu Beznea 		return dev_err_probe(dev, irq, "Failed to get alarm IRQ!\n");
673d4488377SClaudiu Beznea 
674d4488377SClaudiu Beznea 	ret = devm_request_irq(dev, irq, rtca3_alarm_handler, 0, "rtca3-alarm", priv);
675d4488377SClaudiu Beznea 	if (ret)
676d4488377SClaudiu Beznea 		return dev_err_probe(dev, ret, "Failed to request alarm IRQ!\n");
677d4488377SClaudiu Beznea 	priv->wakeup_irq = irq;
678d4488377SClaudiu Beznea 
679d4488377SClaudiu Beznea 	irq = platform_get_irq_byname(pdev, "period");
680d4488377SClaudiu Beznea 	if (irq < 0)
681d4488377SClaudiu Beznea 		return dev_err_probe(dev, irq, "Failed to get period IRQ!\n");
682d4488377SClaudiu Beznea 
683d4488377SClaudiu Beznea 	ret = devm_request_irq(dev, irq, rtca3_periodic_handler, 0, "rtca3-period", priv);
684d4488377SClaudiu Beznea 	if (ret)
685d4488377SClaudiu Beznea 		return dev_err_probe(dev, ret, "Failed to request period IRQ!\n");
686d4488377SClaudiu Beznea 
687d4488377SClaudiu Beznea 	/*
688d4488377SClaudiu Beznea 	 * Driver doesn't implement carry handler. Just get the IRQ here
689d4488377SClaudiu Beznea 	 * for backward compatibility, in case carry support will be added later.
690d4488377SClaudiu Beznea 	 */
691d4488377SClaudiu Beznea 	irq = platform_get_irq_byname(pdev, "carry");
692d4488377SClaudiu Beznea 	if (irq < 0)
693d4488377SClaudiu Beznea 		return dev_err_probe(dev, irq, "Failed to get carry IRQ!\n");
694d4488377SClaudiu Beznea 
695d4488377SClaudiu Beznea 	return 0;
696d4488377SClaudiu Beznea }
697d4488377SClaudiu Beznea 
rtca3_action(void * data)698d4488377SClaudiu Beznea static void rtca3_action(void *data)
699d4488377SClaudiu Beznea {
700d4488377SClaudiu Beznea 	struct device *dev = data;
701d4488377SClaudiu Beznea 	struct rtca3_priv *priv = dev_get_drvdata(dev);
702d4488377SClaudiu Beznea 	int ret;
703d4488377SClaudiu Beznea 
704d4488377SClaudiu Beznea 	ret = reset_control_assert(priv->rstc);
705d4488377SClaudiu Beznea 	if (ret)
706d4488377SClaudiu Beznea 		dev_err(dev, "Failed to de-assert reset!");
707d4488377SClaudiu Beznea 
708d4488377SClaudiu Beznea 	ret = pm_runtime_put_sync(dev);
709d4488377SClaudiu Beznea 	if (ret < 0)
710d4488377SClaudiu Beznea 		dev_err(dev, "Failed to runtime suspend!");
711d4488377SClaudiu Beznea }
712d4488377SClaudiu Beznea 
rtca3_probe(struct platform_device * pdev)713d4488377SClaudiu Beznea static int rtca3_probe(struct platform_device *pdev)
714d4488377SClaudiu Beznea {
715d4488377SClaudiu Beznea 	struct device *dev = &pdev->dev;
716d4488377SClaudiu Beznea 	struct rtca3_priv *priv;
717d4488377SClaudiu Beznea 	struct clk *clk;
718d4488377SClaudiu Beznea 	int ret;
719d4488377SClaudiu Beznea 
720d4488377SClaudiu Beznea 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
721d4488377SClaudiu Beznea 	if (!priv)
722d4488377SClaudiu Beznea 		return -ENOMEM;
723d4488377SClaudiu Beznea 
724d4488377SClaudiu Beznea 	priv->base = devm_platform_ioremap_resource(pdev, 0);
725d4488377SClaudiu Beznea 	if (IS_ERR(priv->base))
726d4488377SClaudiu Beznea 		return PTR_ERR(priv->base);
727d4488377SClaudiu Beznea 
728d4488377SClaudiu Beznea 	ret = devm_pm_runtime_enable(dev);
729d4488377SClaudiu Beznea 	if (ret)
730d4488377SClaudiu Beznea 		return ret;
731d4488377SClaudiu Beznea 
732d4488377SClaudiu Beznea 	priv->rstc = devm_reset_control_get_shared(dev, NULL);
733d4488377SClaudiu Beznea 	if (IS_ERR(priv->rstc))
734d4488377SClaudiu Beznea 		return PTR_ERR(priv->rstc);
735d4488377SClaudiu Beznea 
736d4488377SClaudiu Beznea 	ret = pm_runtime_resume_and_get(dev);
737d4488377SClaudiu Beznea 	if (ret)
738d4488377SClaudiu Beznea 		return ret;
739d4488377SClaudiu Beznea 
740d4488377SClaudiu Beznea 	ret = reset_control_deassert(priv->rstc);
741d4488377SClaudiu Beznea 	if (ret) {
742d4488377SClaudiu Beznea 		pm_runtime_put_sync(dev);
743d4488377SClaudiu Beznea 		return ret;
744d4488377SClaudiu Beznea 	}
745d4488377SClaudiu Beznea 
746d4488377SClaudiu Beznea 	dev_set_drvdata(dev, priv);
747d4488377SClaudiu Beznea 	ret = devm_add_action_or_reset(dev, rtca3_action, dev);
748d4488377SClaudiu Beznea 	if (ret)
749d4488377SClaudiu Beznea 		return ret;
750d4488377SClaudiu Beznea 
751d4488377SClaudiu Beznea 	/*
752d4488377SClaudiu Beznea 	 * This must be an always-on clock to keep the RTC running even after
753d4488377SClaudiu Beznea 	 * driver is unbinded.
754d4488377SClaudiu Beznea 	 */
755d4488377SClaudiu Beznea 	clk = devm_clk_get_enabled(dev, "counter");
756d4488377SClaudiu Beznea 	if (IS_ERR(clk))
757d4488377SClaudiu Beznea 		return PTR_ERR(clk);
758d4488377SClaudiu Beznea 
759d4488377SClaudiu Beznea 	spin_lock_init(&priv->lock);
760d4488377SClaudiu Beznea 	atomic_set(&priv->alrm_sstep, RTCA3_ALRM_SSTEP_DONE);
761d4488377SClaudiu Beznea 	init_completion(&priv->set_alarm_completion);
762d4488377SClaudiu Beznea 
763d4488377SClaudiu Beznea 	ret = rtca3_initial_setup(clk, priv);
764d4488377SClaudiu Beznea 	if (ret)
765d4488377SClaudiu Beznea 		return dev_err_probe(dev, ret, "Failed to setup the RTC!\n");
766d4488377SClaudiu Beznea 
767d4488377SClaudiu Beznea 	ret = rtca3_request_irqs(pdev, priv);
768d4488377SClaudiu Beznea 	if (ret)
769d4488377SClaudiu Beznea 		return ret;
770d4488377SClaudiu Beznea 
771*8c28c499SWolfram Sang 	device_init_wakeup(&pdev->dev, true);
772d4488377SClaudiu Beznea 
773d4488377SClaudiu Beznea 	priv->rtc_dev = devm_rtc_allocate_device(&pdev->dev);
774d4488377SClaudiu Beznea 	if (IS_ERR(priv->rtc_dev))
775d4488377SClaudiu Beznea 		return PTR_ERR(priv->rtc_dev);
776d4488377SClaudiu Beznea 
777d4488377SClaudiu Beznea 	priv->rtc_dev->ops = &rtca3_ops;
778d4488377SClaudiu Beznea 	priv->rtc_dev->max_user_freq = 256;
779d4488377SClaudiu Beznea 	priv->rtc_dev->range_min = RTC_TIMESTAMP_BEGIN_2000;
780d4488377SClaudiu Beznea 	priv->rtc_dev->range_max = RTC_TIMESTAMP_END_2099;
781d4488377SClaudiu Beznea 
782d4488377SClaudiu Beznea 	return devm_rtc_register_device(priv->rtc_dev);
783d4488377SClaudiu Beznea }
784d4488377SClaudiu Beznea 
rtca3_remove(struct platform_device * pdev)785d4488377SClaudiu Beznea static void rtca3_remove(struct platform_device *pdev)
786d4488377SClaudiu Beznea {
787d4488377SClaudiu Beznea 	struct rtca3_priv *priv = platform_get_drvdata(pdev);
788d4488377SClaudiu Beznea 
789d4488377SClaudiu Beznea 	guard(spinlock_irqsave)(&priv->lock);
790d4488377SClaudiu Beznea 
791d4488377SClaudiu Beznea 	/*
792d4488377SClaudiu Beznea 	 * Disable alarm, periodic interrupts. The RTC device cannot
793d4488377SClaudiu Beznea 	 * power up the system.
794d4488377SClaudiu Beznea 	 */
795d4488377SClaudiu Beznea 	rtca3_alarm_irq_set_helper(priv, RTCA3_RCR1_AIE | RTCA3_RCR1_PIE, 0);
796d4488377SClaudiu Beznea }
797d4488377SClaudiu Beznea 
rtca3_suspend(struct device * dev)798d4488377SClaudiu Beznea static int rtca3_suspend(struct device *dev)
799d4488377SClaudiu Beznea {
800d4488377SClaudiu Beznea 	struct rtca3_priv *priv = dev_get_drvdata(dev);
801d4488377SClaudiu Beznea 
802d4488377SClaudiu Beznea 	if (!device_may_wakeup(dev))
803d4488377SClaudiu Beznea 		return 0;
804d4488377SClaudiu Beznea 
805d4488377SClaudiu Beznea 	/* Alarm setup in progress. */
806d4488377SClaudiu Beznea 	if (atomic_read(&priv->alrm_sstep) != RTCA3_ALRM_SSTEP_DONE)
807d4488377SClaudiu Beznea 		return -EBUSY;
808d4488377SClaudiu Beznea 
809d4488377SClaudiu Beznea 	enable_irq_wake(priv->wakeup_irq);
810d4488377SClaudiu Beznea 
811d4488377SClaudiu Beznea 	return 0;
812d4488377SClaudiu Beznea }
813d4488377SClaudiu Beznea 
rtca3_clean_alarm(struct rtca3_priv * priv)814d4488377SClaudiu Beznea static int rtca3_clean_alarm(struct rtca3_priv *priv)
815d4488377SClaudiu Beznea {
816d4488377SClaudiu Beznea 	struct rtc_device *rtc_dev = priv->rtc_dev;
817d4488377SClaudiu Beznea 	time64_t alarm_time, now;
818d4488377SClaudiu Beznea 	struct rtc_wkalrm alarm;
819d4488377SClaudiu Beznea 	struct rtc_time tm;
820d4488377SClaudiu Beznea 	u8 pending;
821d4488377SClaudiu Beznea 	int ret;
822d4488377SClaudiu Beznea 
823d4488377SClaudiu Beznea 	ret = rtc_read_alarm(rtc_dev, &alarm);
824d4488377SClaudiu Beznea 	if (ret)
825d4488377SClaudiu Beznea 		return ret;
826d4488377SClaudiu Beznea 
827d4488377SClaudiu Beznea 	if (!alarm.enabled)
828d4488377SClaudiu Beznea 		return 0;
829d4488377SClaudiu Beznea 
830d4488377SClaudiu Beznea 	ret = rtc_read_time(rtc_dev, &tm);
831d4488377SClaudiu Beznea 	if (ret)
832d4488377SClaudiu Beznea 		return ret;
833d4488377SClaudiu Beznea 
834d4488377SClaudiu Beznea 	alarm_time = rtc_tm_to_time64(&alarm.time);
835d4488377SClaudiu Beznea 	now = rtc_tm_to_time64(&tm);
836d4488377SClaudiu Beznea 	if (alarm_time >= now)
837d4488377SClaudiu Beznea 		return 0;
838d4488377SClaudiu Beznea 
839d4488377SClaudiu Beznea 	/*
840d4488377SClaudiu Beznea 	 * Heuristically, it has been determined that when returning from deep
841d4488377SClaudiu Beznea 	 * sleep state the RTCA3_RSR.AF is zero even though the alarm expired.
842d4488377SClaudiu Beznea 	 * Call again the rtc_update_irq() if alarm helper detects this.
843d4488377SClaudiu Beznea 	 */
844d4488377SClaudiu Beznea 
845d4488377SClaudiu Beznea 	guard(spinlock_irqsave)(&priv->lock);
846d4488377SClaudiu Beznea 
847d4488377SClaudiu Beznea 	pending = rtca3_alarm_handler_helper(priv);
848d4488377SClaudiu Beznea 	if (!pending)
849d4488377SClaudiu Beznea 		rtc_update_irq(priv->rtc_dev, 1, RTC_AF | RTC_IRQF);
850d4488377SClaudiu Beznea 
851d4488377SClaudiu Beznea 	return 0;
852d4488377SClaudiu Beznea }
853d4488377SClaudiu Beznea 
rtca3_resume(struct device * dev)854d4488377SClaudiu Beznea static int rtca3_resume(struct device *dev)
855d4488377SClaudiu Beznea {
856d4488377SClaudiu Beznea 	struct rtca3_priv *priv = dev_get_drvdata(dev);
857d4488377SClaudiu Beznea 
858d4488377SClaudiu Beznea 	if (!device_may_wakeup(dev))
859d4488377SClaudiu Beznea 		return 0;
860d4488377SClaudiu Beznea 
861d4488377SClaudiu Beznea 	disable_irq_wake(priv->wakeup_irq);
862d4488377SClaudiu Beznea 
863d4488377SClaudiu Beznea 	/*
864d4488377SClaudiu Beznea 	 * According to the HW manual (section 22.6.4 Notes on writing to
865d4488377SClaudiu Beznea 	 * and reading from registers) we need to wait 1/128 seconds while
866d4488377SClaudiu Beznea 	 * RCR2.START = 1 to be able to read the counters after a return from low
867d4488377SClaudiu Beznea 	 * power consumption state.
868d4488377SClaudiu Beznea 	 */
869d4488377SClaudiu Beznea 	mdelay(8);
870d4488377SClaudiu Beznea 
871d4488377SClaudiu Beznea 	/*
872d4488377SClaudiu Beznea 	 * The alarm cannot wake the system from deep sleep states. In case
873d4488377SClaudiu Beznea 	 * we return from deep sleep states and the alarm expired we need
874d4488377SClaudiu Beznea 	 * to disable it to avoid failures when setting another alarm.
875d4488377SClaudiu Beznea 	 */
876d4488377SClaudiu Beznea 	return rtca3_clean_alarm(priv);
877d4488377SClaudiu Beznea }
878d4488377SClaudiu Beznea 
879d4488377SClaudiu Beznea static DEFINE_SIMPLE_DEV_PM_OPS(rtca3_pm_ops, rtca3_suspend, rtca3_resume);
880d4488377SClaudiu Beznea 
881d4488377SClaudiu Beznea static const struct of_device_id rtca3_of_match[] = {
882d4488377SClaudiu Beznea 	{ .compatible = "renesas,rz-rtca3", },
883d4488377SClaudiu Beznea 	{ /* sentinel */ }
884d4488377SClaudiu Beznea };
885d4488377SClaudiu Beznea MODULE_DEVICE_TABLE(of, rtca3_of_match);
886d4488377SClaudiu Beznea 
887d4488377SClaudiu Beznea static struct platform_driver rtca3_platform_driver = {
888d4488377SClaudiu Beznea 	.driver = {
889d4488377SClaudiu Beznea 		.name = "rtc-rtca3",
890d4488377SClaudiu Beznea 		.pm = pm_ptr(&rtca3_pm_ops),
891d4488377SClaudiu Beznea 		.of_match_table = rtca3_of_match,
892d4488377SClaudiu Beznea 	},
893d4488377SClaudiu Beznea 	.probe = rtca3_probe,
894d4488377SClaudiu Beznea 	.remove = rtca3_remove,
895d4488377SClaudiu Beznea };
896d4488377SClaudiu Beznea module_platform_driver(rtca3_platform_driver);
897d4488377SClaudiu Beznea 
898d4488377SClaudiu Beznea MODULE_DESCRIPTION("Renesas RTCA-3 RTC driver");
899d4488377SClaudiu Beznea MODULE_AUTHOR("Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>");
900d4488377SClaudiu Beznea MODULE_LICENSE("GPL");
901