summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/freescale/fec_main.c
diff options
context:
space:
mode:
authorFugang Duan <fugang.duan@nxp.com>2017-07-18 17:52:44 +0800
committerLeonard Crestez <leonard.crestez@nxp.com>2018-08-24 12:41:33 +0300
commit420521f402f4b486a9d1f85c32be5e2f3acc3b00 (patch)
tree337785a15390082bdb1de1b597f40c7b2cfffa7b /drivers/net/ethernet/freescale/fec_main.c
parent1a72ca381b21b1ea91da3514481908b5a7c713f4 (diff)
MLK-16023-03: net: fec: add MAC delayed clock feature support
i.MX8QM/QXP ENET IP version add new feture to generate delayed TXC/RXC as an alternative option to make sure it can work well with various PHYs, which also is useful for MAC-to-MAC case. Add the new feature support. Signed-off-by: Fugang Duan <fugang.duan@nxp.com>
Diffstat (limited to 'drivers/net/ethernet/freescale/fec_main.c')
-rw-r--r--drivers/net/ethernet/freescale/fec_main.c33
1 files changed, 31 insertions, 2 deletions
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 3230ff613b1c..db669f898329 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -132,7 +132,8 @@ static struct platform_device_id fec_devtype[] = {
FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
FEC_QUIRK_HAS_VLAN | FEC_QUIRK_HAS_AVB |
FEC_QUIRK_ERR007885 | FEC_QUIRK_BUG_CAPTURE |
- FEC_QUIRK_HAS_RACC | FEC_QUIRK_HAS_COALESCE,
+ FEC_QUIRK_HAS_RACC | FEC_QUIRK_HAS_COALESCE |
+ FEC_QUIRK_DELAYED_CLKS_SUPPORT,
}, {
/* sentinel */
}
@@ -1084,6 +1085,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);
@@ -1924,6 +1932,11 @@ static int fec_enet_clk_enable(struct net_device *ndev, bool enable)
if (ret)
goto failed_clk_ref;
}
+ if (fep->clk_2x_txclk) {
+ ret = clk_prepare_enable(fep->clk_2x_txclk);
+ if (ret)
+ goto failed_clk_2x_txclk;
+ }
} else {
if (fep->clk_enet_out)
clk_disable_unprepare(fep->clk_enet_out);
@@ -1935,13 +1948,18 @@ static int fec_enet_clk_enable(struct net_device *ndev, bool enable)
}
if (fep->clk_ref)
clk_disable_unprepare(fep->clk_ref);
+ if (fep->clk_2x_txclk)
+ clk_disable_unprepare(fep->clk_2x_txclk);
}
return 0;
-failed_clk_ref:
+failed_clk_2x_txclk:
if (fep->clk_ref)
clk_disable_unprepare(fep->clk_ref);
+failed_clk_ref:
+ if (fep->clk_ptp)
+ clk_disable_unprepare(fep->clk_ptp);
failed_clk_ptp:
if (fep->clk_enet_out)
clk_disable_unprepare(fep->clk_enet_out);
@@ -3536,6 +3554,12 @@ fec_probe(struct platform_device *pdev)
if (of_get_property(np, "fsl,magic-packet", NULL))
fep->wol_flag |= FEC_WOL_HAS_MAGIC_PACKET;
+ if (of_get_property(np, "fsl,rgmii_txc_dly", NULL))
+ fep->rgmii_txc_dly = true;
+
+ if (of_get_property(np, "fsl,rgmii_rxc_dly", NULL))
+ 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);
@@ -3591,6 +3615,11 @@ fec_probe(struct platform_device *pdev)
if (IS_ERR(fep->clk_ref))
fep->clk_ref = NULL;
+ /* 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)) {