]>
Commit | Line | Data |
---|---|---|
c4d0e811 SL |
1 | /* |
2 | * Copyright 2013 Freescale Semiconductor, Inc. | |
3 | * | |
4 | * Shengzhou Liu <Shengzhou.Liu@freescale.com> | |
5 | * | |
6 | * SPDX-License-Identifier: GPL-2.0+ | |
7 | */ | |
8 | ||
9 | #include <common.h> | |
10 | #include <command.h> | |
11 | #include <netdev.h> | |
12 | #include <asm/mmu.h> | |
13 | #include <asm/processor.h> | |
14 | #include <asm/immap_85xx.h> | |
15 | #include <asm/fsl_law.h> | |
16 | #include <asm/fsl_serdes.h> | |
17 | #include <asm/fsl_portals.h> | |
18 | #include <asm/fsl_liodn.h> | |
19 | #include <malloc.h> | |
20 | #include <fm_eth.h> | |
21 | #include <fsl_mdio.h> | |
22 | #include <miiphy.h> | |
23 | #include <phy.h> | |
8225b2fd | 24 | #include <fsl_dtsec.h> |
c4d0e811 | 25 | #include <asm/fsl_serdes.h> |
f0644da5 | 26 | #include <hwconfig.h> |
c4d0e811 SL |
27 | #include "../common/qixis.h" |
28 | #include "../common/fman.h" | |
254887a5 | 29 | #include "t208xqds_qixis.h" |
c4d0e811 SL |
30 | |
31 | #define EMI_NONE 0xFFFFFFFF | |
32 | #define EMI1_RGMII1 0 | |
33 | #define EMI1_RGMII2 1 | |
34 | #define EMI1_SLOT1 2 | |
80d26188 | 35 | #if defined(CONFIG_TARGET_T2080QDS) |
c4d0e811 SL |
36 | #define EMI1_SLOT2 6 |
37 | #define EMI1_SLOT3 3 | |
38 | #define EMI1_SLOT4 4 | |
39 | #define EMI1_SLOT5 5 | |
6b7679c8 | 40 | #define EMI2 7 |
146ded4d | 41 | #elif defined(CONFIG_TARGET_T2081QDS) |
254887a5 SL |
42 | #define EMI1_SLOT2 3 |
43 | #define EMI1_SLOT3 4 | |
44 | #define EMI1_SLOT5 5 | |
45 | #define EMI1_SLOT6 6 | |
46 | #define EMI1_SLOT7 7 | |
254887a5 | 47 | #define EMI2 8 |
6b7679c8 | 48 | #endif |
c4d0e811 | 49 | |
3ce21c87 SX |
50 | #define PCCR1_SGMIIA_KX_MASK 0x00008000 |
51 | #define PCCR1_SGMIIB_KX_MASK 0x00004000 | |
52 | #define PCCR1_SGMIIC_KX_MASK 0x00002000 | |
53 | #define PCCR1_SGMIID_KX_MASK 0x00001000 | |
54 | #define PCCR1_SGMIIE_KX_MASK 0x00000800 | |
55 | #define PCCR1_SGMIIF_KX_MASK 0x00000400 | |
56 | #define PCCR1_SGMIIG_KX_MASK 0x00000200 | |
57 | #define PCCR1_SGMIIH_KX_MASK 0x00000100 | |
58 | ||
c4d0e811 SL |
59 | static int mdio_mux[NUM_FM_PORTS]; |
60 | ||
61 | static const char * const mdio_names[] = { | |
80d26188 | 62 | #if defined(CONFIG_TARGET_T2080QDS) |
c4d0e811 SL |
63 | "T2080QDS_MDIO_RGMII1", |
64 | "T2080QDS_MDIO_RGMII2", | |
65 | "T2080QDS_MDIO_SLOT1", | |
66 | "T2080QDS_MDIO_SLOT3", | |
67 | "T2080QDS_MDIO_SLOT4", | |
68 | "T2080QDS_MDIO_SLOT5", | |
69 | "T2080QDS_MDIO_SLOT2", | |
70 | "T2080QDS_MDIO_10GC", | |
146ded4d | 71 | #elif defined(CONFIG_TARGET_T2081QDS) |
254887a5 SL |
72 | "T2081QDS_MDIO_RGMII1", |
73 | "T2081QDS_MDIO_RGMII2", | |
74 | "T2081QDS_MDIO_SLOT1", | |
75 | "T2081QDS_MDIO_SLOT2", | |
76 | "T2081QDS_MDIO_SLOT3", | |
77 | "T2081QDS_MDIO_SLOT5", | |
78 | "T2081QDS_MDIO_SLOT6", | |
79 | "T2081QDS_MDIO_SLOT7", | |
80 | "T2081QDS_MDIO_10GC", | |
81 | #endif | |
c4d0e811 SL |
82 | }; |
83 | ||
84 | /* Map SerDes1 8 lanes to default slot, will be initialized dynamically */ | |
80d26188 | 85 | #if defined(CONFIG_TARGET_T2080QDS) |
c4d0e811 | 86 | static u8 lane_to_slot[] = {3, 3, 3, 3, 1, 1, 1, 1}; |
146ded4d | 87 | #elif defined(CONFIG_TARGET_T2081QDS) |
254887a5 SL |
88 | static u8 lane_to_slot[] = {2, 2, 2, 2, 1, 1, 1, 1}; |
89 | #endif | |
c4d0e811 | 90 | |
254887a5 | 91 | static const char *t208xqds_mdio_name_for_muxval(u8 muxval) |
c4d0e811 SL |
92 | { |
93 | return mdio_names[muxval]; | |
94 | } | |
95 | ||
96 | struct mii_dev *mii_dev_for_muxval(u8 muxval) | |
97 | { | |
98 | struct mii_dev *bus; | |
254887a5 | 99 | const char *name = t208xqds_mdio_name_for_muxval(muxval); |
c4d0e811 SL |
100 | |
101 | if (!name) { | |
102 | printf("No bus for muxval %x\n", muxval); | |
103 | return NULL; | |
104 | } | |
105 | ||
106 | bus = miiphy_get_dev_by_name(name); | |
107 | ||
108 | if (!bus) { | |
109 | printf("No bus by name %s\n", name); | |
110 | return NULL; | |
111 | } | |
112 | ||
113 | return bus; | |
114 | } | |
115 | ||
254887a5 | 116 | struct t208xqds_mdio { |
c4d0e811 SL |
117 | u8 muxval; |
118 | struct mii_dev *realbus; | |
119 | }; | |
120 | ||
254887a5 | 121 | static void t208xqds_mux_mdio(u8 muxval) |
c4d0e811 SL |
122 | { |
123 | u8 brdcfg4; | |
254887a5 | 124 | if (muxval < 8) { |
c4d0e811 SL |
125 | brdcfg4 = QIXIS_READ(brdcfg[4]); |
126 | brdcfg4 &= ~BRDCFG4_EMISEL_MASK; | |
127 | brdcfg4 |= (muxval << BRDCFG4_EMISEL_SHIFT); | |
128 | QIXIS_WRITE(brdcfg[4], brdcfg4); | |
129 | } | |
130 | } | |
131 | ||
254887a5 | 132 | static int t208xqds_mdio_read(struct mii_dev *bus, int addr, int devad, |
c4d0e811 SL |
133 | int regnum) |
134 | { | |
254887a5 | 135 | struct t208xqds_mdio *priv = bus->priv; |
c4d0e811 | 136 | |
254887a5 | 137 | t208xqds_mux_mdio(priv->muxval); |
c4d0e811 SL |
138 | |
139 | return priv->realbus->read(priv->realbus, addr, devad, regnum); | |
140 | } | |
141 | ||
254887a5 | 142 | static int t208xqds_mdio_write(struct mii_dev *bus, int addr, int devad, |
c4d0e811 SL |
143 | int regnum, u16 value) |
144 | { | |
254887a5 | 145 | struct t208xqds_mdio *priv = bus->priv; |
c4d0e811 | 146 | |
254887a5 | 147 | t208xqds_mux_mdio(priv->muxval); |
c4d0e811 SL |
148 | |
149 | return priv->realbus->write(priv->realbus, addr, devad, regnum, value); | |
150 | } | |
151 | ||
254887a5 | 152 | static int t208xqds_mdio_reset(struct mii_dev *bus) |
c4d0e811 | 153 | { |
254887a5 | 154 | struct t208xqds_mdio *priv = bus->priv; |
c4d0e811 SL |
155 | |
156 | return priv->realbus->reset(priv->realbus); | |
157 | } | |
158 | ||
254887a5 | 159 | static int t208xqds_mdio_init(char *realbusname, u8 muxval) |
c4d0e811 | 160 | { |
254887a5 | 161 | struct t208xqds_mdio *pmdio; |
c4d0e811 SL |
162 | struct mii_dev *bus = mdio_alloc(); |
163 | ||
164 | if (!bus) { | |
254887a5 | 165 | printf("Failed to allocate t208xqds MDIO bus\n"); |
c4d0e811 SL |
166 | return -1; |
167 | } | |
168 | ||
169 | pmdio = malloc(sizeof(*pmdio)); | |
170 | if (!pmdio) { | |
254887a5 | 171 | printf("Failed to allocate t208xqds private data\n"); |
c4d0e811 SL |
172 | free(bus); |
173 | return -1; | |
174 | } | |
175 | ||
254887a5 SL |
176 | bus->read = t208xqds_mdio_read; |
177 | bus->write = t208xqds_mdio_write; | |
178 | bus->reset = t208xqds_mdio_reset; | |
192bc694 | 179 | strcpy(bus->name, t208xqds_mdio_name_for_muxval(muxval)); |
c4d0e811 SL |
180 | |
181 | pmdio->realbus = miiphy_get_dev_by_name(realbusname); | |
182 | ||
183 | if (!pmdio->realbus) { | |
184 | printf("No bus with name %s\n", realbusname); | |
185 | free(bus); | |
186 | free(pmdio); | |
187 | return -1; | |
188 | } | |
189 | ||
190 | pmdio->muxval = muxval; | |
191 | bus->priv = pmdio; | |
c4d0e811 SL |
192 | return mdio_register(bus); |
193 | } | |
194 | ||
195 | void board_ft_fman_fixup_port(void *fdt, char *compat, phys_addr_t addr, | |
196 | enum fm_port port, int offset) | |
197 | { | |
198 | int phy; | |
199 | char alias[20]; | |
f0644da5 SX |
200 | char lane_mode[2][20] = {"1000BASE-KX", "10GBASE-KR"}; |
201 | char buf[32] = "serdes-1,"; | |
c4d0e811 | 202 | struct fixed_link f_link; |
f0644da5 SX |
203 | int media_type = 0; |
204 | int off; | |
205 | ||
c4d0e811 | 206 | ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); |
80d26188 | 207 | #ifdef CONFIG_TARGET_T2080QDS |
3ce21c87 SX |
208 | serdes_corenet_t *srds_regs = |
209 | (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR; | |
210 | u32 srds1_pccr1 = in_be32(&srds_regs->srdspccr1); | |
211 | #endif | |
c4d0e811 SL |
212 | u32 srds_s1 = in_be32(&gur->rcwsr[4]) & |
213 | FSL_CORENET2_RCWSR4_SRDS1_PRTCL; | |
214 | ||
215 | srds_s1 >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT; | |
216 | ||
217 | if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_SGMII) { | |
218 | phy = fm_info_get_phy_address(port); | |
219 | switch (port) { | |
80d26188 | 220 | #if defined(CONFIG_TARGET_T2080QDS) |
c4d0e811 | 221 | case FM1_DTSEC1: |
3ce21c87 SX |
222 | if (hwconfig_sub("fsl_1gkx", "fm1_1g1")) { |
223 | media_type = 1; | |
224 | fdt_set_phy_handle(fdt, compat, addr, | |
225 | "phy_1gkx1"); | |
226 | fdt_status_okay_by_alias(fdt, "1gkx_pcs_mdio1"); | |
227 | sprintf(buf, "%s%s%s", buf, "lane-c,", | |
228 | (char *)lane_mode[0]); | |
229 | out_be32(&srds_regs->srdspccr1, srds1_pccr1 | | |
230 | PCCR1_SGMIIH_KX_MASK); | |
231 | break; | |
232 | } | |
c4d0e811 | 233 | case FM1_DTSEC2: |
3ce21c87 SX |
234 | if (hwconfig_sub("fsl_1gkx", "fm1_1g2")) { |
235 | media_type = 1; | |
236 | fdt_set_phy_handle(fdt, compat, addr, | |
237 | "phy_1gkx2"); | |
238 | fdt_status_okay_by_alias(fdt, "1gkx_pcs_mdio2"); | |
239 | sprintf(buf, "%s%s%s", buf, "lane-d,", | |
240 | (char *)lane_mode[0]); | |
241 | out_be32(&srds_regs->srdspccr1, srds1_pccr1 | | |
242 | PCCR1_SGMIIG_KX_MASK); | |
243 | break; | |
244 | } | |
c4d0e811 | 245 | case FM1_DTSEC9: |
3ce21c87 SX |
246 | if (hwconfig_sub("fsl_1gkx", "fm1_1g9")) { |
247 | media_type = 1; | |
248 | fdt_set_phy_handle(fdt, compat, addr, | |
249 | "phy_1gkx9"); | |
250 | fdt_status_okay_by_alias(fdt, "1gkx_pcs_mdio9"); | |
251 | sprintf(buf, "%s%s%s", buf, "lane-a,", | |
252 | (char *)lane_mode[0]); | |
253 | out_be32(&srds_regs->srdspccr1, srds1_pccr1 | | |
254 | PCCR1_SGMIIE_KX_MASK); | |
255 | break; | |
256 | } | |
c4d0e811 | 257 | case FM1_DTSEC10: |
3ce21c87 SX |
258 | if (hwconfig_sub("fsl_1gkx", "fm1_1g10")) { |
259 | media_type = 1; | |
260 | fdt_set_phy_handle(fdt, compat, addr, | |
261 | "phy_1gkx10"); | |
262 | fdt_status_okay_by_alias(fdt, | |
263 | "1gkx_pcs_mdio10"); | |
264 | sprintf(buf, "%s%s%s", buf, "lane-b,", | |
265 | (char *)lane_mode[0]); | |
266 | out_be32(&srds_regs->srdspccr1, srds1_pccr1 | | |
267 | PCCR1_SGMIIF_KX_MASK); | |
268 | break; | |
269 | } | |
254887a5 SL |
270 | if (mdio_mux[port] == EMI1_SLOT2) { |
271 | sprintf(alias, "phy_sgmii_s2_%x", phy); | |
272 | fdt_set_phy_handle(fdt, compat, addr, alias); | |
273 | fdt_status_okay_by_alias(fdt, "emi1_slot2"); | |
274 | } else if (mdio_mux[port] == EMI1_SLOT3) { | |
275 | sprintf(alias, "phy_sgmii_s3_%x", phy); | |
276 | fdt_set_phy_handle(fdt, compat, addr, alias); | |
277 | fdt_status_okay_by_alias(fdt, "emi1_slot3"); | |
278 | } | |
c4d0e811 SL |
279 | break; |
280 | case FM1_DTSEC5: | |
3ce21c87 SX |
281 | if (hwconfig_sub("fsl_1gkx", "fm1_1g5")) { |
282 | media_type = 1; | |
283 | fdt_set_phy_handle(fdt, compat, addr, | |
284 | "phy_1gkx5"); | |
285 | fdt_status_okay_by_alias(fdt, "1gkx_pcs_mdio5"); | |
286 | sprintf(buf, "%s%s%s", buf, "lane-g,", | |
287 | (char *)lane_mode[0]); | |
288 | out_be32(&srds_regs->srdspccr1, srds1_pccr1 | | |
289 | PCCR1_SGMIIC_KX_MASK); | |
290 | break; | |
291 | } | |
c4d0e811 | 292 | case FM1_DTSEC6: |
3ce21c87 SX |
293 | if (hwconfig_sub("fsl_1gkx", "fm1_1g6")) { |
294 | media_type = 1; | |
295 | fdt_set_phy_handle(fdt, compat, addr, | |
296 | "phy_1gkx6"); | |
297 | fdt_status_okay_by_alias(fdt, "1gkx_pcs_mdio6"); | |
298 | sprintf(buf, "%s%s%s", buf, "lane-h,", | |
299 | (char *)lane_mode[0]); | |
300 | out_be32(&srds_regs->srdspccr1, srds1_pccr1 | | |
301 | PCCR1_SGMIID_KX_MASK); | |
302 | break; | |
303 | } | |
c4d0e811 SL |
304 | if (mdio_mux[port] == EMI1_SLOT1) { |
305 | sprintf(alias, "phy_sgmii_s1_%x", phy); | |
306 | fdt_set_phy_handle(fdt, compat, addr, alias); | |
307 | fdt_status_okay_by_alias(fdt, "emi1_slot1"); | |
308 | } else if (mdio_mux[port] == EMI1_SLOT2) { | |
309 | sprintf(alias, "phy_sgmii_s2_%x", phy); | |
310 | fdt_set_phy_handle(fdt, compat, addr, alias); | |
311 | fdt_status_okay_by_alias(fdt, "emi1_slot2"); | |
312 | } | |
313 | break; | |
146ded4d | 314 | #elif defined(CONFIG_TARGET_T2081QDS) |
254887a5 SL |
315 | case FM1_DTSEC1: |
316 | case FM1_DTSEC2: | |
317 | case FM1_DTSEC5: | |
318 | case FM1_DTSEC6: | |
319 | case FM1_DTSEC9: | |
320 | case FM1_DTSEC10: | |
321 | if (mdio_mux[port] == EMI1_SLOT2) { | |
322 | sprintf(alias, "phy_sgmii_s2_%x", phy); | |
323 | fdt_set_phy_handle(fdt, compat, addr, alias); | |
324 | fdt_status_okay_by_alias(fdt, "emi1_slot2"); | |
325 | } else if (mdio_mux[port] == EMI1_SLOT3) { | |
326 | sprintf(alias, "phy_sgmii_s3_%x", phy); | |
327 | fdt_set_phy_handle(fdt, compat, addr, alias); | |
328 | fdt_status_okay_by_alias(fdt, "emi1_slot3"); | |
329 | } else if (mdio_mux[port] == EMI1_SLOT5) { | |
330 | sprintf(alias, "phy_sgmii_s5_%x", phy); | |
331 | fdt_set_phy_handle(fdt, compat, addr, alias); | |
332 | fdt_status_okay_by_alias(fdt, "emi1_slot5"); | |
333 | } else if (mdio_mux[port] == EMI1_SLOT6) { | |
334 | sprintf(alias, "phy_sgmii_s6_%x", phy); | |
335 | fdt_set_phy_handle(fdt, compat, addr, alias); | |
336 | fdt_status_okay_by_alias(fdt, "emi1_slot6"); | |
337 | } else if (mdio_mux[port] == EMI1_SLOT7) { | |
338 | sprintf(alias, "phy_sgmii_s7_%x", phy); | |
339 | fdt_set_phy_handle(fdt, compat, addr, alias); | |
340 | fdt_status_okay_by_alias(fdt, "emi1_slot7"); | |
341 | } | |
342 | break; | |
343 | #endif | |
c4d0e811 SL |
344 | default: |
345 | break; | |
346 | } | |
3ce21c87 SX |
347 | if (media_type) { |
348 | /* set property for 1000BASE-KX in dtb */ | |
349 | off = fdt_node_offset_by_compat_reg(fdt, | |
350 | "fsl,fman-memac-mdio", addr + 0x1000); | |
351 | fdt_setprop_string(fdt, off, "lane-instance", buf); | |
352 | } | |
c4d0e811 SL |
353 | |
354 | } else if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_XGMII) { | |
355 | switch (srds_s1) { | |
356 | case 0x66: /* XFI interface */ | |
357 | case 0x6b: | |
358 | case 0x6c: | |
359 | case 0x6d: | |
360 | case 0x71: | |
f0644da5 SX |
361 | /* |
362 | * if the 10G is XFI, check hwconfig to see what is the | |
363 | * media type, there are two types, fiber or copper, | |
364 | * fix the dtb accordingly. | |
365 | */ | |
366 | switch (port) { | |
367 | case FM1_10GEC1: | |
368 | if (hwconfig_sub("fsl_10gkr_copper", "fm1_10g1")) { | |
369 | /* it's MAC9 */ | |
370 | media_type = 1; | |
371 | fdt_set_phy_handle(fdt, compat, addr, | |
372 | "phy_xfi9"); | |
373 | fdt_status_okay_by_alias(fdt, "xfi_pcs_mdio9"); | |
374 | sprintf(buf, "%s%s%s", buf, "lane-a,", | |
375 | (char *)lane_mode[1]); | |
376 | } | |
377 | break; | |
378 | case FM1_10GEC2: | |
379 | if (hwconfig_sub("fsl_10gkr_copper", "fm1_10g2")) { | |
380 | /* it's MAC10 */ | |
381 | media_type = 1; | |
382 | fdt_set_phy_handle(fdt, compat, addr, | |
383 | "phy_xfi10"); | |
384 | fdt_status_okay_by_alias(fdt, "xfi_pcs_mdio10"); | |
385 | sprintf(buf, "%s%s%s", buf, "lane-b,", | |
386 | (char *)lane_mode[1]); | |
387 | } | |
388 | break; | |
389 | case FM1_10GEC3: | |
390 | if (hwconfig_sub("fsl_10gkr_copper", "fm1_10g3")) { | |
391 | /* it's MAC1 */ | |
392 | media_type = 1; | |
393 | fdt_set_phy_handle(fdt, compat, addr, | |
394 | "phy_xfi1"); | |
395 | fdt_status_okay_by_alias(fdt, "xfi_pcs_mdio1"); | |
396 | sprintf(buf, "%s%s%s", buf, "lane-c,", | |
397 | (char *)lane_mode[1]); | |
398 | } | |
399 | break; | |
400 | case FM1_10GEC4: | |
401 | if (hwconfig_sub("fsl_10gkr_copper", "fm1_10g4")) { | |
402 | /* it's MAC2 */ | |
403 | media_type = 1; | |
404 | fdt_set_phy_handle(fdt, compat, addr, | |
405 | "phy_xfi2"); | |
406 | fdt_status_okay_by_alias(fdt, "xfi_pcs_mdio2"); | |
407 | sprintf(buf, "%s%s%s", buf, "lane-d,", | |
408 | (char *)lane_mode[1]); | |
409 | } | |
410 | break; | |
411 | default: | |
412 | return; | |
413 | } | |
414 | ||
415 | if (!media_type) { | |
416 | /* fixed-link is used for XFI fiber cable */ | |
417 | f_link.phy_id = port; | |
418 | f_link.duplex = 1; | |
419 | f_link.link_speed = 10000; | |
420 | f_link.pause = 0; | |
421 | f_link.asym_pause = 0; | |
422 | fdt_delprop(fdt, offset, "phy-handle"); | |
423 | fdt_setprop(fdt, offset, "fixed-link", &f_link, | |
424 | sizeof(f_link)); | |
425 | } else { | |
426 | /* set property for copper cable */ | |
427 | off = fdt_node_offset_by_compat_reg(fdt, | |
428 | "fsl,fman-memac-mdio", addr + 0x1000); | |
429 | fdt_setprop_string(fdt, off, | |
430 | "lane-instance", buf); | |
431 | } | |
c4d0e811 SL |
432 | break; |
433 | default: | |
434 | break; | |
435 | } | |
436 | } | |
437 | } | |
438 | ||
439 | void fdt_fixup_board_enet(void *fdt) | |
440 | { | |
441 | return; | |
442 | } | |
443 | ||
444 | /* | |
254887a5 SL |
445 | * This function reads RCW to check if Serdes1{A:H} is configured |
446 | * to slot 1/2/3/4/5/6/7 and update the lane_to_slot[] array accordingly | |
c4d0e811 SL |
447 | */ |
448 | static void initialize_lane_to_slot(void) | |
449 | { | |
450 | ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); | |
451 | u32 srds_s1 = in_be32(&gur->rcwsr[4]) & | |
452 | FSL_CORENET2_RCWSR4_SRDS1_PRTCL; | |
453 | ||
454 | srds_s1 >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT; | |
455 | ||
456 | switch (srds_s1) { | |
80d26188 | 457 | #if defined(CONFIG_TARGET_T2080QDS) |
c4d0e811 SL |
458 | case 0x51: |
459 | case 0x5f: | |
460 | case 0x65: | |
461 | case 0x6b: | |
462 | case 0x71: | |
463 | lane_to_slot[5] = 2; | |
464 | lane_to_slot[6] = 2; | |
465 | lane_to_slot[7] = 2; | |
466 | break; | |
467 | case 0xa6: | |
468 | case 0x8e: | |
469 | case 0x8f: | |
470 | case 0x82: | |
471 | case 0x83: | |
472 | case 0xd3: | |
473 | case 0xd9: | |
474 | case 0xcb: | |
475 | lane_to_slot[6] = 2; | |
476 | lane_to_slot[7] = 2; | |
477 | break; | |
478 | case 0xda: | |
479 | lane_to_slot[4] = 3; | |
480 | lane_to_slot[5] = 3; | |
481 | lane_to_slot[6] = 3; | |
482 | lane_to_slot[7] = 3; | |
483 | break; | |
146ded4d | 484 | #elif defined(CONFIG_TARGET_T2081QDS) |
254887a5 SL |
485 | case 0x6b: |
486 | lane_to_slot[4] = 1; | |
487 | lane_to_slot[5] = 3; | |
488 | lane_to_slot[6] = 3; | |
489 | lane_to_slot[7] = 3; | |
490 | break; | |
491 | case 0xca: | |
492 | case 0xcb: | |
493 | lane_to_slot[1] = 7; | |
494 | lane_to_slot[2] = 6; | |
495 | lane_to_slot[3] = 5; | |
496 | lane_to_slot[5] = 3; | |
497 | lane_to_slot[6] = 3; | |
498 | lane_to_slot[7] = 3; | |
499 | break; | |
500 | case 0xf2: | |
501 | lane_to_slot[1] = 7; | |
502 | lane_to_slot[2] = 7; | |
503 | lane_to_slot[3] = 7; | |
504 | lane_to_slot[5] = 4; | |
505 | lane_to_slot[6] = 3; | |
506 | lane_to_slot[7] = 7; | |
507 | break; | |
508 | #endif | |
c4d0e811 SL |
509 | default: |
510 | break; | |
511 | } | |
512 | } | |
513 | ||
514 | int board_eth_init(bd_t *bis) | |
515 | { | |
516 | #if defined(CONFIG_FMAN_ENET) | |
517 | int i, idx, lane, slot, interface; | |
518 | struct memac_mdio_info dtsec_mdio_info; | |
519 | struct memac_mdio_info tgec_mdio_info; | |
520 | ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); | |
521 | u32 rcwsr13 = in_be32(&gur->rcwsr[13]); | |
522 | u32 srds_s1; | |
523 | ||
524 | srds_s1 = in_be32(&gur->rcwsr[4]) & | |
525 | FSL_CORENET2_RCWSR4_SRDS1_PRTCL; | |
526 | srds_s1 >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT; | |
527 | ||
528 | initialize_lane_to_slot(); | |
529 | ||
530 | /* Initialize the mdio_mux array so we can recognize empty elements */ | |
531 | for (i = 0; i < NUM_FM_PORTS; i++) | |
532 | mdio_mux[i] = EMI_NONE; | |
533 | ||
534 | dtsec_mdio_info.regs = | |
535 | (struct memac_mdio_controller *)CONFIG_SYS_FM1_DTSEC_MDIO_ADDR; | |
536 | ||
537 | dtsec_mdio_info.name = DEFAULT_FM_MDIO_NAME; | |
538 | ||
539 | /* Register the 1G MDIO bus */ | |
540 | fm_memac_mdio_init(bis, &dtsec_mdio_info); | |
541 | ||
542 | tgec_mdio_info.regs = | |
543 | (struct memac_mdio_controller *)CONFIG_SYS_FM1_TGEC_MDIO_ADDR; | |
544 | tgec_mdio_info.name = DEFAULT_FM_TGEC_MDIO_NAME; | |
545 | ||
546 | /* Register the 10G MDIO bus */ | |
547 | fm_memac_mdio_init(bis, &tgec_mdio_info); | |
548 | ||
549 | /* Register the muxing front-ends to the MDIO buses */ | |
254887a5 SL |
550 | t208xqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII1); |
551 | t208xqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII2); | |
552 | t208xqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT1); | |
553 | t208xqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT2); | |
554 | t208xqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT3); | |
80d26188 | 555 | #if defined(CONFIG_TARGET_T2080QDS) |
254887a5 SL |
556 | t208xqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT4); |
557 | #endif | |
558 | t208xqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT5); | |
146ded4d | 559 | #if defined(CONFIG_TARGET_T2081QDS) |
254887a5 SL |
560 | t208xqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT6); |
561 | t208xqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT7); | |
562 | #endif | |
563 | t208xqds_mdio_init(DEFAULT_FM_TGEC_MDIO_NAME, EMI2); | |
c4d0e811 SL |
564 | |
565 | /* Set the two on-board RGMII PHY address */ | |
566 | fm_info_set_phy_address(FM1_DTSEC3, RGMII_PHY1_ADDR); | |
567 | if ((rcwsr13 & FSL_CORENET_RCWSR13_EC2) == | |
568 | FSL_CORENET_RCWSR13_EC2_DTSEC4_RGMII) | |
569 | fm_info_set_phy_address(FM1_DTSEC4, RGMII_PHY2_ADDR); | |
570 | else | |
571 | fm_info_set_phy_address(FM1_DTSEC10, RGMII_PHY2_ADDR); | |
572 | ||
573 | switch (srds_s1) { | |
9752eb64 | 574 | case 0x1b: |
c4d0e811 SL |
575 | case 0x1c: |
576 | case 0x95: | |
577 | case 0xa2: | |
578 | case 0x94: | |
254887a5 | 579 | /* T2080QDS: SGMII in Slot3; T2081QDS: SGMII in Slot2 */ |
c4d0e811 SL |
580 | fm_info_set_phy_address(FM1_DTSEC9, SGMII_CARD_PORT1_PHY_ADDR); |
581 | fm_info_set_phy_address(FM1_DTSEC10, SGMII_CARD_PORT2_PHY_ADDR); | |
582 | fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT3_PHY_ADDR); | |
583 | fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT4_PHY_ADDR); | |
254887a5 | 584 | /* T2080QDS: SGMII in Slot2; T2081QDS: SGMII in Slot1 */ |
c4d0e811 SL |
585 | fm_info_set_phy_address(FM1_DTSEC5, SGMII_CARD_PORT3_PHY_ADDR); |
586 | fm_info_set_phy_address(FM1_DTSEC6, SGMII_CARD_PORT4_PHY_ADDR); | |
587 | break; | |
9752eb64 | 588 | case 0x50: |
c4d0e811 | 589 | case 0x51: |
9752eb64 | 590 | case 0x5e: |
c4d0e811 | 591 | case 0x5f: |
9752eb64 | 592 | case 0x64: |
c4d0e811 | 593 | case 0x65: |
254887a5 | 594 | /* T2080QDS: XAUI/HiGig in Slot3; T2081QDS: in Slot2 */ |
c4d0e811 | 595 | fm_info_set_phy_address(FM1_10GEC1, FM1_10GEC1_PHY_ADDR); |
254887a5 | 596 | /* T2080QDS: SGMII in Slot2; T2081QDS: in Slot3 */ |
c4d0e811 SL |
597 | fm_info_set_phy_address(FM1_DTSEC5, SGMII_CARD_PORT3_PHY_ADDR); |
598 | fm_info_set_phy_address(FM1_DTSEC6, SGMII_CARD_PORT4_PHY_ADDR); | |
599 | break; | |
600 | case 0x66: | |
9752eb64 | 601 | case 0x67: |
c4d0e811 | 602 | /* |
a187559e | 603 | * XFI does not need a PHY to work, but to avoid U-Boot use |
c4d0e811 SL |
604 | * default PHY address which is zero to a MAC when it found |
605 | * a MAC has no PHY address, we give a PHY address to XFI | |
606 | * MAC, and should not use a real XAUI PHY address, since | |
607 | * MDIO can access it successfully, and then MDIO thinks | |
608 | * the XAUI card is used for the XFI MAC, which will cause | |
609 | * error. | |
610 | */ | |
611 | fm_info_set_phy_address(FM1_10GEC1, 4); | |
612 | fm_info_set_phy_address(FM1_10GEC2, 5); | |
613 | fm_info_set_phy_address(FM1_10GEC3, 6); | |
614 | fm_info_set_phy_address(FM1_10GEC4, 7); | |
615 | break; | |
9752eb64 | 616 | case 0x6a: |
c4d0e811 SL |
617 | case 0x6b: |
618 | fm_info_set_phy_address(FM1_10GEC1, 4); | |
619 | fm_info_set_phy_address(FM1_10GEC2, 5); | |
620 | fm_info_set_phy_address(FM1_10GEC3, 6); | |
621 | fm_info_set_phy_address(FM1_10GEC4, 7); | |
254887a5 | 622 | /* T2080QDS: SGMII in Slot2; T2081QDS: in Slot3 */ |
c4d0e811 SL |
623 | fm_info_set_phy_address(FM1_DTSEC5, SGMII_CARD_PORT3_PHY_ADDR); |
624 | fm_info_set_phy_address(FM1_DTSEC6, SGMII_CARD_PORT2_PHY_ADDR); | |
625 | break; | |
626 | case 0x6c: | |
627 | case 0x6d: | |
1576b558 SL |
628 | fm_info_set_phy_address(FM1_10GEC1, 4); |
629 | fm_info_set_phy_address(FM1_10GEC2, 5); | |
254887a5 | 630 | /* T2080QDS: SGMII in Slot3; T2081QDS: in Slot2 */ |
c4d0e811 | 631 | fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT3_PHY_ADDR); |
1576b558 | 632 | fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT4_PHY_ADDR); |
c4d0e811 | 633 | break; |
9752eb64 | 634 | case 0x70: |
c4d0e811 SL |
635 | case 0x71: |
636 | /* SGMII in Slot3 */ | |
637 | fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT3_PHY_ADDR); | |
638 | fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT4_PHY_ADDR); | |
639 | /* SGMII in Slot2 */ | |
640 | fm_info_set_phy_address(FM1_DTSEC5, SGMII_CARD_PORT3_PHY_ADDR); | |
641 | fm_info_set_phy_address(FM1_DTSEC6, SGMII_CARD_PORT2_PHY_ADDR); | |
642 | break; | |
643 | case 0xa6: | |
644 | case 0x8e: | |
645 | case 0x8f: | |
646 | case 0x82: | |
647 | case 0x83: | |
648 | /* SGMII in Slot3 */ | |
649 | fm_info_set_phy_address(FM1_DTSEC9, SGMII_CARD_PORT1_PHY_ADDR); | |
650 | fm_info_set_phy_address(FM1_DTSEC10, SGMII_CARD_PORT2_PHY_ADDR); | |
651 | fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT3_PHY_ADDR); | |
652 | fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT4_PHY_ADDR); | |
653 | /* SGMII in Slot2 */ | |
654 | fm_info_set_phy_address(FM1_DTSEC5, SGMII_CARD_PORT3_PHY_ADDR); | |
655 | fm_info_set_phy_address(FM1_DTSEC6, SGMII_CARD_PORT2_PHY_ADDR); | |
656 | break; | |
657 | case 0xa4: | |
658 | case 0x96: | |
659 | case 0x8a: | |
660 | /* SGMII in Slot3 */ | |
661 | fm_info_set_phy_address(FM1_DTSEC9, SGMII_CARD_PORT1_PHY_ADDR); | |
662 | fm_info_set_phy_address(FM1_DTSEC10, SGMII_CARD_PORT2_PHY_ADDR); | |
663 | fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT3_PHY_ADDR); | |
664 | fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT4_PHY_ADDR); | |
665 | break; | |
80d26188 | 666 | #if defined(CONFIG_TARGET_T2080QDS) |
c4d0e811 SL |
667 | case 0xd9: |
668 | case 0xd3: | |
669 | case 0xcb: | |
670 | /* SGMII in Slot3 */ | |
671 | fm_info_set_phy_address(FM1_DTSEC10, SGMII_CARD_PORT2_PHY_ADDR); | |
672 | fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT3_PHY_ADDR); | |
673 | fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT4_PHY_ADDR); | |
674 | /* SGMII in Slot2 */ | |
675 | fm_info_set_phy_address(FM1_DTSEC5, SGMII_CARD_PORT3_PHY_ADDR); | |
676 | fm_info_set_phy_address(FM1_DTSEC6, SGMII_CARD_PORT2_PHY_ADDR); | |
677 | break; | |
146ded4d | 678 | #elif defined(CONFIG_TARGET_T2081QDS) |
254887a5 SL |
679 | case 0xca: |
680 | case 0xcb: | |
681 | /* SGMII in Slot3 */ | |
682 | fm_info_set_phy_address(FM1_DTSEC5, SGMII_CARD_PORT1_PHY_ADDR); | |
683 | fm_info_set_phy_address(FM1_DTSEC6, SGMII_CARD_PORT2_PHY_ADDR); | |
684 | /* SGMII in Slot5 */ | |
685 | fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT1_PHY_ADDR); | |
686 | /* SGMII in Slot6 */ | |
687 | fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT1_PHY_ADDR); | |
688 | /* SGMII in Slot7 */ | |
689 | fm_info_set_phy_address(FM1_DTSEC10, SGMII_CARD_PORT3_PHY_ADDR); | |
690 | break; | |
691 | #endif | |
692 | case 0xf2: | |
693 | /* T2080QDS: SGMII in Slot3; T2081QDS: SGMII in Slot7 */ | |
694 | fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT1_PHY_ADDR); | |
695 | fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT2_PHY_ADDR); | |
696 | fm_info_set_phy_address(FM1_DTSEC10, SGMII_CARD_PORT3_PHY_ADDR); | |
697 | fm_info_set_phy_address(FM1_DTSEC6, SGMII_CARD_PORT4_PHY_ADDR); | |
698 | break; | |
c4d0e811 | 699 | default: |
c4d0e811 SL |
700 | break; |
701 | } | |
702 | ||
703 | for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) { | |
704 | idx = i - FM1_DTSEC1; | |
705 | interface = fm_info_get_enet_if(i); | |
706 | switch (interface) { | |
707 | case PHY_INTERFACE_MODE_SGMII: | |
708 | lane = serdes_get_first_lane(FSL_SRDS_1, | |
709 | SGMII_FM1_DTSEC1 + idx); | |
710 | if (lane < 0) | |
711 | break; | |
712 | slot = lane_to_slot[lane]; | |
713 | debug("FM1@DTSEC%u expects SGMII in slot %u\n", | |
714 | idx + 1, slot); | |
715 | if (QIXIS_READ(present2) & (1 << (slot - 1))) | |
716 | fm_disable_port(i); | |
717 | ||
718 | switch (slot) { | |
719 | case 1: | |
720 | mdio_mux[i] = EMI1_SLOT1; | |
721 | fm_info_set_mdio(i, mii_dev_for_muxval( | |
722 | mdio_mux[i])); | |
723 | break; | |
724 | case 2: | |
725 | mdio_mux[i] = EMI1_SLOT2; | |
726 | fm_info_set_mdio(i, mii_dev_for_muxval( | |
727 | mdio_mux[i])); | |
728 | break; | |
1576b558 SL |
729 | case 3: |
730 | mdio_mux[i] = EMI1_SLOT3; | |
731 | fm_info_set_mdio(i, mii_dev_for_muxval( | |
254887a5 SL |
732 | mdio_mux[i])); |
733 | break; | |
146ded4d | 734 | #if defined(CONFIG_TARGET_T2081QDS) |
254887a5 SL |
735 | case 5: |
736 | mdio_mux[i] = EMI1_SLOT5; | |
737 | fm_info_set_mdio(i, mii_dev_for_muxval( | |
738 | mdio_mux[i])); | |
739 | break; | |
740 | case 6: | |
741 | mdio_mux[i] = EMI1_SLOT6; | |
742 | fm_info_set_mdio(i, mii_dev_for_muxval( | |
743 | mdio_mux[i])); | |
744 | break; | |
745 | case 7: | |
746 | mdio_mux[i] = EMI1_SLOT7; | |
747 | fm_info_set_mdio(i, mii_dev_for_muxval( | |
748 | mdio_mux[i])); | |
1576b558 | 749 | break; |
254887a5 | 750 | #endif |
1576b558 | 751 | } |
c4d0e811 SL |
752 | break; |
753 | case PHY_INTERFACE_MODE_RGMII: | |
754 | if (i == FM1_DTSEC3) | |
755 | mdio_mux[i] = EMI1_RGMII1; | |
756 | else if (i == FM1_DTSEC4 || FM1_DTSEC10) | |
757 | mdio_mux[i] = EMI1_RGMII2; | |
758 | fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); | |
759 | break; | |
760 | default: | |
761 | break; | |
762 | } | |
763 | } | |
764 | ||
765 | for (i = FM1_10GEC1; i < FM1_10GEC1 + CONFIG_SYS_NUM_FM1_10GEC; i++) { | |
766 | idx = i - FM1_10GEC1; | |
767 | switch (fm_info_get_enet_if(i)) { | |
768 | case PHY_INTERFACE_MODE_XGMII: | |
769 | if (srds_s1 == 0x51) { | |
770 | lane = serdes_get_first_lane(FSL_SRDS_1, | |
771 | XAUI_FM1_MAC9 + idx); | |
772 | } else if ((srds_s1 == 0x5f) || (srds_s1 == 0x65)) { | |
773 | lane = serdes_get_first_lane(FSL_SRDS_1, | |
774 | HIGIG_FM1_MAC9 + idx); | |
775 | } else { | |
776 | if (i == FM1_10GEC1 || i == FM1_10GEC2) | |
777 | lane = serdes_get_first_lane(FSL_SRDS_1, | |
778 | XFI_FM1_MAC9 + idx); | |
779 | else | |
780 | lane = serdes_get_first_lane(FSL_SRDS_1, | |
781 | XFI_FM1_MAC1 + idx); | |
782 | } | |
783 | ||
784 | if (lane < 0) | |
785 | break; | |
786 | mdio_mux[i] = EMI2; | |
787 | fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); | |
788 | ||
789 | if ((srds_s1 == 0x66) || (srds_s1 == 0x6b) || | |
9752eb64 | 790 | (srds_s1 == 0x6a) || (srds_s1 == 0x70) || |
c4d0e811 SL |
791 | (srds_s1 == 0x6c) || (srds_s1 == 0x6d) || |
792 | (srds_s1 == 0x71)) { | |
793 | /* As XFI is in cage intead of a slot, so | |
794 | * ensure doesn't disable the corresponding port | |
795 | */ | |
796 | break; | |
797 | } | |
798 | ||
799 | slot = lane_to_slot[lane]; | |
800 | if (QIXIS_READ(present2) & (1 << (slot - 1))) | |
801 | fm_disable_port(i); | |
802 | break; | |
803 | default: | |
804 | break; | |
805 | } | |
806 | } | |
807 | ||
808 | cpu_eth_init(bis); | |
809 | #endif /* CONFIG_FMAN_ENET */ | |
810 | ||
811 | return pci_eth_init(bis); | |
812 | } |