]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/rtc/rtc-armada38x.c
rtc: ds3232: Add regmap max_register definition.
[mirror_ubuntu-artful-kernel.git] / drivers / rtc / rtc-armada38x.c
CommitLineData
a3a42806
GC
1/*
2 * RTC driver for the Armada 38x Marvell SoCs
3 *
4 * Copyright (C) 2015 Marvell
5 *
6 * Gregory Clement <gregory.clement@free-electrons.com>
7 *
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.
12 *
13 */
14
15#include <linux/delay.h>
16#include <linux/io.h>
17#include <linux/module.h>
18#include <linux/of.h>
19#include <linux/platform_device.h>
20#include <linux/rtc.h>
21
22#define RTC_STATUS 0x0
23#define RTC_STATUS_ALARM1 BIT(0)
24#define RTC_STATUS_ALARM2 BIT(1)
25#define RTC_IRQ1_CONF 0x4
26#define RTC_IRQ1_AL_EN BIT(0)
27#define RTC_IRQ1_FREQ_EN BIT(1)
28#define RTC_IRQ1_FREQ_1HZ BIT(2)
29#define RTC_TIME 0xC
30#define RTC_ALARM1 0x10
31
844a3073
GC
32#define SOC_RTC_BRIDGE_TIMING_CTL 0x0
33#define SOC_RTC_PERIOD_OFFS 0
34#define SOC_RTC_PERIOD_MASK (0x3FF << SOC_RTC_PERIOD_OFFS)
35#define SOC_RTC_READ_DELAY_OFFS 26
36#define SOC_RTC_READ_DELAY_MASK (0x1F << SOC_RTC_READ_DELAY_OFFS)
37
a3a42806
GC
38#define SOC_RTC_INTERRUPT 0x8
39#define SOC_RTC_ALARM1 BIT(0)
40#define SOC_RTC_ALARM2 BIT(1)
41#define SOC_RTC_ALARM1_MASK BIT(2)
42#define SOC_RTC_ALARM2_MASK BIT(3)
43
844a3073
GC
44#define SAMPLE_NR 100
45
46struct value_to_freq {
47 u32 value;
48 u8 freq;
49};
50
a3a42806
GC
51struct armada38x_rtc {
52 struct rtc_device *rtc_dev;
53 void __iomem *regs;
54 void __iomem *regs_soc;
55 spinlock_t lock;
56 int irq;
844a3073 57 struct value_to_freq *val_to_freq;
a3a42806
GC
58};
59
60/*
61 * According to the datasheet, the OS should wait 5us after every
62 * register write to the RTC hard macro so that the required update
63 * can occur without holding off the system bus
844a3073
GC
64 * According to errata RES-3124064, Write to any RTC register
65 * may fail. As a workaround, before writing to RTC
66 * register, issue a dummy write of 0x0 twice to RTC Status
67 * register.
a3a42806 68 */
844a3073 69
a3a42806
GC
70static void rtc_delayed_write(u32 val, struct armada38x_rtc *rtc, int offset)
71{
844a3073
GC
72 writel(0, rtc->regs + RTC_STATUS);
73 writel(0, rtc->regs + RTC_STATUS);
a3a42806
GC
74 writel(val, rtc->regs + offset);
75 udelay(5);
76}
77
844a3073
GC
78/* Update RTC-MBUS bridge timing parameters */
79static void rtc_update_mbus_timing_params(struct armada38x_rtc *rtc)
80{
81 u32 reg;
82
83 reg = readl(rtc->regs_soc + SOC_RTC_BRIDGE_TIMING_CTL);
84 reg &= ~SOC_RTC_PERIOD_MASK;
85 reg |= 0x3FF << SOC_RTC_PERIOD_OFFS; /* Maximum value */
86 reg &= ~SOC_RTC_READ_DELAY_MASK;
87 reg |= 0x1F << SOC_RTC_READ_DELAY_OFFS; /* Maximum value */
88 writel(reg, rtc->regs_soc + SOC_RTC_BRIDGE_TIMING_CTL);
89}
90
91static u32 read_rtc_register_wa(struct armada38x_rtc *rtc, u8 rtc_reg)
92{
93 int i, index_max = 0, max = 0;
94
95 for (i = 0; i < SAMPLE_NR; i++) {
96 rtc->val_to_freq[i].value = readl(rtc->regs + rtc_reg);
97 rtc->val_to_freq[i].freq = 0;
98 }
99
100 for (i = 0; i < SAMPLE_NR; i++) {
101 int j = 0;
102 u32 value = rtc->val_to_freq[i].value;
103
104 while (rtc->val_to_freq[j].freq) {
105 if (rtc->val_to_freq[j].value == value) {
106 rtc->val_to_freq[j].freq++;
107 break;
108 }
109 j++;
110 }
111
112 if (!rtc->val_to_freq[j].freq) {
113 rtc->val_to_freq[j].value = value;
114 rtc->val_to_freq[j].freq = 1;
115 }
116
117 if (rtc->val_to_freq[j].freq > max) {
118 index_max = j;
119 max = rtc->val_to_freq[j].freq;
120 }
121
122 /*
123 * If a value already has half of the sample this is the most
124 * frequent one and we can stop the research right now
125 */
126 if (max > SAMPLE_NR / 2)
127 break;
128 }
129
130 return rtc->val_to_freq[index_max].value;
131}
132
a3a42806
GC
133static int armada38x_rtc_read_time(struct device *dev, struct rtc_time *tm)
134{
135 struct armada38x_rtc *rtc = dev_get_drvdata(dev);
844a3073 136 unsigned long time, flags;
a3a42806 137
0c6e7183 138 spin_lock_irqsave(&rtc->lock, flags);
844a3073 139 time = read_rtc_register_wa(rtc, RTC_TIME);
0c6e7183 140 spin_unlock_irqrestore(&rtc->lock, flags);
a3a42806 141
844a3073 142 rtc_time_to_tm(time, tm);
a3a42806
GC
143
144 return 0;
145}
146
147static int armada38x_rtc_set_time(struct device *dev, struct rtc_time *tm)
148{
149 struct armada38x_rtc *rtc = dev_get_drvdata(dev);
150 int ret = 0;
0c6e7183 151 unsigned long time, flags;
a3a42806
GC
152
153 ret = rtc_tm_to_time(tm, &time);
154
155 if (ret)
156 goto out;
844a3073 157
0c6e7183 158 spin_lock_irqsave(&rtc->lock, flags);
a3a42806 159 rtc_delayed_write(time, rtc, RTC_TIME);
0c6e7183 160 spin_unlock_irqrestore(&rtc->lock, flags);
a3a42806 161
a3a42806
GC
162out:
163 return ret;
164}
165
166static int armada38x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
167{
168 struct armada38x_rtc *rtc = dev_get_drvdata(dev);
169 unsigned long time, flags;
170 u32 val;
171
172 spin_lock_irqsave(&rtc->lock, flags);
173
844a3073
GC
174 time = read_rtc_register_wa(rtc, RTC_ALARM1);
175 val = read_rtc_register_wa(rtc, RTC_IRQ1_CONF) & RTC_IRQ1_AL_EN;
a3a42806
GC
176
177 spin_unlock_irqrestore(&rtc->lock, flags);
178
179 alrm->enabled = val ? 1 : 0;
180 rtc_time_to_tm(time, &alrm->time);
181
182 return 0;
183}
184
185static int armada38x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
186{
187 struct armada38x_rtc *rtc = dev_get_drvdata(dev);
188 unsigned long time, flags;
189 int ret = 0;
190 u32 val;
191
192 ret = rtc_tm_to_time(&alrm->time, &time);
193
194 if (ret)
195 goto out;
196
197 spin_lock_irqsave(&rtc->lock, flags);
198
199 rtc_delayed_write(time, rtc, RTC_ALARM1);
200
201 if (alrm->enabled) {
202 rtc_delayed_write(RTC_IRQ1_AL_EN, rtc, RTC_IRQ1_CONF);
203 val = readl(rtc->regs_soc + SOC_RTC_INTERRUPT);
204 writel(val | SOC_RTC_ALARM1_MASK,
205 rtc->regs_soc + SOC_RTC_INTERRUPT);
206 }
207
208 spin_unlock_irqrestore(&rtc->lock, flags);
209
210out:
211 return ret;
212}
213
214static int armada38x_rtc_alarm_irq_enable(struct device *dev,
215 unsigned int enabled)
216{
217 struct armada38x_rtc *rtc = dev_get_drvdata(dev);
218 unsigned long flags;
219
220 spin_lock_irqsave(&rtc->lock, flags);
221
222 if (enabled)
223 rtc_delayed_write(RTC_IRQ1_AL_EN, rtc, RTC_IRQ1_CONF);
224 else
225 rtc_delayed_write(0, rtc, RTC_IRQ1_CONF);
226
227 spin_unlock_irqrestore(&rtc->lock, flags);
228
229 return 0;
230}
231
232static irqreturn_t armada38x_rtc_alarm_irq(int irq, void *data)
233{
234 struct armada38x_rtc *rtc = data;
235 u32 val;
236 int event = RTC_IRQF | RTC_AF;
237
238 dev_dbg(&rtc->rtc_dev->dev, "%s:irq(%d)\n", __func__, irq);
239
240 spin_lock(&rtc->lock);
241
242 val = readl(rtc->regs_soc + SOC_RTC_INTERRUPT);
243
244 writel(val & ~SOC_RTC_ALARM1, rtc->regs_soc + SOC_RTC_INTERRUPT);
844a3073 245 val = read_rtc_register_wa(rtc, RTC_IRQ1_CONF);
a3a42806
GC
246 /* disable all the interrupts for alarm 1 */
247 rtc_delayed_write(0, rtc, RTC_IRQ1_CONF);
248 /* Ack the event */
249 rtc_delayed_write(RTC_STATUS_ALARM1, rtc, RTC_STATUS);
250
251 spin_unlock(&rtc->lock);
252
253 if (val & RTC_IRQ1_FREQ_EN) {
254 if (val & RTC_IRQ1_FREQ_1HZ)
255 event |= RTC_UF;
256 else
257 event |= RTC_PF;
258 }
259
260 rtc_update_irq(rtc->rtc_dev, 1, event);
261
262 return IRQ_HANDLED;
263}
264
d748c981 265static const struct rtc_class_ops armada38x_rtc_ops = {
a3a42806
GC
266 .read_time = armada38x_rtc_read_time,
267 .set_time = armada38x_rtc_set_time,
268 .read_alarm = armada38x_rtc_read_alarm,
269 .set_alarm = armada38x_rtc_set_alarm,
270 .alarm_irq_enable = armada38x_rtc_alarm_irq_enable,
271};
272
d748c981
RK
273static const struct rtc_class_ops armada38x_rtc_ops_noirq = {
274 .read_time = armada38x_rtc_read_time,
275 .set_time = armada38x_rtc_set_time,
276 .read_alarm = armada38x_rtc_read_alarm,
277};
278
a3a42806
GC
279static __init int armada38x_rtc_probe(struct platform_device *pdev)
280{
d748c981 281 const struct rtc_class_ops *ops;
a3a42806
GC
282 struct resource *res;
283 struct armada38x_rtc *rtc;
284 int ret;
285
286 rtc = devm_kzalloc(&pdev->dev, sizeof(struct armada38x_rtc),
287 GFP_KERNEL);
288 if (!rtc)
289 return -ENOMEM;
290
844a3073
GC
291 rtc->val_to_freq = devm_kcalloc(&pdev->dev, SAMPLE_NR,
292 sizeof(struct value_to_freq), GFP_KERNEL);
293 if (!rtc->val_to_freq)
294 return -ENOMEM;
295
a3a42806
GC
296 spin_lock_init(&rtc->lock);
297
298 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rtc");
299 rtc->regs = devm_ioremap_resource(&pdev->dev, res);
300 if (IS_ERR(rtc->regs))
301 return PTR_ERR(rtc->regs);
302 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rtc-soc");
303 rtc->regs_soc = devm_ioremap_resource(&pdev->dev, res);
304 if (IS_ERR(rtc->regs_soc))
305 return PTR_ERR(rtc->regs_soc);
306
307 rtc->irq = platform_get_irq(pdev, 0);
308
309 if (rtc->irq < 0) {
310 dev_err(&pdev->dev, "no irq\n");
311 return rtc->irq;
312 }
313 if (devm_request_irq(&pdev->dev, rtc->irq, armada38x_rtc_alarm_irq,
314 0, pdev->name, rtc) < 0) {
315 dev_warn(&pdev->dev, "Interrupt not available.\n");
316 rtc->irq = -1;
d748c981
RK
317 }
318 platform_set_drvdata(pdev, rtc);
319
320 if (rtc->irq != -1) {
321 device_init_wakeup(&pdev->dev, 1);
322 ops = &armada38x_rtc_ops;
323 } else {
a3a42806
GC
324 /*
325 * If there is no interrupt available then we can't
326 * use the alarm
327 */
d748c981 328 ops = &armada38x_rtc_ops_noirq;
a3a42806 329 }
a3a42806 330
844a3073
GC
331 /* Update RTC-MBUS bridge timing parameters */
332 rtc_update_mbus_timing_params(rtc);
333
a3a42806 334 rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
d748c981 335 ops, THIS_MODULE);
a3a42806
GC
336 if (IS_ERR(rtc->rtc_dev)) {
337 ret = PTR_ERR(rtc->rtc_dev);
338 dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
339 return ret;
340 }
341 return 0;
342}
343
344#ifdef CONFIG_PM_SLEEP
345static int armada38x_rtc_suspend(struct device *dev)
346{
347 if (device_may_wakeup(dev)) {
348 struct armada38x_rtc *rtc = dev_get_drvdata(dev);
349
350 return enable_irq_wake(rtc->irq);
351 }
352
353 return 0;
354}
355
356static int armada38x_rtc_resume(struct device *dev)
357{
358 if (device_may_wakeup(dev)) {
359 struct armada38x_rtc *rtc = dev_get_drvdata(dev);
360
844a3073
GC
361 /* Update RTC-MBUS bridge timing parameters */
362 rtc_update_mbus_timing_params(rtc);
363
a3a42806
GC
364 return disable_irq_wake(rtc->irq);
365 }
366
367 return 0;
368}
369#endif
370
371static SIMPLE_DEV_PM_OPS(armada38x_rtc_pm_ops,
372 armada38x_rtc_suspend, armada38x_rtc_resume);
373
374#ifdef CONFIG_OF
375static const struct of_device_id armada38x_rtc_of_match_table[] = {
376 { .compatible = "marvell,armada-380-rtc", },
377 {}
378};
73798d5c 379MODULE_DEVICE_TABLE(of, armada38x_rtc_of_match_table);
a3a42806
GC
380#endif
381
382static struct platform_driver armada38x_rtc_driver = {
383 .driver = {
384 .name = "armada38x-rtc",
385 .pm = &armada38x_rtc_pm_ops,
386 .of_match_table = of_match_ptr(armada38x_rtc_of_match_table),
387 },
388};
389
390module_platform_driver_probe(armada38x_rtc_driver, armada38x_rtc_probe);
391
392MODULE_DESCRIPTION("Marvell Armada 38x RTC driver");
393MODULE_AUTHOR("Gregory CLEMENT <gregory.clement@free-electrons.com>");
394MODULE_LICENSE("GPL");