[U-Boot] [PATCH 4/9] board: freescale: ls1012a: enable network support on ls1012a platforms

Calvin Johnson calvin.johnson at nxp.com
Mon Oct 9 09:11:39 UTC 2017


Ethernet support on all three LS1012A platforms(FRDM, QDS and RDB) is
enabled with this patch.

eth.c files for all 3 platforms contain board ethernet initialization
function and also function to reset phy.

Signed-off-by: Calvin Johnson <calvin.johnson at nxp.com>
Signed-off-by: Anjaneyulu Jagarlmudi <anji.jagarlmudi at nxp.com>
---
 board/freescale/ls1012afrdm/Makefile          |   1 +
 board/freescale/ls1012afrdm/eth.c             |  86 +++++++++
 board/freescale/ls1012afrdm/ls1012afrdm.c     |   5 -
 board/freescale/ls1012aqds/Makefile           |   1 +
 board/freescale/ls1012aqds/eth.c              | 263 ++++++++++++++++++++++++++
 board/freescale/ls1012aqds/ls1012aqds.c       |  97 +++++++++-
 board/freescale/ls1012aqds/ls1012aqds_pfe.h   |  48 +++++
 board/freescale/ls1012aqds/ls1012aqds_qixis.h |   2 +-
 board/freescale/ls1012ardb/Makefile           |   1 +
 board/freescale/ls1012ardb/eth.c              |  70 +++++++
 board/freescale/ls1012ardb/ls1012ardb.c       |   4 -
 include/configs/ls1012ardb.h                  |   5 +
 12 files changed, 568 insertions(+), 15 deletions(-)
 create mode 100644 board/freescale/ls1012afrdm/eth.c
 create mode 100644 board/freescale/ls1012aqds/eth.c
 create mode 100644 board/freescale/ls1012aqds/ls1012aqds_pfe.h
 create mode 100644 board/freescale/ls1012ardb/eth.c

diff --git a/board/freescale/ls1012afrdm/Makefile b/board/freescale/ls1012afrdm/Makefile
index dbfa2ce..1364f22 100644
--- a/board/freescale/ls1012afrdm/Makefile
+++ b/board/freescale/ls1012afrdm/Makefile
@@ -5,3 +5,4 @@
 #
 
 obj-y += ls1012afrdm.o
+obj-y += eth.o
diff --git a/board/freescale/ls1012afrdm/eth.c b/board/freescale/ls1012afrdm/eth.c
new file mode 100644
index 0000000..d9583ce
--- /dev/null
+++ b/board/freescale/ls1012afrdm/eth.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <netdev.h>
+#include <fm_eth.h>
+#include <fsl_mdio.h>
+#include <malloc.h>
+#include <fsl_dtsec.h>
+#include <asm/arch/soc.h>
+#include <asm/arch-fsl-layerscape/config.h>
+#include <asm/arch/fsl_serdes.h>
+
+#include <pfe_eth/pfe_eth.h>
+#include <asm/arch-fsl-layerscape/immap_lsch2.h>
+
+#define DEFAULT_PFE_MDIO_NAME "PFE_MDIO"
+#define DEFAULT_PFE_MDIO1_NAME "PFE_MDIO1"
+
+#define MASK_ETH_PHY_RST	0x00000100
+
+void reset_phy(void)
+{
+	unsigned int val;
+	struct ccsr_gpio *pgpio = (void *)(GPIO1_BASE_ADDR);
+
+	setbits_be32(&pgpio->gpdir, MASK_ETH_PHY_RST);
+
+	val = in_be32(&pgpio->gpdat);
+	setbits_be32(&pgpio->gpdat, val & ~MASK_ETH_PHY_RST);
+	mdelay(10);
+
+	val = in_be32(&pgpio->gpdat);
+	setbits_be32(&pgpio->gpdat, val | MASK_ETH_PHY_RST);
+	mdelay(50);
+}
+
+int board_eth_init(bd_t *bis)
+{
+#ifdef CONFIG_FSL_PFE
+	struct mii_dev *bus;
+	struct mdio_info mac1_mdio_info;
+
+	reset_phy();
+
+	init_pfe_scfg_dcfg_regs();
+
+	mac1_mdio_info.reg_base = (void *)EMAC1_BASE_ADDR;
+	mac1_mdio_info.name = DEFAULT_PFE_MDIO_NAME;
+
+	bus = ls1012a_mdio_init(&mac1_mdio_info);
+	if (!bus) {
+		printf("Failed to register mdio\n");
+		return -1;
+	}
+
+	/* We don't really need this MDIO bus,
+	 * this is called just to initialize EMAC2 MDIO interface */
+	mac1_mdio_info.reg_base = (void *)0x04220000; /*EMAC2_BASE_ADDR*/
+	mac1_mdio_info.name = DEFAULT_PFE_MDIO1_NAME;
+
+	bus = ls1012a_mdio_init(&mac1_mdio_info);
+	if (!bus) {
+		printf("Failed to register mdio\n");
+		return -1;
+	}
+
+	/* MAC1 */
+	ls1012a_set_mdio(0, miiphy_get_dev_by_name(DEFAULT_PFE_MDIO_NAME));
+	ls1012a_set_phy_address_mode(0, EMAC1_PHY_ADDR,
+				     PHY_INTERFACE_MODE_SGMII);
+
+	/* MAC2 */
+	ls1012a_set_mdio(1, miiphy_get_dev_by_name(DEFAULT_PFE_MDIO_NAME));
+	ls1012a_set_phy_address_mode(1, EMAC2_PHY_ADDR,
+				     PHY_INTERFACE_MODE_SGMII);
+
+
+	return cpu_eth_init(bis);
+#endif
+}
diff --git a/board/freescale/ls1012afrdm/ls1012afrdm.c b/board/freescale/ls1012afrdm/ls1012afrdm.c
index 9afd1c4..0145886 100644
--- a/board/freescale/ls1012afrdm/ls1012afrdm.c
+++ b/board/freescale/ls1012afrdm/ls1012afrdm.c
@@ -57,11 +57,6 @@ int dram_init(void)
 	return 0;
 }
 
