From fc539459e900a891dda5b586d7b5e3fd5db14218 Mon Sep 17 00:00:00 2001 From: Fugang Duan Date: Wed, 28 Jul 2021 19:52:01 +0800 Subject: net: fec: add MAC internal delayed clock feature support i.MX8QM ENET IP version support timing specification that MAC integrate clock delay in RGMII mode, the delayed TXC/RXC as an alternative option to work well with various PHYs. Signed-off-by: Fugang Duan Signed-off-by: Joakim Zhang Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec_main.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'drivers/net/ethernet/freescale/fec_main.c') diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index f13a9da180a2..40ea318d7396 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -1137,6 +1137,13 @@ fec_restart(struct net_device *ndev) if (fep->bufdesc_ex) ecntl |= (1 << 4); + if (fep->quirks & FEC_QUIRK_DELAYED_CLKS_SUPPORT && + fep->rgmii_txc_dly) + ecntl |= FEC_ENET_TXC_DLY; + if (fep->quirks & FEC_QUIRK_DELAYED_CLKS_SUPPORT && + fep->rgmii_rxc_dly) + ecntl |= FEC_ENET_RXC_DLY; + #ifndef CONFIG_M5272 /* Enable the MIB statistic event counters */ writel(0 << 31, fep->hwp + FEC_MIB_CTRLSTAT); @@ -2000,6 +2007,10 @@ static int fec_enet_clk_enable(struct net_device *ndev, bool enable) if (ret) goto failed_clk_ref; + ret = clk_prepare_enable(fep->clk_2x_txclk); + if (ret) + goto failed_clk_2x_txclk; + fec_enet_phy_reset_after_clk_enable(ndev); } else { clk_disable_unprepare(fep->clk_enet_out); @@ -2010,10 +2021,14 @@ static int fec_enet_clk_enable(struct net_device *ndev, bool enable) mutex_unlock(&fep->ptp_clk_mutex); } clk_disable_unprepare(fep->clk_ref); + clk_disable_unprepare(fep->clk_2x_txclk); } return 0; +failed_clk_2x_txclk: + if (fep->clk_ref) + clk_disable_unprepare(fep->clk_ref); failed_clk_ref: if (fep->clk_ptp) { mutex_lock(&fep->ptp_clk_mutex); @@ -3704,6 +3719,7 @@ fec_probe(struct platform_device *pdev) char irq_name[8]; int irq_cnt; struct fec_devinfo *dev_info; + u32 rgmii_delay; fec_enet_get_queue_num(pdev, &num_tx_qs, &num_rx_qs); @@ -3761,6 +3777,12 @@ fec_probe(struct platform_device *pdev) if (ret) goto failed_stop_mode; + /* For rgmii internal delay, valid values are 0ps and 2000ps */ + if (of_property_read_u32(np, "tx-internal-delay-ps", &rgmii_delay)) + fep->rgmii_txc_dly = true; + if (of_property_read_u32(np, "rx-internal-delay-ps", &rgmii_delay)) + fep->rgmii_rxc_dly = true; + phy_node = of_parse_phandle(np, "phy-handle", 0); if (!phy_node && of_phy_is_fixed_link(np)) { ret = of_phy_register_fixed_link(np); @@ -3812,6 +3834,11 @@ fec_probe(struct platform_device *pdev) fep->clk_ref = NULL; fep->clk_ref_rate = clk_get_rate(fep->clk_ref); + /* clk_2x_txclk is optional, depends on board */ + fep->clk_2x_txclk = devm_clk_get(&pdev->dev, "enet_2x_txclk"); + if (IS_ERR(fep->clk_2x_txclk)) + fep->clk_2x_txclk = NULL; + fep->bufdesc_ex = fep->quirks & FEC_QUIRK_HAS_BUFDESC_EX; fep->clk_ptp = devm_clk_get(&pdev->dev, "ptp"); if (IS_ERR(fep->clk_ptp)) { -- cgit v1.2.3-59-g8ed1b