2 * MDIO bus driver for the Xilinx TEMAC device
4 * Copyright (c) 2009 Secret Lab Technologies, Ltd.
8 #include <linux/netdevice.h>
9 #include <linux/mutex.h>
10 #include <linux/phy.h>
12 #include <linux/of_device.h>
13 #include <linux/of_mdio.h>
17 /* ---------------------------------------------------------------------
20 static int temac_mdio_read(struct mii_bus
*bus
, int phy_id
, int reg
)
22 struct temac_local
*lp
= bus
->priv
;
25 /* Write the PHY address to the MIIM Access Initiator register.
26 * When the transfer completes, the PHY register value will appear
27 * in the LSW0 register */
28 mutex_lock(&lp
->indirect_mutex
);
29 temac_iow(lp
, XTE_LSW0_OFFSET
, (phy_id
<< 5) | reg
);
30 rc
= temac_indirect_in32(lp
, XTE_MIIMAI_OFFSET
);
31 mutex_unlock(&lp
->indirect_mutex
);
33 dev_dbg(lp
->dev
, "temac_mdio_read(phy_id=%i, reg=%x) == %x\n",
39 static int temac_mdio_write(struct mii_bus
*bus
, int phy_id
, int reg
, u16 val
)
41 struct temac_local
*lp
= bus
->priv
;
43 dev_dbg(lp
->dev
, "temac_mdio_write(phy_id=%i, reg=%x, val=%x)\n",
46 /* First write the desired value into the write data register
47 * and then write the address into the access initiator register
49 mutex_lock(&lp
->indirect_mutex
);
50 temac_indirect_out32(lp
, XTE_MGTDR_OFFSET
, val
);
51 temac_indirect_out32(lp
, XTE_MIIMAI_OFFSET
, (phy_id
<< 5) | reg
);
52 mutex_unlock(&lp
->indirect_mutex
);
57 int temac_mdio_setup(struct temac_local
*lp
, struct device_node
*np
)
65 /* Calculate a reasonable divisor for the clock rate */
66 clk_div
= 0x3f; /* worst-case default setting */
67 bus_hz
= of_get_property(np
, "clock-frequency", &size
);
68 if (bus_hz
&& size
>= sizeof(*bus_hz
)) {
69 clk_div
= (*bus_hz
) / (2500 * 1000 * 2) - 1;
76 /* Enable the MDIO bus by asserting the enable bit and writing
77 * in the clock config */
78 mutex_lock(&lp
->indirect_mutex
);
79 temac_indirect_out32(lp
, XTE_MC_OFFSET
, 1 << 6 | clk_div
);
80 mutex_unlock(&lp
->indirect_mutex
);
82 bus
= mdiobus_alloc();
86 of_address_to_resource(np
, 0, &res
);
87 snprintf(bus
->id
, MII_BUS_ID_SIZE
, "%.8llx",
88 (unsigned long long)res
.start
);
90 bus
->name
= "Xilinx TEMAC MDIO";
91 bus
->read
= temac_mdio_read
;
92 bus
->write
= temac_mdio_write
;
93 bus
->parent
= lp
->dev
;
94 bus
->irq
= lp
->mdio_irqs
; /* preallocated IRQ table */
98 rc
= of_mdiobus_register(bus
, np
);
102 mutex_lock(&lp
->indirect_mutex
);
103 dev_dbg(lp
->dev
, "MDIO bus registered; MC:%x\n",
104 temac_indirect_in32(lp
, XTE_MC_OFFSET
));
105 mutex_unlock(&lp
->indirect_mutex
);
113 void temac_mdio_teardown(struct temac_local
*lp
)
115 mdiobus_unregister(lp
->mii_bus
);
116 kfree(lp
->mii_bus
->irq
);
117 mdiobus_free(lp
->mii_bus
);