-int board_eth_init(bd_t *bis)
-{
-	return pci_eth_init(bis);
-}
-
 int board_early_init_f(void)
 {
 	fsl_lsch2_early_init_f();
diff --git a/board/freescale/ls1012aqds/Makefile b/board/freescale/ls1012aqds/Makefile
index 0b813f9..b18494a 100644
--- a/board/freescale/ls1012aqds/Makefile
+++ b/board/freescale/ls1012aqds/Makefile
@@ -5,3 +5,4 @@
 #
 
 obj-y += ls1012aqds.o
+obj-y += eth.o
diff --git a/board/freescale/ls1012aqds/eth.c b/board/freescale/ls1012aqds/eth.c
new file mode 100644
index 0000000..bf916f3
--- /dev/null
+++ b/board/freescale/ls1012aqds/eth.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <netdev.h>
+#include <fm_eth.h>
+#include <fsl_mdio.h>
+#include <malloc.h>
+#include <fsl_dtsec.h>
+#include <asm/arch/soc.h>
+#include <asm/arch-fsl-layerscape/config.h>
+#include <asm/arch/fsl_serdes.h>
+
+#include "../common/qixis.h"
+#include <pfe_eth/pfe_eth.h>
+#include "ls1012aqds_qixis.h"
+#include <asm/arch-fsl-layerscape/immap_lsch2.h>
+
+#define EMI_NONE	0xFF
+#define EMI1_RGMII	1
+#define EMI1_SLOT1	2
+#define EMI1_SLOT2	3
+
+#define DEFAULT_PFE_MDIO_NAME "PFE_MDIO"
+#define DEFAULT_PFE_MDIO1_NAME "PFE_MDIO1"
+
+static const char * const mdio_names[] = {
+	"NULL",
+	"LS1012AQDS_MDIO_RGMII",
+	"LS1012AQDS_MDIO_SLOT1",
+	"LS1012AQDS_MDIO_SLOT2",
+	"NULL",
+};
+
+static const char *ls1012aqds_mdio_name_for_muxval(u8 muxval)
+{
+	return mdio_names[muxval];
+}
+
+struct ls1012aqds_mdio {
+	u8 muxval;
+	struct mii_dev *realbus;
+};
+
+static void ls1012aqds_mux_mdio(u8 muxval)
+{
+	u8 brdcfg4;
+
+	if (muxval < 7) {
+		brdcfg4 = QIXIS_READ(brdcfg[4]);
+		brdcfg4 &= ~BRDCFG4_EMISEL_MASK;
+		brdcfg4 |= (muxval << BRDCFG4_EMISEL_SHIFT);
+		QIXIS_WRITE(brdcfg[4], brdcfg4);
+	}
+}
+
+static int ls1012aqds_mdio_read(struct mii_dev *bus, int addr, int devad,
+			      int regnum)
+{
+	struct ls1012aqds_mdio *priv = bus->priv;
+
+	ls1012aqds_mux_mdio(priv->muxval);
+
+	return priv->realbus->read(priv->realbus, addr, devad, regnum);
+}
+
+static int ls1012aqds_mdio_write(struct mii_dev *bus, int addr, int devad,
+			       int regnum, u16 value)
+{
+	struct ls1012aqds_mdio *priv = bus->priv;
+
+	ls1012aqds_mux_mdio(priv->muxval);
+
+	return priv->realbus->write(priv->realbus, addr, devad, regnum, value);
+}
+
+static int ls1012aqds_mdio_reset(struct mii_dev *bus)
+{
+	struct ls1012aqds_mdio *priv = bus->priv;
+
+	if (priv->realbus->reset)
+		return priv->realbus->reset(priv->realbus);
+	else
+		return -1;
+}
+
+static int ls1012aqds_mdio_init(char *realbusname, u8 muxval)
+{
+	struct ls1012aqds_mdio *pmdio;
+	struct mii_dev *bus = mdio_alloc();
+
+	if (!bus) {
+		printf("Failed to allocate ls1012aqds MDIO bus\n");
+		return -1;
+	}
+
+	pmdio = malloc(sizeof(*pmdio));
+	if (!pmdio) {
+		printf("Failed to allocate ls1012aqds private data\n");
+		free(bus);
+		return -1;
+	}
+
+	bus->read = ls1012aqds_mdio_read;
+	bus->write = ls1012aqds_mdio_write;
+	bus->reset = ls1012aqds_mdio_reset;
+	sprintf(bus->name, ls1012aqds_mdio_name_for_muxval(muxval));
+
+	pmdio->realbus = miiphy_get_dev_by_name(realbusname);
+
+	if (!pmdio->realbus) {
+		printf("No bus with name %s\n", realbusname);
+		free(bus);
+		free(pmdio);
+		return -1;
+	}
+
+	pmdio->muxval = muxval;
+	bus->priv = pmdio;
+	return mdio_register(bus);
+}
+
+int board_eth_init(bd_t *bis)
+{
+#ifdef CONFIG_FSL_PFE
+	struct mii_dev *bus;
+	static const char *mdio_name;
+	struct mdio_info mac1_mdio_info;
+	struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
+	u8 data8;
+
+	int srds_s1 = in_be32(&gur->rcwsr[4]) &
+			FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
+	srds_s1 >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;
+
+	init_pfe_scfg_dcfg_regs();
+
+	ls1012aqds_mux_mdio(2);
+
+	mac1_mdio_info.reg_base = (void *)EMAC1_BASE_ADDR;
+	mac1_mdio_info.name = DEFAULT_PFE_MDIO_NAME;
+
+	bus = ls1012a_mdio_init(&mac1_mdio_info);
+	if (!bus) {
+		printf("Failed to register mdio\n");
+		return -1;
+	}
+
+	mac1_mdio_info.reg_base = (void *)0x04220000; /*EMAC2_BASE_ADDR*/
+	mac1_mdio_info.name = DEFAULT_PFE_MDIO1_NAME;
+
+	bus = ls1012a_mdio_init(&mac1_mdio_info);
+	if (!bus) {
+		printf("Failed to register mdio\n");
+		return -1;
+	}
+
+	switch (srds_s1) {
+	case 0x3508:
+		printf("ls1012aqds:supported SerDes PRCTL= %d\n", srds_s1);
+#ifdef RGMII_RESET_WA
+		/* Work around for FPGA registers initialization
+		 * This is needed for RGMII to work */
+		printf("Reset RGMII WA....\n");
+		data8 = QIXIS_READ(rst_frc[0]);
+		data8 |= 0x2;
+		QIXIS_WRITE(rst_frc[0], data8);
+		data8 = QIXIS_READ(rst_frc[0]);
+
+		data8 = QIXIS_READ(res8[6]);
+		data8 |= 0xff;
+		QIXIS_WRITE(res8[6], data8);
+		data8 = QIXIS_READ(res8[6]);
+#endif
+		mdio_name = ls1012aqds_mdio_name_for_muxval(EMI1_RGMII);
+		if (ls1012aqds_mdio_init(DEFAULT_PFE_MDIO_NAME, EMI1_RGMII) <
+		    0) {
+			printf("Failed to register mdio for %s\n", mdio_name);
+			return -1;
+		}
+
+		mdio_name = ls1012aqds_mdio_name_for_muxval(EMI1_SLOT1);
+		if (ls1012aqds_mdio_init(DEFAULT_PFE_MDIO_NAME, EMI1_SLOT1) <
+		    0) {
+				printf("Failed to register mdio for %s\n",
+				       mdio_name);
+				return -1;
+		}
+
+		/* MAC2*/
+		mdio_name = ls1012aqds_mdio_name_for_muxval(EMI1_RGMII);
+		bus = miiphy_get_dev_by_name(mdio_name);
+		ls1012a_set_mdio(1, bus);
+		ls1012a_set_phy_address_mode(1,  EMAC2_PHY_ADDR,
+					     PHY_INTERFACE_MODE_RGMII);
+
+		/* MAC1*/
+		mdio_name = ls1012aqds_mdio_name_for_muxval(EMI1_SLOT1);
+		bus = miiphy_get_dev_by_name(mdio_name);
+		ls1012a_set_mdio(0, bus);
+		ls1012a_set_phy_address_mode(0, EMAC1_PHY_ADDR,
+					     PHY_INTERFACE_MODE_SGMII);
+		break;
+
+	case 0x2205:
+		printf("ls1012aqds:supported SerDes PRCTL= %d\n", srds_s1);
+		/* Work around for FPGA registers initialization
+		 * This is needed for RGMII to work */
+		printf("Reset SLOT1 SLOT2....\n");
+		data8 = QIXIS_READ(rst_frc[2]);
+		data8 |= 0xc0;
+		QIXIS_WRITE(rst_frc[2], data8);
+		mdelay(100);
+		data8 = QIXIS_READ(rst_frc[2]);
+		data8 &= 0x3f;
+		QIXIS_WRITE(rst_frc[2], data8);
+
+		mdio_name = ls1012aqds_mdio_name_for_muxval(EMI1_SLOT1);
+		if (ls1012aqds_mdio_init(DEFAULT_PFE_MDIO_NAME, EMI1_SLOT1) <
+		    0) {
+				printf("Failed to register mdio for %s\n",
+				       mdio_name);
+				return -1;
+		}
+
+		mdio_name = ls1012aqds_mdio_name_for_muxval(EMI1_SLOT2);
+		if (ls1012aqds_mdio_init(DEFAULT_PFE_MDIO_NAME, EMI1_SLOT2) <
+		    0) {
+			printf("Failed to register mdio for %s\n", mdio_name);
+			return -1;
+		}
+		/* MAC2*/
+		mdio_name = ls1012aqds_mdio_name_for_muxval(EMI1_SLOT2);
+		bus = miiphy_get_dev_by_name(mdio_name);
+		ls1012a_set_mdio(1, bus);
+		ls1012a_set_phy_address_mode(1,  SGMII_2500_PHY2_ADDR,
+					     PHY_INTERFACE_MODE_SGMII_2500);
+
+		data8 = QIXIS_READ(brdcfg[12]);
+		data8 |= 0x20;
+		QIXIS_WRITE(brdcfg[12], data8);
+
+		/* MAC1*/
+		mdio_name = ls1012aqds_mdio_name_for_muxval(EMI1_SLOT1);
+		bus = miiphy_get_dev_by_name(mdio_name);
+		ls1012a_set_mdio(0, bus);
+		ls1012a_set_phy_address_mode(0, SGMII_2500_PHY1_ADDR,
+					     PHY_INTERFACE_MODE_SGMII_2500);
+		break;
+
+	default:
+		printf("ls1012aqds:unsupported SerDes PRCTL= %d\n", srds_s1);
+		break;
+	}
+	cpu_eth_init(bis);
+#endif
+	return pci_eth_init(bis);
+}
diff --git a/board/freescale/ls1012aqds/ls1012aqds.c b/board/freescale/ls1012aqds/ls1012aqds.c
index 406194d..5669d1f 100644
--- a/board/freescale/ls1012aqds/ls1012aqds.c
+++ b/board/freescale/ls1012aqds/ls1012aqds.c
@@ -29,6 +29,8 @@
 #include "../common/qixis.h"
 #include "ls1012aqds_qixis.h"
 
+#include "ls1012aqds_pfe.h"
+
 DECLARE_GLOBAL_DATA_PTR;
 
 int checkboard(void)
@@ -128,11 +130,6 @@ int board_init(void)
 	return 0;
 }
 
