Add PTP interrupt handling infrastructure, which is used to read the transmit timestamps from two hardware queues.
Signed-off-by: Russell King <rmk+ker...@armlinux.org.uk> --- drivers/net/ethernet/marvell/mvpp2/mvpp2.h | 8 ++++ .../net/ethernet/marvell/mvpp2/mvpp2_main.c | 44 +++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h index 75467411900e..50956551b336 100644 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h @@ -463,8 +463,10 @@ #define MVPP22_CTRL4_QSGMII_BYPASS_ACTIVE BIT(7) #define MVPP22_GMAC_INT_SUM_STAT 0xa0 #define MVPP22_GMAC_INT_SUM_STAT_INTERNAL BIT(1) +#define MVPP22_GMAC_INT_SUM_STAT_PTP BIT(2) #define MVPP22_GMAC_INT_SUM_MASK 0xa4 #define MVPP22_GMAC_INT_SUM_MASK_LINK_STAT BIT(1) +#define MVPP22_GMAC_INT_SUM_MASK_PTP BIT(2) /* Per-port XGMAC registers. PPv2.2 only, only for GOP port 0, * relative to port->base. @@ -492,9 +494,11 @@ #define MVPP22_XLG_CTRL3_MACMODESELECT_10G (1 << 13) #define MVPP22_XLG_EXT_INT_STAT 0x158 #define MVPP22_XLG_EXT_INT_STAT_XLG BIT(1) +#define MVPP22_XLG_EXT_INT_STAT_PTP BIT(7) #define MVPP22_XLG_EXT_INT_MASK 0x15c #define MVPP22_XLG_EXT_INT_MASK_XLG BIT(1) #define MVPP22_XLG_EXT_INT_MASK_GIG BIT(2) +#define MVPP22_XLG_EXT_INT_MASK_PTP BIT(7) #define MVPP22_XLG_CTRL4_REG 0x184 #define MVPP22_XLG_CTRL4_FWD_FC BIT(5) #define MVPP22_XLG_CTRL4_FWD_PFC BIT(6) @@ -598,7 +602,11 @@ /* PTP registers. PPv2.2 only */ #define MVPP22_PTP_BASE(port) (0x7800 + (port * 0x1000)) #define MVPP22_PTP_INT_CAUSE 0x00 +#define MVPP22_PTP_INT_CAUSE_QUEUE1 BIT(6) +#define MVPP22_PTP_INT_CAUSE_QUEUE0 BIT(5) #define MVPP22_PTP_INT_MASK 0x04 +#define MVPP22_PTP_INT_MASK_QUEUE1 BIT(6) +#define MVPP22_PTP_INT_MASK_QUEUE0 BIT(5) #define MVPP22_PTP_GCR 0x08 #define MVPP22_PTP_GCR_RX_RESET BIT(13) #define MVPP22_PTP_GCR_TX_RESET BIT(1) diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c index c20fde0fc73c..f3148e033bfe 100644 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c @@ -1379,6 +1379,10 @@ static void mvpp22_gop_setup_irq(struct mvpp2_port *port) { u32 val; + mvpp2_modify(port->base + MVPP22_GMAC_INT_SUM_MASK, + MVPP22_GMAC_INT_SUM_MASK_PTP, + MVPP22_GMAC_INT_SUM_MASK_PTP); + if (port->phylink || phy_interface_mode_is_rgmii(port->phy_interface) || phy_interface_mode_is_8023z(port->phy_interface) || @@ -1392,6 +1396,10 @@ static void mvpp22_gop_setup_irq(struct mvpp2_port *port) val = readl(port->base + MVPP22_XLG_INT_MASK); val |= MVPP22_XLG_INT_MASK_LINK; writel(val, port->base + MVPP22_XLG_INT_MASK); + + mvpp2_modify(port->base + MVPP22_XLG_EXT_INT_MASK, + MVPP22_XLG_EXT_INT_MASK_PTP, + MVPP22_XLG_EXT_INT_MASK_PTP); } mvpp22_gop_unmask_irq(port); @@ -2974,6 +2982,38 @@ static irqreturn_t mvpp2_isr(int irq, void *dev_id) return IRQ_HANDLED; } +static void mvpp2_isr_handle_ptp_queue(struct mvpp2_port *port, int nq) +{ + void __iomem *ptp_q; + u32 r0, r1, r2; + + ptp_q = port->priv->iface_base + MVPP22_PTP_BASE(port->gop_id); + if (nq) + ptp_q += MVPP22_PTP_TX_Q1_R0 - MVPP22_PTP_TX_Q0_R0; + + while (1) { + r0 = readl_relaxed(ptp_q + MVPP22_PTP_TX_Q0_R0) & 0xffff; + if (!r0) + break; + + r1 = readl_relaxed(ptp_q + MVPP22_PTP_TX_Q0_R1) & 0xffff; + r2 = readl_relaxed(ptp_q + MVPP22_PTP_TX_Q0_R2) & 0xffff; + } +} + +static void mvpp2_isr_handle_ptp(struct mvpp2_port *port) +{ + void __iomem *ptp; + u32 val; + + ptp = port->priv->iface_base + MVPP22_PTP_BASE(port->gop_id); + val = readl(ptp + MVPP22_PTP_INT_CAUSE); + if (val & MVPP22_PTP_INT_CAUSE_QUEUE0) + mvpp2_isr_handle_ptp_queue(port, 0); + if (val & MVPP22_PTP_INT_CAUSE_QUEUE1) + mvpp2_isr_handle_ptp_queue(port, 1); +} + static void mvpp2_isr_handle_link(struct mvpp2_port *port, bool link) { struct net_device *dev = port->dev; @@ -3049,6 +3089,8 @@ static irqreturn_t mvpp2_port_isr(int irq, void *dev_id) val = readl(port->base + MVPP22_XLG_EXT_INT_STAT); if (val & MVPP22_XLG_EXT_INT_STAT_XLG) mvpp2_isr_handle_xlg(port); + if (val & MVPP22_XLG_EXT_INT_STAT_PTP) + mvpp2_isr_handle_ptp(port); } else { /* If it's not the XLG, we must be using the GMAC. * Check the summary status. @@ -3056,6 +3098,8 @@ static irqreturn_t mvpp2_port_isr(int irq, void *dev_id) val = readl(port->base + MVPP22_GMAC_INT_SUM_STAT); if (val & MVPP22_GMAC_INT_SUM_STAT_INTERNAL) mvpp2_isr_handle_gmac_internal(port); + if (val & MVPP22_GMAC_INT_SUM_STAT_PTP) + mvpp2_isr_handle_ptp(port); } mvpp22_gop_unmask_irq(port); -- 2.20.1