net: fec: fix MAC internal delay doesn't work
This patch intends to fix MAC internal delay doesn't work, due to use
of_property_read_u32() incorrectly, and improve this feature a bit:
1) check the delay value if valid, only program register when it's 2000ps.
2) only enable "enet_2x_txclk" clock when require MAC internal delay.
Fixes: fc539459e9
("net: fec: add MAC internal delayed clock feature support")
Signed-off-by: Joakim Zhang <qiangqing.zhang@nxp.com>
Link: https://lore.kernel.org/r/20210803052424.19008-1-qiangqing.zhang@nxp.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
421297efe6
commit
b820c114eb
|
@ -2042,6 +2042,34 @@ failed_clk_ptp:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int fec_enet_parse_rgmii_delay(struct fec_enet_private *fep,
|
||||||
|
struct device_node *np)
|
||||||
|
{
|
||||||
|
u32 rgmii_tx_delay, rgmii_rx_delay;
|
||||||
|
|
||||||
|
/* For rgmii tx internal delay, valid values are 0ps and 2000ps */
|
||||||
|
if (!of_property_read_u32(np, "tx-internal-delay-ps", &rgmii_tx_delay)) {
|
||||||
|
if (rgmii_tx_delay != 0 && rgmii_tx_delay != 2000) {
|
||||||
|
dev_err(&fep->pdev->dev, "The only allowed RGMII TX delay values are: 0ps, 2000ps");
|
||||||
|
return -EINVAL;
|
||||||
|
} else if (rgmii_tx_delay == 2000) {
|
||||||
|
fep->rgmii_txc_dly = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For rgmii rx internal delay, valid values are 0ps and 2000ps */
|
||||||
|
if (!of_property_read_u32(np, "rx-internal-delay-ps", &rgmii_rx_delay)) {
|
||||||
|
if (rgmii_rx_delay != 0 && rgmii_rx_delay != 2000) {
|
||||||
|
dev_err(&fep->pdev->dev, "The only allowed RGMII RX delay values are: 0ps, 2000ps");
|
||||||
|
return -EINVAL;
|
||||||
|
} else if (rgmii_rx_delay == 2000) {
|
||||||
|
fep->rgmii_rxc_dly = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int fec_enet_mii_probe(struct net_device *ndev)
|
static int fec_enet_mii_probe(struct net_device *ndev)
|
||||||
{
|
{
|
||||||
struct fec_enet_private *fep = netdev_priv(ndev);
|
struct fec_enet_private *fep = netdev_priv(ndev);
|
||||||
|
@ -3719,7 +3747,6 @@ fec_probe(struct platform_device *pdev)
|
||||||
char irq_name[8];
|
char irq_name[8];
|
||||||
int irq_cnt;
|
int irq_cnt;
|
||||||
struct fec_devinfo *dev_info;
|
struct fec_devinfo *dev_info;
|
||||||
u32 rgmii_delay;
|
|
||||||
|
|
||||||
fec_enet_get_queue_num(pdev, &num_tx_qs, &num_rx_qs);
|
fec_enet_get_queue_num(pdev, &num_tx_qs, &num_rx_qs);
|
||||||
|
|
||||||
|
@ -3777,12 +3804,6 @@ fec_probe(struct platform_device *pdev)
|
||||||
if (ret)
|
if (ret)
|
||||||
goto failed_stop_mode;
|
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);
|
phy_node = of_parse_phandle(np, "phy-handle", 0);
|
||||||
if (!phy_node && of_phy_is_fixed_link(np)) {
|
if (!phy_node && of_phy_is_fixed_link(np)) {
|
||||||
ret = of_phy_register_fixed_link(np);
|
ret = of_phy_register_fixed_link(np);
|
||||||
|
@ -3806,6 +3827,10 @@ fec_probe(struct platform_device *pdev)
|
||||||
fep->phy_interface = interface;
|
fep->phy_interface = interface;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = fec_enet_parse_rgmii_delay(fep, np);
|
||||||
|
if (ret)
|
||||||
|
goto failed_rgmii_delay;
|
||||||
|
|
||||||
fep->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
|
fep->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
|
||||||
if (IS_ERR(fep->clk_ipg)) {
|
if (IS_ERR(fep->clk_ipg)) {
|
||||||
ret = PTR_ERR(fep->clk_ipg);
|
ret = PTR_ERR(fep->clk_ipg);
|
||||||
|
@ -3835,9 +3860,11 @@ fec_probe(struct platform_device *pdev)
|
||||||
fep->clk_ref_rate = clk_get_rate(fep->clk_ref);
|
fep->clk_ref_rate = clk_get_rate(fep->clk_ref);
|
||||||
|
|
||||||
/* clk_2x_txclk is optional, depends on board */
|
/* clk_2x_txclk is optional, depends on board */
|
||||||
fep->clk_2x_txclk = devm_clk_get(&pdev->dev, "enet_2x_txclk");
|
if (fep->rgmii_txc_dly || fep->rgmii_rxc_dly) {
|
||||||
if (IS_ERR(fep->clk_2x_txclk))
|
fep->clk_2x_txclk = devm_clk_get(&pdev->dev, "enet_2x_txclk");
|
||||||
fep->clk_2x_txclk = NULL;
|
if (IS_ERR(fep->clk_2x_txclk))
|
||||||
|
fep->clk_2x_txclk = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
fep->bufdesc_ex = fep->quirks & FEC_QUIRK_HAS_BUFDESC_EX;
|
fep->bufdesc_ex = fep->quirks & FEC_QUIRK_HAS_BUFDESC_EX;
|
||||||
fep->clk_ptp = devm_clk_get(&pdev->dev, "ptp");
|
fep->clk_ptp = devm_clk_get(&pdev->dev, "ptp");
|
||||||
|
@ -3955,6 +3982,7 @@ failed_clk_ahb:
|
||||||
failed_clk_ipg:
|
failed_clk_ipg:
|
||||||
fec_enet_clk_enable(ndev, false);
|
fec_enet_clk_enable(ndev, false);
|
||||||
failed_clk:
|
failed_clk:
|
||||||
|
failed_rgmii_delay:
|
||||||
if (of_phy_is_fixed_link(np))
|
if (of_phy_is_fixed_link(np))
|
||||||
of_phy_deregister_fixed_link(np);
|
of_phy_deregister_fixed_link(np);
|
||||||
of_node_put(phy_node);
|
of_node_put(phy_node);
|
||||||
|
|
Loading…
Reference in New Issue