1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright 2012 Freescale Semiconductor, Inc.
4 * Author: Sandeep Kumar Singh <sandeep@freescale.com>
7 /* This file is based on board/freescale/corenet_ds/eth_superhydra.c */
10 * This file handles the board muxing between the Fman Ethernet MACs and
11 * the RGMII/SGMII/XGMII PHYs on a Freescale B4860 "Centaur". The SGMII
12 * PHYs are the two on-board 1Gb ports. There are no RGMII PHY on board.
13 * The 10Gb XGMII PHY is provided via the XAUI riser card. There is only
14 * one Fman device on B4860. The SERDES configuration is used to determine
15 * where the SGMII and XAUI cards exist, and also which Fman MACs are routed
16 * to which PHYs. So for a given Fman MAC, there is one and only PHY it
17 * connects to. MACs cannot be routed to PHYs dynamically. This configuration
18 * is done at boot time by reading SERDES protocol from RCW.
25 #include <asm/fsl_serdes.h>
29 #include <fdt_support.h>
30 #include <fsl_dtsec.h>
32 #include "../common/ngpixis.h"
33 #include "../common/fman.h"
34 #include "../common/qixis.h"
35 #include "b4860qds_qixis.h"
37 #define EMI_NONE 0xFFFFFFFF
39 #ifdef CONFIG_FMAN_ENET
42 * Mapping of all 16 SERDES lanes to board slots. A value n(>0) will mean that
43 * lane at index is mapped to slot number n. A value of '0' will mean
44 * that the mapping must be determined dynamically, or that the lane maps to
45 * something other than a board slot
47 static u8 lane_to_slot[] = {
55 * This function initializes the lane_to_slot[] array. It reads RCW to check
56 * if Serdes2{E,F,G,H} is configured as slot 2 or as SFP and initializes
57 * lane_to_slot[] accordingly
59 static void initialize_lane_to_slot(void)
61 unsigned int serdes2_prtcl;
62 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
63 serdes2_prtcl = in_be32(&gur->rcwsr[4]) &
64 FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
65 serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
66 debug("Initializing lane to slot: Serdes2 protocol: %x\n",
69 switch (serdes2_prtcl) {
75 * Lanes: A,B,C,D: SGMII
85 * Lanes: E,F,G,H: XAUI2
91 * Lanes: A,B,C,D: SGMII
92 * Lanes: E,F,G,H: XAUI2
98 * Lanes: A,B,C,D: XAUI2
99 * Lanes: E,F,G,H: XAUI2
107 * Lanes: E,F,G,H: XAUI2
113 * Lanes: A,B,C,D: PCI
114 * Lanes: E,F,G,H: XAUI2
123 * Lanes: A,B,C,D: PCI
124 * Lanes: E,F: SGMII 3&4
133 * Lanes: E,F,G,H: XAUI2
135 lane_to_slot[12] = 2;
136 lane_to_slot[13] = lane_to_slot[12];
137 lane_to_slot[14] = lane_to_slot[12];
138 lane_to_slot[15] = lane_to_slot[12];
142 printf("Fman: Unsupported SerDes2 Protocol 0x%02x\n",
149 #endif /* #ifdef CONFIG_FMAN_ENET */
151 int board_eth_init(bd_t *bis)
153 #ifdef CONFIG_FMAN_ENET
154 struct memac_mdio_info memac_mdio_info;
155 struct memac_mdio_info tg_memac_mdio_info;
157 unsigned int serdes1_prtcl, serdes2_prtcl;
160 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
161 serdes1_prtcl = in_be32(&gur->rcwsr[4]) &
162 FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
163 if (!serdes1_prtcl) {
164 printf("SERDES1 is not enabled\n");
167 serdes1_prtcl >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
168 debug("Using SERDES1 Protocol: 0x%x:\n", serdes1_prtcl);
170 serdes2_prtcl = in_be32(&gur->rcwsr[4]) &
171 FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
172 if (!serdes2_prtcl) {
173 printf("SERDES2 is not enabled\n");
176 serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
177 debug("Using SERDES2 Protocol: 0x%x:\n", serdes2_prtcl);
179 printf("Initializing Fman\n");
181 initialize_lane_to_slot();
183 memac_mdio_info.regs =
184 (struct memac_mdio_controller *)CONFIG_SYS_FM1_DTSEC_MDIO_ADDR;
185 memac_mdio_info.name = DEFAULT_FM_MDIO_NAME;
187 /* Register the real 1G MDIO bus */
188 fm_memac_mdio_init(bis, &memac_mdio_info);
190 tg_memac_mdio_info.regs =
191 (struct memac_mdio_controller *)CONFIG_SYS_FM1_TGEC_MDIO_ADDR;
192 tg_memac_mdio_info.name = DEFAULT_FM_TGEC_MDIO_NAME;
194 /* Register the real 10G MDIO bus */
195 fm_memac_mdio_init(bis, &tg_memac_mdio_info);
198 * Program the two on board DTSEC PHY addresses assuming that they are
199 * all SGMII. RGMII is not supported on this board. Setting SGMII 5 and
200 * 6 to on board SGMII phys
202 fm_info_set_phy_address(FM1_DTSEC5, CONFIG_SYS_FM1_ONBOARD_PHY1_ADDR);
203 fm_info_set_phy_address(FM1_DTSEC6, CONFIG_SYS_FM1_ONBOARD_PHY2_ADDR);
205 switch (serdes1_prtcl) {
208 /* Serdes 1: A-B SGMII, Configuring DTSEC 5 and 6 */
209 debug("Set phy addresses for FM1_DTSEC5:%x, FM1_DTSEC6:%x\n",
210 CONFIG_SYS_FM1_ONBOARD_PHY1_ADDR,
211 CONFIG_SYS_FM1_ONBOARD_PHY2_ADDR);
212 fm_info_set_phy_address(FM1_DTSEC5,
213 CONFIG_SYS_FM1_ONBOARD_PHY1_ADDR);
214 fm_info_set_phy_address(FM1_DTSEC6,
215 CONFIG_SYS_FM1_ONBOARD_PHY2_ADDR);
217 #ifdef CONFIG_ARCH_B4420
220 /* Serdes 1: A-D SGMII, Configuring on board dual SGMII Phy */
221 debug("Set phy addresses for FM1_DTSEC3:%x, FM1_DTSEC4:%x\n",
222 CONFIG_SYS_FM1_ONBOARD_PHY1_ADDR,
223 CONFIG_SYS_FM1_ONBOARD_PHY2_ADDR);
224 /* Fixing Serdes clock by programming FPGA register */
225 QIXIS_WRITE(brdcfg[4], QIXIS_SRDS1CLK_125);
226 fm_info_set_phy_address(FM1_DTSEC3,
227 CONFIG_SYS_FM1_ONBOARD_PHY1_ADDR);
228 fm_info_set_phy_address(FM1_DTSEC4,
229 CONFIG_SYS_FM1_ONBOARD_PHY2_ADDR);
233 printf("Fman: Unsupported SerDes1 Protocol 0x%02x\n",
237 switch (serdes2_prtcl) {
240 debug("Set phy address on SGMII Riser for FM1_DTSEC1:%x\n",
241 CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR);
242 fm_info_set_phy_address(FM1_DTSEC1,
243 CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR);
244 fm_info_set_phy_address(FM1_DTSEC2,
245 CONFIG_SYS_FM1_DTSEC2_RISER_PHY_ADDR);
246 fm_info_set_phy_address(FM1_DTSEC3,
247 CONFIG_SYS_FM1_DTSEC3_RISER_PHY_ADDR);
248 fm_info_set_phy_address(FM1_DTSEC4,
249 CONFIG_SYS_FM1_DTSEC4_RISER_PHY_ADDR);
253 debug("Set phy address on SGMII Riser for FM1_DTSEC1:%x\n",
254 CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR);
255 fm_info_set_phy_address(FM1_DTSEC1,
256 CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR);
257 fm_info_set_phy_address(FM1_DTSEC2,
258 CONFIG_SYS_FM1_DTSEC2_RISER_PHY_ADDR);
259 fm_info_set_phy_address(FM1_DTSEC3,
260 CONFIG_SYS_FM1_DTSEC3_RISER_PHY_ADDR);
266 debug("Set phy addresses on SGMII Riser for FM1_DTSEC1:%x\n",
267 CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR);
268 fm_info_set_phy_address(FM1_DTSEC3,
269 CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR);
270 fm_info_set_phy_address(FM1_DTSEC4,
271 CONFIG_SYS_FM1_DTSEC2_RISER_PHY_ADDR);
273 * XFI does not need a PHY to work, but to make U-Boot
274 * happy, assign a fake PHY address for a XFI port.
276 fm_info_set_phy_address(FM1_10GEC1, 0);
277 fm_info_set_phy_address(FM1_10GEC2, 1);
280 /* XAUI in Slot1 and Slot2 */
281 debug("Set phy address of AMC2PEX-2S for FM1_10GEC1:%x\n",
282 CONFIG_SYS_FM1_10GEC1_PHY_ADDR);
283 fm_info_set_phy_address(FM1_10GEC1,
284 CONFIG_SYS_FM1_10GEC1_PHY_ADDR);
285 debug("Set phy address of AMC2PEX-2S for FM1_10GEC2:%x\n",
286 CONFIG_SYS_FM1_10GEC2_PHY_ADDR);
287 fm_info_set_phy_address(FM1_10GEC2,
288 CONFIG_SYS_FM1_10GEC2_PHY_ADDR);
292 debug("Sett phy address of AMC2PEX-2S for FM1_10GEC2:%x\n",
293 CONFIG_SYS_FM1_10GEC2_PHY_ADDR);
294 fm_info_set_phy_address(FM1_10GEC2,
295 CONFIG_SYS_FM1_10GEC2_PHY_ADDR);
298 printf("Fman: Unsupported SerDes2 Protocol 0x%02x\n",
303 /*set PHY address for QSGMII Riser Card on slot2*/
304 bus = miiphy_get_dev_by_name(DEFAULT_FM_MDIO_NAME);
305 qsgmii = is_qsgmii_riser_card(bus, PHY_BASE_ADDR, PORT_NUM, REGNUM);
308 switch (serdes2_prtcl) {
311 fm_info_set_phy_address(FM1_DTSEC3, PHY_BASE_ADDR);
312 fm_info_set_phy_address(FM1_DTSEC4, PHY_BASE_ADDR + 1);
319 for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) {
320 int idx = i - FM1_DTSEC1;
322 switch (fm_info_get_enet_if(i)) {
323 case PHY_INTERFACE_MODE_SGMII:
325 miiphy_get_dev_by_name(DEFAULT_FM_MDIO_NAME));
327 case PHY_INTERFACE_MODE_NONE:
328 fm_info_set_phy_address(i, 0);
331 printf("Fman1: DTSEC%u set to unknown interface %i\n",
332 idx + 1, fm_info_get_enet_if(i));
333 fm_info_set_phy_address(i, 0);
338 for (i = FM1_10GEC1; i < FM1_10GEC1 + CONFIG_SYS_NUM_FM1_10GEC; i++) {
339 int idx = i - FM1_10GEC1;
341 switch (fm_info_get_enet_if(i)) {
342 case PHY_INTERFACE_MODE_XGMII:
344 miiphy_get_dev_by_name
345 (DEFAULT_FM_TGEC_MDIO_NAME));
347 case PHY_INTERFACE_MODE_NONE:
348 fm_info_set_phy_address(i, 0);
351 printf("Fman1: TGEC%u set to unknown interface %i\n",
352 idx + 1, fm_info_get_enet_if(i));
353 fm_info_set_phy_address(i, 0);
361 return pci_eth_init(bis);
364 void board_ft_fman_fixup_port(void *fdt, char *compat, phys_addr_t addr,
365 enum fm_port port, int offset)
369 struct fixed_link f_link;
370 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
371 u32 prtcl2 = in_be32(&gur->rcwsr[4]) & FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
373 prtcl2 >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
375 if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_SGMII) {
376 phy = fm_info_get_phy_address(port);
378 sprintf(alias, "phy_sgmii_%x", phy);
379 fdt_set_phy_handle(fdt, compat, addr, alias);
380 fdt_status_okay_by_alias(fdt, alias);
381 } else if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_XGMII) {
382 /* check if it's XFI interface for 10g */
401 f_link.phy_id = port;
403 f_link.link_speed = 10000;
405 f_link.asym_pause = 0;
407 fdt_delprop(fdt, offset, "phy-handle");
408 fdt_setprop(fdt, offset, "fixed-link", &f_link,
411 case 0x98: /* XAUI interface */
412 strcpy(alias, "phy_xaui_slot1");
413 fdt_status_okay_by_alias(fdt, alias);
415 strcpy(alias, "phy_xaui_slot2");
416 fdt_status_okay_by_alias(fdt, alias);
418 case 0x9e: /* XAUI interface */
422 strcpy(alias, "phy_xaui_slot1");
423 fdt_status_okay_by_alias(fdt, alias);
425 case 0x97: /* XAUI interface */
427 strcpy(alias, "phy_xaui_slot2");
428 fdt_status_okay_by_alias(fdt, alias);
437 * Set status to disabled for unused ethernet node
439 void fdt_fixup_board_enet(void *fdt)
444 for (i = FM1_DTSEC1; i <= FM1_10GEC2; i++) {
445 switch (fm_info_get_enet_if(i)) {
446 case PHY_INTERFACE_MODE_NONE:
447 sprintf(alias, "ethernet%u", i);
448 fdt_status_disabled_by_alias(fdt, alias);