net: stmmac: Introduce dwmac1000 ptp_clock_info and operations

The PTP configuration for GMAC3_X differs from the other implementations
in several ways :

 - There's only one external snapshot trigger
 - The snapshot configuration is done through the PTP_TCR register,
   whereas the other dwmac variants have a dedicated ACR (auxiliary
   control reg) for that purpose
 - The layout for the PTP_TCR register also differs, as bits 24/25 are
   used for the snapshot configuration. These bits are reserved on other
   variants.

On GMAC3_X, we also can't discover the number of snapshot triggers
automatically.

The GMAC3_X has one PPS output, however it's configuration isn't
supported yet so report 0 n_per_out for now.

Introduce a dedicated set of ptp_clock_info ops and configuration
parameters to reflect these differences specific to GMAC3_X.

This was tested on dwmac_socfpga.

Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Link: https://patch.msgid.link/20241112170658.2388529-5-maxime.chevallier@bootlin.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Maxime Chevallier 2024-11-12 18:06:52 +01:00 committed by Jakub Kicinski
parent 0bfd0afc74
commit 8e7620726b
6 changed files with 77 additions and 2 deletions

View File

@ -552,6 +552,7 @@ extern const struct stmmac_hwtimestamp stmmac_ptp;
extern const struct stmmac_mode_ops dwmac4_ring_mode_ops;
extern const struct ptp_clock_info stmmac_ptp_clock_ops;
extern const struct ptp_clock_info dwmac1000_ptp_clock_ops;
struct mac_link {
u32 caps;

View File

@ -329,5 +329,10 @@ enum rtc_control {
#define GMAC_MMC_RX_CSUM_OFFLOAD 0x208
#define GMAC_EXTHASH_BASE 0x500
/* PTP and timestamping registers */
#define GMAC_PTP_TCR_ATSFC BIT(24)
#define GMAC_PTP_TCR_ATSEN0 BIT(25)
extern const struct stmmac_dma_ops dwmac1000_dma_ops;
#endif /* __DWMAC1000_H__ */

View File

@ -18,6 +18,7 @@
#include <linux/io.h>
#include "stmmac.h"
#include "stmmac_pcs.h"
#include "stmmac_ptp.h"
#include "dwmac1000.h"
static void dwmac1000_core_init(struct mac_device_info *hw,
@ -551,3 +552,47 @@ int dwmac1000_setup(struct stmmac_priv *priv)
return 0;
}
/* DWMAC 1000 ptp_clock_info ops */
int dwmac1000_ptp_enable(struct ptp_clock_info *ptp,
struct ptp_clock_request *rq, int on)
{
struct stmmac_priv *priv =
container_of(ptp, struct stmmac_priv, ptp_clock_ops);
void __iomem *ptpaddr = priv->ptpaddr;
int ret = -EOPNOTSUPP;
u32 tcr_val;
switch (rq->type) {
case PTP_CLK_REQ_EXTTS:
mutex_lock(&priv->aux_ts_lock);
tcr_val = readl(ptpaddr + PTP_TCR);
if (on) {
tcr_val |= GMAC_PTP_TCR_ATSEN0;
tcr_val |= GMAC_PTP_TCR_ATSFC;
priv->plat->flags |= STMMAC_FLAG_EXT_SNAPSHOT_EN;
} else {
tcr_val &= ~GMAC_PTP_TCR_ATSEN0;
priv->plat->flags &= ~STMMAC_FLAG_EXT_SNAPSHOT_EN;
}
netdev_dbg(priv->dev, "Auxiliary Snapshot %s.\n",
on ? "enabled" : "disabled");
writel(tcr_val, ptpaddr + PTP_TCR);
/* wait for auxts fifo clear to finish */
ret = readl_poll_timeout(ptpaddr + PTP_TCR, tcr_val,
!(tcr_val & GMAC_PTP_TCR_ATSFC),
10, 10000);
mutex_unlock(&priv->aux_ts_lock);
break;
default:
break;
}
return ret;
}

View File

@ -135,7 +135,7 @@ static const struct stmmac_hwif_entry {
.dma = &dwmac100_dma_ops,
.mac = &dwmac100_ops,
.hwtimestamp = &stmmac_ptp,
.ptp = &stmmac_ptp_clock_ops,
.ptp = &dwmac1000_ptp_clock_ops,
.mode = NULL,
.tc = NULL,
.mmc = &dwmac_mmc_ops,
@ -154,7 +154,7 @@ static const struct stmmac_hwif_entry {
.dma = &dwmac1000_dma_ops,
.mac = &dwmac1000_ops,
.hwtimestamp = &stmmac_ptp,
.ptp = &stmmac_ptp_clock_ops,
.ptp = &dwmac1000_ptp_clock_ops,
.mode = NULL,
.tc = NULL,
.mmc = &dwmac_mmc_ops,

View File

@ -282,6 +282,24 @@ const struct ptp_clock_info stmmac_ptp_clock_ops = {
.getcrosststamp = stmmac_getcrosststamp,
};
/* structure describing a PTP hardware clock */
const struct ptp_clock_info dwmac1000_ptp_clock_ops = {
.owner = THIS_MODULE,
.name = "stmmac ptp",
.max_adj = 62500000,
.n_alarm = 0,
.n_ext_ts = 1,
.n_per_out = 0,
.n_pins = 0,
.pps = 0,
.adjfine = stmmac_adjust_freq,
.adjtime = stmmac_adjust_time,
.gettime64 = stmmac_get_time,
.settime64 = stmmac_set_time,
.enable = dwmac1000_ptp_enable,
.getcrosststamp = stmmac_getcrosststamp,
};
/**
* stmmac_ptp_register
* @priv: driver private structure

View File

@ -94,4 +94,10 @@ enum aux_snapshot {
AUX_SNAPSHOT3 = 0x80,
};
struct ptp_clock_info;
struct ptp_clock_request;
int dwmac1000_ptp_enable(struct ptp_clock_info *ptp,
struct ptp_clock_request *rq, int on);
#endif /* __STMMAC_PTP_H__ */