Merge tag 'rtc-5.3' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux
[sfrench/cifs-2.6.git] / drivers / rtc / rtc-cadence.c
1 // SPDX-License-Identifier: GPL-2.0
2
3 /*
4  * Copyright 2019 Cadence
5  *
6  * Authors:
7  *  Jan Kotas <jank@cadence.com>
8  */
9
10 #include <linux/module.h>
11 #include <linux/platform_device.h>
12 #include <linux/of.h>
13 #include <linux/io.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>
20
21 /* Registers */
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
35
36 /* Control */
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)
40
41 /* Status */
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)
48
49 /* Keep RTC */
50 #define CDNS_RTC_KRTCR_KRTC     BIT(0)
51
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)
60
61 /* Time */
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)
68
69 /* Calendar */
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)
76
77 #define CDNS_RTC_MAX_REGS_TRIES 3
78
79 struct cdns_rtc {
80         struct rtc_device *rtc_dev;
81         struct clk *pclk;
82         struct clk *ref_clk;
83         void __iomem *regs;
84         int irq;
85 };
86
87 static void cdns_rtc_set_enabled(struct cdns_rtc *crtc, bool enabled)
88 {
89         u32 reg = enabled ? 0x0 : CDNS_RTC_CTLR_TIME_CAL;
90
91         writel(reg, crtc->regs + CDNS_RTC_CTLR);
92 }
93
94 static bool cdns_rtc_get_enabled(struct cdns_rtc *crtc)
95 {
96         return !(readl(crtc->regs + CDNS_RTC_CTLR) & CDNS_RTC_CTLR_TIME_CAL);
97 }
98
99 static irqreturn_t cdns_rtc_irq_handler(int irq, void *id)
100 {
101         struct device *dev = id;
102         struct cdns_rtc *crtc = dev_get_drvdata(dev);
103
104         /* Reading the register clears it */
105         if (!(readl(crtc->regs + CDNS_RTC_EFLR) & CDNS_RTC_AEI_ALRM))
106                 return IRQ_NONE;
107
108         rtc_update_irq(crtc->rtc_dev, 1, RTC_IRQF | RTC_AF);
109         return IRQ_HANDLED;
110 }
111
112 static u32 cdns_rtc_time2reg(struct rtc_time *tm)
113 {
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));
117 }
118
119 static void cdns_rtc_reg2time(u32 reg, struct rtc_time *tm)
120 {
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));
124 }
125
126 static int cdns_rtc_read_time(struct device *dev, struct rtc_time *tm)
127 {
128         struct cdns_rtc *crtc = dev_get_drvdata(dev);
129         u32 reg;
130
131         /* If the RTC is disabled, assume the values are invalid */
132         if (!cdns_rtc_get_enabled(crtc))
133                 return -EINVAL;
134
135         cdns_rtc_set_enabled(crtc, false);
136
137         reg = readl(crtc->regs + CDNS_RTC_TIMR);
138         cdns_rtc_reg2time(reg, tm);
139
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;
146
147         cdns_rtc_set_enabled(crtc, true);
148         return 0;
149 }
150
151 static int cdns_rtc_set_time(struct device *dev, struct rtc_time *tm)
152 {
153         struct cdns_rtc *crtc = dev_get_drvdata(dev);
154         u32 timr, calr, stsr;
155         int ret = -EIO;
156         int year = tm->tm_year + 1900;
157         int tries;
158
159         cdns_rtc_set_enabled(crtc, false);
160
161         timr = cdns_rtc_time2reg(tm);
162
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);
168
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);
174
175                 if ((stsr & CDNS_RTC_STSR_VT_VC) == CDNS_RTC_STSR_VT_VC) {
176                         ret = 0;
177                         break;
178                 }
179         }
180
181         cdns_rtc_set_enabled(crtc, true);
182         return ret;
183 }
184
185 static int cdns_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
186 {
187         struct cdns_rtc *crtc = dev_get_drvdata(dev);
188
189         if (enabled) {
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);
194         } else {
195                 writel(0, crtc->regs + CDNS_RTC_AENR);
196                 writel(CDNS_RTC_AEI_ALRM, crtc->regs + CDNS_RTC_IDISR);
197         }
198
199         return 0;
200 }
201
202 static int cdns_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
203 {
204         struct cdns_rtc *crtc = dev_get_drvdata(dev);
205         u32 reg;
206
207         reg = readl(crtc->regs + CDNS_RTC_TIMAR);
208         cdns_rtc_reg2time(reg, &alarm->time);
209
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;
213
214         return 0;
215 }
216
217 static int cdns_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
218 {
219         struct cdns_rtc *crtc = dev_get_drvdata(dev);
220         int ret = -EIO;
221         int tries;
222         u32 timar, calar, stsr;
223
224         cdns_rtc_alarm_irq_enable(dev, 0);
225
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));
229
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);
235
236                 if ((stsr & CDNS_RTC_STSR_VTA_VCA) == CDNS_RTC_STSR_VTA_VCA) {
237                         ret = 0;
238                         break;
239                 }
240         }
241
242         if (!ret)
243                 cdns_rtc_alarm_irq_enable(dev, alarm->enabled);
244         return ret;
245 }
246
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,
253 };
254
255 static int cdns_rtc_probe(struct platform_device *pdev)
256 {
257         struct cdns_rtc *crtc;
258         struct resource *res;
259         int ret;
260         unsigned long ref_clk_freq;
261
262         crtc = devm_kzalloc(&pdev->dev, sizeof(*crtc), GFP_KERNEL);
263         if (!crtc)
264                 return -ENOMEM;
265
266         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
267         crtc->regs = devm_ioremap_resource(&pdev->dev, res);
268         if (IS_ERR(crtc->regs))
269                 return PTR_ERR(crtc->regs);
270
271         crtc->irq = platform_get_irq(pdev, 0);
272         if (crtc->irq < 0)
273                 return -EINVAL;
274
275         crtc->pclk = devm_clk_get(&pdev->dev, "pclk");
276         if (IS_ERR(crtc->pclk)) {
277                 ret = PTR_ERR(crtc->pclk);
278                 dev_err(&pdev->dev,
279                         "Failed to retrieve the peripheral clock, %d\n", ret);
280                 return ret;
281         }
282
283         crtc->ref_clk = devm_clk_get(&pdev->dev, "ref_clk");
284         if (IS_ERR(crtc->ref_clk)) {
285                 ret = PTR_ERR(crtc->ref_clk);
286                 dev_err(&pdev->dev,
287                         "Failed to retrieve the reference clock, %d\n", ret);
288                 return ret;
289         }
290
291         crtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev);
292         if (IS_ERR(crtc->rtc_dev)) {
293                 ret = PTR_ERR(crtc->rtc_dev);
294                 dev_err(&pdev->dev,
295                         "Failed to allocate the RTC device, %d\n", ret);
296                 return ret;
297         }
298
299         platform_set_drvdata(pdev, crtc);
300
301         ret = clk_prepare_enable(crtc->pclk);
302         if (ret) {
303                 dev_err(&pdev->dev,
304                         "Failed to enable the peripheral clock, %d\n", ret);
305                 return ret;
306         }
307
308         ret = clk_prepare_enable(crtc->ref_clk);
309         if (ret) {
310                 dev_err(&pdev->dev,
311                         "Failed to enable the reference clock, %d\n", ret);
312                 goto err_disable_pclk;
313         }
314
315         ref_clk_freq = clk_get_rate(crtc->ref_clk);
316         if ((ref_clk_freq != 1) && (ref_clk_freq != 100)) {
317                 dev_err(&pdev->dev,
318                         "Invalid reference clock frequency %lu Hz.\n",
319                         ref_clk_freq);
320                 ret = -EINVAL;
321                 goto err_disable_ref_clk;
322         }
323
324         ret = devm_request_irq(&pdev->dev, crtc->irq,
325                                cdns_rtc_irq_handler, 0,
326                                dev_name(&pdev->dev), &pdev->dev);
327         if (ret) {
328                 dev_err(&pdev->dev,
329                         "Failed to request interrupt for the device, %d\n",
330                         ret);
331                 goto err_disable_ref_clk;
332         }
333
334         /* The RTC supports 01.01.1900 - 31.12.2999 */
335         crtc->rtc_dev->range_min = mktime64(1900,  1,  1,  0,  0,  0);
336         crtc->rtc_dev->range_max = mktime64(2999, 12, 31, 23, 59, 59);
337
338         crtc->rtc_dev->ops = &cdns_rtc_ops;
339         device_init_wakeup(&pdev->dev, true);
340
341         /* Always use 24-hour mode and keep the RTC values */
342         writel(0, crtc->regs + CDNS_RTC_HMR);
343         writel(CDNS_RTC_KRTCR_KRTC, crtc->regs + CDNS_RTC_KRTCR);
344
345         ret = rtc_register_device(crtc->rtc_dev);
346         if (ret) {
347                 dev_err(&pdev->dev,
348                         "Failed to register the RTC device, %d\n", ret);
349                 goto err_disable_wakeup;
350         }
351
352         return 0;
353
354 err_disable_wakeup:
355         device_init_wakeup(&pdev->dev, false);
356
357 err_disable_ref_clk:
358         clk_disable_unprepare(crtc->ref_clk);
359
360 err_disable_pclk:
361         clk_disable_unprepare(crtc->pclk);
362
363         return ret;
364 }
365
366 static int cdns_rtc_remove(struct platform_device *pdev)
367 {
368         struct cdns_rtc *crtc = platform_get_drvdata(pdev);
369
370         cdns_rtc_alarm_irq_enable(&pdev->dev, 0);
371         device_init_wakeup(&pdev->dev, 0);
372
373         clk_disable_unprepare(crtc->pclk);
374         clk_disable_unprepare(crtc->ref_clk);
375
376         return 0;
377 }
378
379 #ifdef CONFIG_PM_SLEEP
380 static int cdns_rtc_suspend(struct device *dev)
381 {
382         struct cdns_rtc *crtc = dev_get_drvdata(dev);
383
384         if (device_may_wakeup(dev))
385                 enable_irq_wake(crtc->irq);
386
387         return 0;
388 }
389
390 static int cdns_rtc_resume(struct device *dev)
391 {
392         struct cdns_rtc *crtc = dev_get_drvdata(dev);
393
394         if (device_may_wakeup(dev))
395                 disable_irq_wake(crtc->irq);
396
397         return 0;
398 }
399 #endif
400
401 static SIMPLE_DEV_PM_OPS(cdns_rtc_pm_ops, cdns_rtc_suspend, cdns_rtc_resume);
402
403 static const struct of_device_id cdns_rtc_of_match[] = {
404         { .compatible = "cdns,rtc-r109v3" },
405         { },
406 };
407 MODULE_DEVICE_TABLE(of, cdns_rtc_of_match);
408
409 static struct platform_driver cdns_rtc_driver = {
410         .driver = {
411                 .name = "cdns-rtc",
412                 .of_match_table = cdns_rtc_of_match,
413                 .pm = &cdns_rtc_pm_ops,
414         },
415         .probe = cdns_rtc_probe,
416         .remove = cdns_rtc_remove,
417 };
418 module_platform_driver(cdns_rtc_driver);
419
420 MODULE_AUTHOR("Jan Kotas <jank@cadence.com>");
421 MODULE_DESCRIPTION("Cadence RTC driver");
422 MODULE_LICENSE("GPL v2");
423 MODULE_ALIAS("platform:cdns-rtc");