diff options
author | Michael Tretter <m.tretter@pengutronix.de> | 2020-10-15 15:20:47 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2020-10-19 10:01:52 +0200 |
commit | dc62c9c65c50dea80a738a0819c661c7151c5ed7 (patch) | |
tree | 85a17f04e431bf49ddcf29b1bcc8769ab906f4eb /drivers | |
parent | 677f6a97f34f0dcbfcb5744089ef9566b9f8a3f0 (diff) | |
download | barebox-dc62c9c65c50dea80a738a0819c661c7151c5ed7.tar.gz barebox-dc62c9c65c50dea80a738a0819c661c7151c5ed7.tar.xz |
net: macb: adjust clk_tx rate for link speed changes
Changes of the link speed might require an adjustment of the clk_tx.
Read the clk_tx from the device tree and change the rate if the link
speed changes.
If the clk_tx rate is already correct, changing the clock is not
required and, thus, not being able to get the clock rate is not fatal.
Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers')
-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 09b58ffd01..fa530cfe8e 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -258,9 +258,38 @@ static int macb_recv(struct eth_device *edev) return 0; } +static int macb_set_tx_clk(struct macb_device *macb, int speed) +{ + int rate; + int rate_rounded; + + if (!macb->txclk) { + dev_dbg(macb->dev, "txclk not available\n"); + return 0; + } + + switch (speed) { + case SPEED_100: + rate = 25000000; + break; + case SPEED_1000: + rate = 125000000; + break; + default: + return -EINVAL; + } + + rate_rounded = clk_round_rate(macb->txclk, rate); + if (rate_rounded <= 0) + return -EINVAL; + + return clk_set_rate(macb->txclk, rate_rounded); +} + static void macb_adjust_link(struct eth_device *edev) { struct macb_device *macb = edev->priv; + int err; u32 reg; reg = macb_readl(macb, NCFGR); @@ -276,6 +305,10 @@ static void macb_adjust_link(struct eth_device *edev) reg |= GEM_BIT(GBE); macb_or_gem_writel(macb, NCFGR, reg); + + err = macb_set_tx_clk(macb, edev->phydev->speed); + if (err) + dev_warn(macb->dev, "cannot set txclk\n"); } static int macb_open(struct eth_device *edev) @@ -724,6 +757,8 @@ static int macb_probe(struct device_d *dev) macb->txclk = clk_get(dev, "tx_clk"); if (!IS_ERR(macb->txclk)) clk_enable(macb->txclk); + else + macb->txclk = NULL; macb->rxclk = clk_get(dev, "rx_clk"); if (!IS_ERR(macb->rxclk)) |