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