Lines Matching full:ocelot
2 /* Microsemi Ocelot PTP clock driver
9 #include <linux/dsa/ocelot.h>
14 #include <soc/mscc/ocelot.h>
15 #include "ocelot.h"
21 struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info); in ocelot_ptp_gettime64() local
27 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_gettime64()
29 val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN); in ocelot_ptp_gettime64()
32 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN); in ocelot_ptp_gettime64()
34 s = ocelot_read_rix(ocelot, PTP_PIN_TOD_SEC_MSB, TOD_ACC_PIN) & 0xffff; in ocelot_ptp_gettime64()
36 s += ocelot_read_rix(ocelot, PTP_PIN_TOD_SEC_LSB, TOD_ACC_PIN); in ocelot_ptp_gettime64()
37 ns = ocelot_read_rix(ocelot, PTP_PIN_TOD_NSEC, TOD_ACC_PIN); in ocelot_ptp_gettime64()
39 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_gettime64()
56 struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info); in ocelot_ptp_settime64() local
60 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_settime64()
62 val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN); in ocelot_ptp_settime64()
66 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN); in ocelot_ptp_settime64()
68 ocelot_write_rix(ocelot, lower_32_bits(ts->tv_sec), PTP_PIN_TOD_SEC_LSB, in ocelot_ptp_settime64()
70 ocelot_write_rix(ocelot, upper_32_bits(ts->tv_sec), PTP_PIN_TOD_SEC_MSB, in ocelot_ptp_settime64()
72 ocelot_write_rix(ocelot, ts->tv_nsec, PTP_PIN_TOD_NSEC, TOD_ACC_PIN); in ocelot_ptp_settime64()
74 val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN); in ocelot_ptp_settime64()
78 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN); in ocelot_ptp_settime64()
80 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_settime64()
82 if (ocelot->ops->tas_clock_adjust) in ocelot_ptp_settime64()
83 ocelot->ops->tas_clock_adjust(ocelot); in ocelot_ptp_settime64()
92 struct ocelot *ocelot = container_of(ptp, struct ocelot, in ocelot_ptp_adjtime() local
97 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_adjtime()
99 val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN); in ocelot_ptp_adjtime()
104 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN); in ocelot_ptp_adjtime()
106 ocelot_write_rix(ocelot, 0, PTP_PIN_TOD_SEC_LSB, TOD_ACC_PIN); in ocelot_ptp_adjtime()
107 ocelot_write_rix(ocelot, 0, PTP_PIN_TOD_SEC_MSB, TOD_ACC_PIN); in ocelot_ptp_adjtime()
108 ocelot_write_rix(ocelot, delta, PTP_PIN_TOD_NSEC, TOD_ACC_PIN); in ocelot_ptp_adjtime()
110 val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN); in ocelot_ptp_adjtime()
115 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN); in ocelot_ptp_adjtime()
117 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_adjtime()
119 if (ocelot->ops->tas_clock_adjust) in ocelot_ptp_adjtime()
120 ocelot->ops->tas_clock_adjust(ocelot); in ocelot_ptp_adjtime()
140 struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info); in ocelot_ptp_adjfine() local
145 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_adjfine()
169 ocelot_write(ocelot, unit | adj, PTP_CLK_CFG_ADJ_FREQ); in ocelot_ptp_adjfine()
170 ocelot_write(ocelot, PTP_CFG_CLK_ADJ_CFG_ENA | direction, in ocelot_ptp_adjfine()
173 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_adjfine()
177 ocelot_write(ocelot, 0, PTP_CLK_CFG_ADJ_CFG); in ocelot_ptp_adjfine()
179 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_adjfine()
202 struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info); in ocelot_ptp_enable() local
219 pin = ptp_find_pin(ocelot->ptp_clock, PTP_PF_PEROUT, in ocelot_ptp_enable()
240 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_enable()
242 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, ptp_pin); in ocelot_ptp_enable()
243 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_enable()
256 dev_warn(ocelot->dev, in ocelot_ptp_enable()
258 dev_warn(ocelot->dev, in ocelot_ptp_enable()
285 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_enable()
286 ocelot_write_rix(ocelot, ts_phase.tv_nsec, in ocelot_ptp_enable()
288 ocelot_write_rix(ocelot, wf_high, in ocelot_ptp_enable()
292 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, ptp_pin); in ocelot_ptp_enable()
293 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_enable()
303 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_enable()
304 ocelot_write_rix(ocelot, wf_low, PTP_PIN_WF_LOW_PERIOD, in ocelot_ptp_enable()
306 ocelot_write_rix(ocelot, wf_high, PTP_PIN_WF_HIGH_PERIOD, in ocelot_ptp_enable()
309 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, ptp_pin); in ocelot_ptp_enable()
310 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_enable()
366 static int ocelot_l2_ptp_trap_add(struct ocelot *ocelot, int port) in ocelot_l2_ptp_trap_add() argument
368 unsigned long l2_cookie = OCELOT_VCAP_IS2_L2_PTP_TRAP(ocelot); in ocelot_l2_ptp_trap_add()
370 return ocelot_trap_add(ocelot, port, l2_cookie, true, in ocelot_l2_ptp_trap_add()
374 static int ocelot_l2_ptp_trap_del(struct ocelot *ocelot, int port) in ocelot_l2_ptp_trap_del() argument
376 unsigned long l2_cookie = OCELOT_VCAP_IS2_L2_PTP_TRAP(ocelot); in ocelot_l2_ptp_trap_del()
378 return ocelot_trap_del(ocelot, port, l2_cookie); in ocelot_l2_ptp_trap_del()
381 static int ocelot_ipv4_ptp_trap_add(struct ocelot *ocelot, int port) in ocelot_ipv4_ptp_trap_add() argument
383 unsigned long ipv4_gen_cookie = OCELOT_VCAP_IS2_IPV4_GEN_PTP_TRAP(ocelot); in ocelot_ipv4_ptp_trap_add()
384 unsigned long ipv4_ev_cookie = OCELOT_VCAP_IS2_IPV4_EV_PTP_TRAP(ocelot); in ocelot_ipv4_ptp_trap_add()
387 err = ocelot_trap_add(ocelot, port, ipv4_ev_cookie, true, in ocelot_ipv4_ptp_trap_add()
392 err = ocelot_trap_add(ocelot, port, ipv4_gen_cookie, false, in ocelot_ipv4_ptp_trap_add()
395 ocelot_trap_del(ocelot, port, ipv4_ev_cookie); in ocelot_ipv4_ptp_trap_add()
400 static int ocelot_ipv4_ptp_trap_del(struct ocelot *ocelot, int port) in ocelot_ipv4_ptp_trap_del() argument
402 unsigned long ipv4_gen_cookie = OCELOT_VCAP_IS2_IPV4_GEN_PTP_TRAP(ocelot); in ocelot_ipv4_ptp_trap_del()
403 unsigned long ipv4_ev_cookie = OCELOT_VCAP_IS2_IPV4_EV_PTP_TRAP(ocelot); in ocelot_ipv4_ptp_trap_del()
406 err = ocelot_trap_del(ocelot, port, ipv4_ev_cookie); in ocelot_ipv4_ptp_trap_del()
407 err |= ocelot_trap_del(ocelot, port, ipv4_gen_cookie); in ocelot_ipv4_ptp_trap_del()
411 static int ocelot_ipv6_ptp_trap_add(struct ocelot *ocelot, int port) in ocelot_ipv6_ptp_trap_add() argument
413 unsigned long ipv6_gen_cookie = OCELOT_VCAP_IS2_IPV6_GEN_PTP_TRAP(ocelot); in ocelot_ipv6_ptp_trap_add()
414 unsigned long ipv6_ev_cookie = OCELOT_VCAP_IS2_IPV6_EV_PTP_TRAP(ocelot); in ocelot_ipv6_ptp_trap_add()
417 err = ocelot_trap_add(ocelot, port, ipv6_ev_cookie, true, in ocelot_ipv6_ptp_trap_add()
422 err = ocelot_trap_add(ocelot, port, ipv6_gen_cookie, false, in ocelot_ipv6_ptp_trap_add()
425 ocelot_trap_del(ocelot, port, ipv6_ev_cookie); in ocelot_ipv6_ptp_trap_add()
430 static int ocelot_ipv6_ptp_trap_del(struct ocelot *ocelot, int port) in ocelot_ipv6_ptp_trap_del() argument
432 unsigned long ipv6_gen_cookie = OCELOT_VCAP_IS2_IPV6_GEN_PTP_TRAP(ocelot); in ocelot_ipv6_ptp_trap_del()
433 unsigned long ipv6_ev_cookie = OCELOT_VCAP_IS2_IPV6_EV_PTP_TRAP(ocelot); in ocelot_ipv6_ptp_trap_del()
436 err = ocelot_trap_del(ocelot, port, ipv6_ev_cookie); in ocelot_ipv6_ptp_trap_del()
437 err |= ocelot_trap_del(ocelot, port, ipv6_gen_cookie); in ocelot_ipv6_ptp_trap_del()
441 static int ocelot_setup_ptp_traps(struct ocelot *ocelot, int port, in ocelot_setup_ptp_traps() argument
444 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_setup_ptp_traps()
451 err = ocelot_l2_ptp_trap_add(ocelot, port); in ocelot_setup_ptp_traps()
453 err = ocelot_l2_ptp_trap_del(ocelot, port); in ocelot_setup_ptp_traps()
458 err = ocelot_ipv4_ptp_trap_add(ocelot, port); in ocelot_setup_ptp_traps()
462 err = ocelot_ipv6_ptp_trap_add(ocelot, port); in ocelot_setup_ptp_traps()
466 err = ocelot_ipv4_ptp_trap_del(ocelot, port); in ocelot_setup_ptp_traps()
468 err |= ocelot_ipv6_ptp_trap_del(ocelot, port); in ocelot_setup_ptp_traps()
481 ocelot_ipv4_ptp_trap_del(ocelot, port); in ocelot_setup_ptp_traps()
484 ocelot_l2_ptp_trap_del(ocelot, port); in ocelot_setup_ptp_traps()
522 int ocelot_hwstamp_get(struct ocelot *ocelot, int port, struct ifreq *ifr) in ocelot_hwstamp_get() argument
524 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_hwstamp_get()
545 int ocelot_hwstamp_set(struct ocelot *ocelot, int port, struct ifreq *ifr) in ocelot_hwstamp_set() argument
547 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_hwstamp_set()
588 err = ocelot_setup_ptp_traps(ocelot, port, l2, l4); in ocelot_hwstamp_set()
603 ocelot_setup_ptp_traps(ocelot, port, old_l2, old_l4); in ocelot_hwstamp_set()
609 int ocelot_get_ts_info(struct ocelot *ocelot, int port, in ocelot_get_ts_info() argument
612 if (ocelot->ptp_clock) { in ocelot_get_ts_info()
613 info->phc_index = ptp_clock_index(ocelot->ptp_clock); in ocelot_get_ts_info()
633 static struct sk_buff *ocelot_port_dequeue_ptp_tx_skb(struct ocelot *ocelot, in ocelot_port_dequeue_ptp_tx_skb() argument
637 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_port_dequeue_ptp_tx_skb()
641 spin_lock(&ocelot->ts_id_lock); in ocelot_port_dequeue_ptp_tx_skb()
656 ocelot->ptp_skbs_in_flight--; in ocelot_port_dequeue_ptp_tx_skb()
661 spin_unlock(&ocelot->ts_id_lock); in ocelot_port_dequeue_ptp_tx_skb()
666 static int ocelot_port_queue_ptp_tx_skb(struct ocelot *ocelot, int port, in ocelot_port_queue_ptp_tx_skb() argument
669 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_port_queue_ptp_tx_skb()
674 spin_lock(&ocelot->ts_id_lock); in ocelot_port_queue_ptp_tx_skb()
687 dev_dbg_ratelimited(ocelot->dev, in ocelot_port_queue_ptp_tx_skb()
693 ocelot->ptp_skbs_in_flight--; in ocelot_port_queue_ptp_tx_skb()
699 if (ocelot->ptp_skbs_in_flight == OCELOT_PTP_FIFO_SIZE) { in ocelot_port_queue_ptp_tx_skb()
700 spin_unlock(&ocelot->ts_id_lock); in ocelot_port_queue_ptp_tx_skb()
706 spin_unlock(&ocelot->ts_id_lock); in ocelot_port_queue_ptp_tx_skb()
713 ocelot->ptp_skbs_in_flight++; in ocelot_port_queue_ptp_tx_skb()
716 spin_unlock(&ocelot->ts_id_lock); in ocelot_port_queue_ptp_tx_skb()
718 dev_dbg_ratelimited(ocelot->dev, "port %d timestamp id %lu\n", port, n); in ocelot_port_queue_ptp_tx_skb()
742 int ocelot_port_txtstamp_request(struct ocelot *ocelot, int port, in ocelot_port_txtstamp_request() argument
746 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_port_txtstamp_request()
785 err = ocelot_port_queue_ptp_tx_skb(ocelot, port, *clone); in ocelot_port_txtstamp_request()
806 static void ocelot_get_hwtimestamp(struct ocelot *ocelot, in ocelot_get_hwtimestamp() argument
812 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags); in ocelot_get_hwtimestamp()
815 val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN); in ocelot_get_hwtimestamp()
819 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN); in ocelot_get_hwtimestamp()
820 ts->tv_sec = ocelot_read_rix(ocelot, PTP_PIN_TOD_SEC_LSB, TOD_ACC_PIN); in ocelot_get_hwtimestamp()
823 val = ocelot_read(ocelot, SYS_PTP_TXSTAMP); in ocelot_get_hwtimestamp()
830 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags); in ocelot_get_hwtimestamp()
833 void ocelot_get_txtstamp(struct ocelot *ocelot) in ocelot_get_txtstamp() argument
844 val = ocelot_read(ocelot, SYS_PTP_STATUS); in ocelot_get_txtstamp()
856 ocelot_port = ocelot->ports[txport]; in ocelot_get_txtstamp()
859 skb_match = ocelot_port_dequeue_ptp_tx_skb(ocelot, txport, id, in ocelot_get_txtstamp()
866 dev_dbg_ratelimited(ocelot->dev, in ocelot_get_txtstamp()
878 ocelot_get_hwtimestamp(ocelot, &ts); in ocelot_get_txtstamp()
886 ocelot_write(ocelot, SYS_PTP_NXT_PTP_NXT, SYS_PTP_NXT); in ocelot_get_txtstamp()
891 int ocelot_init_timestamp(struct ocelot *ocelot, in ocelot_init_timestamp() argument
897 ocelot->ptp_info = *info; in ocelot_init_timestamp()
900 struct ptp_pin_desc *p = &ocelot->ptp_pins[i]; in ocelot_init_timestamp()
907 ocelot->ptp_info.pin_config = &ocelot->ptp_pins[0]; in ocelot_init_timestamp()
909 ptp_clock = ptp_clock_register(&ocelot->ptp_info, ocelot->dev); in ocelot_init_timestamp()
916 ocelot->ptp_clock = ptp_clock; in ocelot_init_timestamp()
918 ocelot_write(ocelot, SYS_PTP_CFG_PTP_STAMP_WID(30), SYS_PTP_CFG); in ocelot_init_timestamp()
919 ocelot_write(ocelot, 0xffffffff, ANA_TABLES_PTP_ID_LOW); in ocelot_init_timestamp()
920 ocelot_write(ocelot, 0xffffffff, ANA_TABLES_PTP_ID_HIGH); in ocelot_init_timestamp()
922 ocelot_write(ocelot, PTP_CFG_MISC_PTP_EN, PTP_CFG_MISC); in ocelot_init_timestamp()
928 int ocelot_deinit_timestamp(struct ocelot *ocelot) in ocelot_deinit_timestamp() argument
930 if (ocelot->ptp_clock) in ocelot_deinit_timestamp()
931 ptp_clock_unregister(ocelot->ptp_clock); in ocelot_deinit_timestamp()