]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
net: stmmac: Introduce dwmac1000 ptp_clock_info and operations
authorMaxime Chevallier <maxime.chevallier@bootlin.com>
Tue, 12 Nov 2024 17:06:52 +0000 (18:06 +0100)
committerJakub Kicinski <kuba@kernel.org>
Thu, 14 Nov 2024 02:52:13 +0000 (18:52 -0800)
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>
drivers/net/ethernet/stmicro/stmmac/common.h
drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
drivers/net/ethernet/stmicro/stmmac/hwif.c
drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h

index 4a0a1708c391360891c7375b4a8f13e7c9a933e6..6f68a6b298c9afd10498a19350eaeac8b07a3bf4 100644 (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;
index 4296ddda8aaa6c91b44e3c0a1fddd13d1405e8e9..01eafeb1272fa8fa79ced6df21ab4a1557d44daa 100644 (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__ */
index d413d76a893680f658c41ff70b0913918aec5e7a..a14509d88fe74d72e1802cdc661ad5a6abd0f01f 100644 (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;
+}
index 47458cbcbc94c19db5aecb1e2d678759ed982bbe..1f508843fb5a120e3f6e82d2645a939c108a34d1 100644 (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,
index 8ea2b4226234fa7cbfe45863ed53f6d4e2671123..430905f591b22730b5ebfbbb40f58f89173aa84f 100644 (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
index fce3fba2ffd240db3864bf19bafff932397c79d0..fa46118553110cc4e3834349caf79800055b6d35 100644 (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__ */