1 // SPDX-License-Identifier: GPL-2.0
3 * MDIO bus driver for the Xilinx TEMAC device
5 * Copyright (c) 2009 Secret Lab Technologies, Ltd.
9 #include <linux/netdevice.h>
10 #include <linux/mutex.h>
11 #include <linux/phy.h>
13 #include <linux/of_device.h>
14 #include <linux/of_address.h>
15 #include <linux/slab.h>
16 #include <linux/of_mdio.h>
17 #include <linux/platform_data/xilinx-ll-temac.h>
21 /* ---------------------------------------------------------------------
24 static int temac_mdio_read(struct mii_bus
*bus
, int phy_id
, int reg
)
26 struct temac_local
*lp
= bus
->priv
;
30 /* Write the PHY address to the MIIM Access Initiator register.
31 * When the transfer completes, the PHY register value will appear
32 * in the LSW0 register */
33 spin_lock_irqsave(lp
->indirect_lock
, flags
);
34 temac_iow(lp
, XTE_LSW0_OFFSET
, (phy_id
<< 5) | reg
);
35 rc
= temac_indirect_in32_locked(lp
, XTE_MIIMAI_OFFSET
);
36 spin_unlock_irqrestore(lp
->indirect_lock
, flags
);
38 dev_dbg(lp
->dev
, "temac_mdio_read(phy_id=%i, reg=%x) == %x\n",
44 static int temac_mdio_write(struct mii_bus
*bus
, int phy_id
, int reg
, u16 val
)
46 struct temac_local
*lp
= bus
->priv
;
49 dev_dbg(lp
->dev
, "temac_mdio_write(phy_id=%i, reg=%x, val=%x)\n",
52 /* First write the desired value into the write data register
53 * and then write the address into the access initiator register
55 spin_lock_irqsave(lp
->indirect_lock
, flags
);
56 temac_indirect_out32_locked(lp
, XTE_MGTDR_OFFSET
, val
);
57 temac_indirect_out32_locked(lp
, XTE_MIIMAI_OFFSET
, (phy_id
<< 5) | reg
);
58 spin_unlock_irqrestore(lp
->indirect_lock
, flags
);
63 int temac_mdio_setup(struct temac_local
*lp
, struct platform_device
*pdev
)
65 struct ll_temac_platform_data
*pdata
= dev_get_platdata(&pdev
->dev
);
66 struct device_node
*np
= dev_of_node(&pdev
->dev
);
73 /* Get MDIO bus frequency (if specified) */
76 of_property_read_u32(np
, "clock-frequency", &bus_hz
);
78 bus_hz
= pdata
->mdio_clk_freq
;
80 /* Calculate a reasonable divisor for the clock rate */
81 clk_div
= 0x3f; /* worst-case default setting */
83 clk_div
= bus_hz
/ (2500 * 1000 * 2) - 1;
90 /* Enable the MDIO bus by asserting the enable bit and writing
91 * in the clock config */
92 temac_indirect_out32(lp
, XTE_MC_OFFSET
, 1 << 6 | clk_div
);
94 bus
= devm_mdiobus_alloc(&pdev
->dev
);
99 of_address_to_resource(np
, 0, &res
);
100 snprintf(bus
->id
, MII_BUS_ID_SIZE
, "%.8llx",
101 (unsigned long long)res
.start
);
103 snprintf(bus
->id
, MII_BUS_ID_SIZE
, "%.8llx",
108 bus
->name
= "Xilinx TEMAC MDIO";
109 bus
->read
= temac_mdio_read
;
110 bus
->write
= temac_mdio_write
;
111 bus
->parent
= lp
->dev
;
115 rc
= of_mdiobus_register(bus
, np
);
119 dev_dbg(lp
->dev
, "MDIO bus registered; MC:%x\n",
120 temac_indirect_in32(lp
, XTE_MC_OFFSET
));
124 void temac_mdio_teardown(struct temac_local
*lp
)
126 mdiobus_unregister(lp
->mii_bus
);