net: stmmac: Introduce dwmac1000 timestamping operations

In GMAC3_X, the timestamping configuration differs from GMAC4 in the
layout of the registers accessed to grab the number of snapshots in FIFO
as well as the register offset to grab the aux snapshot timestamp.

Introduce dedicated ops to configure timestamping on dwmac100 and
dwmac1000. The latency correction doesn't seem to exist on GMAC3, so its
corresponding operation isn't populated.

Reviewed-by: Daniel Machon <daniel.machon@microchip.com>
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Link: https://patch.msgid.link/20241112170658.2388529-6-maxime.chevallier@bootlin.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Maxime Chevallier 2024-11-12 18:06:53 +01:00 committed by Jakub Kicinski
parent 8e7620726b
commit 477c3e1f63
6 changed files with 65 additions and 2 deletions

View file

@ -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;

View file

@ -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__ */

View file

@ -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,

View file

@ -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,

View file

@ -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,
};

View file

@ -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__ */