20 #include <linux/device.h>
21 #include <linux/hrtimer.h>
24 #include <linux/kernel.h>
25 #include <linux/module.h>
28 #include <linux/timex.h>
76 #define TCLK_PERIOD_SHIFT (16)
77 #define TCLK_PERIOD_MASK (0x3ff)
89 #define CKSEL_SHIFT (0)
90 #define CKSEL_MASK (0x3)
102 #define ETS2EN (1<<25)
103 #define ETS1EN (1<<24)
104 #define ALM2EN (1<<17)
105 #define ALM1EN (1<<16)
115 #define TXP2EN (1<<9)
116 #define TXP1EN (1<<8)
120 #define STAT_VEC_SHIFT (0)
121 #define STAT_VEC_MASK (0x3f)
124 #define PRSC_OCK_SHIFT (0)
125 #define PRSC_OCK_MASK (0xffff)
128 #define DRIVER "gianfar_ptp"
129 #define DEFAULT_CKSEL 1
132 #define REG_SIZE sizeof(struct gianfar_ptp_registers)
161 lo = gfar_read(&etsects->
regs->tmr_cnt_l);
162 hi = gfar_read(&etsects->
regs->tmr_cnt_h);
163 ns = ((
u64) hi) << 32;
172 u32 lo = ns & 0xffffffff;
174 gfar_write(&etsects->
regs->tmr_cnt_l, lo);
175 gfar_write(&etsects->
regs->tmr_cnt_h, hi);
184 ns = tmr_cnt_read(etsects) + 1500000000ULL;
185 ns = div_u64(ns, 1000000000
UL) * 1000000000ULL;
188 lo = ns & 0xffffffff;
189 gfar_write(&etsects->
regs->tmr_alarm1_l, lo);
190 gfar_write(&etsects->
regs->tmr_alarm1_h, hi);
212 val = gfar_read(&etsects->
regs->tmr_tevent);
216 hi = gfar_read(&etsects->
regs->tmr_etts1_h);
217 lo = gfar_read(&etsects->
regs->tmr_etts1_l);
220 event.timestamp = ((
u64) hi) << 32;
221 event.timestamp |=
lo;
227 hi = gfar_read(&etsects->
regs->tmr_etts2_h);
228 lo = gfar_read(&etsects->
regs->tmr_etts2_l);
231 event.timestamp = ((
u64) hi) << 32;
232 event.timestamp |=
lo;
247 lo = ns & 0xffffffff;
248 spin_lock(&etsects->
lock);
249 gfar_write(&etsects->
regs->tmr_alarm2_l, lo);
250 gfar_write(&etsects->
regs->tmr_alarm2_h, hi);
251 spin_unlock(&etsects->
lock);
254 gfar_write(&etsects->
regs->tmr_tevent, ALM2);
255 spin_lock(&etsects->
lock);
256 mask = gfar_read(&etsects->
regs->tmr_temask);
258 gfar_write(&etsects->
regs->tmr_temask, mask);
259 spin_unlock(&etsects->
lock);
272 gfar_write(&etsects->
regs->tmr_tevent, ack);
296 diff = div_u64(adj, 1000000000ULL);
298 tmr_add = neg_adj ? tmr_add - diff : tmr_add + diff;
300 gfar_write(&etsects->
regs->tmr_add, tmr_add);
313 now = tmr_cnt_read(etsects);
315 tmr_cnt_write(etsects, now);
317 spin_unlock_irqrestore(&etsects->
lock, flags);
333 ns = tmr_cnt_read(etsects);
335 spin_unlock_irqrestore(&etsects->
lock, flags);
337 ts->
tv_sec = div_u64_rem(ns, 1000000000, &remainder);
349 ns = ts->
tv_sec * 1000000000ULL;
354 tmr_cnt_write(etsects, ns);
357 spin_unlock_irqrestore(&etsects->
lock, flags);
370 case PTP_CLK_REQ_EXTTS:
371 switch (rq->
extts.index) {
382 mask = gfar_read(&etsects->
regs->tmr_temask);
387 gfar_write(&etsects->
regs->tmr_temask, mask);
388 spin_unlock_irqrestore(&etsects->
lock, flags);
391 case PTP_CLK_REQ_PPS:
393 mask = gfar_read(&etsects->
regs->tmr_temask);
398 gfar_write(&etsects->
regs->tmr_temask, mask);
399 spin_unlock_irqrestore(&etsects->
lock, flags);
411 .name =
"gianfar clock",
417 .adjfreq = ptp_gianfar_adjfreq,
418 .adjtime = ptp_gianfar_adjtime,
419 .gettime = ptp_gianfar_gettime,
420 .settime = ptp_gianfar_settime,
421 .enable = ptp_gianfar_enable,
431 if (!prop || plen !=
sizeof(*prop))
440 struct etsects *etsects;
446 etsects = kzalloc(
sizeof(*etsects),
GFP_KERNEL);
452 etsects->
caps = ptp_gianfar_caps;
455 if (get_of_u32(node,
"fsl,tclk-period", &etsects->
tclk_period) ||
456 get_of_u32(node,
"fsl,tmr-prsc", &etsects->
tmr_prsc) ||
457 get_of_u32(node,
"fsl,tmr-add", &etsects->
tmr_add) ||
458 get_of_u32(node,
"fsl,tmr-fiper1", &etsects->
tmr_fiper1) ||
459 get_of_u32(node,
"fsl,tmr-fiper2", &etsects->
tmr_fiper2) ||
460 get_of_u32(node,
"fsl,max-adj", &etsects->
caps.max_adj)) {
461 pr_err(
"device tree node missing required elements\n");
468 pr_err(
"irq not in device tree\n");
472 pr_err(
"request_irq failed\n");
477 if (!etsects->
rsrc) {
482 pr_err(
"resource busy\n");
489 resource_size(etsects->
rsrc));
490 if (!etsects->
regs) {
491 pr_err(
"ioremap ptp registers failed\n");
495 ptp_gianfar_settime(&etsects->
caps, &now);
503 gfar_write(&etsects->
regs->tmr_ctrl, tmr_ctrl);
504 gfar_write(&etsects->
regs->tmr_add, etsects->
tmr_add);
505 gfar_write(&etsects->
regs->tmr_prsc, etsects->
tmr_prsc);
511 spin_unlock_irqrestore(&etsects->
lock, flags);
514 if (IS_ERR(etsects->
clock)) {
515 err = PTR_ERR(etsects->
clock);
539 gfar_write(&etsects->
regs->tmr_temask, 0);
540 gfar_write(&etsects->
regs->tmr_ctrl, 0);
553 { .compatible =
"fsl,etsec-ptp" },
559 .name =
"gianfar_ptp",
560 .of_match_table = match_table,
563 .probe = gianfar_ptp_probe,
564 .remove = gianfar_ptp_remove,