1 // SPDX-License-Identifier: GPL-2.0
4 * Copyright 2019 Cadence
7 * Jan Kotas <jank@cadence.com>
10 #include <linux/module.h>
11 #include <linux/platform_device.h>
14 #include <linux/rtc.h>
15 #include <linux/clk.h>
16 #include <linux/bcd.h>
17 #include <linux/bitfield.h>
18 #include <linux/interrupt.h>
19 #include <linux/pm_wakeirq.h>
22 #define CDNS_RTC_CTLR 0x00
23 #define CDNS_RTC_HMR 0x04
24 #define CDNS_RTC_TIMR 0x08
25 #define CDNS_RTC_CALR 0x0C
26 #define CDNS_RTC_TIMAR 0x10
27 #define CDNS_RTC_CALAR 0x14
28 #define CDNS_RTC_AENR 0x18
29 #define CDNS_RTC_EFLR 0x1C
30 #define CDNS_RTC_IENR 0x20
31 #define CDNS_RTC_IDISR 0x24
32 #define CDNS_RTC_IMSKR 0x28
33 #define CDNS_RTC_STSR 0x2C
34 #define CDNS_RTC_KRTCR 0x30
37 #define CDNS_RTC_CTLR_TIME BIT(0)
38 #define CDNS_RTC_CTLR_CAL BIT(1)
39 #define CDNS_RTC_CTLR_TIME_CAL (CDNS_RTC_CTLR_TIME | CDNS_RTC_CTLR_CAL)
42 #define CDNS_RTC_STSR_VT BIT(0)
43 #define CDNS_RTC_STSR_VC BIT(1)
44 #define CDNS_RTC_STSR_VTA BIT(2)
45 #define CDNS_RTC_STSR_VCA BIT(3)
46 #define CDNS_RTC_STSR_VT_VC (CDNS_RTC_STSR_VT | CDNS_RTC_STSR_VC)
47 #define CDNS_RTC_STSR_VTA_VCA (CDNS_RTC_STSR_VTA | CDNS_RTC_STSR_VCA)
50 #define CDNS_RTC_KRTCR_KRTC BIT(0)
52 /* Alarm, Event, Interrupt */
53 #define CDNS_RTC_AEI_HOS BIT(0)
54 #define CDNS_RTC_AEI_SEC BIT(1)
55 #define CDNS_RTC_AEI_MIN BIT(2)
56 #define CDNS_RTC_AEI_HOUR BIT(3)
57 #define CDNS_RTC_AEI_DATE BIT(4)
58 #define CDNS_RTC_AEI_MNTH BIT(5)
59 #define CDNS_RTC_AEI_ALRM BIT(6)
62 #define CDNS_RTC_TIME_H GENMASK(7, 0)
63 #define CDNS_RTC_TIME_S GENMASK(14, 8)
64 #define CDNS_RTC_TIME_M GENMASK(22, 16)
65 #define CDNS_RTC_TIME_HR GENMASK(29, 24)
66 #define CDNS_RTC_TIME_PM BIT(30)
67 #define CDNS_RTC_TIME_CH BIT(31)
70 #define CDNS_RTC_CAL_DAY GENMASK(2, 0)
71 #define CDNS_RTC_CAL_M GENMASK(7, 3)
72 #define CDNS_RTC_CAL_D GENMASK(13, 8)
73 #define CDNS_RTC_CAL_Y GENMASK(23, 16)
74 #define CDNS_RTC_CAL_C GENMASK(29, 24)
75 #define CDNS_RTC_CAL_CH BIT(31)
77 #define CDNS_RTC_MAX_REGS_TRIES 3
80 struct rtc_device
*rtc_dev
;
87 static void cdns_rtc_set_enabled(struct cdns_rtc
*crtc
, bool enabled
)
89 u32 reg
= enabled
? 0x0 : CDNS_RTC_CTLR_TIME_CAL
;
91 writel(reg
, crtc
->regs
+ CDNS_RTC_CTLR
);
94 static bool cdns_rtc_get_enabled(struct cdns_rtc
*crtc
)
96 return !(readl(crtc
->regs
+ CDNS_RTC_CTLR
) & CDNS_RTC_CTLR_TIME_CAL
);
99 static irqreturn_t
cdns_rtc_irq_handler(int irq
, void *id
)
101 struct device
*dev
= id
;
102 struct cdns_rtc
*crtc
= dev_get_drvdata(dev
);
104 /* Reading the register clears it */
105 if (!(readl(crtc
->regs
+ CDNS_RTC_EFLR
) & CDNS_RTC_AEI_ALRM
))
108 rtc_update_irq(crtc
->rtc_dev
, 1, RTC_IRQF
| RTC_AF
);
112 static u32
cdns_rtc_time2reg(struct rtc_time
*tm
)
114 return FIELD_PREP(CDNS_RTC_TIME_S
, bin2bcd(tm
->tm_sec
))
115 | FIELD_PREP(CDNS_RTC_TIME_M
, bin2bcd(tm
->tm_min
))
116 | FIELD_PREP(CDNS_RTC_TIME_HR
, bin2bcd(tm
->tm_hour
));
119 static void cdns_rtc_reg2time(u32 reg
, struct rtc_time
*tm
)
121 tm
->tm_sec
= bcd2bin(FIELD_GET(CDNS_RTC_TIME_S
, reg
));
122 tm
->tm_min
= bcd2bin(FIELD_GET(CDNS_RTC_TIME_M
, reg
));
123 tm
->tm_hour
= bcd2bin(FIELD_GET(CDNS_RTC_TIME_HR
, reg
));
126 static int cdns_rtc_read_time(struct device
*dev
, struct rtc_time
*tm
)
128 struct cdns_rtc
*crtc
= dev_get_drvdata(dev
);
131 /* If the RTC is disabled, assume the values are invalid */
132 if (!cdns_rtc_get_enabled(crtc
))
135 cdns_rtc_set_enabled(crtc
, false);
137 reg
= readl(crtc
->regs
+ CDNS_RTC_TIMR
);
138 cdns_rtc_reg2time(reg
, tm
);
140 reg
= readl(crtc
->regs
+ CDNS_RTC_CALR
);
141 tm
->tm_mday
= bcd2bin(FIELD_GET(CDNS_RTC_CAL_D
, reg
));
142 tm
->tm_mon
= bcd2bin(FIELD_GET(CDNS_RTC_CAL_M
, reg
)) - 1;
143 tm
->tm_year
= bcd2bin(FIELD_GET(CDNS_RTC_CAL_Y
, reg
))
144 + bcd2bin(FIELD_GET(CDNS_RTC_CAL_C
, reg
)) * 100 - 1900;
145 tm
->tm_wday
= bcd2bin(FIELD_GET(CDNS_RTC_CAL_DAY
, reg
)) - 1;
147 cdns_rtc_set_enabled(crtc
, true);
151 static int cdns_rtc_set_time(struct device
*dev
, struct rtc_time
*tm
)
153 struct cdns_rtc
*crtc
= dev_get_drvdata(dev
);
154 u32 timr
, calr
, stsr
;
156 int year
= tm
->tm_year
+ 1900;
159 cdns_rtc_set_enabled(crtc
, false);
161 timr
= cdns_rtc_time2reg(tm
);
163 calr
= FIELD_PREP(CDNS_RTC_CAL_D
, bin2bcd(tm
->tm_mday
))
164 | FIELD_PREP(CDNS_RTC_CAL_M
, bin2bcd(tm
->tm_mon
+ 1))
165 | FIELD_PREP(CDNS_RTC_CAL_Y
, bin2bcd(year
% 100))
166 | FIELD_PREP(CDNS_RTC_CAL_C
, bin2bcd(year
/ 100))
167 | FIELD_PREP(CDNS_RTC_CAL_DAY
, tm
->tm_wday
+ 1);
169 /* Update registers, check valid flags */
170 for (tries
= 0; tries
< CDNS_RTC_MAX_REGS_TRIES
; tries
++) {
171 writel(timr
, crtc
->regs
+ CDNS_RTC_TIMR
);
172 writel(calr
, crtc
->regs
+ CDNS_RTC_CALR
);
173 stsr
= readl(crtc
->regs
+ CDNS_RTC_STSR
);
175 if ((stsr
& CDNS_RTC_STSR_VT_VC
) == CDNS_RTC_STSR_VT_VC
) {
181 cdns_rtc_set_enabled(crtc
, true);
185 static int cdns_rtc_alarm_irq_enable(struct device
*dev
, unsigned int enabled
)
187 struct cdns_rtc
*crtc
= dev_get_drvdata(dev
);
190 writel((CDNS_RTC_AEI_SEC
| CDNS_RTC_AEI_MIN
| CDNS_RTC_AEI_HOUR
191 | CDNS_RTC_AEI_DATE
| CDNS_RTC_AEI_MNTH
),
192 crtc
->regs
+ CDNS_RTC_AENR
);
193 writel(CDNS_RTC_AEI_ALRM
, crtc
->regs
+ CDNS_RTC_IENR
);
195 writel(0, crtc
->regs
+ CDNS_RTC_AENR
);
196 writel(CDNS_RTC_AEI_ALRM
, crtc
->regs
+ CDNS_RTC_IDISR
);
202 static int cdns_rtc_read_alarm(struct device
*dev
, struct rtc_wkalrm
*alarm
)
204 struct cdns_rtc
*crtc
= dev_get_drvdata(dev
);
207 reg
= readl(crtc
->regs
+ CDNS_RTC_TIMAR
);
208 cdns_rtc_reg2time(reg
, &alarm
->time
);
210 reg
= readl(crtc
->regs
+ CDNS_RTC_CALAR
);
211 alarm
->time
.tm_mday
= bcd2bin(FIELD_GET(CDNS_RTC_CAL_D
, reg
));
212 alarm
->time
.tm_mon
= bcd2bin(FIELD_GET(CDNS_RTC_CAL_M
, reg
)) - 1;
217 static int cdns_rtc_set_alarm(struct device
*dev
, struct rtc_wkalrm
*alarm
)
219 struct cdns_rtc
*crtc
= dev_get_drvdata(dev
);
222 u32 timar
, calar
, stsr
;
224 cdns_rtc_alarm_irq_enable(dev
, 0);
226 timar
= cdns_rtc_time2reg(&alarm
->time
);
227 calar
= FIELD_PREP(CDNS_RTC_CAL_D
, bin2bcd(alarm
->time
.tm_mday
))
228 | FIELD_PREP(CDNS_RTC_CAL_M
, bin2bcd(alarm
->time
.tm_mon
+ 1));
230 /* Update registers, check valid alarm flags */
231 for (tries
= 0; tries
< CDNS_RTC_MAX_REGS_TRIES
; tries
++) {
232 writel(timar
, crtc
->regs
+ CDNS_RTC_TIMAR
);
233 writel(calar
, crtc
->regs
+ CDNS_RTC_CALAR
);
234 stsr
= readl(crtc
->regs
+ CDNS_RTC_STSR
);
236 if ((stsr
& CDNS_RTC_STSR_VTA_VCA
) == CDNS_RTC_STSR_VTA_VCA
) {
243 cdns_rtc_alarm_irq_enable(dev
, alarm
->enabled
);
247 static const struct rtc_class_ops cdns_rtc_ops
= {
248 .read_time
= cdns_rtc_read_time
,
249 .set_time
= cdns_rtc_set_time
,
250 .read_alarm
= cdns_rtc_read_alarm
,
251 .set_alarm
= cdns_rtc_set_alarm
,
252 .alarm_irq_enable
= cdns_rtc_alarm_irq_enable
,
255 static int cdns_rtc_probe(struct platform_device
*pdev
)
257 struct cdns_rtc
*crtc
;
259 unsigned long ref_clk_freq
;
261 crtc
= devm_kzalloc(&pdev
->dev
, sizeof(*crtc
), GFP_KERNEL
);
265 crtc
->regs
= devm_platform_ioremap_resource(pdev
, 0);
266 if (IS_ERR(crtc
->regs
))
267 return PTR_ERR(crtc
->regs
);
269 crtc
->irq
= platform_get_irq(pdev
, 0);
273 crtc
->pclk
= devm_clk_get(&pdev
->dev
, "pclk");
274 if (IS_ERR(crtc
->pclk
)) {
275 ret
= PTR_ERR(crtc
->pclk
);
277 "Failed to retrieve the peripheral clock, %d\n", ret
);
281 crtc
->ref_clk
= devm_clk_get(&pdev
->dev
, "ref_clk");
282 if (IS_ERR(crtc
->ref_clk
)) {
283 ret
= PTR_ERR(crtc
->ref_clk
);
285 "Failed to retrieve the reference clock, %d\n", ret
);
289 crtc
->rtc_dev
= devm_rtc_allocate_device(&pdev
->dev
);
290 if (IS_ERR(crtc
->rtc_dev
))
291 return PTR_ERR(crtc
->rtc_dev
);
293 platform_set_drvdata(pdev
, crtc
);
295 ret
= clk_prepare_enable(crtc
->pclk
);
298 "Failed to enable the peripheral clock, %d\n", ret
);
302 ret
= clk_prepare_enable(crtc
->ref_clk
);
305 "Failed to enable the reference clock, %d\n", ret
);
306 goto err_disable_pclk
;
309 ref_clk_freq
= clk_get_rate(crtc
->ref_clk
);
310 if ((ref_clk_freq
!= 1) && (ref_clk_freq
!= 100)) {
312 "Invalid reference clock frequency %lu Hz.\n",
315 goto err_disable_ref_clk
;
318 ret
= devm_request_irq(&pdev
->dev
, crtc
->irq
,
319 cdns_rtc_irq_handler
, 0,
320 dev_name(&pdev
->dev
), &pdev
->dev
);
323 "Failed to request interrupt for the device, %d\n",
325 goto err_disable_ref_clk
;
328 /* The RTC supports 01.01.1900 - 31.12.2999 */
329 crtc
->rtc_dev
->range_min
= mktime64(1900, 1, 1, 0, 0, 0);
330 crtc
->rtc_dev
->range_max
= mktime64(2999, 12, 31, 23, 59, 59);
332 crtc
->rtc_dev
->ops
= &cdns_rtc_ops
;
333 device_init_wakeup(&pdev
->dev
, true);
335 /* Always use 24-hour mode and keep the RTC values */
336 writel(0, crtc
->regs
+ CDNS_RTC_HMR
);
337 writel(CDNS_RTC_KRTCR_KRTC
, crtc
->regs
+ CDNS_RTC_KRTCR
);
339 ret
= rtc_register_device(crtc
->rtc_dev
);
341 goto err_disable_wakeup
;
346 device_init_wakeup(&pdev
->dev
, false);
349 clk_disable_unprepare(crtc
->ref_clk
);
352 clk_disable_unprepare(crtc
->pclk
);
357 static int cdns_rtc_remove(struct platform_device
*pdev
)
359 struct cdns_rtc
*crtc
= platform_get_drvdata(pdev
);
361 cdns_rtc_alarm_irq_enable(&pdev
->dev
, 0);
362 device_init_wakeup(&pdev
->dev
, 0);
364 clk_disable_unprepare(crtc
->pclk
);
365 clk_disable_unprepare(crtc
->ref_clk
);
370 #ifdef CONFIG_PM_SLEEP
371 static int cdns_rtc_suspend(struct device
*dev
)
373 struct cdns_rtc
*crtc
= dev_get_drvdata(dev
);
375 if (device_may_wakeup(dev
))
376 enable_irq_wake(crtc
->irq
);
381 static int cdns_rtc_resume(struct device
*dev
)
383 struct cdns_rtc
*crtc
= dev_get_drvdata(dev
);
385 if (device_may_wakeup(dev
))
386 disable_irq_wake(crtc
->irq
);
392 static SIMPLE_DEV_PM_OPS(cdns_rtc_pm_ops
, cdns_rtc_suspend
, cdns_rtc_resume
);
394 static const struct of_device_id cdns_rtc_of_match
[] = {
395 { .compatible
= "cdns,rtc-r109v3" },
398 MODULE_DEVICE_TABLE(of
, cdns_rtc_of_match
);
400 static struct platform_driver cdns_rtc_driver
= {
403 .of_match_table
= cdns_rtc_of_match
,
404 .pm
= &cdns_rtc_pm_ops
,
406 .probe
= cdns_rtc_probe
,
407 .remove
= cdns_rtc_remove
,
409 module_platform_driver(cdns_rtc_driver
);
411 MODULE_AUTHOR("Jan Kotas <jank@cadence.com>");
412 MODULE_DESCRIPTION("Cadence RTC driver");
413 MODULE_LICENSE("GPL v2");
414 MODULE_ALIAS("platform:cdns-rtc");