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