summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/phy/nxp-c45-tja11xx.c60
1 files changed, 52 insertions, 8 deletions
diff --git a/drivers/net/phy/nxp-c45-tja11xx.c b/drivers/net/phy/nxp-c45-tja11xx.c
index dbfaf1e07ad5..8393c17a83cc 100644
--- a/drivers/net/phy/nxp-c45-tja11xx.c
+++ b/drivers/net/phy/nxp-c45-tja11xx.c
@@ -101,6 +101,10 @@
#define VEND1_PTP_CONFIG 0x1102
#define EXT_TRG_EDGE BIT(1)
+#define TJA1120_SYNC_TRIG_FILTER 0x1010
+#define PTP_TRIG_RISE_TS BIT(3)
+#define PTP_TRIG_FALLING_TS BIT(2)
+
#define CLK_RATE_ADJ_LD BIT(15)
#define CLK_RATE_ADJ_DIR BIT(14)
@@ -238,6 +242,7 @@ struct nxp_c45_phy_data {
const struct nxp_c45_phy_stats *stats;
int n_stats;
u8 ptp_clk_period;
+ bool ext_ts_both_edges;
void (*counters_enable)(struct phy_device *phydev);
void (*ptp_init)(struct phy_device *phydev);
void (*ptp_enable)(struct phy_device *phydev, bool enable);
@@ -684,9 +689,48 @@ static int nxp_c45_perout_enable(struct nxp_c45_phy *priv,
return 0;
}
+static void nxp_c45_set_rising_or_falling(struct phy_device *phydev,
+ struct ptp_extts_request *extts)
+{
+ if (extts->flags & PTP_RISING_EDGE)
+ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
+ VEND1_PTP_CONFIG, EXT_TRG_EDGE);
+
+ if (extts->flags & PTP_FALLING_EDGE)
+ phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
+ VEND1_PTP_CONFIG, EXT_TRG_EDGE);
+}
+
+static void nxp_c45_set_rising_and_falling(struct phy_device *phydev,
+ struct ptp_extts_request *extts)
+{
+ /* PTP_EXTTS_REQUEST may have only the PTP_ENABLE_FEATURE flag set. In
+ * this case external ts will be enabled on rising edge.
+ */
+ if (extts->flags & PTP_RISING_EDGE ||
+ extts->flags == PTP_ENABLE_FEATURE)
+ phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
+ TJA1120_SYNC_TRIG_FILTER,
+ PTP_TRIG_RISE_TS);
+ else
+ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
+ TJA1120_SYNC_TRIG_FILTER,
+ PTP_TRIG_RISE_TS);
+
+ if (extts->flags & PTP_FALLING_EDGE)
+ phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
+ TJA1120_SYNC_TRIG_FILTER,
+ PTP_TRIG_FALLING_TS);
+ else
+ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
+ TJA1120_SYNC_TRIG_FILTER,
+ PTP_TRIG_FALLING_TS);
+}
+
static int nxp_c45_extts_enable(struct nxp_c45_phy *priv,
struct ptp_extts_request *extts, int on)
{
+ const struct nxp_c45_phy_data *data = nxp_c45_get_data(priv->phydev);
int pin;
if (extts->flags & ~(PTP_ENABLE_FEATURE |
@@ -697,7 +741,8 @@ static int nxp_c45_extts_enable(struct nxp_c45_phy *priv,
/* Sampling on both edges is not supported */
if ((extts->flags & PTP_RISING_EDGE) &&
- (extts->flags & PTP_FALLING_EDGE))
+ (extts->flags & PTP_FALLING_EDGE) &&
+ !data->ext_ts_both_edges)
return -EOPNOTSUPP;
pin = ptp_find_pin(priv->ptp_clock, PTP_PF_EXTTS, extts->index);
@@ -711,13 +756,10 @@ static int nxp_c45_extts_enable(struct nxp_c45_phy *priv,
return 0;
}
- if (extts->flags & PTP_RISING_EDGE)
- phy_clear_bits_mmd(priv->phydev, MDIO_MMD_VEND1,
- VEND1_PTP_CONFIG, EXT_TRG_EDGE);
-
- if (extts->flags & PTP_FALLING_EDGE)
- phy_set_bits_mmd(priv->phydev, MDIO_MMD_VEND1,
- VEND1_PTP_CONFIG, EXT_TRG_EDGE);
+ if (data->ext_ts_both_edges)
+ nxp_c45_set_rising_and_falling(priv->phydev, extts);
+ else
+ nxp_c45_set_rising_or_falling(priv->phydev, extts);
nxp_c45_gpio_config(priv, pin, GPIO_EXTTS_OUT_CFG);
priv->extts = true;
@@ -1545,6 +1587,7 @@ static const struct nxp_c45_phy_data tja1103_phy_data = {
.stats = tja1103_hw_stats,
.n_stats = ARRAY_SIZE(tja1103_hw_stats),
.ptp_clk_period = PTP_CLK_PERIOD_100BT1,
+ .ext_ts_both_edges = false,
.counters_enable = tja1103_counters_enable,
.ptp_init = tja1103_ptp_init,
.ptp_enable = tja1103_ptp_enable,
@@ -1640,6 +1683,7 @@ static const struct nxp_c45_phy_data tja1120_phy_data = {
.stats = tja1120_hw_stats,
.n_stats = ARRAY_SIZE(tja1120_hw_stats),
.ptp_clk_period = PTP_CLK_PERIOD_1000BT1,
+ .ext_ts_both_edges = true,
.counters_enable = tja1120_counters_enable,
.ptp_init = tja1120_ptp_init,
.ptp_enable = tja1120_ptp_enable,