Linux 4.16.11
[linux/fpc-iii.git] / drivers / rtc / rtc-armada38x.c
blob1e4978c96ffd273c617e9c8d89f49a9b2a0838ec
1 /*
2 * RTC driver for the Armada 38x Marvell SoCs
4 * Copyright (C) 2015 Marvell
6 * Gregory Clement <gregory.clement@free-electrons.com>
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) any later version.
15 #include <linux/delay.h>
16 #include <linux/io.h>
17 #include <linux/module.h>
18 #include <linux/of.h>
19 #include <linux/of_device.h>
20 #include <linux/platform_device.h>
21 #include <linux/rtc.h>
23 #define RTC_STATUS 0x0
24 #define RTC_STATUS_ALARM1 BIT(0)
25 #define RTC_STATUS_ALARM2 BIT(1)
26 #define RTC_IRQ1_CONF 0x4
27 #define RTC_IRQ2_CONF 0x8
28 #define RTC_IRQ_AL_EN BIT(0)
29 #define RTC_IRQ_FREQ_EN BIT(1)
30 #define RTC_IRQ_FREQ_1HZ BIT(2)
31 #define RTC_CCR 0x18
32 #define RTC_CCR_MODE BIT(15)
34 #define RTC_TIME 0xC
35 #define RTC_ALARM1 0x10
36 #define RTC_ALARM2 0x14
38 /* Armada38x SoC registers */
39 #define RTC_38X_BRIDGE_TIMING_CTL 0x0
40 #define RTC_38X_PERIOD_OFFS 0
41 #define RTC_38X_PERIOD_MASK (0x3FF << RTC_38X_PERIOD_OFFS)
42 #define RTC_38X_READ_DELAY_OFFS 26
43 #define RTC_38X_READ_DELAY_MASK (0x1F << RTC_38X_READ_DELAY_OFFS)
45 /* Armada 7K/8K registers */
46 #define RTC_8K_BRIDGE_TIMING_CTL0 0x0
47 #define RTC_8K_WRCLK_PERIOD_OFFS 0
48 #define RTC_8K_WRCLK_PERIOD_MASK (0xFFFF << RTC_8K_WRCLK_PERIOD_OFFS)
49 #define RTC_8K_WRCLK_SETUP_OFFS 16
50 #define RTC_8K_WRCLK_SETUP_MASK (0xFFFF << RTC_8K_WRCLK_SETUP_OFFS)
51 #define RTC_8K_BRIDGE_TIMING_CTL1 0x4
52 #define RTC_8K_READ_DELAY_OFFS 0
53 #define RTC_8K_READ_DELAY_MASK (0xFFFF << RTC_8K_READ_DELAY_OFFS)
55 #define RTC_8K_ISR 0x10
56 #define RTC_8K_IMR 0x14
57 #define RTC_8K_ALARM2 BIT(0)
59 #define SOC_RTC_INTERRUPT 0x8
60 #define SOC_RTC_ALARM1 BIT(0)
61 #define SOC_RTC_ALARM2 BIT(1)
62 #define SOC_RTC_ALARM1_MASK BIT(2)
63 #define SOC_RTC_ALARM2_MASK BIT(3)
65 #define SAMPLE_NR 100
67 struct value_to_freq {
68 u32 value;
69 u8 freq;
72 struct armada38x_rtc {
73 struct rtc_device *rtc_dev;
74 void __iomem *regs;
75 void __iomem *regs_soc;
76 spinlock_t lock;
77 int irq;
78 struct value_to_freq *val_to_freq;
79 struct armada38x_rtc_data *data;
82 #define ALARM1 0
83 #define ALARM2 1
85 #define ALARM_REG(base, alarm) ((base) + (alarm) * sizeof(u32))
87 struct armada38x_rtc_data {
88 /* Initialize the RTC-MBUS bridge timing */
89 void (*update_mbus_timing)(struct armada38x_rtc *rtc);
90 u32 (*read_rtc_reg)(struct armada38x_rtc *rtc, u8 rtc_reg);
91 void (*clear_isr)(struct armada38x_rtc *rtc);
92 void (*unmask_interrupt)(struct armada38x_rtc *rtc);
93 u32 alarm;
97 * According to the datasheet, the OS should wait 5us after every
98 * register write to the RTC hard macro so that the required update
99 * can occur without holding off the system bus
100 * According to errata RES-3124064, Write to any RTC register
101 * may fail. As a workaround, before writing to RTC
102 * register, issue a dummy write of 0x0 twice to RTC Status
103 * register.
106 static void rtc_delayed_write(u32 val, struct armada38x_rtc *rtc, int offset)
108 writel(0, rtc->regs + RTC_STATUS);
109 writel(0, rtc->regs + RTC_STATUS);
110 writel(val, rtc->regs + offset);
111 udelay(5);
114 /* Update RTC-MBUS bridge timing parameters */
115 static void rtc_update_38x_mbus_timing_params(struct armada38x_rtc *rtc)
117 u32 reg;
119 reg = readl(rtc->regs_soc + RTC_38X_BRIDGE_TIMING_CTL);
120 reg &= ~RTC_38X_PERIOD_MASK;
121 reg |= 0x3FF << RTC_38X_PERIOD_OFFS; /* Maximum value */
122 reg &= ~RTC_38X_READ_DELAY_MASK;
123 reg |= 0x1F << RTC_38X_READ_DELAY_OFFS; /* Maximum value */
124 writel(reg, rtc->regs_soc + RTC_38X_BRIDGE_TIMING_CTL);
127 static void rtc_update_8k_mbus_timing_params(struct armada38x_rtc *rtc)
129 u32 reg;
131 reg = readl(rtc->regs_soc + RTC_8K_BRIDGE_TIMING_CTL0);
132 reg &= ~RTC_8K_WRCLK_PERIOD_MASK;
133 reg |= 0x3FF << RTC_8K_WRCLK_PERIOD_OFFS;
134 reg &= ~RTC_8K_WRCLK_SETUP_MASK;
135 reg |= 0x29 << RTC_8K_WRCLK_SETUP_OFFS;
136 writel(reg, rtc->regs_soc + RTC_8K_BRIDGE_TIMING_CTL0);
138 reg = readl(rtc->regs_soc + RTC_8K_BRIDGE_TIMING_CTL1);
139 reg &= ~RTC_8K_READ_DELAY_MASK;
140 reg |= 0x3F << RTC_8K_READ_DELAY_OFFS;
141 writel(reg, rtc->regs_soc + RTC_8K_BRIDGE_TIMING_CTL1);
144 static u32 read_rtc_register(struct armada38x_rtc *rtc, u8 rtc_reg)
146 return readl(rtc->regs + rtc_reg);
149 static u32 read_rtc_register_38x_wa(struct armada38x_rtc *rtc, u8 rtc_reg)
151 int i, index_max = 0, max = 0;
153 for (i = 0; i < SAMPLE_NR; i++) {
154 rtc->val_to_freq[i].value = readl(rtc->regs + rtc_reg);
155 rtc->val_to_freq[i].freq = 0;
158 for (i = 0; i < SAMPLE_NR; i++) {
159 int j = 0;
160 u32 value = rtc->val_to_freq[i].value;
162 while (rtc->val_to_freq[j].freq) {
163 if (rtc->val_to_freq[j].value == value) {
164 rtc->val_to_freq[j].freq++;
165 break;
167 j++;
170 if (!rtc->val_to_freq[j].freq) {
171 rtc->val_to_freq[j].value = value;
172 rtc->val_to_freq[j].freq = 1;
175 if (rtc->val_to_freq[j].freq > max) {
176 index_max = j;
177 max = rtc->val_to_freq[j].freq;
181 * If a value already has half of the sample this is the most
182 * frequent one and we can stop the research right now
184 if (max > SAMPLE_NR / 2)
185 break;
188 return rtc->val_to_freq[index_max].value;
191 static void armada38x_clear_isr(struct armada38x_rtc *rtc)
193 u32 val = readl(rtc->regs_soc + SOC_RTC_INTERRUPT);
195 writel(val & ~SOC_RTC_ALARM1, rtc->regs_soc + SOC_RTC_INTERRUPT);
198 static void armada38x_unmask_interrupt(struct armada38x_rtc *rtc)
200 u32 val = readl(rtc->regs_soc + SOC_RTC_INTERRUPT);
202 writel(val | SOC_RTC_ALARM1_MASK, rtc->regs_soc + SOC_RTC_INTERRUPT);
205 static void armada8k_clear_isr(struct armada38x_rtc *rtc)
207 writel(RTC_8K_ALARM2, rtc->regs_soc + RTC_8K_ISR);
210 static void armada8k_unmask_interrupt(struct armada38x_rtc *rtc)
212 writel(RTC_8K_ALARM2, rtc->regs_soc + RTC_8K_IMR);
215 static int armada38x_rtc_read_time(struct device *dev, struct rtc_time *tm)
217 struct armada38x_rtc *rtc = dev_get_drvdata(dev);
218 unsigned long time, flags;
220 spin_lock_irqsave(&rtc->lock, flags);
221 time = rtc->data->read_rtc_reg(rtc, RTC_TIME);
222 spin_unlock_irqrestore(&rtc->lock, flags);
224 rtc_time_to_tm(time, tm);
226 return 0;
229 static int armada38x_rtc_set_time(struct device *dev, struct rtc_time *tm)
231 struct armada38x_rtc *rtc = dev_get_drvdata(dev);
232 int ret = 0;
233 unsigned long time, flags;
235 ret = rtc_tm_to_time(tm, &time);
237 if (ret)
238 goto out;
240 spin_lock_irqsave(&rtc->lock, flags);
241 rtc_delayed_write(time, rtc, RTC_TIME);
242 spin_unlock_irqrestore(&rtc->lock, flags);
244 out:
245 return ret;
248 static int armada38x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
250 struct armada38x_rtc *rtc = dev_get_drvdata(dev);
251 unsigned long time, flags;
252 u32 reg = ALARM_REG(RTC_ALARM1, rtc->data->alarm);
253 u32 reg_irq = ALARM_REG(RTC_IRQ1_CONF, rtc->data->alarm);
254 u32 val;
256 spin_lock_irqsave(&rtc->lock, flags);
258 time = rtc->data->read_rtc_reg(rtc, reg);
259 val = rtc->data->read_rtc_reg(rtc, reg_irq) & RTC_IRQ_AL_EN;
261 spin_unlock_irqrestore(&rtc->lock, flags);
263 alrm->enabled = val ? 1 : 0;
264 rtc_time_to_tm(time, &alrm->time);
266 return 0;
269 static int armada38x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
271 struct armada38x_rtc *rtc = dev_get_drvdata(dev);
272 u32 reg = ALARM_REG(RTC_ALARM1, rtc->data->alarm);
273 u32 reg_irq = ALARM_REG(RTC_IRQ1_CONF, rtc->data->alarm);
274 unsigned long time, flags;
275 int ret = 0;
277 ret = rtc_tm_to_time(&alrm->time, &time);
279 if (ret)
280 goto out;
282 spin_lock_irqsave(&rtc->lock, flags);
284 rtc_delayed_write(time, rtc, reg);
286 if (alrm->enabled) {
287 rtc_delayed_write(RTC_IRQ_AL_EN, rtc, reg_irq);
288 rtc->data->unmask_interrupt(rtc);
291 spin_unlock_irqrestore(&rtc->lock, flags);
293 out:
294 return ret;
297 static int armada38x_rtc_alarm_irq_enable(struct device *dev,
298 unsigned int enabled)
300 struct armada38x_rtc *rtc = dev_get_drvdata(dev);
301 u32 reg_irq = ALARM_REG(RTC_IRQ1_CONF, rtc->data->alarm);
302 unsigned long flags;
304 spin_lock_irqsave(&rtc->lock, flags);
306 if (enabled)
307 rtc_delayed_write(RTC_IRQ_AL_EN, rtc, reg_irq);
308 else
309 rtc_delayed_write(0, rtc, reg_irq);
311 spin_unlock_irqrestore(&rtc->lock, flags);
313 return 0;
316 static irqreturn_t armada38x_rtc_alarm_irq(int irq, void *data)
318 struct armada38x_rtc *rtc = data;
319 u32 val;
320 int event = RTC_IRQF | RTC_AF;
321 u32 reg_irq = ALARM_REG(RTC_IRQ1_CONF, rtc->data->alarm);
323 dev_dbg(&rtc->rtc_dev->dev, "%s:irq(%d)\n", __func__, irq);
325 spin_lock(&rtc->lock);
327 rtc->data->clear_isr(rtc);
328 val = rtc->data->read_rtc_reg(rtc, reg_irq);
329 /* disable all the interrupts for alarm*/
330 rtc_delayed_write(0, rtc, reg_irq);
331 /* Ack the event */
332 rtc_delayed_write(1 << rtc->data->alarm, rtc, RTC_STATUS);
334 spin_unlock(&rtc->lock);
336 if (val & RTC_IRQ_FREQ_EN) {
337 if (val & RTC_IRQ_FREQ_1HZ)
338 event |= RTC_UF;
339 else
340 event |= RTC_PF;
343 rtc_update_irq(rtc->rtc_dev, 1, event);
345 return IRQ_HANDLED;
349 * The information given in the Armada 388 functional spec is complex.
350 * They give two different formulas for calculating the offset value,
351 * but when considering "Offset" as an 8-bit signed integer, they both
352 * reduce down to (we shall rename "Offset" as "val" here):
354 * val = (f_ideal / f_measured - 1) / resolution where f_ideal = 32768
356 * Converting to time, f = 1/t:
357 * val = (t_measured / t_ideal - 1) / resolution where t_ideal = 1/32768
359 * => t_measured / t_ideal = val * resolution + 1
361 * "offset" in the RTC interface is defined as:
362 * t = t0 * (1 + offset * 1e-9)
363 * where t is the desired period, t0 is the measured period with a zero
364 * offset, which is t_measured above. With t0 = t_measured and t = t_ideal,
365 * offset = (t_ideal / t_measured - 1) / 1e-9
367 * => t_ideal / t_measured = offset * 1e-9 + 1
369 * so:
371 * offset * 1e-9 + 1 = 1 / (val * resolution + 1)
373 * We want "resolution" to be an integer, so resolution = R * 1e-9, giving
374 * offset = 1e18 / (val * R + 1e9) - 1e9
375 * val = (1e18 / (offset + 1e9) - 1e9) / R
376 * with a common transformation:
377 * f(x) = 1e18 / (x + 1e9) - 1e9
378 * offset = f(val * R)
379 * val = f(offset) / R
381 * Armada 38x supports two modes, fine mode (954ppb) and coarse mode (3815ppb).
383 static long armada38x_ppb_convert(long ppb)
385 long div = ppb + 1000000000L;
387 return div_s64(1000000000000000000LL + div / 2, div) - 1000000000L;
390 static int armada38x_rtc_read_offset(struct device *dev, long *offset)
392 struct armada38x_rtc *rtc = dev_get_drvdata(dev);
393 unsigned long ccr, flags;
394 long ppb_cor;
396 spin_lock_irqsave(&rtc->lock, flags);
397 ccr = rtc->data->read_rtc_reg(rtc, RTC_CCR);
398 spin_unlock_irqrestore(&rtc->lock, flags);
400 ppb_cor = (ccr & RTC_CCR_MODE ? 3815 : 954) * (s8)ccr;
401 /* ppb_cor + 1000000000L can never be zero */
402 *offset = armada38x_ppb_convert(ppb_cor);
404 return 0;
407 static int armada38x_rtc_set_offset(struct device *dev, long offset)
409 struct armada38x_rtc *rtc = dev_get_drvdata(dev);
410 unsigned long ccr = 0;
411 long ppb_cor, off;
414 * The maximum ppb_cor is -128 * 3815 .. 127 * 3815, but we
415 * need to clamp the input. This equates to -484270 .. 488558.
416 * Not only is this to stop out of range "off" but also to
417 * avoid the division by zero in armada38x_ppb_convert().
419 offset = clamp(offset, -484270L, 488558L);
421 ppb_cor = armada38x_ppb_convert(offset);
424 * Use low update mode where possible, which gives a better
425 * resolution of correction.
427 off = DIV_ROUND_CLOSEST(ppb_cor, 954);
428 if (off > 127 || off < -128) {
429 ccr = RTC_CCR_MODE;
430 off = DIV_ROUND_CLOSEST(ppb_cor, 3815);
434 * Armada 388 requires a bit pattern in bits 14..8 depending on
435 * the sign bit: { 0, ~S, S, S, S, S, S }
437 ccr |= (off & 0x3fff) ^ 0x2000;
438 rtc_delayed_write(ccr, rtc, RTC_CCR);
440 return 0;
443 static const struct rtc_class_ops armada38x_rtc_ops = {
444 .read_time = armada38x_rtc_read_time,
445 .set_time = armada38x_rtc_set_time,
446 .read_alarm = armada38x_rtc_read_alarm,
447 .set_alarm = armada38x_rtc_set_alarm,
448 .alarm_irq_enable = armada38x_rtc_alarm_irq_enable,
449 .read_offset = armada38x_rtc_read_offset,
450 .set_offset = armada38x_rtc_set_offset,
453 static const struct rtc_class_ops armada38x_rtc_ops_noirq = {
454 .read_time = armada38x_rtc_read_time,
455 .set_time = armada38x_rtc_set_time,
456 .read_alarm = armada38x_rtc_read_alarm,
457 .read_offset = armada38x_rtc_read_offset,
458 .set_offset = armada38x_rtc_set_offset,
461 static const struct armada38x_rtc_data armada38x_data = {
462 .update_mbus_timing = rtc_update_38x_mbus_timing_params,
463 .read_rtc_reg = read_rtc_register_38x_wa,
464 .clear_isr = armada38x_clear_isr,
465 .unmask_interrupt = armada38x_unmask_interrupt,
466 .alarm = ALARM1,
469 static const struct armada38x_rtc_data armada8k_data = {
470 .update_mbus_timing = rtc_update_8k_mbus_timing_params,
471 .read_rtc_reg = read_rtc_register,
472 .clear_isr = armada8k_clear_isr,
473 .unmask_interrupt = armada8k_unmask_interrupt,
474 .alarm = ALARM2,
477 #ifdef CONFIG_OF
478 static const struct of_device_id armada38x_rtc_of_match_table[] = {
480 .compatible = "marvell,armada-380-rtc",
481 .data = &armada38x_data,
484 .compatible = "marvell,armada-8k-rtc",
485 .data = &armada8k_data,
489 MODULE_DEVICE_TABLE(of, armada38x_rtc_of_match_table);
490 #endif
492 static __init int armada38x_rtc_probe(struct platform_device *pdev)
494 const struct rtc_class_ops *ops;
495 struct resource *res;
496 struct armada38x_rtc *rtc;
497 const struct of_device_id *match;
498 int ret;
500 match = of_match_device(armada38x_rtc_of_match_table, &pdev->dev);
501 if (!match)
502 return -ENODEV;
504 rtc = devm_kzalloc(&pdev->dev, sizeof(struct armada38x_rtc),
505 GFP_KERNEL);
506 if (!rtc)
507 return -ENOMEM;
509 rtc->val_to_freq = devm_kcalloc(&pdev->dev, SAMPLE_NR,
510 sizeof(struct value_to_freq), GFP_KERNEL);
511 if (!rtc->val_to_freq)
512 return -ENOMEM;
514 spin_lock_init(&rtc->lock);
516 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rtc");
517 rtc->regs = devm_ioremap_resource(&pdev->dev, res);
518 if (IS_ERR(rtc->regs))
519 return PTR_ERR(rtc->regs);
520 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rtc-soc");
521 rtc->regs_soc = devm_ioremap_resource(&pdev->dev, res);
522 if (IS_ERR(rtc->regs_soc))
523 return PTR_ERR(rtc->regs_soc);
525 rtc->irq = platform_get_irq(pdev, 0);
527 if (rtc->irq < 0) {
528 dev_err(&pdev->dev, "no irq\n");
529 return rtc->irq;
531 if (devm_request_irq(&pdev->dev, rtc->irq, armada38x_rtc_alarm_irq,
532 0, pdev->name, rtc) < 0) {
533 dev_warn(&pdev->dev, "Interrupt not available.\n");
534 rtc->irq = -1;
536 platform_set_drvdata(pdev, rtc);
538 if (rtc->irq != -1) {
539 device_init_wakeup(&pdev->dev, 1);
540 ops = &armada38x_rtc_ops;
541 } else {
543 * If there is no interrupt available then we can't
544 * use the alarm
546 ops = &armada38x_rtc_ops_noirq;
548 rtc->data = (struct armada38x_rtc_data *)match->data;
551 /* Update RTC-MBUS bridge timing parameters */
552 rtc->data->update_mbus_timing(rtc);
554 rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
555 ops, THIS_MODULE);
556 if (IS_ERR(rtc->rtc_dev)) {
557 ret = PTR_ERR(rtc->rtc_dev);
558 dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
559 return ret;
561 return 0;
564 #ifdef CONFIG_PM_SLEEP
565 static int armada38x_rtc_suspend(struct device *dev)
567 if (device_may_wakeup(dev)) {
568 struct armada38x_rtc *rtc = dev_get_drvdata(dev);
570 return enable_irq_wake(rtc->irq);
573 return 0;
576 static int armada38x_rtc_resume(struct device *dev)
578 if (device_may_wakeup(dev)) {
579 struct armada38x_rtc *rtc = dev_get_drvdata(dev);
581 /* Update RTC-MBUS bridge timing parameters */
582 rtc->data->update_mbus_timing(rtc);
584 return disable_irq_wake(rtc->irq);
587 return 0;
589 #endif
591 static SIMPLE_DEV_PM_OPS(armada38x_rtc_pm_ops,
592 armada38x_rtc_suspend, armada38x_rtc_resume);
594 static struct platform_driver armada38x_rtc_driver = {
595 .driver = {
596 .name = "armada38x-rtc",
597 .pm = &armada38x_rtc_pm_ops,
598 .of_match_table = of_match_ptr(armada38x_rtc_of_match_table),
602 module_platform_driver_probe(armada38x_rtc_driver, armada38x_rtc_probe);
604 MODULE_DESCRIPTION("Marvell Armada 38x RTC driver");
605 MODULE_AUTHOR("Gregory CLEMENT <gregory.clement@free-electrons.com>");
606 MODULE_LICENSE("GPL");