xref: /openbmc/u-boot/board/gdsys/a38x/ihs_phys.c (revision 15f05610438981297ff628bb87e6d5789ee3fad0)
1*15f05610SDirk Eibach #include <common.h>
2*15f05610SDirk Eibach #include <dm.h>
3*15f05610SDirk Eibach #include <miiphy.h>
4*15f05610SDirk Eibach #include <asm-generic/gpio.h>
5*15f05610SDirk Eibach 
6*15f05610SDirk Eibach #include "ihs_phys.h"
7*15f05610SDirk Eibach #include "dt_helpers.h"
8*15f05610SDirk Eibach 
9*15f05610SDirk Eibach enum {
10*15f05610SDirk Eibach 	PORTTYPE_MAIN_CAT,
11*15f05610SDirk Eibach 	PORTTYPE_TOP_CAT,
12*15f05610SDirk Eibach 	PORTTYPE_16C_16F,
13*15f05610SDirk Eibach 	PORTTYPE_UNKNOWN
14*15f05610SDirk Eibach };
15*15f05610SDirk Eibach 
16*15f05610SDirk Eibach static struct porttype {
17*15f05610SDirk Eibach 	bool phy_invert_in_pol;
18*15f05610SDirk Eibach 	bool phy_invert_out_pol;
19*15f05610SDirk Eibach } porttypes[] = {
20*15f05610SDirk Eibach 	{ true, false },
21*15f05610SDirk Eibach 	{ false, true },
22*15f05610SDirk Eibach 	{ false, false },
23*15f05610SDirk Eibach };
24*15f05610SDirk Eibach 
ihs_phy_config(struct phy_device * phydev,bool qinpn,bool qoutpn)25*15f05610SDirk Eibach static void ihs_phy_config(struct phy_device *phydev, bool qinpn, bool qoutpn)
26*15f05610SDirk Eibach {
27*15f05610SDirk Eibach 	u16 reg;
28*15f05610SDirk Eibach 
29*15f05610SDirk Eibach 	phy_config(phydev);
30*15f05610SDirk Eibach 
31*15f05610SDirk Eibach 	/* enable QSGMII autonegotiation with flow control */
32*15f05610SDirk Eibach 	phy_write(phydev, MDIO_DEVAD_NONE, 22, 0x0004);
33*15f05610SDirk Eibach 	reg = phy_read(phydev, MDIO_DEVAD_NONE, 16);
34*15f05610SDirk Eibach 	reg |= (3 << 6);
35*15f05610SDirk Eibach 	phy_write(phydev, MDIO_DEVAD_NONE, 16, reg);
36*15f05610SDirk Eibach 
37*15f05610SDirk Eibach 	/*
38*15f05610SDirk Eibach 	 * invert QSGMII Q_INP/N and Q_OUTP/N if required
39*15f05610SDirk Eibach 	 * and perform global reset
40*15f05610SDirk Eibach 	 */
41*15f05610SDirk Eibach 	reg = phy_read(phydev, MDIO_DEVAD_NONE, 26);
42*15f05610SDirk Eibach 	if (qinpn)
43*15f05610SDirk Eibach 		reg |= (1 << 13);
44*15f05610SDirk Eibach 	if (qoutpn)
45*15f05610SDirk Eibach 		reg |= (1 << 12);
46*15f05610SDirk Eibach 	reg |= (1 << 15);
47*15f05610SDirk Eibach 	phy_write(phydev, MDIO_DEVAD_NONE, 26, reg);
48*15f05610SDirk Eibach 
49*15f05610SDirk Eibach 	/* advertise 1000BASE-T full-duplex only  */
50*15f05610SDirk Eibach 	phy_write(phydev, MDIO_DEVAD_NONE, 22, 0x0000);
51*15f05610SDirk Eibach 	reg = phy_read(phydev, MDIO_DEVAD_NONE, 4);
52*15f05610SDirk Eibach 	reg &= ~0x1e0;
53*15f05610SDirk Eibach 	phy_write(phydev, MDIO_DEVAD_NONE, 4, reg);
54*15f05610SDirk Eibach 	reg = phy_read(phydev, MDIO_DEVAD_NONE, 9);
55*15f05610SDirk Eibach 	reg = (reg & ~0x300) | 0x200;
56*15f05610SDirk Eibach 	phy_write(phydev, MDIO_DEVAD_NONE, 9, reg);
57*15f05610SDirk Eibach 
58*15f05610SDirk Eibach 	/* copper power up */
59*15f05610SDirk Eibach 	reg = phy_read(phydev, MDIO_DEVAD_NONE, 16);
60*15f05610SDirk Eibach 	reg &= ~0x0004;
61*15f05610SDirk Eibach 	phy_write(phydev, MDIO_DEVAD_NONE, 16, reg);
62*15f05610SDirk Eibach }
63*15f05610SDirk Eibach 
calculate_octo_phy_mask(void)64*15f05610SDirk Eibach uint calculate_octo_phy_mask(void)
65*15f05610SDirk Eibach {
66*15f05610SDirk Eibach 	uint k;
67*15f05610SDirk Eibach 	uint octo_phy_mask = 0;
68*15f05610SDirk Eibach 	struct gpio_desc gpio = {};
69*15f05610SDirk Eibach 	char gpio_name[64];
70*15f05610SDirk Eibach 	static const char * const dev_name[] = {"pca9698@23", "pca9698@21",
71*15f05610SDirk Eibach 						"pca9698@24", "pca9698@25",
72*15f05610SDirk Eibach 						"pca9698@26"};
73*15f05610SDirk Eibach 
74*15f05610SDirk Eibach 	/* mark all octo phys that should be present */
75*15f05610SDirk Eibach 	for (k = 0; k < 5; ++k) {
76*15f05610SDirk Eibach 		snprintf(gpio_name, 64, "cat-gpio-%u", k);
77*15f05610SDirk Eibach 
78*15f05610SDirk Eibach 		if (request_gpio_by_name(&gpio, dev_name[k], 0x20, gpio_name))
79*15f05610SDirk Eibach 			continue;
80*15f05610SDirk Eibach 
81*15f05610SDirk Eibach 		/* check CAT flag */
82*15f05610SDirk Eibach 		if (dm_gpio_get_value(&gpio))
83*15f05610SDirk Eibach 			octo_phy_mask |= (1 << (k * 2));
84*15f05610SDirk Eibach 		else
85*15f05610SDirk Eibach 			/* If CAT == 0, there's no second octo phy -> skip */
86*15f05610SDirk Eibach 			continue;
87*15f05610SDirk Eibach 
88*15f05610SDirk Eibach 		snprintf(gpio_name, 64, "second-octo-gpio-%u", k);
89*15f05610SDirk Eibach 
90*15f05610SDirk Eibach 		if (request_gpio_by_name(&gpio, dev_name[k], 0x27, gpio_name)) {
91*15f05610SDirk Eibach 			/* default: second octo phy is present */
92*15f05610SDirk Eibach 			octo_phy_mask |= (1 << (k * 2 + 1));
93*15f05610SDirk Eibach 			continue;
94*15f05610SDirk Eibach 		}
95*15f05610SDirk Eibach 
96*15f05610SDirk Eibach 		if (dm_gpio_get_value(&gpio) == 0)
97*15f05610SDirk Eibach 			octo_phy_mask |= (1 << (k * 2 + 1));
98*15f05610SDirk Eibach 	}
99*15f05610SDirk Eibach 
100*15f05610SDirk Eibach 	return octo_phy_mask;
101*15f05610SDirk Eibach }
102*15f05610SDirk Eibach 
register_miiphy_bus(uint k,struct mii_dev ** bus)103*15f05610SDirk Eibach int register_miiphy_bus(uint k, struct mii_dev **bus)
104*15f05610SDirk Eibach {
105*15f05610SDirk Eibach 	int retval;
106*15f05610SDirk Eibach 	struct mii_dev *mdiodev = mdio_alloc();
107*15f05610SDirk Eibach 	char *name = bb_miiphy_buses[k].name;
108*15f05610SDirk Eibach 
109*15f05610SDirk Eibach 	if (!mdiodev)
110*15f05610SDirk Eibach 		return -ENOMEM;
111*15f05610SDirk Eibach 	strncpy(mdiodev->name,
112*15f05610SDirk Eibach 		name,
113*15f05610SDirk Eibach 		MDIO_NAME_LEN);
114*15f05610SDirk Eibach 	mdiodev->read = bb_miiphy_read;
115*15f05610SDirk Eibach 	mdiodev->write = bb_miiphy_write;
116*15f05610SDirk Eibach 
117*15f05610SDirk Eibach 	retval = mdio_register(mdiodev);
118*15f05610SDirk Eibach 	if (retval < 0)
119*15f05610SDirk Eibach 		return retval;
120*15f05610SDirk Eibach 	*bus = miiphy_get_dev_by_name(name);
121*15f05610SDirk Eibach 
122*15f05610SDirk Eibach 	return 0;
123*15f05610SDirk Eibach }
124*15f05610SDirk Eibach 
get_porttype(uint octo_phy_mask,uint k)125*15f05610SDirk Eibach struct porttype *get_porttype(uint octo_phy_mask, uint k)
126*15f05610SDirk Eibach {
127*15f05610SDirk Eibach 	uint octo_index = k * 4;
128*15f05610SDirk Eibach 
129*15f05610SDirk Eibach 	if (!k) {
130*15f05610SDirk Eibach 		if (octo_phy_mask & 0x01)
131*15f05610SDirk Eibach 			return &porttypes[PORTTYPE_MAIN_CAT];
132*15f05610SDirk Eibach 		else if (!(octo_phy_mask & 0x03))
133*15f05610SDirk Eibach 			return &porttypes[PORTTYPE_16C_16F];
134*15f05610SDirk Eibach 	} else {
135*15f05610SDirk Eibach 		if (octo_phy_mask & (1 << octo_index))
136*15f05610SDirk Eibach 			return &porttypes[PORTTYPE_TOP_CAT];
137*15f05610SDirk Eibach 	}
138*15f05610SDirk Eibach 
139*15f05610SDirk Eibach 	return NULL;
140*15f05610SDirk Eibach }
141*15f05610SDirk Eibach 
init_single_phy(struct porttype * porttype,struct mii_dev * bus,uint bus_idx,uint m,uint phy_idx)142*15f05610SDirk Eibach int init_single_phy(struct porttype *porttype, struct mii_dev *bus,
143*15f05610SDirk Eibach 		    uint bus_idx, uint m, uint phy_idx)
144*15f05610SDirk Eibach {
145*15f05610SDirk Eibach 	struct phy_device *phydev = phy_find_by_mask(
146*15f05610SDirk Eibach 		bus, 1 << (m * 8 + phy_idx),
147*15f05610SDirk Eibach 		PHY_INTERFACE_MODE_MII);
148*15f05610SDirk Eibach 
149*15f05610SDirk Eibach 	printf(" %u", bus_idx * 32 + m * 8 + phy_idx);
150*15f05610SDirk Eibach 
151*15f05610SDirk Eibach 	if (!phydev)
152*15f05610SDirk Eibach 		puts("!");
153*15f05610SDirk Eibach 	else
154*15f05610SDirk Eibach 		ihs_phy_config(phydev, porttype->phy_invert_in_pol,
155*15f05610SDirk Eibach 			       porttype->phy_invert_out_pol);
156*15f05610SDirk Eibach 
157*15f05610SDirk Eibach 	return 0;
158*15f05610SDirk Eibach }
159*15f05610SDirk Eibach 
init_octo_phys(uint octo_phy_mask)160*15f05610SDirk Eibach int init_octo_phys(uint octo_phy_mask)
161*15f05610SDirk Eibach {
162*15f05610SDirk Eibach 	uint bus_idx;
163*15f05610SDirk Eibach 
164*15f05610SDirk Eibach 	/* there are up to four octo-phys on each mdio bus */
165*15f05610SDirk Eibach 	for (bus_idx = 0; bus_idx < bb_miiphy_buses_num; ++bus_idx) {
166*15f05610SDirk Eibach 		uint m;
167*15f05610SDirk Eibach 		uint octo_index = bus_idx * 4;
168*15f05610SDirk Eibach 		struct mii_dev *bus = NULL;
169*15f05610SDirk Eibach 		struct porttype *porttype = NULL;
170*15f05610SDirk Eibach 		int ret;
171*15f05610SDirk Eibach 
172*15f05610SDirk Eibach 		porttype = get_porttype(octo_phy_mask, bus_idx);
173*15f05610SDirk Eibach 
174*15f05610SDirk Eibach 		if (!porttype)
175*15f05610SDirk Eibach 			continue;
176*15f05610SDirk Eibach 
177*15f05610SDirk Eibach 		for (m = 0; m < 4; ++m) {
178*15f05610SDirk Eibach 			uint phy_idx;
179*15f05610SDirk Eibach 
180*15f05610SDirk Eibach 			/**
181*15f05610SDirk Eibach 			 * Register a bus device if there is at least one phy
182*15f05610SDirk Eibach 			 * on the current bus
183*15f05610SDirk Eibach 			 */
184*15f05610SDirk Eibach 			if (!m && octo_phy_mask & (0xf << octo_index)) {
185*15f05610SDirk Eibach 				ret = register_miiphy_bus(bus_idx, &bus);
186*15f05610SDirk Eibach 				if (ret)
187*15f05610SDirk Eibach 					return ret;
188*15f05610SDirk Eibach 			}
189*15f05610SDirk Eibach 
190*15f05610SDirk Eibach 			if (!(octo_phy_mask & BIT(octo_index + m)))
191*15f05610SDirk Eibach 				continue;
192*15f05610SDirk Eibach 
193*15f05610SDirk Eibach 			for (phy_idx = 0; phy_idx < 8; ++phy_idx)
194*15f05610SDirk Eibach 				init_single_phy(porttype, bus, bus_idx, m,
195*15f05610SDirk Eibach 						phy_idx);
196*15f05610SDirk Eibach 		}
197*15f05610SDirk Eibach 	}
198*15f05610SDirk Eibach 
199*15f05610SDirk Eibach 	return 0;
200*15f05610SDirk Eibach }
201*15f05610SDirk Eibach 
202*15f05610SDirk Eibach /*
203*15f05610SDirk Eibach  * MII GPIO bitbang implementation
204*15f05610SDirk Eibach  * MDC MDIO bus
205*15f05610SDirk Eibach  * 13  14   PHY1-4
206*15f05610SDirk Eibach  * 25  45   PHY5-8
207*15f05610SDirk Eibach  * 46  24   PHY9-10
208*15f05610SDirk Eibach  */
209*15f05610SDirk Eibach 
210*15f05610SDirk Eibach struct gpio_mii {
211*15f05610SDirk Eibach 	int index;
212*15f05610SDirk Eibach 	struct gpio_desc mdc_gpio;
213*15f05610SDirk Eibach 	struct gpio_desc mdio_gpio;
214*15f05610SDirk Eibach 	int mdc_num;
215*15f05610SDirk Eibach 	int mdio_num;
216*15f05610SDirk Eibach 	int mdio_value;
217*15f05610SDirk Eibach } gpio_mii_set[] = {
218*15f05610SDirk Eibach 	{ 0, {}, {}, 13, 14, 1 },
219*15f05610SDirk Eibach 	{ 1, {}, {}, 25, 45, 1 },
220*15f05610SDirk Eibach 	{ 2, {}, {}, 46, 24, 1 },
221*15f05610SDirk Eibach };
222*15f05610SDirk Eibach 
mii_mdio_init(struct bb_miiphy_bus * bus)223*15f05610SDirk Eibach static int mii_mdio_init(struct bb_miiphy_bus *bus)
224*15f05610SDirk Eibach {
225*15f05610SDirk Eibach 	struct gpio_mii *gpio_mii = bus->priv;
226*15f05610SDirk Eibach 	char name[32] = {};
227*15f05610SDirk Eibach 	struct udevice *gpio_dev1 = NULL;
228*15f05610SDirk Eibach 	struct udevice *gpio_dev2 = NULL;
229*15f05610SDirk Eibach 
230*15f05610SDirk Eibach 	if (uclass_get_device_by_name(UCLASS_GPIO, "gpio@18100", &gpio_dev1) ||
231*15f05610SDirk Eibach 	    uclass_get_device_by_name(UCLASS_GPIO, "gpio@18140", &gpio_dev2)) {
232*15f05610SDirk Eibach 		printf("Could not get GPIO device.\n");
233*15f05610SDirk Eibach 		return 1;
234*15f05610SDirk Eibach 	}
235*15f05610SDirk Eibach 
236*15f05610SDirk Eibach 	if (gpio_mii->mdc_num > 31) {
237*15f05610SDirk Eibach 		gpio_mii->mdc_gpio.dev = gpio_dev2;
238*15f05610SDirk Eibach 		gpio_mii->mdc_gpio.offset = gpio_mii->mdc_num - 32;
239*15f05610SDirk Eibach 	} else {
240*15f05610SDirk Eibach 		gpio_mii->mdc_gpio.dev = gpio_dev1;
241*15f05610SDirk Eibach 		gpio_mii->mdc_gpio.offset = gpio_mii->mdc_num;
242*15f05610SDirk Eibach 	}
243*15f05610SDirk Eibach 	gpio_mii->mdc_gpio.flags = 0;
244*15f05610SDirk Eibach 	snprintf(name, 32, "bb_miiphy_bus-%d-mdc", gpio_mii->index);
245*15f05610SDirk Eibach 	dm_gpio_request(&gpio_mii->mdc_gpio, name);
246*15f05610SDirk Eibach 
247*15f05610SDirk Eibach 	if (gpio_mii->mdio_num > 31) {
248*15f05610SDirk Eibach 		gpio_mii->mdio_gpio.dev = gpio_dev2;
249*15f05610SDirk Eibach 		gpio_mii->mdio_gpio.offset = gpio_mii->mdio_num - 32;
250*15f05610SDirk Eibach 	} else {
251*15f05610SDirk Eibach 		gpio_mii->mdio_gpio.dev = gpio_dev1;
252*15f05610SDirk Eibach 		gpio_mii->mdio_gpio.offset = gpio_mii->mdio_num;
253*15f05610SDirk Eibach 	}
254*15f05610SDirk Eibach 	gpio_mii->mdio_gpio.flags = 0;
255*15f05610SDirk Eibach 	snprintf(name, 32, "bb_miiphy_bus-%d-mdio", gpio_mii->index);
256*15f05610SDirk Eibach 	dm_gpio_request(&gpio_mii->mdio_gpio, name);
257*15f05610SDirk Eibach 
258*15f05610SDirk Eibach 	dm_gpio_set_dir_flags(&gpio_mii->mdc_gpio, GPIOD_IS_OUT);
259*15f05610SDirk Eibach 	dm_gpio_set_value(&gpio_mii->mdc_gpio, 1);
260*15f05610SDirk Eibach 
261*15f05610SDirk Eibach 	return 0;
262*15f05610SDirk Eibach }
263*15f05610SDirk Eibach 
mii_mdio_active(struct bb_miiphy_bus * bus)264*15f05610SDirk Eibach static int mii_mdio_active(struct bb_miiphy_bus *bus)
265*15f05610SDirk Eibach {
266*15f05610SDirk Eibach 	struct gpio_mii *gpio_mii = bus->priv;
267*15f05610SDirk Eibach 
268*15f05610SDirk Eibach 	dm_gpio_set_value(&gpio_mii->mdc_gpio, gpio_mii->mdio_value);
269*15f05610SDirk Eibach 
270*15f05610SDirk Eibach 	return 0;
271*15f05610SDirk Eibach }
272*15f05610SDirk Eibach 
mii_mdio_tristate(struct bb_miiphy_bus * bus)273*15f05610SDirk Eibach static int mii_mdio_tristate(struct bb_miiphy_bus *bus)
274*15f05610SDirk Eibach {
275*15f05610SDirk Eibach 	struct gpio_mii *gpio_mii = bus->priv;
276*15f05610SDirk Eibach 
277*15f05610SDirk Eibach 	dm_gpio_set_dir_flags(&gpio_mii->mdio_gpio, GPIOD_IS_IN);
278*15f05610SDirk Eibach 
279*15f05610SDirk Eibach 	return 0;
280*15f05610SDirk Eibach }
281*15f05610SDirk Eibach 
mii_set_mdio(struct bb_miiphy_bus * bus,int v)282*15f05610SDirk Eibach static int mii_set_mdio(struct bb_miiphy_bus *bus, int v)
283*15f05610SDirk Eibach {
284*15f05610SDirk Eibach 	struct gpio_mii *gpio_mii = bus->priv;
285*15f05610SDirk Eibach 
286*15f05610SDirk Eibach 	dm_gpio_set_dir_flags(&gpio_mii->mdio_gpio, GPIOD_IS_OUT);
287*15f05610SDirk Eibach 	dm_gpio_set_value(&gpio_mii->mdio_gpio, v);
288*15f05610SDirk Eibach 	gpio_mii->mdio_value = v;
289*15f05610SDirk Eibach 
290*15f05610SDirk Eibach 	return 0;
291*15f05610SDirk Eibach }
292*15f05610SDirk Eibach 
mii_get_mdio(struct bb_miiphy_bus * bus,int * v)293*15f05610SDirk Eibach static int mii_get_mdio(struct bb_miiphy_bus *bus, int *v)
294*15f05610SDirk Eibach {
295*15f05610SDirk Eibach 	struct gpio_mii *gpio_mii = bus->priv;
296*15f05610SDirk Eibach 
297*15f05610SDirk Eibach 	dm_gpio_set_dir_flags(&gpio_mii->mdio_gpio, GPIOD_IS_IN);
298*15f05610SDirk Eibach 	*v = (dm_gpio_get_value(&gpio_mii->mdio_gpio));
299*15f05610SDirk Eibach 
300*15f05610SDirk Eibach 	return 0;
301*15f05610SDirk Eibach }
302*15f05610SDirk Eibach 
mii_set_mdc(struct bb_miiphy_bus * bus,int v)303*15f05610SDirk Eibach static int mii_set_mdc(struct bb_miiphy_bus *bus, int v)
304*15f05610SDirk Eibach {
305*15f05610SDirk Eibach 	struct gpio_mii *gpio_mii = bus->priv;
306*15f05610SDirk Eibach 
307*15f05610SDirk Eibach 	dm_gpio_set_value(&gpio_mii->mdc_gpio, v);
308*15f05610SDirk Eibach 
309*15f05610SDirk Eibach 	return 0;
310*15f05610SDirk Eibach }
311*15f05610SDirk Eibach 
mii_delay(struct bb_miiphy_bus * bus)312*15f05610SDirk Eibach static int mii_delay(struct bb_miiphy_bus *bus)
313*15f05610SDirk Eibach {
314*15f05610SDirk Eibach 	udelay(1);
315*15f05610SDirk Eibach 
316*15f05610SDirk Eibach 	return 0;
317*15f05610SDirk Eibach }
318*15f05610SDirk Eibach 
319*15f05610SDirk Eibach struct bb_miiphy_bus bb_miiphy_buses[] = {
320*15f05610SDirk Eibach 	{
321*15f05610SDirk Eibach 		.name = "ihs0",
322*15f05610SDirk Eibach 		.init = mii_mdio_init,
323*15f05610SDirk Eibach 		.mdio_active = mii_mdio_active,
324*15f05610SDirk Eibach 		.mdio_tristate = mii_mdio_tristate,
325*15f05610SDirk Eibach 		.set_mdio = mii_set_mdio,
326*15f05610SDirk Eibach 		.get_mdio = mii_get_mdio,
327*15f05610SDirk Eibach 		.set_mdc = mii_set_mdc,
328*15f05610SDirk Eibach 		.delay = mii_delay,
329*15f05610SDirk Eibach 		.priv = &gpio_mii_set[0],
330*15f05610SDirk Eibach 	},
331*15f05610SDirk Eibach 	{
332*15f05610SDirk Eibach 		.name = "ihs1",
333*15f05610SDirk Eibach 		.init = mii_mdio_init,
334*15f05610SDirk Eibach 		.mdio_active = mii_mdio_active,
335*15f05610SDirk Eibach 		.mdio_tristate = mii_mdio_tristate,
336*15f05610SDirk Eibach 		.set_mdio = mii_set_mdio,
337*15f05610SDirk Eibach 		.get_mdio = mii_get_mdio,
338*15f05610SDirk Eibach 		.set_mdc = mii_set_mdc,
339*15f05610SDirk Eibach 		.delay = mii_delay,
340*15f05610SDirk Eibach 		.priv = &gpio_mii_set[1],
341*15f05610SDirk Eibach 	},
342*15f05610SDirk Eibach 	{
343*15f05610SDirk Eibach 		.name = "ihs2",
344*15f05610SDirk Eibach 		.init = mii_mdio_init,
345*15f05610SDirk Eibach 		.mdio_active = mii_mdio_active,
346*15f05610SDirk Eibach 		.mdio_tristate = mii_mdio_tristate,
347*15f05610SDirk Eibach 		.set_mdio = mii_set_mdio,
348*15f05610SDirk Eibach 		.get_mdio = mii_get_mdio,
349*15f05610SDirk Eibach 		.set_mdc = mii_set_mdc,
350*15f05610SDirk Eibach 		.delay = mii_delay,
351*15f05610SDirk Eibach 		.priv = &gpio_mii_set[2],
352*15f05610SDirk Eibach 	},
353*15f05610SDirk Eibach };
354*15f05610SDirk Eibach 
355*15f05610SDirk Eibach int bb_miiphy_buses_num = ARRAY_SIZE(bb_miiphy_buses);
356