xref: /linux/drivers/rtc/rtc-armada38x.c (revision 2ba9268dd603d23e17643437b2246acb6844953b)
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 
32 #define SOC_RTC_INTERRUPT   0x8
33 #define SOC_RTC_ALARM1		BIT(0)
34 #define SOC_RTC_ALARM2		BIT(1)
35 #define SOC_RTC_ALARM1_MASK	BIT(2)
36 #define SOC_RTC_ALARM2_MASK	BIT(3)
37 
38 struct armada38x_rtc {
39 	struct rtc_device   *rtc_dev;
40 	void __iomem	    *regs;
41 	void __iomem	    *regs_soc;
42 	spinlock_t	    lock;
43 	int		    irq;
44 };
45 
46 /*
47  * According to the datasheet, the OS should wait 5us after every
48  * register write to the RTC hard macro so that the required update
49  * can occur without holding off the system bus
50  */
51 static void rtc_delayed_write(u32 val, struct armada38x_rtc *rtc, int offset)
52 {
53 	writel(val, rtc->regs + offset);
54 	udelay(5);
55 }
56 
57 static int armada38x_rtc_read_time(struct device *dev, struct rtc_time *tm)
58 {
59 	struct armada38x_rtc *rtc = dev_get_drvdata(dev);
60 	unsigned long time, time_check, flags;
61 
62 	spin_lock_irqsave(&rtc->lock, flags);
63 
64 	time = readl(rtc->regs + RTC_TIME);
65 	/*
66 	 * WA for failing time set attempts. As stated in HW ERRATA if
67 	 * more than one second between two time reads is detected
68 	 * then read once again.
69 	 */
70 	time_check = readl(rtc->regs + RTC_TIME);
71 	if ((time_check - time) > 1)
72 		time_check = readl(rtc->regs + RTC_TIME);
73 
74 	spin_unlock_irqrestore(&rtc->lock, flags);
75 
76 	rtc_time_to_tm(time_check, tm);
77 
78 	return 0;
79 }
80 
81 static int armada38x_rtc_set_time(struct device *dev, struct rtc_time *tm)
82 {
83 	struct armada38x_rtc *rtc = dev_get_drvdata(dev);
84 	int ret = 0;
85 	unsigned long time, flags;
86 
87 	ret = rtc_tm_to_time(tm, &time);
88 
89 	if (ret)
90 		goto out;
91 	/*
92 	 * Setting the RTC time not always succeeds. According to the
93 	 * errata we need to first write on the status register and
94 	 * then wait for 100ms before writing to the time register to be
95 	 * sure that the data will be taken into account.
96 	 */
97 	spin_lock_irqsave(&rtc->lock, flags);
98 
99 	rtc_delayed_write(0, rtc, RTC_STATUS);
100 
101 	spin_unlock_irqrestore(&rtc->lock, flags);
102 
103 	msleep(100);
104 
105 	spin_lock_irqsave(&rtc->lock, flags);
106 
107 	rtc_delayed_write(time, rtc, RTC_TIME);
108 
109 	spin_unlock_irqrestore(&rtc->lock, flags);
110 out:
111 	return ret;
112 }
113 
114 static int armada38x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
115 {
116 	struct armada38x_rtc *rtc = dev_get_drvdata(dev);
117 	unsigned long time, flags;
118 	u32 val;
119 
120 	spin_lock_irqsave(&rtc->lock, flags);
121 
122 	time = readl(rtc->regs + RTC_ALARM1);
123 	val = readl(rtc->regs + RTC_IRQ1_CONF) & RTC_IRQ1_AL_EN;
124 
125 	spin_unlock_irqrestore(&rtc->lock, flags);
126 
127 	alrm->enabled = val ? 1 : 0;
128 	rtc_time_to_tm(time,  &alrm->time);
129 
130 	return 0;
131 }
132 
133 static int armada38x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
134 {
135 	struct armada38x_rtc *rtc = dev_get_drvdata(dev);
136 	unsigned long time, flags;
137 	int ret = 0;
138 	u32 val;
139 
140 	ret = rtc_tm_to_time(&alrm->time, &time);
141 
142 	if (ret)
143 		goto out;
144 
145 	spin_lock_irqsave(&rtc->lock, flags);
146 
147 	rtc_delayed_write(time, rtc, RTC_ALARM1);
148 
149 	if (alrm->enabled) {
150 			rtc_delayed_write(RTC_IRQ1_AL_EN, rtc, RTC_IRQ1_CONF);
151 			val = readl(rtc->regs_soc + SOC_RTC_INTERRUPT);
152 			writel(val | SOC_RTC_ALARM1_MASK,
153 			       rtc->regs_soc + SOC_RTC_INTERRUPT);
154 	}
155 
156 	spin_unlock_irqrestore(&rtc->lock, flags);
157 
158 out:
159 	return ret;
160 }
161 
162 static int armada38x_rtc_alarm_irq_enable(struct device *dev,
163 					 unsigned int enabled)
164 {
165 	struct armada38x_rtc *rtc = dev_get_drvdata(dev);
166 	unsigned long flags;
167 
168 	spin_lock_irqsave(&rtc->lock, flags);
169 
170 	if (enabled)
171 		rtc_delayed_write(RTC_IRQ1_AL_EN, rtc, RTC_IRQ1_CONF);
172 	else
173 		rtc_delayed_write(0, rtc, RTC_IRQ1_CONF);
174 
175 	spin_unlock_irqrestore(&rtc->lock, flags);
176 
177 	return 0;
178 }
179 
180 static irqreturn_t armada38x_rtc_alarm_irq(int irq, void *data)
181 {
182 	struct armada38x_rtc *rtc = data;
183 	u32 val;
184 	int event = RTC_IRQF | RTC_AF;
185 
186 	dev_dbg(&rtc->rtc_dev->dev, "%s:irq(%d)\n", __func__, irq);
187 
188 	spin_lock(&rtc->lock);
189 
190 	val = readl(rtc->regs_soc + SOC_RTC_INTERRUPT);
191 
192 	writel(val & ~SOC_RTC_ALARM1, rtc->regs_soc + SOC_RTC_INTERRUPT);
193 	val = readl(rtc->regs + RTC_IRQ1_CONF);
194 	/* disable all the interrupts for alarm 1 */
195 	rtc_delayed_write(0, rtc, RTC_IRQ1_CONF);
196 	/* Ack the event */
197 	rtc_delayed_write(RTC_STATUS_ALARM1, rtc, RTC_STATUS);
198 
199 	spin_unlock(&rtc->lock);
200 
201 	if (val & RTC_IRQ1_FREQ_EN) {
202 		if (val & RTC_IRQ1_FREQ_1HZ)
203 			event |= RTC_UF;
204 		else
205 			event |= RTC_PF;
206 	}
207 
208 	rtc_update_irq(rtc->rtc_dev, 1, event);
209 
210 	return IRQ_HANDLED;
211 }
212 
213 static struct rtc_class_ops armada38x_rtc_ops = {
214 	.read_time = armada38x_rtc_read_time,
215 	.set_time = armada38x_rtc_set_time,
216 	.read_alarm = armada38x_rtc_read_alarm,
217 	.set_alarm = armada38x_rtc_set_alarm,
218 	.alarm_irq_enable = armada38x_rtc_alarm_irq_enable,
219 };
220 
221 static __init int armada38x_rtc_probe(struct platform_device *pdev)
222 {
223 	struct resource *res;
224 	struct armada38x_rtc *rtc;
225 	int ret;
226 
227 	rtc = devm_kzalloc(&pdev->dev, sizeof(struct armada38x_rtc),
228 			    GFP_KERNEL);
229 	if (!rtc)
230 		return -ENOMEM;
231 
232 	spin_lock_init(&rtc->lock);
233 
234 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rtc");
235 	rtc->regs = devm_ioremap_resource(&pdev->dev, res);
236 	if (IS_ERR(rtc->regs))
237 		return PTR_ERR(rtc->regs);
238 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rtc-soc");
239 	rtc->regs_soc = devm_ioremap_resource(&pdev->dev, res);
240 	if (IS_ERR(rtc->regs_soc))
241 		return PTR_ERR(rtc->regs_soc);
242 
243 	rtc->irq = platform_get_irq(pdev, 0);
244 
245 	if (rtc->irq < 0) {
246 		dev_err(&pdev->dev, "no irq\n");
247 		return rtc->irq;
248 	}
249 	if (devm_request_irq(&pdev->dev, rtc->irq, armada38x_rtc_alarm_irq,
250 				0, pdev->name, rtc) < 0) {
251 		dev_warn(&pdev->dev, "Interrupt not available.\n");
252 		rtc->irq = -1;
253 		/*
254 		 * If there is no interrupt available then we can't
255 		 * use the alarm
256 		 */
257 		armada38x_rtc_ops.set_alarm = NULL;
258 		armada38x_rtc_ops.alarm_irq_enable = NULL;
259 	}
260 	platform_set_drvdata(pdev, rtc);
261 	if (rtc->irq != -1)
262 		device_init_wakeup(&pdev->dev, 1);
263 
264 	rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
265 					&armada38x_rtc_ops, THIS_MODULE);
266 	if (IS_ERR(rtc->rtc_dev)) {
267 		ret = PTR_ERR(rtc->rtc_dev);
268 		dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
269 		return ret;
270 	}
271 	return 0;
272 }
273 
274 #ifdef CONFIG_PM_SLEEP
275 static int armada38x_rtc_suspend(struct device *dev)
276 {
277 	if (device_may_wakeup(dev)) {
278 		struct armada38x_rtc *rtc = dev_get_drvdata(dev);
279 
280 		return enable_irq_wake(rtc->irq);
281 	}
282 
283 	return 0;
284 }
285 
286 static int armada38x_rtc_resume(struct device *dev)
287 {
288 	if (device_may_wakeup(dev)) {
289 		struct armada38x_rtc *rtc = dev_get_drvdata(dev);
290 
291 		return disable_irq_wake(rtc->irq);
292 	}
293 
294 	return 0;
295 }
296 #endif
297 
298 static SIMPLE_DEV_PM_OPS(armada38x_rtc_pm_ops,
299 			 armada38x_rtc_suspend, armada38x_rtc_resume);
300 
301 #ifdef CONFIG_OF
302 static const struct of_device_id armada38x_rtc_of_match_table[] = {
303 	{ .compatible = "marvell,armada-380-rtc", },
304 	{}
305 };
306 #endif
307 
308 static struct platform_driver armada38x_rtc_driver = {
309 	.driver		= {
310 		.name	= "armada38x-rtc",
311 		.pm	= &armada38x_rtc_pm_ops,
312 		.of_match_table = of_match_ptr(armada38x_rtc_of_match_table),
313 	},
314 };
315 
316 module_platform_driver_probe(armada38x_rtc_driver, armada38x_rtc_probe);
317 
318 MODULE_DESCRIPTION("Marvell Armada 38x RTC driver");
319 MODULE_AUTHOR("Gregory CLEMENT <gregory.clement@free-electrons.com>");
320 MODULE_LICENSE("GPL");
321