2 * SPDX-License-Identifier: GPL-2.0 IBM-pibs
4 /*-----------------------------------------------------------------------------+
8 | Function: This module has utilities for accessing the MII PHY through
13 +-----------------------------------------------------------------------------*/
15 /* define DEBUG for debugging output (obviously ;-)) */
21 #include <asm/processor.h>
23 #include <ppc_asm.tmpl>
25 #include <asm/ppc4xx.h>
26 #include <asm/ppc4xx-emac.h>
27 #include <asm/ppc4xx-mal.h>
30 #if !defined(CONFIG_PHY_CLK_FREQ)
31 #define CONFIG_PHY_CLK_FREQ 0
34 /***********************************************************/
35 /* Dump out to the screen PHY regs */
36 /***********************************************************/
38 void miiphy_dump (char *devname, unsigned char addr)
43 for (i = 0; i < 0x1A; i++) {
44 if (miiphy_read (devname, addr, i, &data)) {
45 printf ("read error for reg %lx\n", i);
48 printf ("Phy reg %lx ==> %4x\n", i, data);
50 /* jump to the next set of regs */
57 /***********************************************************/
58 /* (Re)start autonegotiation */
59 /***********************************************************/
60 int phy_setup_aneg (char *devname, unsigned char addr)
64 #if defined(CONFIG_PHY_DYNAMIC_ANEG)
66 * Set up advertisement based on capablilities reported by the PHY.
67 * This should work for both copper and fiber.
70 #if defined(CONFIG_PHY_GIGE)
74 miiphy_read (devname, addr, MII_BMSR, &bmsr);
76 #if defined(CONFIG_PHY_GIGE)
77 if (bmsr & BMSR_ESTATEN)
78 miiphy_read (devname, addr, MII_ESTATUS, &exsr);
80 if (exsr & (ESTATUS_1000XF | ESTATUS_1000XH)) {
84 if (exsr & ESTATUS_1000XF)
85 anar |= ADVERTISE_1000XFULL;
87 if (exsr & ESTATUS_1000XH)
88 anar |= ADVERTISE_1000XHALF;
90 miiphy_write (devname, addr, MII_ADVERTISE, anar);
96 miiphy_read (devname, addr, MII_ADVERTISE, &anar);
97 anar &= ~(0x5000 | LPA_100BASE4 | LPA_100FULL |
98 LPA_100HALF | LPA_10FULL | LPA_10HALF);
100 miiphy_read (devname, addr, MII_CTRL1000, &btcr);
101 btcr &= ~(0x00FF | PHY_1000BTCR_1000FD | PHY_1000BTCR_1000HD);
103 if (bmsr & BMSR_100BASE4)
104 anar |= LPA_100BASE4;
106 if (bmsr & BMSR_100FULL)
109 if (bmsr & BMSR_100HALF)
112 if (bmsr & BMSR_10FULL)
115 if (bmsr & BMSR_10HALF)
118 miiphy_write (devname, addr, MII_ADVERTISE, anar);
120 #if defined(CONFIG_PHY_GIGE)
121 if (exsr & ESTATUS_1000_TFULL)
122 btcr |= PHY_1000BTCR_1000FD;
124 if (exsr & ESTATUS_1000_THALF)
125 btcr |= PHY_1000BTCR_1000HD;
127 miiphy_write (devname, addr, MII_CTRL1000, btcr);
131 #else /* defined(CONFIG_PHY_DYNAMIC_ANEG) */
133 * Set up standard advertisement
137 miiphy_read (devname, addr, MII_ADVERTISE, &adv);
138 adv |= (LPA_LPACK | LPA_100FULL | LPA_100HALF |
139 LPA_10FULL | LPA_10HALF);
140 miiphy_write (devname, addr, MII_ADVERTISE, adv);
142 miiphy_read (devname, addr, MII_CTRL1000, &adv);
144 miiphy_write (devname, addr, MII_CTRL1000, adv);
146 #endif /* defined(CONFIG_PHY_DYNAMIC_ANEG) */
148 /* Start/Restart aneg */
149 miiphy_read (devname, addr, MII_BMCR, &bmcr);
150 bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART);
151 miiphy_write (devname, addr, MII_BMCR, bmcr);
156 /***********************************************************/
157 /* read a phy reg and return the value with a rc */
158 /***********************************************************/
160 * Find out of the choice for the emac for MDIO is from the bridges,
161 * i.e. ZMII or RGMII as approporiate. If the bridges are not used
162 * to determine the emac for MDIO, then is the SDR0_ETH_CFG[MDIO_SEL]
163 * used? If so, then this routine below does not apply to the 460EX/GT.
165 * sr: Currently on 460EX only EMAC0 works with MDIO, so we always
166 * return EMAC0 offset here
167 * vg: For 460EX/460GT if internal GPCS PHY address is specified
168 * return appropriate EMAC offset
170 unsigned int miiphy_getemac_offset(u8 addr)
172 #if defined(CONFIG_440) && \
173 !defined(CONFIG_440SP) && !defined(CONFIG_440SPE) && \
174 !defined(CONFIG_460EX) && !defined(CONFIG_460GT)
176 unsigned long eoffset;
178 /* Need to find out which mdi port we're using */
179 zmii = in_be32((void *)ZMII0_FER);
181 if (zmii & (ZMII_FER_MDI << ZMII_FER_V (0)))
185 else if (zmii & (ZMII_FER_MDI << ZMII_FER_V (1)))
189 else if (zmii & (ZMII_FER_MDI << ZMII_FER_V (2)))
193 else if (zmii & (ZMII_FER_MDI << ZMII_FER_V (3)))
198 /* None of the mdi ports are enabled! */
200 zmii |= ZMII_FER_MDI << ZMII_FER_V (0);
201 out_be32((void *)ZMII0_FER, zmii);
203 /* need to soft reset port 0 */
204 zmii = in_be32((void *)EMAC0_MR0);
205 zmii |= EMAC_MR0_SRST;
206 out_be32((void *)EMAC0_MR0, zmii);
212 #if defined(CONFIG_405EX)
216 rgmii = in_be32((void *)RGMII_FER);
217 if (rgmii & (1 << (19 - devnum)))
221 #if defined(CONFIG_460EX) || defined(CONFIG_460GT)
225 #if defined(CONFIG_HAS_ETH1) && defined(CONFIG_GPCS_PHY1_ADDR)
226 case CONFIG_GPCS_PHY1_ADDR:
227 if (addr == EMAC_MR1_IPPA_GET(in_be32((void *)EMAC0_MR1 + 0x100)))
231 #if defined(CONFIG_HAS_ETH2) && defined(CONFIG_GPCS_PHY2_ADDR)
232 case CONFIG_GPCS_PHY2_ADDR:
233 if (addr == EMAC_MR1_IPPA_GET(in_be32((void *)EMAC0_MR1 + 0x300)))
237 #if defined(CONFIG_HAS_ETH3) && defined(CONFIG_GPCS_PHY3_ADDR)
238 case CONFIG_GPCS_PHY3_ADDR:
239 if (addr == EMAC_MR1_IPPA_GET(in_be32((void *)EMAC0_MR1 + 0x400)))
254 static int emac_miiphy_wait(u32 emac_reg)
259 /* wait for completion */
262 sta_reg = in_be32((void *)EMAC0_STACR + emac_reg);
264 debug("%s [%d]: Timeout! EMAC0_STACR=0x%0x\n", __func__,
269 } while ((sta_reg & EMAC_STACR_OC) == EMAC_STACR_OC_MASK);
274 static int emac_miiphy_command(u8 addr, u8 reg, int cmd, u16 value)
279 emac_reg = miiphy_getemac_offset(addr);
281 /* wait for completion */
282 if (emac_miiphy_wait(emac_reg) != 0)
285 sta_reg = reg; /* reg address */
287 /* set clock (50MHz) and read flags */
288 #if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
289 defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
290 defined(CONFIG_460EX) || defined(CONFIG_460GT) || \
291 defined(CONFIG_405EX)
292 #if defined(CONFIG_IBM_EMAC4_V4) /* EMAC4 V4 changed bit setting */
293 sta_reg = (sta_reg & ~EMAC_STACR_OP_MASK) | cmd;
298 sta_reg = (sta_reg | cmd) & ~EMAC_STACR_CLK_100MHZ;
301 /* Some boards (mainly 405EP based) define the PHY clock freqency fixed */
302 sta_reg = sta_reg | CONFIG_PHY_CLK_FREQ;
303 sta_reg = sta_reg | ((u32)addr << 5); /* Phy address */
304 sta_reg = sta_reg | EMAC_STACR_OC_MASK; /* new IBM emac v4 */
305 if (cmd == EMAC_STACR_WRITE)
306 memcpy(&sta_reg, &value, 2); /* put in data */
308 out_be32((void *)EMAC0_STACR + emac_reg, sta_reg);
309 debug("%s [%d]: sta_reg=%08x\n", __func__, __LINE__, sta_reg);
311 /* wait for completion */
312 if (emac_miiphy_wait(emac_reg) != 0)
315 debug("%s [%d]: sta_reg=%08x\n", __func__, __LINE__, sta_reg);
316 if ((sta_reg & EMAC_STACR_PHYE) != 0)
322 int emac4xx_miiphy_read(struct mii_dev *bus, int addr, int devad, int reg)
324 unsigned long sta_reg;
325 unsigned long emac_reg;
327 emac_reg = miiphy_getemac_offset(addr);
329 if (emac_miiphy_command(addr, reg, EMAC_STACR_READ, 0) != 0)
332 sta_reg = in_be32((void *)EMAC0_STACR + emac_reg);
333 return sta_reg >> 16;
336 /***********************************************************/
337 /* write a phy reg and return the value with a rc */
338 /***********************************************************/
340 int emac4xx_miiphy_write(struct mii_dev *bus, int addr, int devad, int reg,
343 return emac_miiphy_command(addr, reg, EMAC_STACR_WRITE, value);