GNU Linux-libre 4.9.333-gnu1
[releases.git] / drivers / rtc / rtc-snvs.c
1 /*
2  * Copyright (C) 2011-2012 Freescale Semiconductor, Inc.
3  *
4  * The code contained herein is licensed under the GNU General Public
5  * License. You may obtain a copy of the GNU General Public License
6  * Version 2 or later at the following locations:
7  *
8  * http://www.opensource.org/licenses/gpl-license.html
9  * http://www.gnu.org/copyleft/gpl.html
10  */
11
12 #include <linux/init.h>
13 #include <linux/io.h>
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/of.h>
17 #include <linux/of_device.h>
18 #include <linux/platform_device.h>
19 #include <linux/rtc.h>
20 #include <linux/clk.h>
21 #include <linux/mfd/syscon.h>
22 #include <linux/regmap.h>
23
24 #define SNVS_LPREGISTER_OFFSET  0x34
25
26 /* These register offsets are relative to LP (Low Power) range */
27 #define SNVS_LPCR               0x04
28 #define SNVS_LPSR               0x18
29 #define SNVS_LPSRTCMR           0x1c
30 #define SNVS_LPSRTCLR           0x20
31 #define SNVS_LPTAR              0x24
32 #define SNVS_LPPGDR             0x30
33
34 #define SNVS_LPCR_SRTC_ENV      (1 << 0)
35 #define SNVS_LPCR_LPTA_EN       (1 << 1)
36 #define SNVS_LPCR_LPWUI_EN      (1 << 3)
37 #define SNVS_LPSR_LPTA          (1 << 0)
38
39 #define SNVS_LPPGDR_INIT        0x41736166
40 #define CNTR_TO_SECS_SH         15
41
42 struct snvs_rtc_data {
43         struct rtc_device *rtc;
44         struct regmap *regmap;
45         int offset;
46         int irq;
47         struct clk *clk;
48 };
49
50 /* Read 64 bit timer register, which could be in inconsistent state */
51 static u64 rtc_read_lpsrt(struct snvs_rtc_data *data)
52 {
53         u32 msb, lsb;
54
55         regmap_read(data->regmap, data->offset + SNVS_LPSRTCMR, &msb);
56         regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &lsb);
57         return (u64)msb << 32 | lsb;
58 }
59
60 /* Read the secure real time counter, taking care to deal with the cases of the
61  * counter updating while being read.
62  */
63 static u32 rtc_read_lp_counter(struct snvs_rtc_data *data)
64 {
65         u64 read1, read2;
66         unsigned int timeout = 100;
67
68         /* As expected, the registers might update between the read of the LSB
69          * reg and the MSB reg.  It's also possible that one register might be
70          * in partially modified state as well.
71          */
72         read1 = rtc_read_lpsrt(data);
73         do {
74                 read2 = read1;
75                 read1 = rtc_read_lpsrt(data);
76         } while (read1 != read2 && --timeout);
77         if (!timeout)
78                 dev_err(&data->rtc->dev, "Timeout trying to get valid LPSRT Counter read\n");
79
80         /* Convert 47-bit counter to 32-bit raw second count */
81         return (u32) (read1 >> CNTR_TO_SECS_SH);
82 }
83
84 /* Just read the lsb from the counter, dealing with inconsistent state */
85 static int rtc_read_lp_counter_lsb(struct snvs_rtc_data *data, u32 *lsb)
86 {
87         u32 count1, count2;
88         unsigned int timeout = 100;
89
90         regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count1);
91         do {
92                 count2 = count1;
93                 regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count1);
94         } while (count1 != count2 && --timeout);
95         if (!timeout) {
96                 dev_err(&data->rtc->dev, "Timeout trying to get valid LPSRT Counter read\n");
97                 return -ETIMEDOUT;
98         }
99
100         *lsb = count1;
101         return 0;
102 }
103
104 static int rtc_write_sync_lp(struct snvs_rtc_data *data)
105 {
106         u32 count1, count2;
107         u32 elapsed;
108         unsigned int timeout = 1000;
109         int ret;
110
111         ret = rtc_read_lp_counter_lsb(data, &count1);
112         if (ret)
113                 return ret;
114
115         /* Wait for 3 CKIL cycles, about 61.0-91.5 µs */
116         do {
117                 ret = rtc_read_lp_counter_lsb(data, &count2);
118                 if (ret)
119                         return ret;
120                 elapsed = count2 - count1; /* wrap around _is_ handled! */
121         } while (elapsed < 3 && --timeout);
122         if (!timeout) {
123                 dev_err(&data->rtc->dev, "Timeout waiting for LPSRT Counter to change\n");
124                 return -ETIMEDOUT;
125         }
126         return 0;
127 }
128
129 static int snvs_rtc_enable(struct snvs_rtc_data *data, bool enable)
130 {
131         int timeout = 1000;
132         u32 lpcr;
133
134         regmap_update_bits(data->regmap, data->offset + SNVS_LPCR, SNVS_LPCR_SRTC_ENV,
135                            enable ? SNVS_LPCR_SRTC_ENV : 0);
136
137         while (--timeout) {
138                 regmap_read(data->regmap, data->offset + SNVS_LPCR, &lpcr);
139
140                 if (enable) {
141                         if (lpcr & SNVS_LPCR_SRTC_ENV)
142                                 break;
143                 } else {
144                         if (!(lpcr & SNVS_LPCR_SRTC_ENV))
145                                 break;
146                 }
147         }
148
149         if (!timeout)
150                 return -ETIMEDOUT;
151
152         return 0;
153 }
154
155 static int snvs_rtc_read_time(struct device *dev, struct rtc_time *tm)
156 {
157         struct snvs_rtc_data *data = dev_get_drvdata(dev);
158         unsigned long time = rtc_read_lp_counter(data);
159
160         rtc_time_to_tm(time, tm);
161
162         return 0;
163 }
164
165 static int snvs_rtc_set_time(struct device *dev, struct rtc_time *tm)
166 {
167         struct snvs_rtc_data *data = dev_get_drvdata(dev);
168         unsigned long time;
169         int ret;
170
171         rtc_tm_to_time(tm, &time);
172
173         /* Disable RTC first */
174         ret = snvs_rtc_enable(data, false);
175         if (ret)
176                 return ret;
177
178         /* Write 32-bit time to 47-bit timer, leaving 15 LSBs blank */
179         regmap_write(data->regmap, data->offset + SNVS_LPSRTCLR, time << CNTR_TO_SECS_SH);
180         regmap_write(data->regmap, data->offset + SNVS_LPSRTCMR, time >> (32 - CNTR_TO_SECS_SH));
181
182         /* Enable RTC again */
183         ret = snvs_rtc_enable(data, true);
184
185         return ret;
186 }
187
188 static int snvs_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
189 {
190         struct snvs_rtc_data *data = dev_get_drvdata(dev);
191         u32 lptar, lpsr;
192
193         regmap_read(data->regmap, data->offset + SNVS_LPTAR, &lptar);
194         rtc_time_to_tm(lptar, &alrm->time);
195
196         regmap_read(data->regmap, data->offset + SNVS_LPSR, &lpsr);
197         alrm->pending = (lpsr & SNVS_LPSR_LPTA) ? 1 : 0;
198
199         return 0;
200 }
201
202 static int snvs_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
203 {
204         struct snvs_rtc_data *data = dev_get_drvdata(dev);
205
206         regmap_update_bits(data->regmap, data->offset + SNVS_LPCR,
207                            (SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN),
208                            enable ? (SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN) : 0);
209
210         return rtc_write_sync_lp(data);
211 }
212
213 static int snvs_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
214 {
215         struct snvs_rtc_data *data = dev_get_drvdata(dev);
216         struct rtc_time *alrm_tm = &alrm->time;
217         unsigned long time;
218         int ret;
219
220         rtc_tm_to_time(alrm_tm, &time);
221
222         regmap_update_bits(data->regmap, data->offset + SNVS_LPCR, SNVS_LPCR_LPTA_EN, 0);
223         ret = rtc_write_sync_lp(data);
224         if (ret)
225                 return ret;
226         regmap_write(data->regmap, data->offset + SNVS_LPTAR, time);
227
228         /* Clear alarm interrupt status bit */
229         regmap_write(data->regmap, data->offset + SNVS_LPSR, SNVS_LPSR_LPTA);
230
231         return snvs_rtc_alarm_irq_enable(dev, alrm->enabled);
232 }
233
234 static const struct rtc_class_ops snvs_rtc_ops = {
235         .read_time = snvs_rtc_read_time,
236         .set_time = snvs_rtc_set_time,
237         .read_alarm = snvs_rtc_read_alarm,
238         .set_alarm = snvs_rtc_set_alarm,
239         .alarm_irq_enable = snvs_rtc_alarm_irq_enable,
240 };
241
242 static irqreturn_t snvs_rtc_irq_handler(int irq, void *dev_id)
243 {
244         struct device *dev = dev_id;
245         struct snvs_rtc_data *data = dev_get_drvdata(dev);
246         u32 lpsr;
247         u32 events = 0;
248
249         regmap_read(data->regmap, data->offset + SNVS_LPSR, &lpsr);
250
251         if (lpsr & SNVS_LPSR_LPTA) {
252                 events |= (RTC_AF | RTC_IRQF);
253
254                 /* RTC alarm should be one-shot */
255                 snvs_rtc_alarm_irq_enable(dev, 0);
256
257                 rtc_update_irq(data->rtc, 1, events);
258         }
259
260         /* clear interrupt status */
261         regmap_write(data->regmap, data->offset + SNVS_LPSR, lpsr);
262
263         return events ? IRQ_HANDLED : IRQ_NONE;
264 }
265
266 static const struct regmap_config snvs_rtc_config = {
267         .reg_bits = 32,
268         .val_bits = 32,
269         .reg_stride = 4,
270 };
271
272 static int snvs_rtc_probe(struct platform_device *pdev)
273 {
274         struct snvs_rtc_data *data;
275         struct resource *res;
276         int ret;
277         void __iomem *mmio;
278
279         data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
280         if (!data)
281                 return -ENOMEM;
282
283         data->regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "regmap");
284
285         if (IS_ERR(data->regmap)) {
286                 dev_warn(&pdev->dev, "snvs rtc: you use old dts file, please update it\n");
287                 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
288
289                 mmio = devm_ioremap_resource(&pdev->dev, res);
290                 if (IS_ERR(mmio))
291                         return PTR_ERR(mmio);
292
293                 data->regmap = devm_regmap_init_mmio(&pdev->dev, mmio, &snvs_rtc_config);
294         } else {
295                 data->offset = SNVS_LPREGISTER_OFFSET;
296                 of_property_read_u32(pdev->dev.of_node, "offset", &data->offset);
297         }
298
299         if (IS_ERR(data->regmap)) {
300                 dev_err(&pdev->dev, "Can't find snvs syscon\n");
301                 return -ENODEV;
302         }
303
304         data->irq = platform_get_irq(pdev, 0);
305         if (data->irq < 0)
306                 return data->irq;
307
308         data->clk = devm_clk_get(&pdev->dev, "snvs-rtc");
309         if (IS_ERR(data->clk)) {
310                 data->clk = NULL;
311         } else {
312                 ret = clk_prepare_enable(data->clk);
313                 if (ret) {
314                         dev_err(&pdev->dev,
315                                 "Could not prepare or enable the snvs clock\n");
316                         return ret;
317                 }
318         }
319
320         platform_set_drvdata(pdev, data);
321
322         /* Initialize glitch detect */
323         regmap_write(data->regmap, data->offset + SNVS_LPPGDR, SNVS_LPPGDR_INIT);
324
325         /* Clear interrupt status */
326         regmap_write(data->regmap, data->offset + SNVS_LPSR, 0xffffffff);
327
328         /* Enable RTC */
329         ret = snvs_rtc_enable(data, true);
330         if (ret) {
331                 dev_err(&pdev->dev, "failed to enable rtc %d\n", ret);
332                 goto error_rtc_device_register;
333         }
334
335         device_init_wakeup(&pdev->dev, true);
336
337         ret = devm_request_irq(&pdev->dev, data->irq, snvs_rtc_irq_handler,
338                                IRQF_SHARED, "rtc alarm", &pdev->dev);
339         if (ret) {
340                 dev_err(&pdev->dev, "failed to request irq %d: %d\n",
341                         data->irq, ret);
342                 goto error_rtc_device_register;
343         }
344
345         data->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
346                                         &snvs_rtc_ops, THIS_MODULE);
347         if (IS_ERR(data->rtc)) {
348                 ret = PTR_ERR(data->rtc);
349                 dev_err(&pdev->dev, "failed to register rtc: %d\n", ret);
350                 goto error_rtc_device_register;
351         }
352
353         return 0;
354
355 error_rtc_device_register:
356         if (data->clk)
357                 clk_disable_unprepare(data->clk);
358
359         return ret;
360 }
361
362 #ifdef CONFIG_PM_SLEEP
363 static int snvs_rtc_suspend(struct device *dev)
364 {
365         struct snvs_rtc_data *data = dev_get_drvdata(dev);
366
367         if (device_may_wakeup(dev))
368                 return enable_irq_wake(data->irq);
369
370         return 0;
371 }
372
373 static int snvs_rtc_suspend_noirq(struct device *dev)
374 {
375         struct snvs_rtc_data *data = dev_get_drvdata(dev);
376
377         if (data->clk)
378                 clk_disable_unprepare(data->clk);
379
380         return 0;
381 }
382
383 static int snvs_rtc_resume(struct device *dev)
384 {
385         struct snvs_rtc_data *data = dev_get_drvdata(dev);
386
387         if (device_may_wakeup(dev))
388                 return disable_irq_wake(data->irq);
389
390         return 0;
391 }
392
393 static int snvs_rtc_resume_noirq(struct device *dev)
394 {
395         struct snvs_rtc_data *data = dev_get_drvdata(dev);
396
397         if (data->clk)
398                 return clk_prepare_enable(data->clk);
399
400         return 0;
401 }
402
403 static const struct dev_pm_ops snvs_rtc_pm_ops = {
404         .suspend = snvs_rtc_suspend,
405         .suspend_noirq = snvs_rtc_suspend_noirq,
406         .resume = snvs_rtc_resume,
407         .resume_noirq = snvs_rtc_resume_noirq,
408 };
409
410 #define SNVS_RTC_PM_OPS (&snvs_rtc_pm_ops)
411
412 #else
413
414 #define SNVS_RTC_PM_OPS NULL
415
416 #endif
417
418 static const struct of_device_id snvs_dt_ids[] = {
419         { .compatible = "fsl,sec-v4.0-mon-rtc-lp", },
420         { /* sentinel */ }
421 };
422 MODULE_DEVICE_TABLE(of, snvs_dt_ids);
423
424 static struct platform_driver snvs_rtc_driver = {
425         .driver = {
426                 .name   = "snvs_rtc",
427                 .pm     = SNVS_RTC_PM_OPS,
428                 .of_match_table = snvs_dt_ids,
429         },
430         .probe          = snvs_rtc_probe,
431 };
432 module_platform_driver(snvs_rtc_driver);
433
434 MODULE_AUTHOR("Freescale Semiconductor, Inc.");
435 MODULE_DESCRIPTION("Freescale SNVS RTC Driver");
436 MODULE_LICENSE("GPL");