-int board_eth_init(bd_t *bis)
-{
-	return pci_eth_init(bis);
-}
-
 int esdhc_status_fixup(void *blob, const char *compat)
 {
 	char esdhc0_path[] = "/soc/esdhc at 1560000";
@@ -161,12 +158,102 @@ int esdhc_status_fixup(void *blob, const char *compat)
 	return 0;
 }
 
+static int pfe_set_properties(void *set_blob, struct pfe_prop_val prop_val,
+			      char *enet_path, char *mdio_path)
+{
+	do_fixup_by_path(set_blob, enet_path, "fsl,gemac-bus-id",
+			 &prop_val.busid, PFE_PROP_LEN, 1);
+	do_fixup_by_path(set_blob, enet_path, "fsl,gemac-phy-id",
+			 &prop_val.phyid, PFE_PROP_LEN, 1);
+	do_fixup_by_path(set_blob, enet_path, "fsl,mdio-mux-val",
+			 &prop_val.mux_val, PFE_PROP_LEN, 1);
+	do_fixup_by_path(set_blob, enet_path, "phy-mode",
+			 prop_val.phy_mode, strlen(prop_val.phy_mode) + 1, 1);
+	do_fixup_by_path(set_blob, mdio_path, "fsl,mdio-phy-mask",
+			 &prop_val.phy_mask, PFE_PROP_LEN, 1);
+	return 0;
+}
+
+static void fdt_fsl_fixup_of_pfe(void *blob)
+{
+	int i = 0;
+	struct pfe_prop_val prop_val;
+	void *l_blob = blob;
+
+	struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
+	unsigned int srds_s1 = in_be32(&gur->rcwsr[4]) &
+		FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
+	srds_s1 >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;
+
+	for (i = 0; i < NUM_ETH_NODE; i++) {
+		switch (srds_s1) {
+		case SERDES_1_G_PROTOCOL:
+			if (i == 0) {
+				prop_val.busid = cpu_to_fdt32(
+						ETH_1_1G_BUS_ID);
+				prop_val.phyid = cpu_to_fdt32(
+						ETH_1_1G_PHY_ID);
+				prop_val.mux_val = cpu_to_fdt32(
+						ETH_1_1G_MDIO_MUX);
+				prop_val.phy_mask = cpu_to_fdt32(
+						ETH_1G_MDIO_PHY_MASK);
+				prop_val.phy_mode = "sgmii";
+				pfe_set_properties(l_blob, prop_val, ETH_1_PATH,
+						   ETH_1_MDIO);
+				} else {
+				prop_val.busid = cpu_to_fdt32(
+						ETH_2_1G_BUS_ID);
+				prop_val.phyid = cpu_to_fdt32(
+						ETH_2_1G_PHY_ID);
+				prop_val.mux_val = cpu_to_fdt32(
+						ETH_2_1G_MDIO_MUX);
+				prop_val.phy_mask = cpu_to_fdt32(
+						ETH_1G_MDIO_PHY_MASK);
+				prop_val.phy_mode = "rgmii";
+				pfe_set_properties(l_blob, prop_val, ETH_2_PATH,
+						   ETH_2_MDIO);
+				}
+		break;
+		case SERDES_2_5_G_PROTOCOL:
+			if (i == 0) {
+				prop_val.busid = cpu_to_fdt32(
+						ETH_1_2_5G_BUS_ID);
+				prop_val.phyid = cpu_to_fdt32(
+						ETH_1_2_5G_PHY_ID);
+				prop_val.mux_val = cpu_to_fdt32(
+						ETH_1_2_5G_MDIO_MUX);
+				prop_val.phy_mask = cpu_to_fdt32(
+						ETH_2_5G_MDIO_PHY_MASK);
+				prop_val.phy_mode = "sgmii-2500";
+				pfe_set_properties(l_blob, prop_val, ETH_1_PATH,
+						   ETH_1_MDIO);
+				} else {
+				prop_val.busid = cpu_to_fdt32(
+						ETH_2_2_5G_BUS_ID);
+				prop_val.phyid = cpu_to_fdt32(
+						ETH_2_2_5G_PHY_ID);
+				prop_val.mux_val = cpu_to_fdt32(
+						ETH_2_2_5G_MDIO_MUX);
+				prop_val.phy_mask = cpu_to_fdt32(
+						ETH_2_5G_MDIO_PHY_MASK);
+				prop_val.phy_mode = "sgmii-2500";
+				pfe_set_properties(l_blob, prop_val, ETH_2_PATH,
+						   ETH_2_MDIO);
+				}
+		break;
+		default:
+			printf("serdes:[%d]\n", srds_s1);
+		}
+	}
+}
+
 #ifdef CONFIG_OF_BOARD_SETUP
 int ft_board_setup(void *blob, bd_t *bd)
 {
 	arch_fixup_fdt(blob);
 
 	ft_cpu_setup(blob, bd);
+	fdt_fsl_fixup_of_pfe(blob);
 
 	return 0;
 }
