diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/phy/nxp-c45-tja11xx.c | 60 |
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, |