diff options
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/common.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwmac1000.h | 7 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c | 40 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/hwif.c | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c | 11 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h | 4 |
6 files changed, 65 insertions, 2 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index 6f68a6b298c9..1367fa5c9b8e 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -549,6 +549,7 @@ extern const struct stmmac_desc_ops ndesc_ops; struct mac_device_info; extern const struct stmmac_hwtimestamp stmmac_ptp; +extern const struct stmmac_hwtimestamp dwmac1000_ptp; extern const struct stmmac_mode_ops dwmac4_ring_mode_ops; extern const struct ptp_clock_info stmmac_ptp_clock_ops; diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h index 01eafeb1272f..600fea8f712f 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h @@ -331,8 +331,15 @@ enum rtc_control { /* PTP and timestamping registers */ +#define GMAC3_X_ATSNS GENMASK(19, 16) +#define GMAC3_X_ATSNS_SHIFT 16 + #define GMAC_PTP_TCR_ATSFC BIT(24) #define GMAC_PTP_TCR_ATSEN0 BIT(25) +#define GMAC3_X_TIMESTAMP_STATUS 0x28 +#define GMAC_PTP_ATNR 0x30 +#define GMAC_PTP_ATSR 0x34 + extern const struct stmmac_dma_ops dwmac1000_dma_ops; #endif /* __DWMAC1000_H__ */ diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c index a14509d88fe7..73bba4fdc2e4 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c @@ -553,6 +553,46 @@ int dwmac1000_setup(struct stmmac_priv *priv) return 0; } +/* DWMAC 1000 HW Timestaming ops */ + +void dwmac1000_get_ptptime(void __iomem *ptpaddr, u64 *ptp_time) +{ + u64 ns; + + ns = readl(ptpaddr + GMAC_PTP_ATNR); + ns += readl(ptpaddr + GMAC_PTP_ATSR) * NSEC_PER_SEC; + + *ptp_time = ns; +} + +void dwmac1000_timestamp_interrupt(struct stmmac_priv *priv) +{ + struct ptp_clock_event event; + u32 ts_status, num_snapshot; + unsigned long flags; + u64 ptp_time; + int i; + + /* Clears the timestamp interrupt */ + ts_status = readl(priv->ptpaddr + GMAC3_X_TIMESTAMP_STATUS); + + if (!(priv->plat->flags & STMMAC_FLAG_EXT_SNAPSHOT_EN)) + return; + + num_snapshot = (ts_status & GMAC3_X_ATSNS) >> GMAC3_X_ATSNS_SHIFT; + + for (i = 0; i < num_snapshot; i++) { + read_lock_irqsave(&priv->ptp_lock, flags); + stmmac_get_ptptime(priv, priv->ptpaddr, &ptp_time); + read_unlock_irqrestore(&priv->ptp_lock, flags); + + event.type = PTP_CLOCK_EXTTS; + event.index = 0; + event.timestamp = ptp_time; + ptp_clock_event(priv->ptp_clock, &event); + } +} + /* DWMAC 1000 ptp_clock_info ops */ int dwmac1000_ptp_enable(struct ptp_clock_info *ptp, diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.c b/drivers/net/ethernet/stmicro/stmmac/hwif.c index 1f508843fb5a..a72d336a8350 100644 --- a/drivers/net/ethernet/stmicro/stmmac/hwif.c +++ b/drivers/net/ethernet/stmicro/stmmac/hwif.c @@ -134,7 +134,7 @@ static const struct stmmac_hwif_entry { .desc = NULL, .dma = &dwmac100_dma_ops, .mac = &dwmac100_ops, - .hwtimestamp = &stmmac_ptp, + .hwtimestamp = &dwmac1000_ptp, .ptp = &dwmac1000_ptp_clock_ops, .mode = NULL, .tc = NULL, @@ -153,7 +153,7 @@ static const struct stmmac_hwif_entry { .desc = NULL, .dma = &dwmac1000_dma_ops, .mac = &dwmac1000_ops, - .hwtimestamp = &stmmac_ptp, + .hwtimestamp = &dwmac1000_ptp, .ptp = &dwmac1000_ptp_clock_ops, .mode = NULL, .tc = NULL, diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c index 5ef52ef2698f..a94829ef8cfb 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c @@ -269,3 +269,14 @@ const struct stmmac_hwtimestamp stmmac_ptp = { .timestamp_interrupt = timestamp_interrupt, .hwtstamp_correct_latency = hwtstamp_correct_latency, }; + +const struct stmmac_hwtimestamp dwmac1000_ptp = { + .config_hw_tstamping = config_hw_tstamping, + .init_systime = init_systime, + .config_sub_second_increment = config_sub_second_increment, + .config_addend = config_addend, + .adjust_systime = adjust_systime, + .get_systime = get_systime, + .get_ptptime = dwmac1000_get_ptptime, + .timestamp_interrupt = dwmac1000_timestamp_interrupt, +}; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h index fa4611855311..4cc70480ce0f 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h @@ -96,8 +96,12 @@ enum aux_snapshot { struct ptp_clock_info; struct ptp_clock_request; +struct stmmac_priv; int dwmac1000_ptp_enable(struct ptp_clock_info *ptp, struct ptp_clock_request *rq, int on); +void dwmac1000_get_ptptime(void __iomem *ptpaddr, u64 *ptp_time); +void dwmac1000_timestamp_interrupt(struct stmmac_priv *priv); + #endif /* __STMMAC_PTP_H__ */ |