diff options
author | Bin Meng <bmeng.cn@gmail.com> | 2019-05-22 00:09:46 -0700 |
---|---|---|
committer | Joe Hershberger <joe.hershberger@ni.com> | 2019-06-01 13:33:17 -0500 |
commit | 3ef64444de157a2e4f6a61b3ea617b9d201a6836 (patch) | |
tree | c4754e75f073584577c59bc4ee56bb922cbc8ba9 /drivers/net/macb.c | |
parent | a5e3d2350b271d6281c01ae7ad0dd7290ba66aee (diff) | |
download | u-boot-3ef64444de157a2e4f6a61b3ea617b9d201a6836.tar.gz |
dm: net: macb: Implement link speed change callback
At present the link speed change callback is a nop. According to
macb device tree bindings, an optional "tx_clk" is used to clock
the ethernet controller's TX_CLK under different link speed.
In 10/100 MII mode, transmit logic must be clocked from a free
running clock generated by the external PHY. In gigabit GMII mode,
the controller, not the external PHY, must generate the 125 MHz
transmit clock towards the PHY.
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
Tested-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
Acked-by: Joe Hershberger <joe.hershberger@ni.com>
Diffstat (limited to 'drivers/net/macb.c')
-rw-r--r-- | drivers/net/macb.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/drivers/net/macb.c b/drivers/net/macb.c index b7f404e857..c5560a7111 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -497,6 +497,41 @@ static int macb_phy_find(struct macb_device *macb, const char *name) #ifdef CONFIG_DM_ETH int __weak macb_linkspd_cb(struct udevice *dev, unsigned int speed) { +#ifdef CONFIG_CLK + struct clk tx_clk; + ulong rate; + int ret; + + /* + * "tx_clk" is an optional clock source for MACB. + * Ignore if it does not exist in DT. + */ + ret = clk_get_by_name(dev, "tx_clk", &tx_clk); + if (ret) + return 0; + + switch (speed) { + case _10BASET: + rate = 2500000; /* 2.5 MHz */ + break; + case _100BASET: + rate = 25000000; /* 25 MHz */ + break; + case _1000BASET: + rate = 125000000; /* 125 MHz */ + break; + default: + /* does not change anything */ + return 0; + } + + if (tx_clk.dev) { + ret = clk_set_rate(&tx_clk, rate); + if (ret) + return ret; + } +#endif + return 0; } #else |