blob: 23b59bcc09dfc548290225a9d92e6aa9abcaf7ef [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Shengzhou Liu07886942013-11-22 17:39:11 +08002/*
3 * Copyright 2013 Freescale Semiconductor, Inc.
4 *
5 * Shengzhou Liu <Shengzhou.Liu@freescale.com>
Shengzhou Liu07886942013-11-22 17:39:11 +08006 */
7
8#include <common.h>
9#include <command.h>
10#include <netdev.h>
11#include <asm/mmu.h>
12#include <asm/processor.h>
13#include <asm/immap_85xx.h>
14#include <asm/fsl_law.h>
15#include <asm/fsl_serdes.h>
16#include <asm/fsl_portals.h>
17#include <asm/fsl_liodn.h>
18#include <malloc.h>
19#include <fm_eth.h>
20#include <fsl_mdio.h>
21#include <miiphy.h>
22#include <phy.h>
Shaohui Xie513eaf22015-10-26 19:47:47 +080023#include <fsl_dtsec.h>
Shengzhou Liu07886942013-11-22 17:39:11 +080024#include <asm/fsl_serdes.h>
shaohui xie2f50d612014-10-20 19:48:19 +080025#include <hwconfig.h>
Shengzhou Liu07886942013-11-22 17:39:11 +080026#include "../common/qixis.h"
27#include "../common/fman.h"
Shengzhou Liu031228a2014-02-21 13:16:19 +080028#include "t208xqds_qixis.h"
Shengzhou Liu07886942013-11-22 17:39:11 +080029
30#define EMI_NONE 0xFFFFFFFF
31#define EMI1_RGMII1 0
32#define EMI1_RGMII2 1
33#define EMI1_SLOT1 2
York Sunc68b12d2016-12-28 08:43:36 -080034#if defined(CONFIG_TARGET_T2080QDS)
Shengzhou Liu07886942013-11-22 17:39:11 +080035#define EMI1_SLOT2 6
36#define EMI1_SLOT3 3
37#define EMI1_SLOT4 4
38#define EMI1_SLOT5 5
Shengzhou Liubdfeaf62014-03-06 15:07:39 +080039#define EMI2 7
York Sun99eb6072016-12-28 08:43:38 -080040#elif defined(CONFIG_TARGET_T2081QDS)
Shengzhou Liu031228a2014-02-21 13:16:19 +080041#define EMI1_SLOT2 3
42#define EMI1_SLOT3 4
43#define EMI1_SLOT5 5
44#define EMI1_SLOT6 6
45#define EMI1_SLOT7 7
Shengzhou Liu031228a2014-02-21 13:16:19 +080046#define EMI2 8
Shengzhou Liubdfeaf62014-03-06 15:07:39 +080047#endif
Shengzhou Liu07886942013-11-22 17:39:11 +080048
Shaohui Xie2ec2f302014-10-20 19:51:21 +080049#define PCCR1_SGMIIA_KX_MASK 0x00008000
50#define PCCR1_SGMIIB_KX_MASK 0x00004000
51#define PCCR1_SGMIIC_KX_MASK 0x00002000
52#define PCCR1_SGMIID_KX_MASK 0x00001000
53#define PCCR1_SGMIIE_KX_MASK 0x00000800
54#define PCCR1_SGMIIF_KX_MASK 0x00000400
55#define PCCR1_SGMIIG_KX_MASK 0x00000200
56#define PCCR1_SGMIIH_KX_MASK 0x00000100
57
Shengzhou Liu07886942013-11-22 17:39:11 +080058static int mdio_mux[NUM_FM_PORTS];
59
60static const char * const mdio_names[] = {
York Sunc68b12d2016-12-28 08:43:36 -080061#if defined(CONFIG_TARGET_T2080QDS)
Shengzhou Liu07886942013-11-22 17:39:11 +080062 "T2080QDS_MDIO_RGMII1",
63 "T2080QDS_MDIO_RGMII2",
64 "T2080QDS_MDIO_SLOT1",
65 "T2080QDS_MDIO_SLOT3",
66 "T2080QDS_MDIO_SLOT4",
67 "T2080QDS_MDIO_SLOT5",
68 "T2080QDS_MDIO_SLOT2",
69 "T2080QDS_MDIO_10GC",
York Sun99eb6072016-12-28 08:43:38 -080070#elif defined(CONFIG_TARGET_T2081QDS)
Shengzhou Liu031228a2014-02-21 13:16:19 +080071 "T2081QDS_MDIO_RGMII1",
72 "T2081QDS_MDIO_RGMII2",
73 "T2081QDS_MDIO_SLOT1",
74 "T2081QDS_MDIO_SLOT2",
75 "T2081QDS_MDIO_SLOT3",
76 "T2081QDS_MDIO_SLOT5",
77 "T2081QDS_MDIO_SLOT6",
78 "T2081QDS_MDIO_SLOT7",
79 "T2081QDS_MDIO_10GC",
80#endif
Shengzhou Liu07886942013-11-22 17:39:11 +080081};
82
83/* Map SerDes1 8 lanes to default slot, will be initialized dynamically */
York Sunc68b12d2016-12-28 08:43:36 -080084#if defined(CONFIG_TARGET_T2080QDS)
Shengzhou Liu07886942013-11-22 17:39:11 +080085static u8 lane_to_slot[] = {3, 3, 3, 3, 1, 1, 1, 1};
York Sun99eb6072016-12-28 08:43:38 -080086#elif defined(CONFIG_TARGET_T2081QDS)
Shengzhou Liu031228a2014-02-21 13:16:19 +080087static u8 lane_to_slot[] = {2, 2, 2, 2, 1, 1, 1, 1};
88#endif
Shengzhou Liu07886942013-11-22 17:39:11 +080089
Shengzhou Liu031228a2014-02-21 13:16:19 +080090static const char *t208xqds_mdio_name_for_muxval(u8 muxval)
Shengzhou Liu07886942013-11-22 17:39:11 +080091{
92 return mdio_names[muxval];
93}
94
95struct mii_dev *mii_dev_for_muxval(u8 muxval)
96{
97 struct mii_dev *bus;
Shengzhou Liu031228a2014-02-21 13:16:19 +080098 const char *name = t208xqds_mdio_name_for_muxval(muxval);
Shengzhou Liu07886942013-11-22 17:39:11 +080099
100 if (!name) {
101 printf("No bus for muxval %x\n", muxval);
102 return NULL;
103 }
104
105 bus = miiphy_get_dev_by_name(name);
106
107 if (!bus) {
108 printf("No bus by name %s\n", name);
109 return NULL;
110 }
111
112 return bus;
113}
114
Shengzhou Liu031228a2014-02-21 13:16:19 +0800115struct t208xqds_mdio {
Shengzhou Liu07886942013-11-22 17:39:11 +0800116 u8 muxval;
117 struct mii_dev *realbus;
118};
119
Shengzhou Liu031228a2014-02-21 13:16:19 +0800120static void t208xqds_mux_mdio(u8 muxval)
Shengzhou Liu07886942013-11-22 17:39:11 +0800121{
122 u8 brdcfg4;
Shengzhou Liu031228a2014-02-21 13:16:19 +0800123 if (muxval < 8) {
Shengzhou Liu07886942013-11-22 17:39:11 +0800124 brdcfg4 = QIXIS_READ(brdcfg[4]);
125 brdcfg4 &= ~BRDCFG4_EMISEL_MASK;
126 brdcfg4 |= (muxval << BRDCFG4_EMISEL_SHIFT);
127 QIXIS_WRITE(brdcfg[4], brdcfg4);
128 }
129}
130
Shengzhou Liu031228a2014-02-21 13:16:19 +0800131static int t208xqds_mdio_read(struct mii_dev *bus, int addr, int devad,
Shengzhou Liu07886942013-11-22 17:39:11 +0800132 int regnum)
133{
Shengzhou Liu031228a2014-02-21 13:16:19 +0800134 struct t208xqds_mdio *priv = bus->priv;
Shengzhou Liu07886942013-11-22 17:39:11 +0800135
Shengzhou Liu031228a2014-02-21 13:16:19 +0800136 t208xqds_mux_mdio(priv->muxval);
Shengzhou Liu07886942013-11-22 17:39:11 +0800137
138 return priv->realbus->read(priv->realbus, addr, devad, regnum);
139}
140
Shengzhou Liu031228a2014-02-21 13:16:19 +0800141static int t208xqds_mdio_write(struct mii_dev *bus, int addr, int devad,
Shengzhou Liu07886942013-11-22 17:39:11 +0800142 int regnum, u16 value)
143{
Shengzhou Liu031228a2014-02-21 13:16:19 +0800144 struct t208xqds_mdio *priv = bus->priv;
Shengzhou Liu07886942013-11-22 17:39:11 +0800145
Shengzhou Liu031228a2014-02-21 13:16:19 +0800146 t208xqds_mux_mdio(priv->muxval);
Shengzhou Liu07886942013-11-22 17:39:11 +0800147
148 return priv->realbus->write(priv->realbus, addr, devad, regnum, value);
149}
150
Shengzhou Liu031228a2014-02-21 13:16:19 +0800151static int t208xqds_mdio_reset(struct mii_dev *bus)
Shengzhou Liu07886942013-11-22 17:39:11 +0800152{
Shengzhou Liu031228a2014-02-21 13:16:19 +0800153 struct t208xqds_mdio *priv = bus->priv;
Shengzhou Liu07886942013-11-22 17:39:11 +0800154
155 return priv->realbus->reset(priv->realbus);
156}
157
Shengzhou Liu031228a2014-02-21 13:16:19 +0800158static int t208xqds_mdio_init(char *realbusname, u8 muxval)
Shengzhou Liu07886942013-11-22 17:39:11 +0800159{
Shengzhou Liu031228a2014-02-21 13:16:19 +0800160 struct t208xqds_mdio *pmdio;
Shengzhou Liu07886942013-11-22 17:39:11 +0800161 struct mii_dev *bus = mdio_alloc();
162
163 if (!bus) {
Shengzhou Liu031228a2014-02-21 13:16:19 +0800164 printf("Failed to allocate t208xqds MDIO bus\n");
Shengzhou Liu07886942013-11-22 17:39:11 +0800165 return -1;
166 }
167
168 pmdio = malloc(sizeof(*pmdio));
169 if (!pmdio) {
Shengzhou Liu031228a2014-02-21 13:16:19 +0800170 printf("Failed to allocate t208xqds private data\n");
Shengzhou Liu07886942013-11-22 17:39:11 +0800171 free(bus);
172 return -1;
173 }
174
Shengzhou Liu031228a2014-02-21 13:16:19 +0800175 bus->read = t208xqds_mdio_read;
176 bus->write = t208xqds_mdio_write;
177 bus->reset = t208xqds_mdio_reset;
Ben Whitten34fd6c92015-12-30 13:05:58 +0000178 strcpy(bus->name, t208xqds_mdio_name_for_muxval(muxval));
Shengzhou Liu07886942013-11-22 17:39:11 +0800179
180 pmdio->realbus = miiphy_get_dev_by_name(realbusname);
181
182 if (!pmdio->realbus) {
183 printf("No bus with name %s\n", realbusname);
184 free(bus);
185 free(pmdio);
186 return -1;
187 }
188
189 pmdio->muxval = muxval;
190 bus->priv = pmdio;
Shengzhou Liu07886942013-11-22 17:39:11 +0800191 return mdio_register(bus);
192}
193
194void board_ft_fman_fixup_port(void *fdt, char *compat, phys_addr_t addr,
195 enum fm_port port, int offset)
196{
197 int phy;
198 char alias[20];
shaohui xie2f50d612014-10-20 19:48:19 +0800199 char lane_mode[2][20] = {"1000BASE-KX", "10GBASE-KR"};
200 char buf[32] = "serdes-1,";
Shengzhou Liu07886942013-11-22 17:39:11 +0800201 struct fixed_link f_link;
shaohui xie2f50d612014-10-20 19:48:19 +0800202 int media_type = 0;
203 int off;
204
Shengzhou Liu07886942013-11-22 17:39:11 +0800205 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
York Sunc68b12d2016-12-28 08:43:36 -0800206#ifdef CONFIG_TARGET_T2080QDS
Shaohui Xie2ec2f302014-10-20 19:51:21 +0800207 serdes_corenet_t *srds_regs =
208 (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
209 u32 srds1_pccr1 = in_be32(&srds_regs->srdspccr1);
210#endif
Shengzhou Liu07886942013-11-22 17:39:11 +0800211 u32 srds_s1 = in_be32(&gur->rcwsr[4]) &
212 FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
213
214 srds_s1 >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
215
216 if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_SGMII) {
217 phy = fm_info_get_phy_address(port);
218 switch (port) {
York Sunc68b12d2016-12-28 08:43:36 -0800219#if defined(CONFIG_TARGET_T2080QDS)
Shengzhou Liu07886942013-11-22 17:39:11 +0800220 case FM1_DTSEC1:
Shaohui Xie2ec2f302014-10-20 19:51:21 +0800221 if (hwconfig_sub("fsl_1gkx", "fm1_1g1")) {
222 media_type = 1;
223 fdt_set_phy_handle(fdt, compat, addr,
224 "phy_1gkx1");
225 fdt_status_okay_by_alias(fdt, "1gkx_pcs_mdio1");
226 sprintf(buf, "%s%s%s", buf, "lane-c,",
227 (char *)lane_mode[0]);
228 out_be32(&srds_regs->srdspccr1, srds1_pccr1 |
229 PCCR1_SGMIIH_KX_MASK);
230 break;
231 }
Shengzhou Liu07886942013-11-22 17:39:11 +0800232 case FM1_DTSEC2:
Shaohui Xie2ec2f302014-10-20 19:51:21 +0800233 if (hwconfig_sub("fsl_1gkx", "fm1_1g2")) {
234 media_type = 1;
235 fdt_set_phy_handle(fdt, compat, addr,
236 "phy_1gkx2");
237 fdt_status_okay_by_alias(fdt, "1gkx_pcs_mdio2");
238 sprintf(buf, "%s%s%s", buf, "lane-d,",
239 (char *)lane_mode[0]);
240 out_be32(&srds_regs->srdspccr1, srds1_pccr1 |
241 PCCR1_SGMIIG_KX_MASK);
242 break;
243 }
Shengzhou Liu07886942013-11-22 17:39:11 +0800244 case FM1_DTSEC9:
Shaohui Xie2ec2f302014-10-20 19:51:21 +0800245 if (hwconfig_sub("fsl_1gkx", "fm1_1g9")) {
246 media_type = 1;
247 fdt_set_phy_handle(fdt, compat, addr,
248 "phy_1gkx9");
249 fdt_status_okay_by_alias(fdt, "1gkx_pcs_mdio9");
250 sprintf(buf, "%s%s%s", buf, "lane-a,",
251 (char *)lane_mode[0]);
252 out_be32(&srds_regs->srdspccr1, srds1_pccr1 |
253 PCCR1_SGMIIE_KX_MASK);
254 break;
255 }
Shengzhou Liu07886942013-11-22 17:39:11 +0800256 case FM1_DTSEC10:
Shaohui Xie2ec2f302014-10-20 19:51:21 +0800257 if (hwconfig_sub("fsl_1gkx", "fm1_1g10")) {
258 media_type = 1;
259 fdt_set_phy_handle(fdt, compat, addr,
260 "phy_1gkx10");
261 fdt_status_okay_by_alias(fdt,
262 "1gkx_pcs_mdio10");
263 sprintf(buf, "%s%s%s", buf, "lane-b,",
264 (char *)lane_mode[0]);
265 out_be32(&srds_regs->srdspccr1, srds1_pccr1 |
266 PCCR1_SGMIIF_KX_MASK);
267 break;
268 }
Shengzhou Liu031228a2014-02-21 13:16:19 +0800269 if (mdio_mux[port] == EMI1_SLOT2) {
270 sprintf(alias, "phy_sgmii_s2_%x", phy);
271 fdt_set_phy_handle(fdt, compat, addr, alias);
272 fdt_status_okay_by_alias(fdt, "emi1_slot2");
273 } else if (mdio_mux[port] == EMI1_SLOT3) {
274 sprintf(alias, "phy_sgmii_s3_%x", phy);
275 fdt_set_phy_handle(fdt, compat, addr, alias);
276 fdt_status_okay_by_alias(fdt, "emi1_slot3");
277 }
Shengzhou Liu07886942013-11-22 17:39:11 +0800278 break;
279 case FM1_DTSEC5:
Shaohui Xie2ec2f302014-10-20 19:51:21 +0800280 if (hwconfig_sub("fsl_1gkx", "fm1_1g5")) {
281 media_type = 1;
282 fdt_set_phy_handle(fdt, compat, addr,
283 "phy_1gkx5");
284 fdt_status_okay_by_alias(fdt, "1gkx_pcs_mdio5");
285 sprintf(buf, "%s%s%s", buf, "lane-g,",
286 (char *)lane_mode[0]);
287 out_be32(&srds_regs->srdspccr1, srds1_pccr1 |
288 PCCR1_SGMIIC_KX_MASK);
289 break;
290 }
Shengzhou Liu07886942013-11-22 17:39:11 +0800291 case FM1_DTSEC6:
Shaohui Xie2ec2f302014-10-20 19:51:21 +0800292 if (hwconfig_sub("fsl_1gkx", "fm1_1g6")) {
293 media_type = 1;
294 fdt_set_phy_handle(fdt, compat, addr,
295 "phy_1gkx6");
296 fdt_status_okay_by_alias(fdt, "1gkx_pcs_mdio6");
297 sprintf(buf, "%s%s%s", buf, "lane-h,",
298 (char *)lane_mode[0]);
299 out_be32(&srds_regs->srdspccr1, srds1_pccr1 |
300 PCCR1_SGMIID_KX_MASK);
301 break;
302 }
Shengzhou Liu07886942013-11-22 17:39:11 +0800303 if (mdio_mux[port] == EMI1_SLOT1) {
304 sprintf(alias, "phy_sgmii_s1_%x", phy);
305 fdt_set_phy_handle(fdt, compat, addr, alias);
306 fdt_status_okay_by_alias(fdt, "emi1_slot1");
307 } else if (mdio_mux[port] == EMI1_SLOT2) {
308 sprintf(alias, "phy_sgmii_s2_%x", phy);
309 fdt_set_phy_handle(fdt, compat, addr, alias);
310 fdt_status_okay_by_alias(fdt, "emi1_slot2");
311 }
312 break;
York Sun99eb6072016-12-28 08:43:38 -0800313#elif defined(CONFIG_TARGET_T2081QDS)
Shengzhou Liu031228a2014-02-21 13:16:19 +0800314 case FM1_DTSEC1:
315 case FM1_DTSEC2:
316 case FM1_DTSEC5:
317 case FM1_DTSEC6:
318 case FM1_DTSEC9:
319 case FM1_DTSEC10:
320 if (mdio_mux[port] == EMI1_SLOT2) {
321 sprintf(alias, "phy_sgmii_s2_%x", phy);
322 fdt_set_phy_handle(fdt, compat, addr, alias);
323 fdt_status_okay_by_alias(fdt, "emi1_slot2");
324 } else if (mdio_mux[port] == EMI1_SLOT3) {
325 sprintf(alias, "phy_sgmii_s3_%x", phy);
326 fdt_set_phy_handle(fdt, compat, addr, alias);
327 fdt_status_okay_by_alias(fdt, "emi1_slot3");
328 } else if (mdio_mux[port] == EMI1_SLOT5) {
329 sprintf(alias, "phy_sgmii_s5_%x", phy);
330 fdt_set_phy_handle(fdt, compat, addr, alias);
331 fdt_status_okay_by_alias(fdt, "emi1_slot5");
332 } else if (mdio_mux[port] == EMI1_SLOT6) {
333 sprintf(alias, "phy_sgmii_s6_%x", phy);
334 fdt_set_phy_handle(fdt, compat, addr, alias);
335 fdt_status_okay_by_alias(fdt, "emi1_slot6");
336 } else if (mdio_mux[port] == EMI1_SLOT7) {
337 sprintf(alias, "phy_sgmii_s7_%x", phy);
338 fdt_set_phy_handle(fdt, compat, addr, alias);
339 fdt_status_okay_by_alias(fdt, "emi1_slot7");
340 }
341 break;
342#endif
Shengzhou Liu07886942013-11-22 17:39:11 +0800343 default:
344 break;
345 }
Shaohui Xie2ec2f302014-10-20 19:51:21 +0800346 if (media_type) {
347 /* set property for 1000BASE-KX in dtb */
348 off = fdt_node_offset_by_compat_reg(fdt,
349 "fsl,fman-memac-mdio", addr + 0x1000);
350 fdt_setprop_string(fdt, off, "lane-instance", buf);
351 }
Shengzhou Liu07886942013-11-22 17:39:11 +0800352
353 } else if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_XGMII) {
354 switch (srds_s1) {
355 case 0x66: /* XFI interface */
356 case 0x6b:
357 case 0x6c:
358 case 0x6d:
359 case 0x71:
shaohui xie2f50d612014-10-20 19:48:19 +0800360 /*
361 * if the 10G is XFI, check hwconfig to see what is the
362 * media type, there are two types, fiber or copper,
363 * fix the dtb accordingly.
364 */
365 switch (port) {
366 case FM1_10GEC1:
367 if (hwconfig_sub("fsl_10gkr_copper", "fm1_10g1")) {
368 /* it's MAC9 */
369 media_type = 1;
370 fdt_set_phy_handle(fdt, compat, addr,
371 "phy_xfi9");
372 fdt_status_okay_by_alias(fdt, "xfi_pcs_mdio9");
373 sprintf(buf, "%s%s%s", buf, "lane-a,",
374 (char *)lane_mode[1]);
375 }
376 break;
377 case FM1_10GEC2:
378 if (hwconfig_sub("fsl_10gkr_copper", "fm1_10g2")) {
379 /* it's MAC10 */
380 media_type = 1;
381 fdt_set_phy_handle(fdt, compat, addr,
382 "phy_xfi10");
383 fdt_status_okay_by_alias(fdt, "xfi_pcs_mdio10");
384 sprintf(buf, "%s%s%s", buf, "lane-b,",
385 (char *)lane_mode[1]);
386 }
387 break;
388 case FM1_10GEC3:
389 if (hwconfig_sub("fsl_10gkr_copper", "fm1_10g3")) {
390 /* it's MAC1 */
391 media_type = 1;
392 fdt_set_phy_handle(fdt, compat, addr,
393 "phy_xfi1");
394 fdt_status_okay_by_alias(fdt, "xfi_pcs_mdio1");
395 sprintf(buf, "%s%s%s", buf, "lane-c,",
396 (char *)lane_mode[1]);
397 }
398 break;
399 case FM1_10GEC4:
400 if (hwconfig_sub("fsl_10gkr_copper", "fm1_10g4")) {
401 /* it's MAC2 */
402 media_type = 1;
403 fdt_set_phy_handle(fdt, compat, addr,
404 "phy_xfi2");
405 fdt_status_okay_by_alias(fdt, "xfi_pcs_mdio2");
406 sprintf(buf, "%s%s%s", buf, "lane-d,",
407 (char *)lane_mode[1]);
408 }
409 break;
410 default:
411 return;
412 }
413
414 if (!media_type) {
415 /* fixed-link is used for XFI fiber cable */
416 f_link.phy_id = port;
417 f_link.duplex = 1;
418 f_link.link_speed = 10000;
419 f_link.pause = 0;
420 f_link.asym_pause = 0;
421 fdt_delprop(fdt, offset, "phy-handle");
422 fdt_setprop(fdt, offset, "fixed-link", &f_link,
423 sizeof(f_link));
424 } else {
425 /* set property for copper cable */
426 off = fdt_node_offset_by_compat_reg(fdt,
427 "fsl,fman-memac-mdio", addr + 0x1000);
428 fdt_setprop_string(fdt, off,
429 "lane-instance", buf);
430 }
Shengzhou Liu07886942013-11-22 17:39:11 +0800431 break;
432 default:
433 break;
434 }
435 }
436}
437
438void fdt_fixup_board_enet(void *fdt)
439{
440 return;
441}
442
443/*
Shengzhou Liu031228a2014-02-21 13:16:19 +0800444 * This function reads RCW to check if Serdes1{A:H} is configured
445 * to slot 1/2/3/4/5/6/7 and update the lane_to_slot[] array accordingly
Shengzhou Liu07886942013-11-22 17:39:11 +0800446 */
447static void initialize_lane_to_slot(void)
448{
449 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
450 u32 srds_s1 = in_be32(&gur->rcwsr[4]) &
451 FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
452
453 srds_s1 >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
454
455 switch (srds_s1) {
York Sunc68b12d2016-12-28 08:43:36 -0800456#if defined(CONFIG_TARGET_T2080QDS)
Shengzhou Liu07886942013-11-22 17:39:11 +0800457 case 0x51:
458 case 0x5f:
459 case 0x65:
460 case 0x6b:
461 case 0x71:
462 lane_to_slot[5] = 2;
463 lane_to_slot[6] = 2;
464 lane_to_slot[7] = 2;
465 break;
466 case 0xa6:
467 case 0x8e:
468 case 0x8f:
469 case 0x82:
470 case 0x83:
471 case 0xd3:
472 case 0xd9:
473 case 0xcb:
474 lane_to_slot[6] = 2;
475 lane_to_slot[7] = 2;
476 break;
477 case 0xda:
478 lane_to_slot[4] = 3;
479 lane_to_slot[5] = 3;
480 lane_to_slot[6] = 3;
481 lane_to_slot[7] = 3;
482 break;
York Sun99eb6072016-12-28 08:43:38 -0800483#elif defined(CONFIG_TARGET_T2081QDS)
Shengzhou Liu031228a2014-02-21 13:16:19 +0800484 case 0x6b:
485 lane_to_slot[4] = 1;
486 lane_to_slot[5] = 3;
487 lane_to_slot[6] = 3;
488 lane_to_slot[7] = 3;
489 break;
490 case 0xca:
491 case 0xcb:
492 lane_to_slot[1] = 7;
493 lane_to_slot[2] = 6;
494 lane_to_slot[3] = 5;
495 lane_to_slot[5] = 3;
496 lane_to_slot[6] = 3;
497 lane_to_slot[7] = 3;
498 break;
499 case 0xf2:
500 lane_to_slot[1] = 7;
501 lane_to_slot[2] = 7;
502 lane_to_slot[3] = 7;
503 lane_to_slot[5] = 4;
504 lane_to_slot[6] = 3;
505 lane_to_slot[7] = 7;
506 break;
507#endif
Shengzhou Liu07886942013-11-22 17:39:11 +0800508 default:
509 break;
510 }
511}
512
513int board_eth_init(bd_t *bis)
514{
515#if defined(CONFIG_FMAN_ENET)
516 int i, idx, lane, slot, interface;
517 struct memac_mdio_info dtsec_mdio_info;
518 struct memac_mdio_info tgec_mdio_info;
519 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
520 u32 rcwsr13 = in_be32(&gur->rcwsr[13]);
521 u32 srds_s1;
522
523 srds_s1 = in_be32(&gur->rcwsr[4]) &
524 FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
525 srds_s1 >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
526
527 initialize_lane_to_slot();
528
529 /* Initialize the mdio_mux array so we can recognize empty elements */
530 for (i = 0; i < NUM_FM_PORTS; i++)
531 mdio_mux[i] = EMI_NONE;
532
533 dtsec_mdio_info.regs =
534 (struct memac_mdio_controller *)CONFIG_SYS_FM1_DTSEC_MDIO_ADDR;
535
536 dtsec_mdio_info.name = DEFAULT_FM_MDIO_NAME;
537
538 /* Register the 1G MDIO bus */
539 fm_memac_mdio_init(bis, &dtsec_mdio_info);
540
541 tgec_mdio_info.regs =
542 (struct memac_mdio_controller *)CONFIG_SYS_FM1_TGEC_MDIO_ADDR;
543 tgec_mdio_info.name = DEFAULT_FM_TGEC_MDIO_NAME;
544
545 /* Register the 10G MDIO bus */
546 fm_memac_mdio_init(bis, &tgec_mdio_info);
547
548 /* Register the muxing front-ends to the MDIO buses */
Shengzhou Liu031228a2014-02-21 13:16:19 +0800549 t208xqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII1);
550 t208xqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII2);
551 t208xqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT1);
552 t208xqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT2);
553 t208xqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT3);
York Sunc68b12d2016-12-28 08:43:36 -0800554#if defined(CONFIG_TARGET_T2080QDS)
Shengzhou Liu031228a2014-02-21 13:16:19 +0800555 t208xqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT4);
556#endif
557 t208xqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT5);
York Sun99eb6072016-12-28 08:43:38 -0800558#if defined(CONFIG_TARGET_T2081QDS)
Shengzhou Liu031228a2014-02-21 13:16:19 +0800559 t208xqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT6);
560 t208xqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT7);
561#endif
562 t208xqds_mdio_init(DEFAULT_FM_TGEC_MDIO_NAME, EMI2);
Shengzhou Liu07886942013-11-22 17:39:11 +0800563
564 /* Set the two on-board RGMII PHY address */
565 fm_info_set_phy_address(FM1_DTSEC3, RGMII_PHY1_ADDR);
566 if ((rcwsr13 & FSL_CORENET_RCWSR13_EC2) ==
567 FSL_CORENET_RCWSR13_EC2_DTSEC4_RGMII)
568 fm_info_set_phy_address(FM1_DTSEC4, RGMII_PHY2_ADDR);
569 else
570 fm_info_set_phy_address(FM1_DTSEC10, RGMII_PHY2_ADDR);
571
572 switch (srds_s1) {
Shengzhou Liu03e2dc82014-05-15 19:24:11 +0800573 case 0x1b:
Shengzhou Liu07886942013-11-22 17:39:11 +0800574 case 0x1c:
575 case 0x95:
576 case 0xa2:
577 case 0x94:
Shengzhou Liu031228a2014-02-21 13:16:19 +0800578 /* T2080QDS: SGMII in Slot3; T2081QDS: SGMII in Slot2 */
Shengzhou Liu07886942013-11-22 17:39:11 +0800579 fm_info_set_phy_address(FM1_DTSEC9, SGMII_CARD_PORT1_PHY_ADDR);
580 fm_info_set_phy_address(FM1_DTSEC10, SGMII_CARD_PORT2_PHY_ADDR);
581 fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT3_PHY_ADDR);
582 fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT4_PHY_ADDR);
Shengzhou Liu031228a2014-02-21 13:16:19 +0800583 /* T2080QDS: SGMII in Slot2; T2081QDS: SGMII in Slot1 */
Shengzhou Liu07886942013-11-22 17:39:11 +0800584 fm_info_set_phy_address(FM1_DTSEC5, SGMII_CARD_PORT3_PHY_ADDR);
585 fm_info_set_phy_address(FM1_DTSEC6, SGMII_CARD_PORT4_PHY_ADDR);
586 break;
Shengzhou Liu03e2dc82014-05-15 19:24:11 +0800587 case 0x50:
Shengzhou Liu07886942013-11-22 17:39:11 +0800588 case 0x51:
Shengzhou Liu03e2dc82014-05-15 19:24:11 +0800589 case 0x5e:
Shengzhou Liu07886942013-11-22 17:39:11 +0800590 case 0x5f:
Shengzhou Liu03e2dc82014-05-15 19:24:11 +0800591 case 0x64:
Shengzhou Liu07886942013-11-22 17:39:11 +0800592 case 0x65:
Shengzhou Liu031228a2014-02-21 13:16:19 +0800593 /* T2080QDS: XAUI/HiGig in Slot3; T2081QDS: in Slot2 */
Shengzhou Liu07886942013-11-22 17:39:11 +0800594 fm_info_set_phy_address(FM1_10GEC1, FM1_10GEC1_PHY_ADDR);
Shengzhou Liu031228a2014-02-21 13:16:19 +0800595 /* T2080QDS: SGMII in Slot2; T2081QDS: in Slot3 */
Shengzhou Liu07886942013-11-22 17:39:11 +0800596 fm_info_set_phy_address(FM1_DTSEC5, SGMII_CARD_PORT3_PHY_ADDR);
597 fm_info_set_phy_address(FM1_DTSEC6, SGMII_CARD_PORT4_PHY_ADDR);
598 break;
599 case 0x66:
Shengzhou Liu03e2dc82014-05-15 19:24:11 +0800600 case 0x67:
Shengzhou Liu07886942013-11-22 17:39:11 +0800601 /*
Bin Meng75574052016-02-05 19:30:11 -0800602 * XFI does not need a PHY to work, but to avoid U-Boot use
Shengzhou Liu07886942013-11-22 17:39:11 +0800603 * default PHY address which is zero to a MAC when it found
604 * a MAC has no PHY address, we give a PHY address to XFI
605 * MAC, and should not use a real XAUI PHY address, since
606 * MDIO can access it successfully, and then MDIO thinks
607 * the XAUI card is used for the XFI MAC, which will cause
608 * error.
609 */
610 fm_info_set_phy_address(FM1_10GEC1, 4);
611 fm_info_set_phy_address(FM1_10GEC2, 5);
612 fm_info_set_phy_address(FM1_10GEC3, 6);
613 fm_info_set_phy_address(FM1_10GEC4, 7);
614 break;
Shengzhou Liu03e2dc82014-05-15 19:24:11 +0800615 case 0x6a:
Shengzhou Liu07886942013-11-22 17:39:11 +0800616 case 0x6b:
617 fm_info_set_phy_address(FM1_10GEC1, 4);
618 fm_info_set_phy_address(FM1_10GEC2, 5);
619 fm_info_set_phy_address(FM1_10GEC3, 6);
620 fm_info_set_phy_address(FM1_10GEC4, 7);
Shengzhou Liu031228a2014-02-21 13:16:19 +0800621 /* T2080QDS: SGMII in Slot2; T2081QDS: in Slot3 */
Shengzhou Liu07886942013-11-22 17:39:11 +0800622 fm_info_set_phy_address(FM1_DTSEC5, SGMII_CARD_PORT3_PHY_ADDR);
623 fm_info_set_phy_address(FM1_DTSEC6, SGMII_CARD_PORT2_PHY_ADDR);
624 break;
625 case 0x6c:
626 case 0x6d:
Shengzhou Liu7fcbd1f2014-01-03 14:48:44 +0800627 fm_info_set_phy_address(FM1_10GEC1, 4);
628 fm_info_set_phy_address(FM1_10GEC2, 5);
Shengzhou Liu031228a2014-02-21 13:16:19 +0800629 /* T2080QDS: SGMII in Slot3; T2081QDS: in Slot2 */
Shengzhou Liu07886942013-11-22 17:39:11 +0800630 fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT3_PHY_ADDR);
Shengzhou Liu7fcbd1f2014-01-03 14:48:44 +0800631 fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT4_PHY_ADDR);
Shengzhou Liu07886942013-11-22 17:39:11 +0800632 break;
Shengzhou Liu03e2dc82014-05-15 19:24:11 +0800633 case 0x70:
Shengzhou Liu07886942013-11-22 17:39:11 +0800634 case 0x71:
635 /* SGMII in Slot3 */
636 fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT3_PHY_ADDR);
637 fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT4_PHY_ADDR);
638 /* SGMII in Slot2 */
639 fm_info_set_phy_address(FM1_DTSEC5, SGMII_CARD_PORT3_PHY_ADDR);
640 fm_info_set_phy_address(FM1_DTSEC6, SGMII_CARD_PORT2_PHY_ADDR);
641 break;
642 case 0xa6:
643 case 0x8e:
644 case 0x8f:
645 case 0x82:
646 case 0x83:
647 /* SGMII in Slot3 */
648 fm_info_set_phy_address(FM1_DTSEC9, SGMII_CARD_PORT1_PHY_ADDR);
649 fm_info_set_phy_address(FM1_DTSEC10, SGMII_CARD_PORT2_PHY_ADDR);
650 fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT3_PHY_ADDR);
651 fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT4_PHY_ADDR);
652 /* SGMII in Slot2 */
653 fm_info_set_phy_address(FM1_DTSEC5, SGMII_CARD_PORT3_PHY_ADDR);
654 fm_info_set_phy_address(FM1_DTSEC6, SGMII_CARD_PORT2_PHY_ADDR);
655 break;
656 case 0xa4:
657 case 0x96:
658 case 0x8a:
659 /* SGMII in Slot3 */
660 fm_info_set_phy_address(FM1_DTSEC9, SGMII_CARD_PORT1_PHY_ADDR);
661 fm_info_set_phy_address(FM1_DTSEC10, SGMII_CARD_PORT2_PHY_ADDR);
662 fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT3_PHY_ADDR);
663 fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT4_PHY_ADDR);
664 break;
York Sunc68b12d2016-12-28 08:43:36 -0800665#if defined(CONFIG_TARGET_T2080QDS)
Shengzhou Liu07886942013-11-22 17:39:11 +0800666 case 0xd9:
667 case 0xd3:
668 case 0xcb:
669 /* SGMII in Slot3 */
670 fm_info_set_phy_address(FM1_DTSEC10, SGMII_CARD_PORT2_PHY_ADDR);
671 fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT3_PHY_ADDR);
672 fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT4_PHY_ADDR);
673 /* SGMII in Slot2 */
674 fm_info_set_phy_address(FM1_DTSEC5, SGMII_CARD_PORT3_PHY_ADDR);
675 fm_info_set_phy_address(FM1_DTSEC6, SGMII_CARD_PORT2_PHY_ADDR);
676 break;
York Sun99eb6072016-12-28 08:43:38 -0800677#elif defined(CONFIG_TARGET_T2081QDS)
Shengzhou Liu031228a2014-02-21 13:16:19 +0800678 case 0xca:
679 case 0xcb:
680 /* SGMII in Slot3 */
681 fm_info_set_phy_address(FM1_DTSEC5, SGMII_CARD_PORT1_PHY_ADDR);
682 fm_info_set_phy_address(FM1_DTSEC6, SGMII_CARD_PORT2_PHY_ADDR);
683 /* SGMII in Slot5 */
684 fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT1_PHY_ADDR);
685 /* SGMII in Slot6 */
686 fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT1_PHY_ADDR);
687 /* SGMII in Slot7 */
688 fm_info_set_phy_address(FM1_DTSEC10, SGMII_CARD_PORT3_PHY_ADDR);
689 break;
690#endif
691 case 0xf2:
692 /* T2080QDS: SGMII in Slot3; T2081QDS: SGMII in Slot7 */
693 fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT1_PHY_ADDR);
694 fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT2_PHY_ADDR);
695 fm_info_set_phy_address(FM1_DTSEC10, SGMII_CARD_PORT3_PHY_ADDR);
696 fm_info_set_phy_address(FM1_DTSEC6, SGMII_CARD_PORT4_PHY_ADDR);
697 break;
Shengzhou Liu07886942013-11-22 17:39:11 +0800698 default:
Shengzhou Liu07886942013-11-22 17:39:11 +0800699 break;
700 }
701
702 for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) {
703 idx = i - FM1_DTSEC1;
704 interface = fm_info_get_enet_if(i);
705 switch (interface) {
706 case PHY_INTERFACE_MODE_SGMII:
707 lane = serdes_get_first_lane(FSL_SRDS_1,
708 SGMII_FM1_DTSEC1 + idx);
709 if (lane < 0)
710 break;
711 slot = lane_to_slot[lane];
712 debug("FM1@DTSEC%u expects SGMII in slot %u\n",
713 idx + 1, slot);
714 if (QIXIS_READ(present2) & (1 << (slot - 1)))
715 fm_disable_port(i);
716
717 switch (slot) {
718 case 1:
719 mdio_mux[i] = EMI1_SLOT1;
720 fm_info_set_mdio(i, mii_dev_for_muxval(
721 mdio_mux[i]));
722 break;
723 case 2:
724 mdio_mux[i] = EMI1_SLOT2;
725 fm_info_set_mdio(i, mii_dev_for_muxval(
726 mdio_mux[i]));
727 break;
Shengzhou Liu7fcbd1f2014-01-03 14:48:44 +0800728 case 3:
729 mdio_mux[i] = EMI1_SLOT3;
730 fm_info_set_mdio(i, mii_dev_for_muxval(
Shengzhou Liu031228a2014-02-21 13:16:19 +0800731 mdio_mux[i]));
732 break;
York Sun99eb6072016-12-28 08:43:38 -0800733#if defined(CONFIG_TARGET_T2081QDS)
Shengzhou Liu031228a2014-02-21 13:16:19 +0800734 case 5:
735 mdio_mux[i] = EMI1_SLOT5;
736 fm_info_set_mdio(i, mii_dev_for_muxval(
737 mdio_mux[i]));
738 break;
739 case 6:
740 mdio_mux[i] = EMI1_SLOT6;
741 fm_info_set_mdio(i, mii_dev_for_muxval(
742 mdio_mux[i]));
743 break;
744 case 7:
745 mdio_mux[i] = EMI1_SLOT7;
746 fm_info_set_mdio(i, mii_dev_for_muxval(
747 mdio_mux[i]));
Shengzhou Liu7fcbd1f2014-01-03 14:48:44 +0800748 break;
Shengzhou Liu031228a2014-02-21 13:16:19 +0800749#endif
Shengzhou Liu7fcbd1f2014-01-03 14:48:44 +0800750 }
Shengzhou Liu07886942013-11-22 17:39:11 +0800751 break;
752 case PHY_INTERFACE_MODE_RGMII:
753 if (i == FM1_DTSEC3)
754 mdio_mux[i] = EMI1_RGMII1;
755 else if (i == FM1_DTSEC4 || FM1_DTSEC10)
756 mdio_mux[i] = EMI1_RGMII2;
757 fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
758 break;
759 default:
760 break;
761 }
762 }
763
764 for (i = FM1_10GEC1; i < FM1_10GEC1 + CONFIG_SYS_NUM_FM1_10GEC; i++) {
765 idx = i - FM1_10GEC1;
766 switch (fm_info_get_enet_if(i)) {
767 case PHY_INTERFACE_MODE_XGMII:
768 if (srds_s1 == 0x51) {
769 lane = serdes_get_first_lane(FSL_SRDS_1,
770 XAUI_FM1_MAC9 + idx);
771 } else if ((srds_s1 == 0x5f) || (srds_s1 == 0x65)) {
772 lane = serdes_get_first_lane(FSL_SRDS_1,
773 HIGIG_FM1_MAC9 + idx);
774 } else {
775 if (i == FM1_10GEC1 || i == FM1_10GEC2)
776 lane = serdes_get_first_lane(FSL_SRDS_1,
777 XFI_FM1_MAC9 + idx);
778 else
779 lane = serdes_get_first_lane(FSL_SRDS_1,
780 XFI_FM1_MAC1 + idx);
781 }
782
783 if (lane < 0)
784 break;
785 mdio_mux[i] = EMI2;
786 fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
787
788 if ((srds_s1 == 0x66) || (srds_s1 == 0x6b) ||
Shengzhou Liu03e2dc82014-05-15 19:24:11 +0800789 (srds_s1 == 0x6a) || (srds_s1 == 0x70) ||
Shengzhou Liu07886942013-11-22 17:39:11 +0800790 (srds_s1 == 0x6c) || (srds_s1 == 0x6d) ||
791 (srds_s1 == 0x71)) {
792 /* As XFI is in cage intead of a slot, so
793 * ensure doesn't disable the corresponding port
794 */
795 break;
796 }
797
798 slot = lane_to_slot[lane];
799 if (QIXIS_READ(present2) & (1 << (slot - 1)))
800 fm_disable_port(i);
801 break;
802 default:
803 break;
804 }
805 }
806
807 cpu_eth_init(bis);
808#endif /* CONFIG_FMAN_ENET */
809
810 return pci_eth_init(bis);
811}