|
18 | 18 | #include <linux/io.h> |
19 | 19 | #include "stmmac.h" |
20 | 20 | #include "stmmac_pcs.h" |
| 21 | +#include "stmmac_ptp.h" |
21 | 22 | #include "dwmac1000.h" |
22 | 23 |
|
23 | 24 | static void dwmac1000_core_init(struct mac_device_info *hw, |
@@ -551,3 +552,47 @@ int dwmac1000_setup(struct stmmac_priv *priv) |
551 | 552 |
|
552 | 553 | return 0; |
553 | 554 | } |
| 555 | + |
| 556 | +/* DWMAC 1000 ptp_clock_info ops */ |
| 557 | + |
| 558 | +int dwmac1000_ptp_enable(struct ptp_clock_info *ptp, |
| 559 | + struct ptp_clock_request *rq, int on) |
| 560 | +{ |
| 561 | + struct stmmac_priv *priv = |
| 562 | + container_of(ptp, struct stmmac_priv, ptp_clock_ops); |
| 563 | + void __iomem *ptpaddr = priv->ptpaddr; |
| 564 | + int ret = -EOPNOTSUPP; |
| 565 | + u32 tcr_val; |
| 566 | + |
| 567 | + switch (rq->type) { |
| 568 | + case PTP_CLK_REQ_EXTTS: |
| 569 | + mutex_lock(&priv->aux_ts_lock); |
| 570 | + tcr_val = readl(ptpaddr + PTP_TCR); |
| 571 | + |
| 572 | + if (on) { |
| 573 | + tcr_val |= GMAC_PTP_TCR_ATSEN0; |
| 574 | + tcr_val |= GMAC_PTP_TCR_ATSFC; |
| 575 | + priv->plat->flags |= STMMAC_FLAG_EXT_SNAPSHOT_EN; |
| 576 | + } else { |
| 577 | + tcr_val &= ~GMAC_PTP_TCR_ATSEN0; |
| 578 | + priv->plat->flags &= ~STMMAC_FLAG_EXT_SNAPSHOT_EN; |
| 579 | + } |
| 580 | + |
| 581 | + netdev_dbg(priv->dev, "Auxiliary Snapshot %s.\n", |
| 582 | + on ? "enabled" : "disabled"); |
| 583 | + writel(tcr_val, ptpaddr + PTP_TCR); |
| 584 | + |
| 585 | + /* wait for auxts fifo clear to finish */ |
| 586 | + ret = readl_poll_timeout(ptpaddr + PTP_TCR, tcr_val, |
| 587 | + !(tcr_val & GMAC_PTP_TCR_ATSFC), |
| 588 | + 10, 10000); |
| 589 | + |
| 590 | + mutex_unlock(&priv->aux_ts_lock); |
| 591 | + break; |
| 592 | + |
| 593 | + default: |
| 594 | + break; |
| 595 | + } |
| 596 | + |
| 597 | + return ret; |
| 598 | +} |
0 commit comments