xref: /openbmc/linux/drivers/ptp/ptp_qoriq.c (revision ba61bb17)
1 /*
2  * PTP 1588 clock for Freescale QorIQ 1588 timer
3  *
4  * Copyright (C) 2010 OMICRON electronics GmbH
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */
20 
21 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
22 
23 #include <linux/device.h>
24 #include <linux/hrtimer.h>
25 #include <linux/interrupt.h>
26 #include <linux/kernel.h>
27 #include <linux/module.h>
28 #include <linux/of.h>
29 #include <linux/of_platform.h>
30 #include <linux/timex.h>
31 #include <linux/slab.h>
32 
33 #include <linux/fsl/ptp_qoriq.h>
34 
35 /*
36  * Register access functions
37  */
38 
39 /* Caller must hold qoriq_ptp->lock. */
40 static u64 tmr_cnt_read(struct qoriq_ptp *qoriq_ptp)
41 {
42 	u64 ns;
43 	u32 lo, hi;
44 
45 	lo = qoriq_read(&qoriq_ptp->regs->tmr_cnt_l);
46 	hi = qoriq_read(&qoriq_ptp->regs->tmr_cnt_h);
47 	ns = ((u64) hi) << 32;
48 	ns |= lo;
49 	return ns;
50 }
51 
52 /* Caller must hold qoriq_ptp->lock. */
53 static void tmr_cnt_write(struct qoriq_ptp *qoriq_ptp, u64 ns)
54 {
55 	u32 hi = ns >> 32;
56 	u32 lo = ns & 0xffffffff;
57 
58 	qoriq_write(&qoriq_ptp->regs->tmr_cnt_l, lo);
59 	qoriq_write(&qoriq_ptp->regs->tmr_cnt_h, hi);
60 }
61 
62 /* Caller must hold qoriq_ptp->lock. */
63 static void set_alarm(struct qoriq_ptp *qoriq_ptp)
64 {
65 	u64 ns;
66 	u32 lo, hi;
67 
68 	ns = tmr_cnt_read(qoriq_ptp) + 1500000000ULL;
69 	ns = div_u64(ns, 1000000000UL) * 1000000000ULL;
70 	ns -= qoriq_ptp->tclk_period;
71 	hi = ns >> 32;
72 	lo = ns & 0xffffffff;
73 	qoriq_write(&qoriq_ptp->regs->tmr_alarm1_l, lo);
74 	qoriq_write(&qoriq_ptp->regs->tmr_alarm1_h, hi);
75 }
76 
77 /* Caller must hold qoriq_ptp->lock. */
78 static void set_fipers(struct qoriq_ptp *qoriq_ptp)
79 {
80 	set_alarm(qoriq_ptp);
81 	qoriq_write(&qoriq_ptp->regs->tmr_fiper1, qoriq_ptp->tmr_fiper1);
82 	qoriq_write(&qoriq_ptp->regs->tmr_fiper2, qoriq_ptp->tmr_fiper2);
83 }
84 
85 /*
86  * Interrupt service routine
87  */
88 
89 static irqreturn_t isr(int irq, void *priv)
90 {
91 	struct qoriq_ptp *qoriq_ptp = priv;
92 	struct ptp_clock_event event;
93 	u64 ns;
94 	u32 ack = 0, lo, hi, mask, val;
95 
96 	val = qoriq_read(&qoriq_ptp->regs->tmr_tevent);
97 
98 	if (val & ETS1) {
99 		ack |= ETS1;
100 		hi = qoriq_read(&qoriq_ptp->regs->tmr_etts1_h);
101 		lo = qoriq_read(&qoriq_ptp->regs->tmr_etts1_l);
102 		event.type = PTP_CLOCK_EXTTS;
103 		event.index = 0;
104 		event.timestamp = ((u64) hi) << 32;
105 		event.timestamp |= lo;
106 		ptp_clock_event(qoriq_ptp->clock, &event);
107 	}
108 
109 	if (val & ETS2) {
110 		ack |= ETS2;
111 		hi = qoriq_read(&qoriq_ptp->regs->tmr_etts2_h);
112 		lo = qoriq_read(&qoriq_ptp->regs->tmr_etts2_l);
113 		event.type = PTP_CLOCK_EXTTS;
114 		event.index = 1;
115 		event.timestamp = ((u64) hi) << 32;
116 		event.timestamp |= lo;
117 		ptp_clock_event(qoriq_ptp->clock, &event);
118 	}
119 
120 	if (val & ALM2) {
121 		ack |= ALM2;
122 		if (qoriq_ptp->alarm_value) {
123 			event.type = PTP_CLOCK_ALARM;
124 			event.index = 0;
125 			event.timestamp = qoriq_ptp->alarm_value;
126 			ptp_clock_event(qoriq_ptp->clock, &event);
127 		}
128 		if (qoriq_ptp->alarm_interval) {
129 			ns = qoriq_ptp->alarm_value + qoriq_ptp->alarm_interval;
130 			hi = ns >> 32;
131 			lo = ns & 0xffffffff;
132 			spin_lock(&qoriq_ptp->lock);
133 			qoriq_write(&qoriq_ptp->regs->tmr_alarm2_l, lo);
134 			qoriq_write(&qoriq_ptp->regs->tmr_alarm2_h, hi);
135 			spin_unlock(&qoriq_ptp->lock);
136 			qoriq_ptp->alarm_value = ns;
137 		} else {
138 			qoriq_write(&qoriq_ptp->regs->tmr_tevent, ALM2);
139 			spin_lock(&qoriq_ptp->lock);
140 			mask = qoriq_read(&qoriq_ptp->regs->tmr_temask);
141 			mask &= ~ALM2EN;
142 			qoriq_write(&qoriq_ptp->regs->tmr_temask, mask);
143 			spin_unlock(&qoriq_ptp->lock);
144 			qoriq_ptp->alarm_value = 0;
145 			qoriq_ptp->alarm_interval = 0;
146 		}
147 	}
148 
149 	if (val & PP1) {
150 		ack |= PP1;
151 		event.type = PTP_CLOCK_PPS;
152 		ptp_clock_event(qoriq_ptp->clock, &event);
153 	}
154 
155 	if (ack) {
156 		qoriq_write(&qoriq_ptp->regs->tmr_tevent, ack);
157 		return IRQ_HANDLED;
158 	} else
159 		return IRQ_NONE;
160 }
161 
162 /*
163  * PTP clock operations
164  */
165 
166 static int ptp_qoriq_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
167 {
168 	u64 adj, diff;
169 	u32 tmr_add;
170 	int neg_adj = 0;
171 	struct qoriq_ptp *qoriq_ptp = container_of(ptp, struct qoriq_ptp, caps);
172 
173 	if (scaled_ppm < 0) {
174 		neg_adj = 1;
175 		scaled_ppm = -scaled_ppm;
176 	}
177 	tmr_add = qoriq_ptp->tmr_add;
178 	adj = tmr_add;
179 
180 	/* calculate diff as adj*(scaled_ppm/65536)/1000000
181 	 * and round() to the nearest integer
182 	 */
183 	adj *= scaled_ppm;
184 	diff = div_u64(adj, 8000000);
185 	diff = (diff >> 13) + ((diff >> 12) & 1);
186 
187 	tmr_add = neg_adj ? tmr_add - diff : tmr_add + diff;
188 
189 	qoriq_write(&qoriq_ptp->regs->tmr_add, tmr_add);
190 
191 	return 0;
192 }
193 
194 static int ptp_qoriq_adjtime(struct ptp_clock_info *ptp, s64 delta)
195 {
196 	s64 now;
197 	unsigned long flags;
198 	struct qoriq_ptp *qoriq_ptp = container_of(ptp, struct qoriq_ptp, caps);
199 
200 	spin_lock_irqsave(&qoriq_ptp->lock, flags);
201 
202 	now = tmr_cnt_read(qoriq_ptp);
203 	now += delta;
204 	tmr_cnt_write(qoriq_ptp, now);
205 	set_fipers(qoriq_ptp);
206 
207 	spin_unlock_irqrestore(&qoriq_ptp->lock, flags);
208 
209 	return 0;
210 }
211 
212 static int ptp_qoriq_gettime(struct ptp_clock_info *ptp,
213 			       struct timespec64 *ts)
214 {
215 	u64 ns;
216 	unsigned long flags;
217 	struct qoriq_ptp *qoriq_ptp = container_of(ptp, struct qoriq_ptp, caps);
218 
219 	spin_lock_irqsave(&qoriq_ptp->lock, flags);
220 
221 	ns = tmr_cnt_read(qoriq_ptp);
222 
223 	spin_unlock_irqrestore(&qoriq_ptp->lock, flags);
224 
225 	*ts = ns_to_timespec64(ns);
226 
227 	return 0;
228 }
229 
230 static int ptp_qoriq_settime(struct ptp_clock_info *ptp,
231 			       const struct timespec64 *ts)
232 {
233 	u64 ns;
234 	unsigned long flags;
235 	struct qoriq_ptp *qoriq_ptp = container_of(ptp, struct qoriq_ptp, caps);
236 
237 	ns = timespec64_to_ns(ts);
238 
239 	spin_lock_irqsave(&qoriq_ptp->lock, flags);
240 
241 	tmr_cnt_write(qoriq_ptp, ns);
242 	set_fipers(qoriq_ptp);
243 
244 	spin_unlock_irqrestore(&qoriq_ptp->lock, flags);
245 
246 	return 0;
247 }
248 
249 static int ptp_qoriq_enable(struct ptp_clock_info *ptp,
250 			      struct ptp_clock_request *rq, int on)
251 {
252 	struct qoriq_ptp *qoriq_ptp = container_of(ptp, struct qoriq_ptp, caps);
253 	unsigned long flags;
254 	u32 bit, mask;
255 
256 	switch (rq->type) {
257 	case PTP_CLK_REQ_EXTTS:
258 		switch (rq->extts.index) {
259 		case 0:
260 			bit = ETS1EN;
261 			break;
262 		case 1:
263 			bit = ETS2EN;
264 			break;
265 		default:
266 			return -EINVAL;
267 		}
268 		spin_lock_irqsave(&qoriq_ptp->lock, flags);
269 		mask = qoriq_read(&qoriq_ptp->regs->tmr_temask);
270 		if (on)
271 			mask |= bit;
272 		else
273 			mask &= ~bit;
274 		qoriq_write(&qoriq_ptp->regs->tmr_temask, mask);
275 		spin_unlock_irqrestore(&qoriq_ptp->lock, flags);
276 		return 0;
277 
278 	case PTP_CLK_REQ_PPS:
279 		spin_lock_irqsave(&qoriq_ptp->lock, flags);
280 		mask = qoriq_read(&qoriq_ptp->regs->tmr_temask);
281 		if (on)
282 			mask |= PP1EN;
283 		else
284 			mask &= ~PP1EN;
285 		qoriq_write(&qoriq_ptp->regs->tmr_temask, mask);
286 		spin_unlock_irqrestore(&qoriq_ptp->lock, flags);
287 		return 0;
288 
289 	default:
290 		break;
291 	}
292 
293 	return -EOPNOTSUPP;
294 }
295 
296 static const struct ptp_clock_info ptp_qoriq_caps = {
297 	.owner		= THIS_MODULE,
298 	.name		= "qoriq ptp clock",
299 	.max_adj	= 512000,
300 	.n_alarm	= 0,
301 	.n_ext_ts	= N_EXT_TS,
302 	.n_per_out	= 0,
303 	.n_pins		= 0,
304 	.pps		= 1,
305 	.adjfine	= ptp_qoriq_adjfine,
306 	.adjtime	= ptp_qoriq_adjtime,
307 	.gettime64	= ptp_qoriq_gettime,
308 	.settime64	= ptp_qoriq_settime,
309 	.enable		= ptp_qoriq_enable,
310 };
311 
312 static int qoriq_ptp_probe(struct platform_device *dev)
313 {
314 	struct device_node *node = dev->dev.of_node;
315 	struct qoriq_ptp *qoriq_ptp;
316 	struct timespec64 now;
317 	int err = -ENOMEM;
318 	u32 tmr_ctrl;
319 	unsigned long flags;
320 
321 	qoriq_ptp = kzalloc(sizeof(*qoriq_ptp), GFP_KERNEL);
322 	if (!qoriq_ptp)
323 		goto no_memory;
324 
325 	err = -ENODEV;
326 
327 	qoriq_ptp->caps = ptp_qoriq_caps;
328 
329 	if (of_property_read_u32(node, "fsl,cksel", &qoriq_ptp->cksel))
330 		qoriq_ptp->cksel = DEFAULT_CKSEL;
331 
332 	if (of_property_read_u32(node,
333 				 "fsl,tclk-period", &qoriq_ptp->tclk_period) ||
334 	    of_property_read_u32(node,
335 				 "fsl,tmr-prsc", &qoriq_ptp->tmr_prsc) ||
336 	    of_property_read_u32(node,
337 				 "fsl,tmr-add", &qoriq_ptp->tmr_add) ||
338 	    of_property_read_u32(node,
339 				 "fsl,tmr-fiper1", &qoriq_ptp->tmr_fiper1) ||
340 	    of_property_read_u32(node,
341 				 "fsl,tmr-fiper2", &qoriq_ptp->tmr_fiper2) ||
342 	    of_property_read_u32(node,
343 				 "fsl,max-adj", &qoriq_ptp->caps.max_adj)) {
344 		pr_err("device tree node missing required elements\n");
345 		goto no_node;
346 	}
347 
348 	qoriq_ptp->irq = platform_get_irq(dev, 0);
349 
350 	if (qoriq_ptp->irq < 0) {
351 		pr_err("irq not in device tree\n");
352 		goto no_node;
353 	}
354 	if (request_irq(qoriq_ptp->irq, isr, 0, DRIVER, qoriq_ptp)) {
355 		pr_err("request_irq failed\n");
356 		goto no_node;
357 	}
358 
359 	qoriq_ptp->rsrc = platform_get_resource(dev, IORESOURCE_MEM, 0);
360 	if (!qoriq_ptp->rsrc) {
361 		pr_err("no resource\n");
362 		goto no_resource;
363 	}
364 	if (request_resource(&iomem_resource, qoriq_ptp->rsrc)) {
365 		pr_err("resource busy\n");
366 		goto no_resource;
367 	}
368 
369 	spin_lock_init(&qoriq_ptp->lock);
370 
371 	qoriq_ptp->regs = ioremap(qoriq_ptp->rsrc->start,
372 				resource_size(qoriq_ptp->rsrc));
373 	if (!qoriq_ptp->regs) {
374 		pr_err("ioremap ptp registers failed\n");
375 		goto no_ioremap;
376 	}
377 	ktime_get_real_ts64(&now);
378 	ptp_qoriq_settime(&qoriq_ptp->caps, &now);
379 
380 	tmr_ctrl =
381 	  (qoriq_ptp->tclk_period & TCLK_PERIOD_MASK) << TCLK_PERIOD_SHIFT |
382 	  (qoriq_ptp->cksel & CKSEL_MASK) << CKSEL_SHIFT;
383 
384 	spin_lock_irqsave(&qoriq_ptp->lock, flags);
385 
386 	qoriq_write(&qoriq_ptp->regs->tmr_ctrl,   tmr_ctrl);
387 	qoriq_write(&qoriq_ptp->regs->tmr_add,    qoriq_ptp->tmr_add);
388 	qoriq_write(&qoriq_ptp->regs->tmr_prsc,   qoriq_ptp->tmr_prsc);
389 	qoriq_write(&qoriq_ptp->regs->tmr_fiper1, qoriq_ptp->tmr_fiper1);
390 	qoriq_write(&qoriq_ptp->regs->tmr_fiper2, qoriq_ptp->tmr_fiper2);
391 	set_alarm(qoriq_ptp);
392 	qoriq_write(&qoriq_ptp->regs->tmr_ctrl,   tmr_ctrl|FIPERST|RTPE|TE|FRD);
393 
394 	spin_unlock_irqrestore(&qoriq_ptp->lock, flags);
395 
396 	qoriq_ptp->clock = ptp_clock_register(&qoriq_ptp->caps, &dev->dev);
397 	if (IS_ERR(qoriq_ptp->clock)) {
398 		err = PTR_ERR(qoriq_ptp->clock);
399 		goto no_clock;
400 	}
401 	qoriq_ptp->phc_index = ptp_clock_index(qoriq_ptp->clock);
402 
403 	platform_set_drvdata(dev, qoriq_ptp);
404 
405 	return 0;
406 
407 no_clock:
408 	iounmap(qoriq_ptp->regs);
409 no_ioremap:
410 	release_resource(qoriq_ptp->rsrc);
411 no_resource:
412 	free_irq(qoriq_ptp->irq, qoriq_ptp);
413 no_node:
414 	kfree(qoriq_ptp);
415 no_memory:
416 	return err;
417 }
418 
419 static int qoriq_ptp_remove(struct platform_device *dev)
420 {
421 	struct qoriq_ptp *qoriq_ptp = platform_get_drvdata(dev);
422 
423 	qoriq_write(&qoriq_ptp->regs->tmr_temask, 0);
424 	qoriq_write(&qoriq_ptp->regs->tmr_ctrl,   0);
425 
426 	ptp_clock_unregister(qoriq_ptp->clock);
427 	iounmap(qoriq_ptp->regs);
428 	release_resource(qoriq_ptp->rsrc);
429 	free_irq(qoriq_ptp->irq, qoriq_ptp);
430 	kfree(qoriq_ptp);
431 
432 	return 0;
433 }
434 
435 static const struct of_device_id match_table[] = {
436 	{ .compatible = "fsl,etsec-ptp" },
437 	{},
438 };
439 MODULE_DEVICE_TABLE(of, match_table);
440 
441 static struct platform_driver qoriq_ptp_driver = {
442 	.driver = {
443 		.name		= "ptp_qoriq",
444 		.of_match_table	= match_table,
445 	},
446 	.probe       = qoriq_ptp_probe,
447 	.remove      = qoriq_ptp_remove,
448 };
449 
450 module_platform_driver(qoriq_ptp_driver);
451 
452 MODULE_AUTHOR("Richard Cochran <richardcochran@gmail.com>");
453 MODULE_DESCRIPTION("PTP clock for Freescale QorIQ 1588 timer");
454 MODULE_LICENSE("GPL");
455