diff --git a/board/freescale/ls1012aqds/ls1012aqds_pfe.h b/board/freescale/ls1012aqds/ls1012aqds_pfe.h
new file mode 100644
index 0000000..c279ef3
--- /dev/null
+++ b/board/freescale/ls1012aqds/ls1012aqds_pfe.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#define ETH_1_1G_BUS_ID		0x1
+#define ETH_1_1G_PHY_ID		0x1e
+#define ETH_1_1G_MDIO_MUX	0x2
+#define ETH_1G_MDIO_PHY_MASK	0xBFFFFFFD
+#define ETH_1_1G_PHY_MODE	"sgmii"
+#define ETH_2_1G_BUS_ID		0x1
+#define ETH_2_1G_PHY_ID		0x1
+#define ETH_2_1G_MDIO_MUX	0x1
+#define ETH_2_1G_PHY_MODE	"rgmii"
+
+#define ETH_1_2_5G_BUS_ID	0x0
+#define ETH_1_2_5G_PHY_ID	0x1
+#define ETH_1_2_5G_MDIO_MUX	0x2
+#define ETH_2_5G_MDIO_PHY_MASK	0xFFFFFFF9
+#define ETH_2_5G_PHY_MODE	"sgmii-2500"
+#define ETH_2_2_5G_BUS_ID	0x1
+#define ETH_2_2_5G_PHY_ID	0x2
+#define ETH_2_2_5G_MDIO_MUX	0x3
+
+#define SERDES_1_G_PROTOCOL	0x3508
+#define SERDES_2_5_G_PROTOCOL	0x2205
+
+#define PFE_PROP_LEN		4
+
+#define ETH_1_SOC_PATH		"/soc/pfe at 04000000/ethernet at 0"
+#define ETH_1_PATH		"/pfe at 04000000/ethernet at 0"
+#define ETH_2_SOC_PATH		"/soc/pfe at 04000000/ethernet at 1"
+#define ETH_2_PATH		"/pfe at 04000000/ethernet at 1"
+
+#define ETH_1_MDIO_SOC_PATH	"/soc/pfe at 04000000/ethernet at 0/mdio at 0"
+#define ETH_1_MDIO		"/pfe at 04000000/ethernet at 0/mdio at 0"
+#define ETH_2_MDIO_SOC_PATH	"/soc/pfe at 04000000/ethernet at 1/mdio at 0"
+#define ETH_2_MDIO		"/pfe at 04000000/ethernet at 1/mdio at 0"
+
+#define NUM_ETH_NODE		2
+struct pfe_prop_val {
+	int busid;
+	int phyid;
+	int mux_val;
+	int phy_mask;
+	char *phy_mode;
+};
diff --git a/board/freescale/ls1012aqds/ls1012aqds_qixis.h b/board/freescale/ls1012aqds/ls1012aqds_qixis.h
index 584f604..7a1ba3d 100644
--- a/board/freescale/ls1012aqds/ls1012aqds_qixis.h
+++ b/board/freescale/ls1012aqds/ls1012aqds_qixis.h
@@ -11,7 +11,7 @@
 
 /* BRDCFG4[4:7] select EC1 and EC2 as a pair */
 #define BRDCFG4_EMISEL_MASK		0xe0
