From 568f4f22cb68236f101516146e4acf5dd0f0111b Mon Sep 17 00:00:00 2001 From: Harini Katakam Date: Thu, 8 Mar 2018 18:20:50 +0530 Subject: [PATCH] net: macb: TSU clock and PTP fixes Enable transmission and reception of PTP unicast packets. Add tsu_clk and get the rate for the same from clock framework. Move definition of tsu_rate to be in sync with master. Add spinlocks in ptp_remove to avoid issues during suspend/resume. Signed-off-by: Harini Katakam Signed-off-by: Michal Simek --- drivers/net/ethernet/cadence/macb.h | 10 +++++-- drivers/net/ethernet/cadence/macb_main.c | 37 ++++++++++++++++++++---- drivers/net/ethernet/cadence/macb_ptp.c | 4 ++- 3 files changed, 42 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h index 83909bcaa466..8feb78d64bd9 100644 --- a/drivers/net/ethernet/cadence/macb.h +++ b/drivers/net/ethernet/cadence/macb.h @@ -94,6 +94,8 @@ #define GEM_SA3T 0x009C /* Specific3 Top */ #define GEM_SA4B 0x00A0 /* Specific4 Bottom */ #define GEM_SA4T 0x00A4 /* Specific4 Top */ +#define GEM_RXPTPUNI 0x00D4 /* PTP RX Unicast address */ +#define GEM_TXPTPUNI 0x00D8 /* PTP TX Unicast address */ #define GEM_EFTSH 0x00e8 /* PTP Event Frame Transmitted Seconds Register 47:32 */ #define GEM_EFRSH 0x00ec /* PTP Event Frame Received Seconds Register 47:32 */ #define GEM_PEFTSH 0x00f0 /* PTP Peer Event Frame Transmitted Seconds Register 47:32 */ @@ -207,6 +209,8 @@ #define MACB_TZQ_OFFSET 12 /* Transmit zero quantum pause frame */ #define MACB_TZQ_SIZE 1 #define MACB_SRTSM_OFFSET 15 +#define MACB_PTPUNI_OFFSET 20 +#define MACB_PTPUNI_SIZE 1 #define MACB_OSSMODE_OFFSET 24 /* Enable One Step Synchro Mode */ #define MACB_OSSMODE_SIZE 1 @@ -962,7 +966,7 @@ struct macb_config { unsigned int dma_burst_length; int (*clk_init)(struct platform_device *pdev, struct clk **pclk, struct clk **hclk, struct clk **tx_clk, - struct clk **rx_clk); + struct clk **rx_clk, struct clk **tsu_clk); int (*init)(struct platform_device *pdev); int jumbo_max_len; }; @@ -1026,6 +1030,7 @@ struct macb { struct clk *hclk; struct clk *tx_clk; struct clk *rx_clk; + struct clk *tsu_clk; struct net_device *dev; struct napi_struct napi; union { @@ -1065,6 +1070,8 @@ struct macb { u32 wol; + unsigned int tsu_rate; + struct tasklet_struct hresp_err_tasklet; /* holds value of rx watermark value for pbuf_rxcutthru register */ @@ -1075,7 +1082,6 @@ struct macb { uint8_t hw_dma_cap; #endif spinlock_t tsu_clk_lock; /* gem tsu clock locking */ - unsigned int tsu_rate; struct ptp_clock *ptp_clock; struct ptp_clock_info ptp_clock_info; struct tsu_incr tsu_incr; diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 0dc321fb7b63..0e00e679c3ad 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -268,6 +268,9 @@ static void macb_set_hwaddr(struct macb *bp) top = cpu_to_le16(*((u16 *)(bp->dev->dev_addr + 4))); macb_or_gem_writel(bp, SA1T, top); + gem_writel(bp, RXPTPUNI, bottom); + gem_writel(bp, TXPTPUNI, bottom); + /* Clear unused address register sets */ macb_or_gem_writel(bp, SA2B, 0); macb_or_gem_writel(bp, SA2T, 0); @@ -2213,7 +2216,8 @@ static void macb_init_hw(struct macb *bp) gem_readl(bp, PCSCNTRL) | GEM_BIT(PCSAUTONEG)); /* Enable TX and RX */ - macb_writel(bp, NCR, MACB_BIT(RE) | MACB_BIT(TE) | MACB_BIT(MPE)); + macb_writel(bp, NCR, MACB_BIT(RE) | MACB_BIT(TE) | MACB_BIT(MPE) | + MACB_BIT(PTPUNI)); } /* The hash address register is 64 bits long and takes up two @@ -2965,7 +2969,7 @@ static void macb_probe_queues(void __iomem *mem, static int macb_clk_init(struct platform_device *pdev, struct clk **pclk, struct clk **hclk, struct clk **tx_clk, - struct clk **rx_clk) + struct clk **rx_clk, struct clk **tsu_clk) { struct macb_platform_data *pdata; int err; @@ -2999,6 +3003,10 @@ static int macb_clk_init(struct platform_device *pdev, struct clk **pclk, if (IS_ERR(*rx_clk)) *rx_clk = NULL; + *tsu_clk = devm_clk_get(&pdev->dev, "tsu_clk"); + if (IS_ERR(*tsu_clk)) + *tsu_clk = NULL; + err = clk_prepare_enable(*pclk); if (err) { dev_err(&pdev->dev, "failed to enable pclk (%u)\n", err); @@ -3023,8 +3031,17 @@ static int macb_clk_init(struct platform_device *pdev, struct clk **pclk, goto err_disable_txclk; } + err = clk_prepare_enable(*tsu_clk); + if (err) { + dev_err(&pdev->dev, "failed to enable tsu_clk (%u)\n", err); + goto err_disable_rxclk; + } + return 0; +err_disable_rxclk: + clk_disable_unprepare(*rx_clk); + err_disable_txclk: clk_disable_unprepare(*tx_clk); @@ -3450,13 +3467,14 @@ static const struct net_device_ops at91ether_netdev_ops = { static int at91ether_clk_init(struct platform_device *pdev, struct clk **pclk, struct clk **hclk, struct clk **tx_clk, - struct clk **rx_clk) + struct clk **rx_clk, struct clk **tsu_clk) { int err; *hclk = NULL; *tx_clk = NULL; *rx_clk = NULL; + *tsu_clk = NULL; *pclk = devm_clk_get(&pdev->dev, "ether_clk"); if (IS_ERR(*pclk)) @@ -3583,13 +3601,14 @@ MODULE_DEVICE_TABLE(of, macb_dt_ids); static int macb_probe(struct platform_device *pdev) { int (*clk_init)(struct platform_device *, struct clk **, - struct clk **, struct clk **, struct clk **) - = macb_clk_init; + struct clk **, struct clk **, struct clk **, + struct clk **) = macb_clk_init; int (*init)(struct platform_device *) = macb_init; struct device_node *np = pdev->dev.of_node; struct device_node *phy_node; const struct macb_config *macb_config = NULL; struct clk *pclk, *hclk = NULL, *tx_clk = NULL, *rx_clk = NULL; + struct clk *tsu_clk = NULL; unsigned int queue_mask, num_queues; struct macb_platform_data *pdata; bool native_io; @@ -3617,7 +3636,7 @@ static int macb_probe(struct platform_device *pdev) } } - err = clk_init(pdev, &pclk, &hclk, &tx_clk, &rx_clk); + err = clk_init(pdev, &pclk, &hclk, &tx_clk, &rx_clk, &tsu_clk); if (err) return err; @@ -3654,6 +3673,10 @@ static int macb_probe(struct platform_device *pdev) bp->hclk = hclk; bp->tx_clk = tx_clk; bp->rx_clk = rx_clk; + bp->tsu_clk = tsu_clk; + if (tsu_clk) + bp->tsu_rate = clk_get_rate(tsu_clk); + if (macb_config) bp->jumbo_max_len = macb_config->jumbo_max_len; @@ -3769,6 +3792,7 @@ err_disable_clocks: clk_disable_unprepare(hclk); clk_disable_unprepare(pclk); clk_disable_unprepare(rx_clk); + clk_disable_unprepare(tsu_clk); return err; } @@ -3797,6 +3821,7 @@ static int macb_remove(struct platform_device *pdev) clk_disable_unprepare(bp->hclk); clk_disable_unprepare(bp->pclk); clk_disable_unprepare(bp->rx_clk); + clk_disable_unprepare(bp->tsu_clk); of_node_put(bp->phy_node); free_netdev(dev); } diff --git a/drivers/net/ethernet/cadence/macb_ptp.c b/drivers/net/ethernet/cadence/macb_ptp.c index 2220c771092b..70377b46d12a 100755 --- a/drivers/net/ethernet/cadence/macb_ptp.c +++ b/drivers/net/ethernet/cadence/macb_ptp.c @@ -364,7 +364,6 @@ void gem_ptp_init(struct net_device *dev) bp->ptp_clock_info = gem_ptp_caps_template; /* nominal frequency and maximum adjustment in ppb */ - bp->tsu_rate = bp->ptp_info->get_tsu_rate(bp); bp->ptp_clock_info.max_adj = bp->ptp_info->get_ptp_max_adj(); gem_ptp_init_timer(bp); bp->ptp_clock = ptp_clock_register(&bp->ptp_clock_info, &dev->dev); @@ -394,11 +393,14 @@ void gem_ptp_init(struct net_device *dev) void gem_ptp_remove(struct net_device *ndev) { struct macb *bp = netdev_priv(ndev); + unsigned long flags; if (bp->ptp_clock) ptp_clock_unregister(bp->ptp_clock); + spin_lock_irqsave(&bp->tsu_clk_lock, flags); gem_ptp_clear_timer(bp); + spin_unlock_irqrestore(&bp->tsu_clk_lock, flags); dev_info(&bp->pdev->dev, "%s ptp clock unregistered.\n", GEM_PTP_TIMER_NAME); -- 2.39.2