diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 18:50:03 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 18:50:03 +0000 |
commit | 01a69402cf9d38ff180345d55c2ee51c7e89fbc7 (patch) | |
tree | b406c5242a088c4f59c6e4b719b783f43aca6ae9 /drivers/net/ethernet/marvell/mvmdio.c | |
parent | Adding upstream version 6.7.12. (diff) | |
download | linux-01a69402cf9d38ff180345d55c2ee51c7e89fbc7.tar.xz linux-01a69402cf9d38ff180345d55c2ee51c7e89fbc7.zip |
Adding upstream version 6.8.9.upstream/6.8.9
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'drivers/net/ethernet/marvell/mvmdio.c')
-rw-r--r-- | drivers/net/ethernet/marvell/mvmdio.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/drivers/net/ethernet/marvell/mvmdio.c b/drivers/net/ethernet/marvell/mvmdio.c index 5f66f779e5..9190eff6c0 100644 --- a/drivers/net/ethernet/marvell/mvmdio.c +++ b/drivers/net/ethernet/marvell/mvmdio.c @@ -53,6 +53,13 @@ #define MVMDIO_XSMI_BUSY BIT(30) #define MVMDIO_XSMI_ADDR_REG 0x8 +#define MVMDIO_XSMI_CFG_REG 0xc +#define MVMDIO_XSMI_CLKDIV_MASK 0x3 +#define MVMDIO_XSMI_CLKDIV_256 0x0 +#define MVMDIO_XSMI_CLKDIV_64 0x1 +#define MVMDIO_XSMI_CLKDIV_32 0x2 +#define MVMDIO_XSMI_CLKDIV_8 0x3 + /* * SMI Timeout measurements: * - Kirkwood 88F6281 (Globalscale Dreamplug): 45us to 95us (Interrupt) @@ -225,6 +232,40 @@ static int orion_mdio_xsmi_write_c45(struct mii_bus *bus, int mii_id, return 0; } +static void orion_mdio_xsmi_set_mdc_freq(struct mii_bus *bus) +{ + struct orion_mdio_dev *dev = bus->priv; + struct clk *mg_core; + u32 div, freq, cfg; + + if (device_property_read_u32(bus->parent, "clock-frequency", &freq)) + return; + + mg_core = of_clk_get_by_name(bus->parent->of_node, "mg_core_clk"); + if (IS_ERR(mg_core)) { + dev_err(bus->parent, + "MG core clock unknown, not changing MDC frequency"); + return; + } + + div = clk_get_rate(mg_core) / (freq + 1) + 1; + clk_put(mg_core); + + if (div <= 8) + div = MVMDIO_XSMI_CLKDIV_8; + else if (div <= 32) + div = MVMDIO_XSMI_CLKDIV_32; + else if (div <= 64) + div = MVMDIO_XSMI_CLKDIV_64; + else + div = MVMDIO_XSMI_CLKDIV_256; + + cfg = readl(dev->regs + MVMDIO_XSMI_CFG_REG); + cfg &= ~MVMDIO_XSMI_CLKDIV_MASK; + cfg |= div; + writel(cfg, dev->regs + MVMDIO_XSMI_CFG_REG); +} + static irqreturn_t orion_mdio_err_irq(int irq, void *dev_id) { struct orion_mdio_dev *dev = dev_id; @@ -303,6 +344,9 @@ static int orion_mdio_probe(struct platform_device *pdev) dev_warn(&pdev->dev, "unsupported number of clocks, limiting to the first " __stringify(ARRAY_SIZE(dev->clk)) "\n"); + + if (type == BUS_TYPE_XSMI) + orion_mdio_xsmi_set_mdc_freq(bus); } else { dev->clk[0] = clk_get(&pdev->dev, NULL); if (PTR_ERR(dev->clk[0]) == -EPROBE_DEFER) { |