blob: 914cd0a9ab5968c08247673bcb373ced1ad9264e [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -07002/*
3 * Copyright 2015 Freescale Semiconductor, Inc.
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -07004 */
5
6#include <common.h>
Simon Glass0af6e2d2019-08-01 09:46:52 -06007#include <env.h>
Simon Glass0f2af882020-05-10 11:40:05 -06008#include <log.h>
Simon Glass0c364412019-12-28 10:44:48 -07009#include <net.h>
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -070010#include <netdev.h>
11#include <asm/io.h>
12#include <asm/arch/fsl_serdes.h>
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +053013#include <hwconfig.h>
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -070014#include <fsl_mdio.h>
15#include <malloc.h>
16#include <fm_eth.h>
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +053017#include <i2c.h>
18#include <miiphy.h>
Bogdan Purcareata08bc0142017-05-24 16:40:21 +000019#include <fsl-mc/fsl_mc.h>
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -070020#include <fsl-mc/ldpaa_wriop.h>
Simon Glassdbd79542020-05-10 11:40:11 -060021#include <linux/delay.h>
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -070022
23#include "../common/qixis.h"
24
Prabhakar Kushwaha122bcfd2015-11-09 16:42:07 +053025#include "ls2080aqds_qixis.h"
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -070026
Pratiyush Mohan Srivastava9abba112016-01-20 12:29:03 +053027#define MC_BOOT_ENV_VAR "mcinitcmd"
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -070028
Ioana Ciornei51a46492020-05-18 14:48:35 +030029#ifndef CONFIG_DM_ETH
30
Santan Kumar1afa9002017-05-05 15:42:29 +053031#if defined(CONFIG_FSL_MC_ENET) && !defined(CONFIG_SPL_BUILD)
Prabhakar Kushwaha122bcfd2015-11-09 16:42:07 +053032 /* - In LS2080A there are only 16 SERDES lanes, spread across 2 SERDES banks.
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -070033 * Bank 1 -> Lanes A, B, C, D, E, F, G, H
34 * Bank 2 -> Lanes A,B, C, D, E, F, G, H
35 */
36
Prabhakar Kushwaha122bcfd2015-11-09 16:42:07 +053037 /* Mapping of 16 SERDES lanes to LS2080A QDS board slots. A value of '0' here
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -070038 * means that the mapping must be determined dynamically, or that the lane
39 * maps to something other than a board slot.
40 */
41
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +053042static u8 lane_to_slot_fsm1[] = {
43 0, 0, 0, 0, 0, 0, 0, 0
44};
45
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -070046static u8 lane_to_slot_fsm2[] = {
47 0, 0, 0, 0, 0, 0, 0, 0
48};
49
50/* On the Vitesse VSC8234XHG SGMII riser card there are 4 SGMII PHYs
51 * housed.
52 */
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +053053
54static int xqsgii_riser_phy_addr[] = {
55 XQSGMII_CARD_PHY1_PORT0_ADDR,
56 XQSGMII_CARD_PHY2_PORT0_ADDR,
57 XQSGMII_CARD_PHY3_PORT0_ADDR,
58 XQSGMII_CARD_PHY4_PORT0_ADDR,
59 XQSGMII_CARD_PHY3_PORT2_ADDR,
60 XQSGMII_CARD_PHY1_PORT2_ADDR,
61 XQSGMII_CARD_PHY4_PORT2_ADDR,
62 XQSGMII_CARD_PHY2_PORT2_ADDR,
63};
64
65static int sgmii_riser_phy_addr[] = {
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -070066 SGMII_CARD_PORT1_PHY_ADDR,
67 SGMII_CARD_PORT2_PHY_ADDR,
68 SGMII_CARD_PORT3_PHY_ADDR,
69 SGMII_CARD_PORT4_PHY_ADDR,
70};
71
72/* Slot2 does not have EMI connections */
Priyanka Jaine2da6232016-11-03 17:50:51 +053073#define EMI_NONE 0xFF
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -070074#define EMI1_SLOT1 0
75#define EMI1_SLOT2 1
76#define EMI1_SLOT3 2
77#define EMI1_SLOT4 3
78#define EMI1_SLOT5 4
79#define EMI1_SLOT6 5
80#define EMI2 6
Prabhakar Kushwaha782d6662015-05-28 14:54:00 +053081#define SFP_TX 0
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -070082
83static const char * const mdio_names[] = {
Prabhakar Kushwaha122bcfd2015-11-09 16:42:07 +053084 "LS2080A_QDS_MDIO0",
85 "LS2080A_QDS_MDIO1",
86 "LS2080A_QDS_MDIO2",
87 "LS2080A_QDS_MDIO3",
88 "LS2080A_QDS_MDIO4",
89 "LS2080A_QDS_MDIO5",
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -070090 DEFAULT_WRIOP_MDIO2_NAME,
91};
92
Prabhakar Kushwaha122bcfd2015-11-09 16:42:07 +053093struct ls2080a_qds_mdio {
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -070094 u8 muxval;
95 struct mii_dev *realbus;
96};
97
Chuanhua Han1ab68c72019-07-26 19:24:01 +080098struct reg_pair {
99 uint addr;
100 u8 *val;
101};
102
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530103static void sgmii_configure_repeater(int serdes_port)
104{
105 struct mii_dev *bus;
106 uint8_t a = 0xf;
Chuanhua Han1ab68c72019-07-26 19:24:01 +0800107 int i, j, k, ret;
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530108 int dpmac_id = 0, dpmac, mii_bus = 0;
109 unsigned short value;
Prabhakar Kushwaha122bcfd2015-11-09 16:42:07 +0530110 char dev[2][20] = {"LS2080A_QDS_MDIO0", "LS2080A_QDS_MDIO3"};
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530111 uint8_t i2c_addr[] = {0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5f, 0x60};
112
113 uint8_t ch_a_eq[] = {0x1, 0x2, 0x3, 0x7};
114 uint8_t ch_a_ctl2[] = {0x81, 0x82, 0x83, 0x84};
115 uint8_t ch_b_eq[] = {0x1, 0x2, 0x3, 0x7};
116 uint8_t ch_b_ctl2[] = {0x81, 0x82, 0x83, 0x84};
117
Chuanhua Han1ab68c72019-07-26 19:24:01 +0800118 u8 reg_val[6] = {0x18, 0x38, 0x4, 0x14, 0xb5, 0x20};
119 struct reg_pair reg_pair[10] = {
120 {6, &reg_val[0]}, {4, &reg_val[1]},
121 {8, &reg_val[2]}, {0xf, NULL},
122 {0x11, NULL}, {0x16, NULL},
123 {0x18, NULL}, {0x23, &reg_val[3]},
124 {0x2d, &reg_val[4]}, {4, &reg_val[5]},
125 };
126
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530127 int *riser_phy_addr = &xqsgii_riser_phy_addr[0];
Igor Opaniukf7c91762021-02-09 13:52:45 +0200128#if CONFIG_IS_ENABLED(DM_I2C)
Chuanhua Han1ab68c72019-07-26 19:24:01 +0800129 struct udevice *udev;
130#endif
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530131
132 /* Set I2c to Slot 1 */
Igor Opaniukf7c91762021-02-09 13:52:45 +0200133#if !CONFIG_IS_ENABLED(DM_I2C)
Chuanhua Han1ab68c72019-07-26 19:24:01 +0800134 ret = i2c_write(0x77, 0, 0, &a, 1);
135#else
136 ret = i2c_get_chip_for_busnum(0, 0x77, 1, &udev);
137 if (!ret)
138 ret = dm_i2c_write(udev, 0, &a, 1);
139#endif
140 if (ret)
141 goto error;
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530142
143 for (dpmac = 0; dpmac < 8; dpmac++) {
144 /* Check the PHY status */
145 switch (serdes_port) {
146 case 1:
147 mii_bus = 0;
148 dpmac_id = dpmac + 1;
149 break;
150 case 2:
151 mii_bus = 1;
152 dpmac_id = dpmac + 9;
153 a = 0xb;
Igor Opaniukf7c91762021-02-09 13:52:45 +0200154#if !CONFIG_IS_ENABLED(DM_I2C)
Chuanhua Han1ab68c72019-07-26 19:24:01 +0800155 ret = i2c_write(0x76, 0, 0, &a, 1);
156#else
157 ret = i2c_get_chip_for_busnum(0, 0x76, 1, &udev);
158 if (!ret)
159 ret = dm_i2c_write(udev, 0, &a, 1);
160#endif
161 if (ret)
162 goto error;
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530163 break;
164 }
165
166 ret = miiphy_set_current_dev(dev[mii_bus]);
167 if (ret > 0)
168 goto error;
169
170 bus = mdio_get_current_dev();
171 debug("Reading from bus %s\n", bus->name);
172
173 ret = miiphy_write(dev[mii_bus], riser_phy_addr[dpmac], 0x1f,
174 3);
175 if (ret > 0)
176 goto error;
177
178 mdelay(10);
179 ret = miiphy_read(dev[mii_bus], riser_phy_addr[dpmac], 0x11,
180 &value);
181 if (ret > 0)
182 goto error;
183
184 mdelay(10);
185
Shaohui Xie84900b52016-10-17 16:20:48 +0800186 if ((value & 0xfff) == 0x401) {
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530187 printf("DPMAC %d:PHY is ..... Configured\n", dpmac_id);
Shaohui Xie84900b52016-10-17 16:20:48 +0800188 miiphy_write(dev[mii_bus], riser_phy_addr[dpmac],
189 0x1f, 0);
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530190 continue;
191 }
192
193 for (i = 0; i < 4; i++) {
194 for (j = 0; j < 4; j++) {
Chuanhua Han1ab68c72019-07-26 19:24:01 +0800195 reg_pair[3].val = &ch_a_eq[i];
196 reg_pair[4].val = &ch_a_ctl2[j];
197 reg_pair[5].val = &ch_b_eq[i];
198 reg_pair[6].val = &ch_b_ctl2[j];
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530199
Chuanhua Han1ab68c72019-07-26 19:24:01 +0800200 for (k = 0; k < 10; k++) {
Igor Opaniukf7c91762021-02-09 13:52:45 +0200201#if !CONFIG_IS_ENABLED(DM_I2C)
Chuanhua Han1ab68c72019-07-26 19:24:01 +0800202 ret = i2c_write(i2c_addr[dpmac],
203 reg_pair[k].addr,
204 1, reg_pair[k].val, 1);
205#else
206 ret = i2c_get_chip_for_busnum(0,
207 i2c_addr[dpmac],
208 1, &udev);
209 if (!ret)
210 ret = dm_i2c_write(udev,
211 reg_pair[k].addr,
212 reg_pair[k].val, 1);
213#endif
214 if (ret)
215 goto error;
216 }
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530217
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530218 mdelay(100);
219 ret = miiphy_read(dev[mii_bus],
220 riser_phy_addr[dpmac],
221 0x11, &value);
222 if (ret > 0)
223 goto error;
224
Shaohui Xie84900b52016-10-17 16:20:48 +0800225 mdelay(100);
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530226 ret = miiphy_read(dev[mii_bus],
227 riser_phy_addr[dpmac],
228 0x11, &value);
229 if (ret > 0)
230 goto error;
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530231
Shaohui Xie84900b52016-10-17 16:20:48 +0800232 if ((value & 0xfff) == 0x401) {
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530233 printf("DPMAC %d :PHY is configured ",
234 dpmac_id);
235 printf("after setting repeater 0x%x\n",
236 value);
237 i = 5;
238 j = 5;
Shaohui Xie84900b52016-10-17 16:20:48 +0800239 } else {
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530240 printf("DPMAC %d :PHY is failed to ",
241 dpmac_id);
242 printf("configure the repeater 0x%x\n",
243 value);
244 }
Shaohui Xie84900b52016-10-17 16:20:48 +0800245 }
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530246 }
Shaohui Xie84900b52016-10-17 16:20:48 +0800247 miiphy_write(dev[mii_bus], riser_phy_addr[dpmac], 0x1f, 0);
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530248 }
249error:
250 if (ret)
251 printf("DPMAC %d ..... FAILED to configure PHY\n", dpmac_id);
252 return;
253}
254
255static void qsgmii_configure_repeater(int dpmac)
256{
257 uint8_t a = 0xf;
Chuanhua Han1ab68c72019-07-26 19:24:01 +0800258 int i, j, k;
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530259 int i2c_phy_addr = 0;
260 int phy_addr = 0;
261 int i2c_addr[] = {0x58, 0x59, 0x5a, 0x5b};
262
263 uint8_t ch_a_eq[] = {0x1, 0x2, 0x3, 0x7};
264 uint8_t ch_a_ctl2[] = {0x81, 0x82, 0x83, 0x84};
265 uint8_t ch_b_eq[] = {0x1, 0x2, 0x3, 0x7};
266 uint8_t ch_b_ctl2[] = {0x81, 0x82, 0x83, 0x84};
267
Chuanhua Han1ab68c72019-07-26 19:24:01 +0800268 u8 reg_val[6] = {0x18, 0x38, 0x4, 0x14, 0xb5, 0x20};
269 struct reg_pair reg_pair[10] = {
270 {6, &reg_val[0]}, {4, &reg_val[1]},
271 {8, &reg_val[2]}, {0xf, NULL},
272 {0x11, NULL}, {0x16, NULL},
273 {0x18, NULL}, {0x23, &reg_val[3]},
274 {0x2d, &reg_val[4]}, {4, &reg_val[5]},
275 };
276
Prabhakar Kushwaha122bcfd2015-11-09 16:42:07 +0530277 const char *dev = "LS2080A_QDS_MDIO0";
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530278 int ret = 0;
279 unsigned short value;
Igor Opaniukf7c91762021-02-09 13:52:45 +0200280#if CONFIG_IS_ENABLED(DM_I2C)
Chuanhua Han1ab68c72019-07-26 19:24:01 +0800281 struct udevice *udev;
282#endif
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530283
284 /* Set I2c to Slot 1 */
Igor Opaniukf7c91762021-02-09 13:52:45 +0200285#if !CONFIG_IS_ENABLED(DM_I2C)
Chuanhua Han1ab68c72019-07-26 19:24:01 +0800286 ret = i2c_write(0x77, 0, 0, &a, 1);
287#else
288 ret = i2c_get_chip_for_busnum(0, 0x77, 1, &udev);
289 if (!ret)
290 ret = dm_i2c_write(udev, 0, &a, 1);
291#endif
292 if (ret)
293 goto error;
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530294
295 switch (dpmac) {
296 case 1:
297 case 2:
298 case 3:
299 case 4:
300 i2c_phy_addr = i2c_addr[0];
301 phy_addr = 0;
302 break;
303
304 case 5:
305 case 6:
306 case 7:
307 case 8:
308 i2c_phy_addr = i2c_addr[1];
309 phy_addr = 4;
310 break;
311
312 case 9:
313 case 10:
314 case 11:
315 case 12:
316 i2c_phy_addr = i2c_addr[2];
317 phy_addr = 8;
318 break;
319
320 case 13:
321 case 14:
322 case 15:
323 case 16:
324 i2c_phy_addr = i2c_addr[3];
325 phy_addr = 0xc;
326 break;
327 }
328
329 /* Check the PHY status */
330 ret = miiphy_set_current_dev(dev);
331 ret = miiphy_write(dev, phy_addr, 0x1f, 3);
332 mdelay(10);
333 ret = miiphy_read(dev, phy_addr, 0x11, &value);
334 mdelay(10);
335 ret = miiphy_read(dev, phy_addr, 0x11, &value);
336 mdelay(10);
337 if ((value & 0xf) == 0xf) {
338 printf("DPMAC %d :PHY is ..... Configured\n", dpmac);
339 return;
340 }
341
342 for (i = 0; i < 4; i++) {
343 for (j = 0; j < 4; j++) {
Chuanhua Han1ab68c72019-07-26 19:24:01 +0800344 reg_pair[3].val = &ch_a_eq[i];
345 reg_pair[4].val = &ch_a_ctl2[j];
346 reg_pair[5].val = &ch_b_eq[i];
347 reg_pair[6].val = &ch_b_ctl2[j];
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530348
Chuanhua Han1ab68c72019-07-26 19:24:01 +0800349 for (k = 0; k < 10; k++) {
Igor Opaniukf7c91762021-02-09 13:52:45 +0200350#if !CONFIG_IS_ENABLED(DM_I2C)
Chuanhua Han1ab68c72019-07-26 19:24:01 +0800351 ret = i2c_write(i2c_phy_addr,
352 reg_pair[k].addr,
353 1, reg_pair[k].val, 1);
354#else
355 ret = i2c_get_chip_for_busnum(0,
356 i2c_phy_addr,
357 1, &udev);
358 if (!ret)
359 ret = dm_i2c_write(udev,
360 reg_pair[k].addr,
361 reg_pair[k].val, 1);
362#endif
363 if (ret)
364 goto error;
365 }
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530366
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530367 mdelay(100);
368 ret = miiphy_read(dev, phy_addr, 0x11, &value);
369 if (ret > 0)
370 goto error;
371 mdelay(1);
372 ret = miiphy_read(dev, phy_addr, 0x11, &value);
373 if (ret > 0)
374 goto error;
375 mdelay(10);
376 if ((value & 0xf) == 0xf) {
377 printf("DPMAC %d :PHY is ..... Configured\n",
378 dpmac);
379 return;
380 }
381 }
382 }
383error:
384 printf("DPMAC %d :PHY ..... FAILED to configure PHY\n", dpmac);
385 return;
386}
387
Prabhakar Kushwaha122bcfd2015-11-09 16:42:07 +0530388static const char *ls2080a_qds_mdio_name_for_muxval(u8 muxval)
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700389{
390 return mdio_names[muxval];
391}
392
393struct mii_dev *mii_dev_for_muxval(u8 muxval)
394{
395 struct mii_dev *bus;
Prabhakar Kushwaha122bcfd2015-11-09 16:42:07 +0530396 const char *name = ls2080a_qds_mdio_name_for_muxval(muxval);
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700397
398 if (!name) {
399 printf("No bus for muxval %x\n", muxval);
400 return NULL;
401 }
402
403 bus = miiphy_get_dev_by_name(name);
404
405 if (!bus) {
406 printf("No bus by name %s\n", name);
407 return NULL;
408 }
409
410 return bus;
411}
412
Prabhakar Kushwaha122bcfd2015-11-09 16:42:07 +0530413static void ls2080a_qds_enable_SFP_TX(u8 muxval)
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700414{
415 u8 brdcfg9;
416
417 brdcfg9 = QIXIS_READ(brdcfg[9]);
418 brdcfg9 &= ~BRDCFG9_SFPTX_MASK;
419 brdcfg9 |= (muxval << BRDCFG9_SFPTX_SHIFT);
420 QIXIS_WRITE(brdcfg[9], brdcfg9);
421}
422
Prabhakar Kushwaha122bcfd2015-11-09 16:42:07 +0530423static void ls2080a_qds_mux_mdio(u8 muxval)
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700424{
425 u8 brdcfg4;
426
427 if (muxval <= 5) {
428 brdcfg4 = QIXIS_READ(brdcfg[4]);
429 brdcfg4 &= ~BRDCFG4_EMISEL_MASK;
430 brdcfg4 |= (muxval << BRDCFG4_EMISEL_SHIFT);
431 QIXIS_WRITE(brdcfg[4], brdcfg4);
432 }
433}
434
Prabhakar Kushwaha122bcfd2015-11-09 16:42:07 +0530435static int ls2080a_qds_mdio_read(struct mii_dev *bus, int addr,
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700436 int devad, int regnum)
437{
Prabhakar Kushwaha122bcfd2015-11-09 16:42:07 +0530438 struct ls2080a_qds_mdio *priv = bus->priv;
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700439
Prabhakar Kushwaha122bcfd2015-11-09 16:42:07 +0530440 ls2080a_qds_mux_mdio(priv->muxval);
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700441
442 return priv->realbus->read(priv->realbus, addr, devad, regnum);
443}
444
Prabhakar Kushwaha122bcfd2015-11-09 16:42:07 +0530445static int ls2080a_qds_mdio_write(struct mii_dev *bus, int addr, int devad,
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700446 int regnum, u16 value)
447{
Prabhakar Kushwaha122bcfd2015-11-09 16:42:07 +0530448 struct ls2080a_qds_mdio *priv = bus->priv;
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700449
Prabhakar Kushwaha122bcfd2015-11-09 16:42:07 +0530450 ls2080a_qds_mux_mdio(priv->muxval);
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700451
452 return priv->realbus->write(priv->realbus, addr, devad, regnum, value);
453}
454
Prabhakar Kushwaha122bcfd2015-11-09 16:42:07 +0530455static int ls2080a_qds_mdio_reset(struct mii_dev *bus)
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700456{
Prabhakar Kushwaha122bcfd2015-11-09 16:42:07 +0530457 struct ls2080a_qds_mdio *priv = bus->priv;
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700458
459 return priv->realbus->reset(priv->realbus);
460}
461
Prabhakar Kushwaha122bcfd2015-11-09 16:42:07 +0530462static int ls2080a_qds_mdio_init(char *realbusname, u8 muxval)
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700463{
Prabhakar Kushwaha122bcfd2015-11-09 16:42:07 +0530464 struct ls2080a_qds_mdio *pmdio;
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700465 struct mii_dev *bus = mdio_alloc();
466
467 if (!bus) {
Prabhakar Kushwaha122bcfd2015-11-09 16:42:07 +0530468 printf("Failed to allocate ls2080a_qds MDIO bus\n");
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700469 return -1;
470 }
471
472 pmdio = malloc(sizeof(*pmdio));
473 if (!pmdio) {
Prabhakar Kushwaha122bcfd2015-11-09 16:42:07 +0530474 printf("Failed to allocate ls2080a_qds private data\n");
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700475 free(bus);
476 return -1;
477 }
478
Prabhakar Kushwaha122bcfd2015-11-09 16:42:07 +0530479 bus->read = ls2080a_qds_mdio_read;
480 bus->write = ls2080a_qds_mdio_write;
481 bus->reset = ls2080a_qds_mdio_reset;
Ben Whitten34fd6c92015-12-30 13:05:58 +0000482 strcpy(bus->name, ls2080a_qds_mdio_name_for_muxval(muxval));
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700483
484 pmdio->realbus = miiphy_get_dev_by_name(realbusname);
485
486 if (!pmdio->realbus) {
487 printf("No bus with name %s\n", realbusname);
488 free(bus);
489 free(pmdio);
490 return -1;
491 }
492
493 pmdio->muxval = muxval;
494 bus->priv = pmdio;
495
496 return mdio_register(bus);
497}
498
499/*
500 * Initialize the dpmac_info array.
501 *
502 */
503static void initialize_dpmac_to_slot(void)
504{
505 struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
506 int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
507 FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
508 >> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
509 int serdes2_prtcl = (in_le32(&gur->rcwsr[28]) &
510 FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK)
511 >> FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT;
512
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530513 char *env_hwconfig;
Simon Glass64b723f2017-08-03 12:22:12 -0600514 env_hwconfig = env_get("hwconfig");
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700515
516 switch (serdes1_prtcl) {
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530517 case 0x07:
518 case 0x09:
519 case 0x33:
520 printf("qds: WRIOP: Supported SerDes1 Protocol 0x%02x\n",
521 serdes1_prtcl);
522 lane_to_slot_fsm1[0] = EMI1_SLOT1;
523 lane_to_slot_fsm1[1] = EMI1_SLOT1;
524 lane_to_slot_fsm1[2] = EMI1_SLOT1;
525 lane_to_slot_fsm1[3] = EMI1_SLOT1;
526 if (hwconfig_f("xqsgmii", env_hwconfig)) {
527 lane_to_slot_fsm1[4] = EMI1_SLOT1;
528 lane_to_slot_fsm1[5] = EMI1_SLOT1;
529 lane_to_slot_fsm1[6] = EMI1_SLOT1;
530 lane_to_slot_fsm1[7] = EMI1_SLOT1;
531 } else {
532 lane_to_slot_fsm1[4] = EMI1_SLOT2;
533 lane_to_slot_fsm1[5] = EMI1_SLOT2;
534 lane_to_slot_fsm1[6] = EMI1_SLOT2;
535 lane_to_slot_fsm1[7] = EMI1_SLOT2;
536 }
537 break;
538
Priyanka Jaine2da6232016-11-03 17:50:51 +0530539 case 0x39:
540 printf("qds: WRIOP: Supported SerDes1 Protocol 0x%02x\n",
541 serdes1_prtcl);
542 if (hwconfig_f("xqsgmii", env_hwconfig)) {
543 lane_to_slot_fsm1[0] = EMI1_SLOT3;
544 lane_to_slot_fsm1[1] = EMI1_SLOT3;
545 lane_to_slot_fsm1[2] = EMI1_SLOT3;
546 lane_to_slot_fsm1[3] = EMI_NONE;
547 } else {
548 lane_to_slot_fsm1[0] = EMI_NONE;
549 lane_to_slot_fsm1[1] = EMI_NONE;
550 lane_to_slot_fsm1[2] = EMI_NONE;
551 lane_to_slot_fsm1[3] = EMI_NONE;
552 }
553 lane_to_slot_fsm1[4] = EMI1_SLOT3;
554 lane_to_slot_fsm1[5] = EMI1_SLOT3;
555 lane_to_slot_fsm1[6] = EMI1_SLOT3;
556 lane_to_slot_fsm1[7] = EMI_NONE;
557 break;
558
559 case 0x4D:
560 printf("qds: WRIOP: Supported SerDes1 Protocol 0x%02x\n",
561 serdes1_prtcl);
562 if (hwconfig_f("xqsgmii", env_hwconfig)) {
563 lane_to_slot_fsm1[0] = EMI1_SLOT3;
564 lane_to_slot_fsm1[1] = EMI1_SLOT3;
565 lane_to_slot_fsm1[2] = EMI_NONE;
566 lane_to_slot_fsm1[3] = EMI_NONE;
567 } else {
568 lane_to_slot_fsm1[0] = EMI_NONE;
569 lane_to_slot_fsm1[1] = EMI_NONE;
570 lane_to_slot_fsm1[2] = EMI_NONE;
571 lane_to_slot_fsm1[3] = EMI_NONE;
572 }
573 lane_to_slot_fsm1[4] = EMI1_SLOT3;
574 lane_to_slot_fsm1[5] = EMI1_SLOT3;
575 lane_to_slot_fsm1[6] = EMI_NONE;
576 lane_to_slot_fsm1[7] = EMI_NONE;
577 break;
578
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700579 case 0x2A:
Priyanka Jaine2da6232016-11-03 17:50:51 +0530580 case 0x4B:
581 case 0x4C:
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530582 printf("qds: WRIOP: Supported SerDes1 Protocol 0x%02x\n",
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700583 serdes1_prtcl);
584 break;
585 default:
Prabhakar Kushwahac5aa4ff2015-11-04 12:25:55 +0530586 printf("%s qds: WRIOP: Unsupported SerDes1 Protocol 0x%02x\n",
587 __func__, serdes1_prtcl);
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700588 break;
589 }
590
591 switch (serdes2_prtcl) {
592 case 0x07:
593 case 0x08:
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530594 case 0x09:
Prabhakar Kushwaha2a6e5dc2015-05-28 14:53:57 +0530595 case 0x49:
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530596 printf("qds: WRIOP: Supported SerDes2 Protocol 0x%02x\n",
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700597 serdes2_prtcl);
598 lane_to_slot_fsm2[0] = EMI1_SLOT4;
599 lane_to_slot_fsm2[1] = EMI1_SLOT4;
600 lane_to_slot_fsm2[2] = EMI1_SLOT4;
601 lane_to_slot_fsm2[3] = EMI1_SLOT4;
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530602
603 if (hwconfig_f("xqsgmii", env_hwconfig)) {
604 lane_to_slot_fsm2[4] = EMI1_SLOT4;
605 lane_to_slot_fsm2[5] = EMI1_SLOT4;
606 lane_to_slot_fsm2[6] = EMI1_SLOT4;
607 lane_to_slot_fsm2[7] = EMI1_SLOT4;
608 } else {
609 /* No MDIO physical connection */
610 lane_to_slot_fsm2[4] = EMI1_SLOT6;
611 lane_to_slot_fsm2[5] = EMI1_SLOT6;
612 lane_to_slot_fsm2[6] = EMI1_SLOT6;
613 lane_to_slot_fsm2[7] = EMI1_SLOT6;
614 }
Priyanka Jaine2da6232016-11-03 17:50:51 +0530615 break;
616
617 case 0x47:
618 printf("qds: WRIOP: Supported SerDes2 Protocol 0x%02x\n",
619 serdes2_prtcl);
620 lane_to_slot_fsm2[0] = EMI_NONE;
621 lane_to_slot_fsm2[1] = EMI1_SLOT5;
622 lane_to_slot_fsm2[2] = EMI1_SLOT5;
623 lane_to_slot_fsm2[3] = EMI1_SLOT5;
624
625 if (hwconfig_f("xqsgmii", env_hwconfig)) {
626 lane_to_slot_fsm2[4] = EMI_NONE;
627 lane_to_slot_fsm2[5] = EMI1_SLOT5;
628 lane_to_slot_fsm2[6] = EMI1_SLOT5;
629 lane_to_slot_fsm2[7] = EMI1_SLOT5;
630 }
631 break;
632
633 case 0x57:
634 printf("qds: WRIOP: Supported SerDes2 Protocol 0x%02x\n",
635 serdes2_prtcl);
636 if (hwconfig_f("xqsgmii", env_hwconfig)) {
637 lane_to_slot_fsm2[0] = EMI_NONE;
638 lane_to_slot_fsm2[1] = EMI_NONE;
639 lane_to_slot_fsm2[2] = EMI_NONE;
640 lane_to_slot_fsm2[3] = EMI_NONE;
641 }
642 lane_to_slot_fsm2[4] = EMI_NONE;
643 lane_to_slot_fsm2[5] = EMI_NONE;
644 lane_to_slot_fsm2[6] = EMI1_SLOT5;
645 lane_to_slot_fsm2[7] = EMI1_SLOT5;
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700646 break;
Priyanka Jaine2da6232016-11-03 17:50:51 +0530647
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700648 default:
Prabhakar Kushwahac5aa4ff2015-11-04 12:25:55 +0530649 printf(" %s qds: WRIOP: Unsupported SerDes2 Protocol 0x%02x\n",
650 __func__ , serdes2_prtcl);
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700651 break;
652 }
653}
654
Prabhakar Kushwaha122bcfd2015-11-09 16:42:07 +0530655void ls2080a_handle_phy_interface_sgmii(int dpmac_id)
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700656{
657 int lane, slot;
658 struct mii_dev *bus;
659 struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
660 int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
661 FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
662 >> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
663 int serdes2_prtcl = (in_le32(&gur->rcwsr[28]) &
664 FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK)
665 >> FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT;
666
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530667 int *riser_phy_addr;
Simon Glass64b723f2017-08-03 12:22:12 -0600668 char *env_hwconfig = env_get("hwconfig");
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530669
670 if (hwconfig_f("xqsgmii", env_hwconfig))
671 riser_phy_addr = &xqsgii_riser_phy_addr[0];
672 else
673 riser_phy_addr = &sgmii_riser_phy_addr[0];
674
675 if (dpmac_id > WRIOP1_DPMAC9)
676 goto serdes2;
677
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700678 switch (serdes1_prtcl) {
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530679 case 0x07:
Priyanka Jaine2da6232016-11-03 17:50:51 +0530680 case 0x39:
681 case 0x4D:
682 lane = serdes_get_first_lane(FSL_SRDS_1, SGMII1 + dpmac_id - 1);
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530683
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530684 slot = lane_to_slot_fsm1[lane];
685
686 switch (++slot) {
687 case 1:
688 /* Slot housing a SGMII riser card? */
Pankaj Bansal50adb5e2018-10-10 14:08:34 +0530689 wriop_set_phy_address(dpmac_id, 0,
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530690 riser_phy_addr[dpmac_id - 1]);
691 dpmac_info[dpmac_id].board_mux = EMI1_SLOT1;
692 bus = mii_dev_for_muxval(EMI1_SLOT1);
693 wriop_set_mdio(dpmac_id, bus);
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530694 break;
695 case 2:
696 /* Slot housing a SGMII riser card? */
Pankaj Bansal50adb5e2018-10-10 14:08:34 +0530697 wriop_set_phy_address(dpmac_id, 0,
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530698 riser_phy_addr[dpmac_id - 1]);
699 dpmac_info[dpmac_id].board_mux = EMI1_SLOT2;
700 bus = mii_dev_for_muxval(EMI1_SLOT2);
701 wriop_set_mdio(dpmac_id, bus);
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530702 break;
703 case 3:
Priyanka Jaine2da6232016-11-03 17:50:51 +0530704 if (slot == EMI_NONE)
705 return;
706 if (serdes1_prtcl == 0x39) {
Pankaj Bansal50adb5e2018-10-10 14:08:34 +0530707 wriop_set_phy_address(dpmac_id, 0,
Priyanka Jaine2da6232016-11-03 17:50:51 +0530708 riser_phy_addr[dpmac_id - 2]);
709 if (dpmac_id >= 6 && hwconfig_f("xqsgmii",
710 env_hwconfig))
Pankaj Bansal50adb5e2018-10-10 14:08:34 +0530711 wriop_set_phy_address(dpmac_id, 0,
Priyanka Jaine2da6232016-11-03 17:50:51 +0530712 riser_phy_addr[dpmac_id - 3]);
713 } else {
Pankaj Bansal50adb5e2018-10-10 14:08:34 +0530714 wriop_set_phy_address(dpmac_id, 0,
Priyanka Jaine2da6232016-11-03 17:50:51 +0530715 riser_phy_addr[dpmac_id - 2]);
716 if (dpmac_id >= 7 && hwconfig_f("xqsgmii",
717 env_hwconfig))
Pankaj Bansal50adb5e2018-10-10 14:08:34 +0530718 wriop_set_phy_address(dpmac_id, 0,
Priyanka Jaine2da6232016-11-03 17:50:51 +0530719 riser_phy_addr[dpmac_id - 3]);
720 }
721 dpmac_info[dpmac_id].board_mux = EMI1_SLOT3;
722 bus = mii_dev_for_muxval(EMI1_SLOT3);
723 wriop_set_mdio(dpmac_id, bus);
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530724 break;
725 case 4:
726 break;
727 case 5:
728 break;
729 case 6:
730 break;
731 }
732 break;
733 default:
Prabhakar Kushwahac5aa4ff2015-11-04 12:25:55 +0530734 printf("%s qds: WRIOP: Unsupported SerDes1 Protocol 0x%02x\n",
735 __func__ , serdes1_prtcl);
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530736 break;
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700737 }
738
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530739serdes2:
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700740 switch (serdes2_prtcl) {
741 case 0x07:
742 case 0x08:
Prabhakar Kushwaha2a6e5dc2015-05-28 14:53:57 +0530743 case 0x49:
Priyanka Jaine2da6232016-11-03 17:50:51 +0530744 case 0x47:
745 case 0x57:
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700746 lane = serdes_get_first_lane(FSL_SRDS_2, SGMII9 +
747 (dpmac_id - 9));
748 slot = lane_to_slot_fsm2[lane];
749
750 switch (++slot) {
751 case 1:
752 break;
753 case 3:
754 break;
755 case 4:
756 /* Slot housing a SGMII riser card? */
Pankaj Bansal50adb5e2018-10-10 14:08:34 +0530757 wriop_set_phy_address(dpmac_id, 0,
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700758 riser_phy_addr[dpmac_id - 9]);
759 dpmac_info[dpmac_id].board_mux = EMI1_SLOT4;
760 bus = mii_dev_for_muxval(EMI1_SLOT4);
761 wriop_set_mdio(dpmac_id, bus);
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700762 break;
763 case 5:
Priyanka Jaine2da6232016-11-03 17:50:51 +0530764 if (slot == EMI_NONE)
765 return;
766 if (serdes2_prtcl == 0x47) {
Pankaj Bansal50adb5e2018-10-10 14:08:34 +0530767 wriop_set_phy_address(dpmac_id, 0,
Priyanka Jaine2da6232016-11-03 17:50:51 +0530768 riser_phy_addr[dpmac_id - 10]);
769 if (dpmac_id >= 14 && hwconfig_f("xqsgmii",
770 env_hwconfig))
Pankaj Bansal50adb5e2018-10-10 14:08:34 +0530771 wriop_set_phy_address(dpmac_id, 0,
Priyanka Jaine2da6232016-11-03 17:50:51 +0530772 riser_phy_addr[dpmac_id - 11]);
773 } else {
Pankaj Bansal50adb5e2018-10-10 14:08:34 +0530774 wriop_set_phy_address(dpmac_id, 0,
Priyanka Jaine2da6232016-11-03 17:50:51 +0530775 riser_phy_addr[dpmac_id - 11]);
776 }
777 dpmac_info[dpmac_id].board_mux = EMI1_SLOT5;
778 bus = mii_dev_for_muxval(EMI1_SLOT5);
779 wriop_set_mdio(dpmac_id, bus);
780 break;
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700781 case 6:
782 /* Slot housing a SGMII riser card? */
Pankaj Bansal50adb5e2018-10-10 14:08:34 +0530783 wriop_set_phy_address(dpmac_id, 0,
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700784 riser_phy_addr[dpmac_id - 13]);
785 dpmac_info[dpmac_id].board_mux = EMI1_SLOT6;
786 bus = mii_dev_for_muxval(EMI1_SLOT6);
787 wriop_set_mdio(dpmac_id, bus);
788 break;
789 }
790 break;
791 default:
Prabhakar Kushwahac5aa4ff2015-11-04 12:25:55 +0530792 printf("%s qds: WRIOP: Unsupported SerDes2 Protocol 0x%02x\n",
793 __func__, serdes2_prtcl);
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700794 break;
795 }
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530796}
797
Prabhakar Kushwaha122bcfd2015-11-09 16:42:07 +0530798void ls2080a_handle_phy_interface_qsgmii(int dpmac_id)
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530799{
800 int lane = 0, slot;
801 struct mii_dev *bus;
802 struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
803 int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
804 FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
805 >> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
806
807 switch (serdes1_prtcl) {
808 case 0x33:
809 switch (dpmac_id) {
810 case 1:
811 case 2:
812 case 3:
813 case 4:
814 lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_A);
815 break;
816 case 5:
817 case 6:
818 case 7:
819 case 8:
820 lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_B);
821 break;
822 case 9:
823 case 10:
824 case 11:
825 case 12:
826 lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_C);
827 break;
828 case 13:
829 case 14:
830 case 15:
831 case 16:
832 lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_D);
833 break;
834 }
835
836 slot = lane_to_slot_fsm1[lane];
837
838 switch (++slot) {
839 case 1:
840 /* Slot housing a QSGMII riser card? */
Pankaj Bansal50adb5e2018-10-10 14:08:34 +0530841 wriop_set_phy_address(dpmac_id, 0, dpmac_id - 1);
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530842 dpmac_info[dpmac_id].board_mux = EMI1_SLOT1;
843 bus = mii_dev_for_muxval(EMI1_SLOT1);
844 wriop_set_mdio(dpmac_id, bus);
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530845 break;
846 case 3:
847 break;
848 case 4:
849 break;
850 case 5:
851 break;
852 case 6:
853 break;
854 }
855 break;
856 default:
857 printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n",
858 serdes1_prtcl);
859 break;
860 }
861
862 qsgmii_configure_repeater(dpmac_id);
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700863}
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530864
Prabhakar Kushwaha122bcfd2015-11-09 16:42:07 +0530865void ls2080a_handle_phy_interface_xsgmii(int i)
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700866{
867 struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
868 int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
869 FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
870 >> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
871
872 switch (serdes1_prtcl) {
873 case 0x2A:
Priyanka Jaine2da6232016-11-03 17:50:51 +0530874 case 0x4B:
875 case 0x4C:
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700876 /*
Bin Meng75574052016-02-05 19:30:11 -0800877 * XFI does not need a PHY to work, but to avoid U-Boot use
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700878 * default PHY address which is zero to a MAC when it found
879 * a MAC has no PHY address, we give a PHY address to XFI
880 * MAC, and should not use a real XAUI PHY address, since
881 * MDIO can access it successfully, and then MDIO thinks
882 * the XAUI card is used for the XFI MAC, which will cause
883 * error.
884 */
Pankaj Bansal50adb5e2018-10-10 14:08:34 +0530885 wriop_set_phy_address(i, 0, i + 4);
Prabhakar Kushwaha122bcfd2015-11-09 16:42:07 +0530886 ls2080a_qds_enable_SFP_TX(SFP_TX);
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700887
888 break;
889 default:
890 printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n",
891 serdes1_prtcl);
892 break;
893 }
894}
895#endif
Ioana Ciornei51a46492020-05-18 14:48:35 +0300896#endif // !CONFIG_DM_ETH
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700897
Masahiro Yamadaf7ed78b2020-06-26 15:13:33 +0900898int board_eth_init(struct bd_info *bis)
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700899{
Ioana Ciornei51a46492020-05-18 14:48:35 +0300900#ifndef CONFIG_DM_ETH
Santan Kumar1afa9002017-05-05 15:42:29 +0530901#if defined(CONFIG_FSL_MC_ENET) && !defined(CONFIG_SPL_BUILD)
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530902 struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
903 int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
904 FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
905 >> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
906 int serdes2_prtcl = (in_le32(&gur->rcwsr[28]) &
907 FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK)
908 >> FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT;
909
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700910 struct memac_mdio_info *memac_mdio0_info;
911 struct memac_mdio_info *memac_mdio1_info;
912 unsigned int i;
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530913 char *env_hwconfig;
Ioana Ciornei51a46492020-05-18 14:48:35 +0300914 int error;
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530915
Simon Glass64b723f2017-08-03 12:22:12 -0600916 env_hwconfig = env_get("hwconfig");
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700917
918 initialize_dpmac_to_slot();
919
920 memac_mdio0_info = (struct memac_mdio_info *)malloc(
921 sizeof(struct memac_mdio_info));
922 memac_mdio0_info->regs =
923 (struct memac_mdio_controller *)
924 CONFIG_SYS_FSL_WRIOP1_MDIO1;
925 memac_mdio0_info->name = DEFAULT_WRIOP_MDIO1_NAME;
926
927 /* Register the real MDIO1 bus */
928 fm_memac_mdio_init(bis, memac_mdio0_info);
929
930 memac_mdio1_info = (struct memac_mdio_info *)malloc(
931 sizeof(struct memac_mdio_info));
932 memac_mdio1_info->regs =
933 (struct memac_mdio_controller *)
934 CONFIG_SYS_FSL_WRIOP1_MDIO2;
935 memac_mdio1_info->name = DEFAULT_WRIOP_MDIO2_NAME;
936
937 /* Register the real MDIO2 bus */
938 fm_memac_mdio_init(bis, memac_mdio1_info);
939
940 /* Register the muxing front-ends to the MDIO buses */
Prabhakar Kushwaha122bcfd2015-11-09 16:42:07 +0530941 ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT1);
942 ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT2);
943 ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT3);
944 ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT4);
945 ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT5);
946 ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT6);
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700947
Prabhakar Kushwaha122bcfd2015-11-09 16:42:07 +0530948 ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO2_NAME, EMI2);
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700949
950 for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) {
951 switch (wriop_get_enet_if(i)) {
952 case PHY_INTERFACE_MODE_QSGMII:
Prabhakar Kushwaha122bcfd2015-11-09 16:42:07 +0530953 ls2080a_handle_phy_interface_qsgmii(i);
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700954 break;
955 case PHY_INTERFACE_MODE_SGMII:
Prabhakar Kushwaha122bcfd2015-11-09 16:42:07 +0530956 ls2080a_handle_phy_interface_sgmii(i);
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700957 break;
958 case PHY_INTERFACE_MODE_XGMII:
Prabhakar Kushwaha122bcfd2015-11-09 16:42:07 +0530959 ls2080a_handle_phy_interface_xsgmii(i);
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700960 break;
961 default:
962 break;
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530963
964 if (i == 16)
965 i = NUM_WRIOP_PORTS;
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700966 }
967 }
968
969 error = cpu_eth_init(bis);
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530970
971 if (hwconfig_f("xqsgmii", env_hwconfig)) {
972 if (serdes1_prtcl == 0x7)
973 sgmii_configure_repeater(1);
974 if (serdes2_prtcl == 0x7 || serdes2_prtcl == 0x8 ||
975 serdes2_prtcl == 0x49)
976 sgmii_configure_repeater(2);
977 }
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700978#endif
Ioana Ciornei51a46492020-05-18 14:48:35 +0300979#endif // !CONFIG_DM_ETH
980
981#ifdef CONFIG_DM_ETH
982 return 0;
983#else
984 return pci_eth_init(bis);
985#endif
Prabhakar Kushwahac158fad2015-03-20 19:28:26 -0700986}
Prabhakar Kushwaha35f93f62015-08-07 18:01:51 +0530987
Bogdan Purcareata08bc0142017-05-24 16:40:21 +0000988#if defined(CONFIG_RESET_PHY_R)
989void reset_phy(void)
990{
991 mc_env_boot();
992}
993#endif /* CONFIG_RESET_PHY_R */
Ioana Ciorneid838b562020-05-18 14:48:36 +0300994
995#if defined(CONFIG_DM_ETH) && defined(CONFIG_MULTI_DTB_FIT)
996
997/* Structure to hold SERDES protocols supported in case of
998 * CONFIG_DM_ETH enabled (network interfaces are described in the DTS).
999 *
1000 * @serdes_block: the index of the SERDES block
1001 * @serdes_protocol: the decimal value of the protocol supported
1002 * @dts_needed: DTS notes describing the current configuration are needed
1003 *
1004 * When dts_needed is true, the board_fit_config_name_match() function
1005 * will try to exactly match the current configuration of the block with a DTS
1006 * name provided.
1007 */
1008static struct serdes_configuration {
1009 u8 serdes_block;
1010 u32 serdes_protocol;
1011 bool dts_needed;
1012} supported_protocols[] = {
1013 /* Serdes block #1 */
1014 {1, 42, true},
1015
1016 /* Serdes block #2 */
1017 {2, 65, false},
1018};
1019
1020#define SUPPORTED_SERDES_PROTOCOLS ARRAY_SIZE(supported_protocols)
1021
1022static bool protocol_supported(u8 serdes_block, u32 protocol)
1023{
1024 struct serdes_configuration serdes_conf;
1025 int i;
1026
1027 for (i = 0; i < SUPPORTED_SERDES_PROTOCOLS; i++) {
1028 serdes_conf = supported_protocols[i];
1029 if (serdes_conf.serdes_block == serdes_block &&
1030 serdes_conf.serdes_protocol == protocol)
1031 return true;
1032 }
1033
1034 return false;
1035}
1036
1037static void get_str_protocol(u8 serdes_block, u32 protocol, char *str)
1038{
1039 struct serdes_configuration serdes_conf;
1040 int i;
1041
1042 for (i = 0; i < SUPPORTED_SERDES_PROTOCOLS; i++) {
1043 serdes_conf = supported_protocols[i];
1044 if (serdes_conf.serdes_block == serdes_block &&
1045 serdes_conf.serdes_protocol == protocol) {
1046 if (serdes_conf.dts_needed == true)
1047 sprintf(str, "%u", protocol);
1048 else
1049 sprintf(str, "x");
1050 return;
1051 }
1052 }
1053}
1054
1055int board_fit_config_name_match(const char *name)
1056{
1057 struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
1058 u32 rcw_status = in_le32(&gur->rcwsr[28]);
1059 char srds_s1_str[2], srds_s2_str[2];
1060 u32 srds_s1, srds_s2;
1061 char expected_dts[100];
1062
1063 srds_s1 = rcw_status & FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK;
1064 srds_s1 >>= FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
1065
1066 srds_s2 = rcw_status & FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK;
1067 srds_s2 >>= FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT;
1068
1069 /* Check for supported protocols. The default DTS will be used
1070 * in this case
1071 */
1072 if (!protocol_supported(1, srds_s1) ||
1073 !protocol_supported(2, srds_s2))
1074 return -1;
1075
1076 get_str_protocol(1, srds_s1, srds_s1_str);
1077 get_str_protocol(2, srds_s2, srds_s2_str);
1078
1079 printf("expected_dts %s\n", expected_dts);
1080 sprintf(expected_dts, "fsl-ls2080a-qds-%s-%s",
1081 srds_s1_str, srds_s2_str);
1082
1083 if (!strcmp(name, expected_dts))
1084 return 0;
1085
1086 printf("this is not!\n");
1087 return -1;
1088}
1089
1090#endif