-#define BRDCFG4_EMISEL_SHIFT		5
+#define BRDCFG4_EMISEL_SHIFT		6
 
 /* SYSCLK */
 #define QIXIS_SYSCLK_66			0x0
diff --git a/board/freescale/ls1012ardb/Makefile b/board/freescale/ls1012ardb/Makefile
index 05fa9d9..bd80ce5 100644
--- a/board/freescale/ls1012ardb/Makefile
+++ b/board/freescale/ls1012ardb/Makefile
@@ -5,3 +5,4 @@
 #
 
 obj-y += ls1012ardb.o
+obj-y += eth.o
diff --git a/board/freescale/ls1012ardb/eth.c b/board/freescale/ls1012ardb/eth.c
new file mode 100644
index 0000000..286bc8a
--- /dev/null
+++ b/board/freescale/ls1012ardb/eth.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * SPDX-License-Identifier:GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <netdev.h>
+#include <fm_eth.h>
+#include <fsl_mdio.h>
+#include <malloc.h>
+#include <fsl_dtsec.h>
+#include <asm/arch/soc.h>
+#include <asm/arch-fsl-layerscape/config.h>
+#include <asm/arch/fsl_serdes.h>
+
+#include <pfe_eth/pfe_eth.h>
+#include <asm/arch-fsl-layerscape/immap_lsch2.h>
+#include <i2c.h>
+
+#define DEFAULT_PFE_MDIO_NAME "PFE_MDIO"
+
+
+void reset_phy(void)
+{
+	/* Through reset IO expander reset both RGMII and SGMII PHYs */
+	i2c_reg_write(I2C_MUX_IO2_ADDR, 6, __PHY_MASK);
+	i2c_reg_write(I2C_MUX_IO2_ADDR, 2, __PHY_ETH2_MASK);
+	mdelay(10);
+	i2c_reg_write(I2C_MUX_IO2_ADDR, 2, __PHY_ETH1_MASK);
+	mdelay(10);
+	i2c_reg_write(I2C_MUX_IO2_ADDR, 2, 0xFF);
+	mdelay(50);
+}
+
+int board_eth_init(bd_t *bis)
+{
+#ifdef CONFIG_FSL_PFE
+	struct mii_dev *bus;
+	struct mdio_info mac1_mdio_info;
+
+	reset_phy();
+
+	init_pfe_scfg_dcfg_regs();
+
+	mac1_mdio_info.reg_base = (void *)EMAC1_BASE_ADDR;
+	mac1_mdio_info.name = DEFAULT_PFE_MDIO_NAME;
+
+	bus = ls1012a_mdio_init(&mac1_mdio_info);
+	if (!bus) {
+		printf("Failed to register mdio\n");
+		return -1;
+	}
+
+	/* MAC1 */
+	ls1012a_set_mdio(0, miiphy_get_dev_by_name(DEFAULT_PFE_MDIO_NAME));
+	ls1012a_set_phy_address_mode(0, EMAC1_PHY_ADDR,
+				     PHY_INTERFACE_MODE_SGMII);
+
+	/* MAC2 */
+	ls1012a_set_mdio(1, miiphy_get_dev_by_name(DEFAULT_PFE_MDIO_NAME));
+	ls1012a_set_phy_address_mode(1, EMAC2_PHY_ADDR,
+				     PHY_INTERFACE_MODE_RGMII);
+
+	cpu_eth_init(bis);
+#endif
+	return pci_eth_init(bis);
+}
diff --git a/board/freescale/ls1012ardb/ls1012ardb.c b/board/freescale/ls1012ardb/ls1012ardb.c
index c6c1c71..41283db 100644
--- a/board/freescale/ls1012ardb/ls1012ardb.c
+++ b/board/freescale/ls1012ardb/ls1012ardb.c
@@ -90,10 +90,6 @@ int dram_init(void)
 	return 0;
 }
 
-int board_eth_init(bd_t *bis)
-{
-	return pci_eth_init(bis);
-}
 
 int board_early_init_f(void)
 {
diff --git a/include/configs/ls1012ardb.h b/include/configs/ls1012ardb.h
index 5fe3218..e47bb7c 100644
--- a/include/configs/ls1012ardb.h
+++ b/include/configs/ls1012ardb.h
@@ -42,6 +42,11 @@
 #define __SW_REV_A		0xF8
 #define __SW_REV_B		0xF0
 
+#define I2C_MUX_IO2_ADDR		0x25
+#define __PHY_MASK			0xF9
+#define __PHY_ETH2_MASK		0xFB
+#define __PHY_ETH1_MASK		0xFD
+
 /*  MMC  */
 #ifdef CONFIG_MMC
 #define CONFIG_FSL_ESDHC
-- 
2.7.4



More information about the U-Boot mailing list