staging: wfx: fix rate control handling
[linux/fpc-iii.git] / drivers / rtc / rtc-cadence.c
blob595d5d252850a4a5315bd75fe93abebe3059a2dc
1 // SPDX-License-Identifier: GPL-2.0
3 /*
4 * Copyright 2019 Cadence
6 * Authors:
7 * Jan Kotas <jank@cadence.com>
8 */
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>
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
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)
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)
49 /* Keep RTC */
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)
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)
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)
77 #define CDNS_RTC_MAX_REGS_TRIES 3
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;
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))
106 return IRQ_NONE;
108 rtc_update_irq(crtc->rtc_dev, 1, RTC_IRQF | RTC_AF);
109 return IRQ_HANDLED;
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);
129 u32 reg;
131 /* If the RTC is disabled, assume the values are invalid */
132 if (!cdns_rtc_get_enabled(crtc))
133 return -EINVAL;
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);
148 return 0;
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;
155 int ret = -EIO;
156 int year = tm->tm_year + 1900;
157 int tries;
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) {
176 ret = 0;
177 break;
181 cdns_rtc_set_enabled(crtc, true);
182 return ret;
185 static int cdns_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
187 struct cdns_rtc *crtc = dev_get_drvdata(dev);
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);
199 return 0;
202 static int cdns_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
204 struct cdns_rtc *crtc = dev_get_drvdata(dev);
205 u32 reg;
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;
214 return 0;
217 static int cdns_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
219 struct cdns_rtc *crtc = dev_get_drvdata(dev);
220 int ret = -EIO;
221 int tries;
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) {
237 ret = 0;
238 break;
242 if (!ret)
243 cdns_rtc_alarm_irq_enable(dev, alarm->enabled);
244 return ret;
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;
258 int ret;
259 unsigned long ref_clk_freq;
261 crtc = devm_kzalloc(&pdev->dev, sizeof(*crtc), GFP_KERNEL);
262 if (!crtc)
263 return -ENOMEM;
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);
270 if (crtc->irq < 0)
271 return -EINVAL;
273 crtc->pclk = devm_clk_get(&pdev->dev, "pclk");
274 if (IS_ERR(crtc->pclk)) {
275 ret = PTR_ERR(crtc->pclk);
276 dev_err(&pdev->dev,
277 "Failed to retrieve the peripheral clock, %d\n", ret);
278 return 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);
284 dev_err(&pdev->dev,
285 "Failed to retrieve the reference clock, %d\n", ret);
286 return 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);
296 if (ret) {
297 dev_err(&pdev->dev,
298 "Failed to enable the peripheral clock, %d\n", ret);
299 return ret;
302 ret = clk_prepare_enable(crtc->ref_clk);
303 if (ret) {
304 dev_err(&pdev->dev,
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)) {
311 dev_err(&pdev->dev,
312 "Invalid reference clock frequency %lu Hz.\n",
313 ref_clk_freq);
314 ret = -EINVAL;
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);
321 if (ret) {
322 dev_err(&pdev->dev,
323 "Failed to request interrupt for the device, %d\n",
324 ret);
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);
340 if (ret)
341 goto err_disable_wakeup;
343 return 0;
345 err_disable_wakeup:
346 device_init_wakeup(&pdev->dev, false);
348 err_disable_ref_clk:
349 clk_disable_unprepare(crtc->ref_clk);
351 err_disable_pclk:
352 clk_disable_unprepare(crtc->pclk);
354 return ret;
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);
367 return 0;
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);
378 return 0;
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);
388 return 0;
390 #endif
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" },
396 { },
398 MODULE_DEVICE_TABLE(of, cdns_rtc_of_match);
400 static struct platform_driver cdns_rtc_driver = {
401 .driver = {
402 .name = "cdns-rtc",
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");