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"
19 struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info); in ocelot_ptp_gettime64() local
25 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_gettime64()
27 val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN); in ocelot_ptp_gettime64()
30 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN); in ocelot_ptp_gettime64()
32 s = ocelot_read_rix(ocelot, PTP_PIN_TOD_SEC_MSB, TOD_ACC_PIN) & 0xffff; in ocelot_ptp_gettime64()
34 s += ocelot_read_rix(ocelot, PTP_PIN_TOD_SEC_LSB, TOD_ACC_PIN); in ocelot_ptp_gettime64()
35 ns = ocelot_read_rix(ocelot, PTP_PIN_TOD_NSEC, TOD_ACC_PIN); in ocelot_ptp_gettime64()
37 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_gettime64()
54 struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info); in ocelot_ptp_settime64() local
58 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_settime64()
60 val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN); in ocelot_ptp_settime64()
64 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN); in ocelot_ptp_settime64()
66 ocelot_write_rix(ocelot, lower_32_bits(ts->tv_sec), PTP_PIN_TOD_SEC_LSB, in ocelot_ptp_settime64()
68 ocelot_write_rix(ocelot, upper_32_bits(ts->tv_sec), PTP_PIN_TOD_SEC_MSB, in ocelot_ptp_settime64()
70 ocelot_write_rix(ocelot, ts->tv_nsec, PTP_PIN_TOD_NSEC, TOD_ACC_PIN); in ocelot_ptp_settime64()
72 val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN); in ocelot_ptp_settime64()
76 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN); in ocelot_ptp_settime64()
78 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_settime64()
80 if (ocelot->ops->tas_clock_adjust) in ocelot_ptp_settime64()
81 ocelot->ops->tas_clock_adjust(ocelot); in ocelot_ptp_settime64()
90 struct ocelot *ocelot = container_of(ptp, struct ocelot, in ocelot_ptp_adjtime() local
95 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_adjtime()
97 val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN); in ocelot_ptp_adjtime()
102 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN); in ocelot_ptp_adjtime()
104 ocelot_write_rix(ocelot, 0, PTP_PIN_TOD_SEC_LSB, TOD_ACC_PIN); in ocelot_ptp_adjtime()
105 ocelot_write_rix(ocelot, 0, PTP_PIN_TOD_SEC_MSB, TOD_ACC_PIN); in ocelot_ptp_adjtime()
106 ocelot_write_rix(ocelot, delta, PTP_PIN_TOD_NSEC, TOD_ACC_PIN); in ocelot_ptp_adjtime()
108 val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN); in ocelot_ptp_adjtime()
113 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN); in ocelot_ptp_adjtime()
115 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_adjtime()
117 if (ocelot->ops->tas_clock_adjust) in ocelot_ptp_adjtime()
118 ocelot->ops->tas_clock_adjust(ocelot); in ocelot_ptp_adjtime()
138 struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info); in ocelot_ptp_adjfine() local
143 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_adjfine()
167 ocelot_write(ocelot, unit | adj, PTP_CLK_CFG_ADJ_FREQ); in ocelot_ptp_adjfine()
168 ocelot_write(ocelot, PTP_CFG_CLK_ADJ_CFG_ENA | direction, in ocelot_ptp_adjfine()
171 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_adjfine()
175 ocelot_write(ocelot, 0, PTP_CLK_CFG_ADJ_CFG); in ocelot_ptp_adjfine()
177 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_adjfine()
200 struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info); in ocelot_ptp_enable() local
217 pin = ptp_find_pin(ocelot->ptp_clock, PTP_PF_PEROUT, in ocelot_ptp_enable()
238 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_enable()
240 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, ptp_pin); in ocelot_ptp_enable()
241 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_enable()
254 dev_warn(ocelot->dev, in ocelot_ptp_enable()
256 dev_warn(ocelot->dev, in ocelot_ptp_enable()
283 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_enable()
284 ocelot_write_rix(ocelot, ts_phase.tv_nsec, in ocelot_ptp_enable()
286 ocelot_write_rix(ocelot, wf_high, in ocelot_ptp_enable()
290 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, ptp_pin); in ocelot_ptp_enable()
291 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_enable()
301 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_enable()
302 ocelot_write_rix(ocelot, wf_low, PTP_PIN_WF_LOW_PERIOD, in ocelot_ptp_enable()
304 ocelot_write_rix(ocelot, wf_high, PTP_PIN_WF_HIGH_PERIOD, in ocelot_ptp_enable()
307 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, ptp_pin); in ocelot_ptp_enable()
308 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_enable()
364 static int ocelot_l2_ptp_trap_add(struct ocelot *ocelot, int port) in ocelot_l2_ptp_trap_add() argument
366 unsigned long l2_cookie = OCELOT_VCAP_IS2_L2_PTP_TRAP(ocelot); in ocelot_l2_ptp_trap_add()
368 return ocelot_trap_add(ocelot, port, l2_cookie, true, in ocelot_l2_ptp_trap_add()
372 static int ocelot_l2_ptp_trap_del(struct ocelot *ocelot, int port) in ocelot_l2_ptp_trap_del() argument
374 unsigned long l2_cookie = OCELOT_VCAP_IS2_L2_PTP_TRAP(ocelot); in ocelot_l2_ptp_trap_del()
376 return ocelot_trap_del(ocelot, port, l2_cookie); in ocelot_l2_ptp_trap_del()
379 static int ocelot_ipv4_ptp_trap_add(struct ocelot *ocelot, int port) in ocelot_ipv4_ptp_trap_add() argument
381 unsigned long ipv4_gen_cookie = OCELOT_VCAP_IS2_IPV4_GEN_PTP_TRAP(ocelot); in ocelot_ipv4_ptp_trap_add()
382 unsigned long ipv4_ev_cookie = OCELOT_VCAP_IS2_IPV4_EV_PTP_TRAP(ocelot); in ocelot_ipv4_ptp_trap_add()
385 err = ocelot_trap_add(ocelot, port, ipv4_ev_cookie, true, in ocelot_ipv4_ptp_trap_add()
390 err = ocelot_trap_add(ocelot, port, ipv4_gen_cookie, false, in ocelot_ipv4_ptp_trap_add()
393 ocelot_trap_del(ocelot, port, ipv4_ev_cookie); in ocelot_ipv4_ptp_trap_add()
398 static int ocelot_ipv4_ptp_trap_del(struct ocelot *ocelot, int port) in ocelot_ipv4_ptp_trap_del() argument
400 unsigned long ipv4_gen_cookie = OCELOT_VCAP_IS2_IPV4_GEN_PTP_TRAP(ocelot); in ocelot_ipv4_ptp_trap_del()
401 unsigned long ipv4_ev_cookie = OCELOT_VCAP_IS2_IPV4_EV_PTP_TRAP(ocelot); in ocelot_ipv4_ptp_trap_del()
404 err = ocelot_trap_del(ocelot, port, ipv4_ev_cookie); in ocelot_ipv4_ptp_trap_del()
405 err |= ocelot_trap_del(ocelot, port, ipv4_gen_cookie); in ocelot_ipv4_ptp_trap_del()
409 static int ocelot_ipv6_ptp_trap_add(struct ocelot *ocelot, int port) in ocelot_ipv6_ptp_trap_add() argument
411 unsigned long ipv6_gen_cookie = OCELOT_VCAP_IS2_IPV6_GEN_PTP_TRAP(ocelot); in ocelot_ipv6_ptp_trap_add()
412 unsigned long ipv6_ev_cookie = OCELOT_VCAP_IS2_IPV6_EV_PTP_TRAP(ocelot); in ocelot_ipv6_ptp_trap_add()
415 err = ocelot_trap_add(ocelot, port, ipv6_ev_cookie, true, in ocelot_ipv6_ptp_trap_add()
420 err = ocelot_trap_add(ocelot, port, ipv6_gen_cookie, false, in ocelot_ipv6_ptp_trap_add()
423 ocelot_trap_del(ocelot, port, ipv6_ev_cookie); in ocelot_ipv6_ptp_trap_add()
428 static int ocelot_ipv6_ptp_trap_del(struct ocelot *ocelot, int port) in ocelot_ipv6_ptp_trap_del() argument
430 unsigned long ipv6_gen_cookie = OCELOT_VCAP_IS2_IPV6_GEN_PTP_TRAP(ocelot); in ocelot_ipv6_ptp_trap_del()
431 unsigned long ipv6_ev_cookie = OCELOT_VCAP_IS2_IPV6_EV_PTP_TRAP(ocelot); in ocelot_ipv6_ptp_trap_del()
434 err = ocelot_trap_del(ocelot, port, ipv6_ev_cookie); in ocelot_ipv6_ptp_trap_del()
435 err |= ocelot_trap_del(ocelot, port, ipv6_gen_cookie); in ocelot_ipv6_ptp_trap_del()
439 static int ocelot_setup_ptp_traps(struct ocelot *ocelot, int port, in ocelot_setup_ptp_traps() argument
442 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_setup_ptp_traps()
449 err = ocelot_l2_ptp_trap_add(ocelot, port); in ocelot_setup_ptp_traps()
451 err = ocelot_l2_ptp_trap_del(ocelot, port); in ocelot_setup_ptp_traps()
456 err = ocelot_ipv4_ptp_trap_add(ocelot, port); in ocelot_setup_ptp_traps()
460 err = ocelot_ipv6_ptp_trap_add(ocelot, port); in ocelot_setup_ptp_traps()
464 err = ocelot_ipv4_ptp_trap_del(ocelot, port); in ocelot_setup_ptp_traps()
466 err |= ocelot_ipv6_ptp_trap_del(ocelot, port); in ocelot_setup_ptp_traps()
479 ocelot_ipv4_ptp_trap_del(ocelot, port); in ocelot_setup_ptp_traps()
482 ocelot_l2_ptp_trap_del(ocelot, port); in ocelot_setup_ptp_traps()
498 int ocelot_hwstamp_get(struct ocelot *ocelot, int port, struct ifreq *ifr) in ocelot_hwstamp_get() argument
500 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_hwstamp_get()
521 int ocelot_hwstamp_set(struct ocelot *ocelot, int port, struct ifreq *ifr) in ocelot_hwstamp_set() argument
523 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_hwstamp_set()
572 err = ocelot_setup_ptp_traps(ocelot, port, l2, l4); in ocelot_hwstamp_set()
582 int ocelot_get_ts_info(struct ocelot *ocelot, int port, in ocelot_get_ts_info() argument
585 if (ocelot->ptp_clock) { in ocelot_get_ts_info()
586 info->phc_index = ptp_clock_index(ocelot->ptp_clock); in ocelot_get_ts_info()
606 static int ocelot_port_add_txtstamp_skb(struct ocelot *ocelot, int port, in ocelot_port_add_txtstamp_skb() argument
609 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_port_add_txtstamp_skb()
612 spin_lock_irqsave(&ocelot->ts_id_lock, flags); in ocelot_port_add_txtstamp_skb()
615 ocelot->ptp_skbs_in_flight == OCELOT_PTP_FIFO_SIZE) { in ocelot_port_add_txtstamp_skb()
616 spin_unlock_irqrestore(&ocelot->ts_id_lock, flags); in ocelot_port_add_txtstamp_skb()
629 ocelot->ptp_skbs_in_flight++; in ocelot_port_add_txtstamp_skb()
633 spin_unlock_irqrestore(&ocelot->ts_id_lock, flags); in ocelot_port_add_txtstamp_skb()
657 int ocelot_port_txtstamp_request(struct ocelot *ocelot, int port, in ocelot_port_txtstamp_request() argument
661 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_port_txtstamp_request()
690 err = ocelot_port_add_txtstamp_skb(ocelot, port, *clone); in ocelot_port_txtstamp_request()
702 static void ocelot_get_hwtimestamp(struct ocelot *ocelot, in ocelot_get_hwtimestamp() argument
708 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags); in ocelot_get_hwtimestamp()
711 val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN); in ocelot_get_hwtimestamp()
715 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN); in ocelot_get_hwtimestamp()
716 ts->tv_sec = ocelot_read_rix(ocelot, PTP_PIN_TOD_SEC_LSB, TOD_ACC_PIN); in ocelot_get_hwtimestamp()
719 val = ocelot_read(ocelot, SYS_PTP_TXSTAMP); in ocelot_get_hwtimestamp()
726 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags); in ocelot_get_hwtimestamp()
740 void ocelot_get_txtstamp(struct ocelot *ocelot) in ocelot_get_txtstamp() argument
752 val = ocelot_read(ocelot, SYS_PTP_STATUS); in ocelot_get_txtstamp()
765 port = ocelot->ports[txport]; in ocelot_get_txtstamp()
767 spin_lock(&ocelot->ts_id_lock); in ocelot_get_txtstamp()
769 ocelot->ptp_skbs_in_flight--; in ocelot_get_txtstamp()
770 spin_unlock(&ocelot->ts_id_lock); in ocelot_get_txtstamp()
790 dev_err_ratelimited(ocelot->dev, in ocelot_get_txtstamp()
798 ocelot_get_hwtimestamp(ocelot, &ts); in ocelot_get_txtstamp()
806 ocelot_write(ocelot, SYS_PTP_NXT_PTP_NXT, SYS_PTP_NXT); in ocelot_get_txtstamp()
811 int ocelot_init_timestamp(struct ocelot *ocelot, in ocelot_init_timestamp() argument
817 ocelot->ptp_info = *info; in ocelot_init_timestamp()
820 struct ptp_pin_desc *p = &ocelot->ptp_pins[i]; in ocelot_init_timestamp()
827 ocelot->ptp_info.pin_config = &ocelot->ptp_pins[0]; in ocelot_init_timestamp()
829 ptp_clock = ptp_clock_register(&ocelot->ptp_info, ocelot->dev); in ocelot_init_timestamp()
836 ocelot->ptp_clock = ptp_clock; in ocelot_init_timestamp()
838 ocelot_write(ocelot, SYS_PTP_CFG_PTP_STAMP_WID(30), SYS_PTP_CFG); in ocelot_init_timestamp()
839 ocelot_write(ocelot, 0xffffffff, ANA_TABLES_PTP_ID_LOW); in ocelot_init_timestamp()
840 ocelot_write(ocelot, 0xffffffff, ANA_TABLES_PTP_ID_HIGH); in ocelot_init_timestamp()
842 ocelot_write(ocelot, PTP_CFG_MISC_PTP_EN, PTP_CFG_MISC); in ocelot_init_timestamp()
848 int ocelot_deinit_timestamp(struct ocelot *ocelot) in ocelot_deinit_timestamp() argument
850 if (ocelot->ptp_clock) in ocelot_deinit_timestamp()
851 ptp_clock_unregister(ocelot->ptp_clock); in ocelot_deinit_timestamp()