summaryrefslogtreecommitdiff
path: root/board
diff options
context:
space:
mode:
Diffstat (limited to 'board')
-rw-r--r--board/freescale/common/Kconfig1
-rw-r--r--board/freescale/common/Makefile1
-rw-r--r--board/freescale/common/i2c_mux.c24
-rw-r--r--board/freescale/common/i2c_mux.h3
-rw-r--r--board/freescale/common/qsfp_eeprom.c90
-rw-r--r--board/freescale/common/qsfp_eeprom.h14
-rw-r--r--board/freescale/ls1021aiot/ls1021aiot.c10
-rw-r--r--board/freescale/ls1021aqds/eth.c5
-rw-r--r--board/freescale/ls1028a/ls1028a.c7
-rw-r--r--board/freescale/ls1043ardb/cpld.c6
-rw-r--r--board/freescale/ls1043ardb/cpld.h1
-rw-r--r--board/freescale/ls1043ardb/ls1043ardb.c79
-rw-r--r--board/freescale/lx2160a/Kconfig9
-rw-r--r--board/freescale/lx2160a/eth_lx2160aqds.c5
-rw-r--r--board/freescale/lx2160a/eth_lx2160ardb.c160
-rw-r--r--board/freescale/lx2160a/lx2160a.c57
-rw-r--r--board/freescale/lx2160a/lx2160a.h20
17 files changed, 474 insertions, 18 deletions
diff --git a/board/freescale/common/Kconfig b/board/freescale/common/Kconfig
index 77d5ca722c..f4ceb21469 100644
--- a/board/freescale/common/Kconfig
+++ b/board/freescale/common/Kconfig
@@ -3,6 +3,7 @@ config CHAIN_OF_TRUST
imply CMD_BLOB
imply CMD_HASH if ARM
select FSL_CAAM
+ select ARCH_MISC_INIT
select SPL_BOARD_INIT if (ARM && SPL)
select SPL_HASH if (ARM && SPL)
select SHA_HW_ACCEL
diff --git a/board/freescale/common/Makefile b/board/freescale/common/Makefile
index f285d3f3ab..18854df253 100644
--- a/board/freescale/common/Makefile
+++ b/board/freescale/common/Makefile
@@ -78,6 +78,7 @@ endif
obj-$(CONFIG_LS102XA_STREAM_ID) += ls102xa_stream_id.o
obj-$(CONFIG_EMC2305) += emc2305.o
+obj-$(CONFIG_QSFP_EEPROM) += qsfp_eeprom.o
# deal with common files for P-series corenet based devices
obj-$(CONFIG_TARGET_P2041RDB) += p_corenet/
diff --git a/board/freescale/common/i2c_mux.c b/board/freescale/common/i2c_mux.c
index 54f89e2576..9523dd0942 100644
--- a/board/freescale/common/i2c_mux.c
+++ b/board/freescale/common/i2c_mux.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2014 Freescale Semiconductor, Inc.
- * Copyright 2020-21 NXP
+ * Copyright 2020-2022 NXP
* Copyright 2021 Microsoft Corporation
*/
@@ -37,4 +37,26 @@ int select_i2c_ch_pca9547(u8 ch, int bus)
return 0;
}
+#ifdef I2C_MUX_PCA_ADDR_SEC
+int select_i2c_ch_pca9547_sec(u8 ch, int bus)
+{
+ int ret;
+ DEVICE_HANDLE_T dev;
+
+ /* Open device handle */
+ ret = fsl_i2c_get_device(I2C_MUX_PCA_ADDR_SEC, bus, &dev);
+ if (ret) {
+ printf("PCA: No PCA9547 device found\n");
+ return ret;
+ }
+
+ ret = I2C_WRITE(dev, 0, &ch, sizeof(ch));
+ if (ret) {
+ printf("PCA: Unable to select channel %d (%d)\n", (int)ch, ret);
+ return ret;
+ }
+
+ return 0;
+}
+#endif
#endif
diff --git a/board/freescale/common/i2c_mux.h b/board/freescale/common/i2c_mux.h
index 0870c1918e..b58a284326 100644
--- a/board/freescale/common/i2c_mux.h
+++ b/board/freescale/common/i2c_mux.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2014 Freescale Semiconductor, Inc.
- * Copyright 2020-21 NXP
+ * Copyright 2020-2022 NXP
* Copyright 2021 Microsoft Corporation
*/
@@ -10,6 +10,7 @@
#ifdef CONFIG_FSL_USE_PCA9547_MUX
int select_i2c_ch_pca9547(u8 ch, int bus);
+int select_i2c_ch_pca9547_sec(u8 ch, int bus);
#endif
#endif
diff --git a/board/freescale/common/qsfp_eeprom.c b/board/freescale/common/qsfp_eeprom.c
new file mode 100644
index 0000000000..d57a10d663
--- /dev/null
+++ b/board/freescale/common/qsfp_eeprom.c
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2019-2022 NXP
+ */
+#include <common.h>
+#include <command.h>
+#include <i2c.h>
+#include <linux/ctype.h>
+
+#define DEV_ID_QSFP 0x0c
+#define DEV_ID_QSFP_PLUS 0x0d
+
+static struct __attribute__ ((__packed__)) qsfp_eeprom_map {
+ struct __attribute__ ((__packed__)) qsfp_low_mem {
+ /* field byte address */
+ u8 identifier; /* 0 */
+ u16 status; /* 1-2 */
+ u8 reserved[124]; /* 3-126 */
+ u8 page_select; /* 127 */
+ } base;
+
+ struct __attribute__ ((__packed__)) qsfp_page00_mem {
+ /* field byte address */
+ u8 identifier; /* 128 */
+ u8 ext_identifier; /* 129 */
+ u8 connector; /* 130 */
+ u8 compat[8]; /* 131-138 */
+ u8 reserved[3]; /* 139-142 */
+ u8 length_fiber[4];
+ u8 length_copper; /* 146 */
+ u8 tech; /* 147 */
+ u8 vendor_name[16]; /* 148-163 */
+ u8 reserved2; /* 164 */
+ u8 oui[3]; /* 165-167 */
+ u8 pn[16]; /* 168-183 */
+ u8 rev[2]; /* 184-185 */
+ u8 reserved3[10]; /* 186-195 */
+ u8 serial[16]; /* 196-211 */
+ u8 date[8]; /* 212-219 */
+ u8 reserved4[35]; /* 220-255 */
+ } page0;
+} qsfp;
+
+unsigned char get_qsfp_compat0(void)
+{
+ int ret;
+ char vendor[20] = {0};
+ char serial[20] = {0};
+ char pname[20] = {0};
+ char mfgdt[20] = {0};
+#ifdef CONFIG_DM_I2C
+ struct udevice *dev;
+#endif
+
+ memset(&qsfp, 0, sizeof(qsfp));
+#ifndef CONFIG_DM_I2C
+ ret = i2c_read(I2C_SFP_EEPROM_ADDR,
+ 0,
+ I2C_SFP_EEPROM_ADDR_LEN,
+ (void *)&qsfp,
+ sizeof(qsfp));
+#else
+ ret = i2c_get_chip_for_busnum(0, I2C_SFP_EEPROM_ADDR, 1, &dev);
+ if (!ret)
+ ret = dm_i2c_read(dev, 0, (void *)&qsfp, sizeof(qsfp));
+#endif
+
+ if (ret != 0) {
+ debug("\nQSFP: no module detected\n");
+ return 0;
+ }
+ /* check if QSFP type */
+ if (qsfp.base.identifier != DEV_ID_QSFP_PLUS) {
+ debug("\nQSFP: unrecognized module\n");
+ return 0;
+ }
+
+ /* copy fields and trim the whitespaces and dump on screen */
+ snprintf(vendor, sizeof(vendor), "%.16s", qsfp.page0.vendor_name);
+ snprintf(serial, sizeof(serial), "%.16s", qsfp.page0.serial);
+ snprintf(pname, sizeof(pname), "%.16s", qsfp.page0.pn);
+ snprintf(mfgdt, sizeof(mfgdt), "%.2s/%.2s/%.2s",
+ &qsfp.page0.date[0], &qsfp.page0.date[2], &qsfp.page0.date[4]);
+
+ printf("QSFP: detected %s %s s/n: %s mfgdt: %s\n",
+ strim(vendor), strim(pname), strim(serial), strim(mfgdt));
+
+ /* return ethernet compatibility code*/
+ return qsfp.page0.compat[0];
+}
diff --git a/board/freescale/common/qsfp_eeprom.h b/board/freescale/common/qsfp_eeprom.h
new file mode 100644
index 0000000000..4aab21997f
--- /dev/null
+++ b/board/freescale/common/qsfp_eeprom.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2019-2022 NXP
+ */
+
+#ifndef __QSFP_EEPROM_H_
+#define __QSFP_EEPROM_H_
+/*
+ * QSFP eeprom reader external API interface.
+ */
+
+/* return the ethernet compatibility field 0 */
+unsigned char get_qsfp_compat0(void);
+#endif /* __QSFP_EEPROM_H_ */
diff --git a/board/freescale/ls1021aiot/ls1021aiot.c b/board/freescale/ls1021aiot/ls1021aiot.c
index 5ab03b3340..5d0dd3afdc 100644
--- a/board/freescale/ls1021aiot/ls1021aiot.c
+++ b/board/freescale/ls1021aiot/ls1021aiot.c
@@ -121,7 +121,10 @@ int board_eth_init(struct bd_info *bis)
if (is_serdes_configured(SGMII_TSEC1)) {
puts("eTSEC1 is in sgmii mode.\n");
tsec_info[num].flags |= TSEC_SGMII;
- }
+ tsec_info[num].interface = PHY_INTERFACE_MODE_SGMII;
+ } else {
+ tsec_info[num].interface = PHY_INTERFACE_MODE_NONE;
+ }
num++;
#endif
#ifdef CONFIG_TSEC2
@@ -129,7 +132,10 @@ int board_eth_init(struct bd_info *bis)
if (is_serdes_configured(SGMII_TSEC2)) {
puts("eTSEC2 is in sgmii mode.\n");
tsec_info[num].flags |= TSEC_SGMII;
- }
+ tsec_info[num].interface = PHY_INTERFACE_MODE_SGMII;
+ } else {
+ tsec_info[num].interface = PHY_INTERFACE_MODE_NONE;
+ }
num++;
#endif
if (!num) {
diff --git a/board/freescale/ls1021aqds/eth.c b/board/freescale/ls1021aqds/eth.c
index a9f162b974..177323031c 100644
--- a/board/freescale/ls1021aqds/eth.c
+++ b/board/freescale/ls1021aqds/eth.c
@@ -141,8 +141,10 @@ int board_eth_init(struct bd_info *bis)
puts("eTSEC1 is in sgmii mode\n");
tsec_info[num].flags |= TSEC_SGMII;
tsec_info[num].mii_devname = "LS1021A_SGMII_MDIO";
+ tsec_info[num].interface = PHY_INTERFACE_MODE_SGMII;
} else {
tsec_info[num].mii_devname = "LS1021A_RGMII_MDIO";
+ tsec_info[num].interface = PHY_INTERFACE_MODE_RGMII;
}
num++;
#endif
@@ -152,14 +154,17 @@ int board_eth_init(struct bd_info *bis)
puts("eTSEC2 is in sgmii mode\n");
tsec_info[num].flags |= TSEC_SGMII;
tsec_info[num].mii_devname = "LS1021A_SGMII_MDIO";
+ tsec_info[num].interface = PHY_INTERFACE_MODE_SGMII;
} else {
tsec_info[num].mii_devname = "LS1021A_RGMII_MDIO";
+ tsec_info[num].interface = PHY_INTERFACE_MODE_RGMII;
}
num++;
#endif
#ifdef CONFIG_TSEC3
SET_STD_TSEC_INFO(tsec_info[num], 3);
tsec_info[num].mii_devname = "LS1021A_RGMII_MDIO";
+ tsec_info[num].interface = PHY_INTERFACE_MODE_RGMII;
num++;
#endif
if (!num) {
diff --git a/board/freescale/ls1028a/ls1028a.c b/board/freescale/ls1028a/ls1028a.c
index 71a086ef67..1a7806fad7 100644
--- a/board/freescale/ls1028a/ls1028a.c
+++ b/board/freescale/ls1028a/ls1028a.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+
/*
- * Copyright 2019, 2021 NXP
+ * Copyright 2019-2022 NXP
*/
#include <common.h>
@@ -328,3 +328,8 @@ int checkboard(void)
return 0;
}
#endif
+
+void *video_hw_init(void)
+{
+ return NULL;
+}
diff --git a/board/freescale/ls1043ardb/cpld.c b/board/freescale/ls1043ardb/cpld.c
index 5d2e8015a0..bf3692a443 100644
--- a/board/freescale/ls1043ardb/cpld.c
+++ b/board/freescale/ls1043ardb/cpld.c
@@ -68,7 +68,11 @@ void cpld_set_defbank(void)
void cpld_set_nand(void)
{
- u16 reg = CPLD_CFG_RCW_SRC_NAND;
+ u16 reg = CPLD_CFG_RCW_SRC_NAND_4K;
+
+ if (CPLD_READ(cpld_ver) < 0x3)
+ reg = CPLD_CFG_RCW_SRC_NAND;
+
u8 reg5 = (u8)(reg >> 1);
u8 reg6 = (u8)(reg & 1);
diff --git a/board/freescale/ls1043ardb/cpld.h b/board/freescale/ls1043ardb/cpld.h
index 2e757b557f..eed34d6354 100644
--- a/board/freescale/ls1043ardb/cpld.h
+++ b/board/freescale/ls1043ardb/cpld.h
@@ -41,5 +41,6 @@ void cpld_rev_bit(unsigned char *value);
#define CPLD_BANK_SEL_ALTBANK 0x04
#define CPLD_CFG_RCW_SRC_NOR 0x025
#define CPLD_CFG_RCW_SRC_NAND 0x106
+#define CPLD_CFG_RCW_SRC_NAND_4K 0x118
#define CPLD_CFG_RCW_SRC_SD 0x040
#endif
diff --git a/board/freescale/ls1043ardb/ls1043ardb.c b/board/freescale/ls1043ardb/ls1043ardb.c
index 002869f435..51228bcf79 100644
--- a/board/freescale/ls1043ardb/ls1043ardb.c
+++ b/board/freescale/ls1043ardb/ls1043ardb.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2015 Freescale Semiconductor, Inc.
- * Copyright 2021 NXP
+ * Copyright 2021-2022 NXP
*/
#include <common.h>
@@ -167,7 +167,7 @@ int checkboard(void)
if (cfg_rcw_src == 0x25)
printf("vBank %d\n", CPLD_READ(vbank));
- else if (cfg_rcw_src == 0x106)
+ else if ((cfg_rcw_src == 0x106) || (cfg_rcw_src == 0x118))
puts("NAND\n");
else
printf("Invalid setting of SW4\n");
@@ -272,6 +272,39 @@ void fdt_del_qe(void *blob)
}
}
+/* Update the address of the Aquantia PHY on the MDIO bus for boards revision
+ * v7.0 and up. Also rename the PHY node to align with the address change.
+ */
+void fdt_fixup_phy_addr(void *blob)
+{
+ const char phy_path[] =
+ "/soc/fman@1a00000/mdio@fd000/ethernet-phy@1";
+ int ret, offset, new_addr = AQR113C_PHY_ADDR;
+ char new_name[] = "ethernet-phy@00";
+
+ if (CPLD_READ(pcba_ver) < 0x7)
+ return;
+
+ offset = fdt_path_offset(blob, phy_path);
+ if (offset < 0) {
+ printf("ethernet-phy@1 node not found in the dts\n");
+ return;
+ }
+
+ ret = fdt_setprop_u32(blob, offset, "reg", new_addr);
+ if (ret < 0) {
+ printf("Unable to set 'reg' for node ethernet-phy@1: %s\n",
+ fdt_strerror(ret));
+ return;
+ }
+
+ sprintf(new_name, "ethernet-phy@%x", new_addr);
+ ret = fdt_set_name(blob, offset, new_name);
+ if (ret < 0)
+ printf("Unable to rename node ethernet-phy@1: %s\n",
+ fdt_strerror(ret));
+}
+
int ft_board_setup(void *blob, struct bd_info *bd)
{
u64 base[CONFIG_NR_DRAM_BANKS];
@@ -290,6 +323,7 @@ int ft_board_setup(void *blob, struct bd_info *bd)
#ifndef CONFIG_DM_ETH
fdt_fixup_fman_ethernet(blob);
#endif
+ fdt_fixup_phy_addr(blob);
#endif
fdt_fixup_icid(blob);
@@ -313,6 +347,47 @@ int ft_board_setup(void *blob, struct bd_info *bd)
return 0;
}
+void nand_fixup()
+{
+ uint32_t csor = 0;
+
+ if (CPLD_READ(pcba_ver) < 0x7)
+ return;
+
+ /* Change NAND Flash PGS/SPRZ configuration */
+ csor = CONFIG_SYS_NAND_CSOR;
+ if ((csor & CSOR_NAND_PGS_MASK) == CSOR_NAND_PGS_2K)
+ csor = (csor & ~(CSOR_NAND_PGS_MASK)) | CSOR_NAND_PGS_4K;
+
+ if ((csor & CSOR_NAND_SPRZ_MASK) == CSOR_NAND_SPRZ_64)
+ csor = (csor & ~(CSOR_NAND_SPRZ_MASK)) | CSOR_NAND_SPRZ_224;
+
+#ifdef CONFIG_TFABOOT
+ set_ifc_csor(IFC_CS1, csor);
+#else
+#ifdef CONFIG_NAND_BOOT
+ set_ifc_csor(IFC_CS0, csor);
+#else
+ set_ifc_csor(IFC_CS1, csor);
+#endif
+#endif
+
+ return;
+}
+
+#if IS_ENABLED(CONFIG_OF_BOARD_FIXUP)
+int board_fix_fdt(void *blob)
+{
+ /* nand driver fix up */
+ nand_fixup();
+
+ /* fdt fix up */
+ fdt_fixup_phy_addr(blob);
+
+ return 0;
+}
+#endif
+
u8 flash_read8(void *addr)
{
return __raw_readb(addr + 1);
diff --git a/board/freescale/lx2160a/Kconfig b/board/freescale/lx2160a/Kconfig
index 7556f7dd21..ce2ef5d23c 100644
--- a/board/freescale/lx2160a/Kconfig
+++ b/board/freescale/lx2160a/Kconfig
@@ -12,6 +12,15 @@ config SYS_SOC
config SYS_CONFIG_NAME
default "lx2160ardb"
+config QSFP_EEPROM
+ bool "Support for reading QSFP+ transceiver eeprom"
+ default y if PHY_CORTINA
+ help
+ This option enables the functionality for reading
+ QSFP+ cable eeprom. It can be used when PHYs are
+ requiring different initialization based on cable
+ type.
+
source "board/freescale/common/Kconfig"
endif
diff --git a/board/freescale/lx2160a/eth_lx2160aqds.c b/board/freescale/lx2160a/eth_lx2160aqds.c
index 1819b27561..639ee37d52 100644
--- a/board/freescale/lx2160a/eth_lx2160aqds.c
+++ b/board/freescale/lx2160a/eth_lx2160aqds.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+
/*
- * Copyright 2018-2020 NXP
+ * Copyright 2018-2022 NXP
*
*/
@@ -25,6 +25,7 @@
#include <fsl-mc/ldpaa_wriop.h>
#include <linux/libfdt.h>
+#include "lx2160a.h"
#include "../common/qixis.h"
DECLARE_GLOBAL_DATA_PTR;
@@ -878,6 +879,8 @@ static struct serdes_configuration {
/* Serdes block #1 */
{1, 3, true},
{1, 7, true},
+ {1, 13, true},
+ {1, 14, true},
{1, 19, true},
{1, 20, true},
diff --git a/board/freescale/lx2160a/eth_lx2160ardb.c b/board/freescale/lx2160a/eth_lx2160ardb.c
index 15cbc58d59..d9b3c4d78e 100644
--- a/board/freescale/lx2160a/eth_lx2160ardb.c
+++ b/board/freescale/lx2160a/eth_lx2160ardb.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+
/*
- * Copyright 2018, 2020 NXP
+ * Copyright 2018-2022 NXP
*
*/
@@ -41,6 +41,49 @@ static bool get_inphi_phy_id(struct mii_dev *bus, int addr, int devad)
return false;
}
+int setup_eth_rev_c(u32 srds_p)
+{
+ struct mii_dev *bus;
+ int i;
+
+ /* difference between SerDes1 protocols 18/19 is 4x10G vs. 40G */
+ switch (srds_p) {
+ case 19:
+ wriop_init_dpmac_enet_if(WRIOP1_DPMAC2,
+ PHY_INTERFACE_MODE_XLAUI);
+ break;
+ case 18:
+ for (i = WRIOP1_DPMAC7; i <= WRIOP1_DPMAC10; i++)
+ wriop_init_dpmac_enet_if(i, PHY_INTERFACE_MODE_XGMII);
+ break;
+ default:
+ printf("SerDes1 protocol 0x%x is not supported on LX2160ARDB\n",
+ srds_p);
+ return -1;
+ }
+
+ /* common interfaces for SerDes1 protocols 18 and 19 initialization */
+ wriop_set_phy_address(WRIOP1_DPMAC3, 0, AQR113C_PHY_ADDR1);
+ wriop_set_phy_address(WRIOP1_DPMAC4, 0, AQR113C_PHY_ADDR2);
+ wriop_set_phy_address(WRIOP1_DPMAC5, 0, INPHI_PHY_ADDR1);
+ wriop_set_phy_address(WRIOP1_DPMAC6, 0, INPHI_PHY_ADDR1);
+ wriop_set_phy_address(WRIOP1_DPMAC17, 0, RGMII_PHY_ADDR1);
+ wriop_set_phy_address(WRIOP1_DPMAC18, 0, RGMII_PHY_ADDR2);
+
+ /* assign DPMAC/PHY to MDIO bus */
+ bus = miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO1_NAME);
+ wriop_set_mdio(WRIOP1_DPMAC3, bus);
+ wriop_set_mdio(WRIOP1_DPMAC4, bus);
+ wriop_set_mdio(WRIOP1_DPMAC17, bus);
+ wriop_set_mdio(WRIOP1_DPMAC18, bus);
+
+ bus = miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO2_NAME);
+ wriop_set_mdio(WRIOP1_DPMAC5, bus);
+ wriop_set_mdio(WRIOP1_DPMAC6, bus);
+
+ return 0;
+}
+
int board_eth_init(struct bd_info *bis)
{
#if defined(CONFIG_FSL_MC_ENET)
@@ -70,6 +113,13 @@ int board_eth_init(struct bd_info *bis)
fm_memac_mdio_init(bis, &mdio_info);
dev = miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO2_NAME);
+
+ /* new LX2160A-RDB2 revC board uses phy-less 25G/40G interfaces */
+ if (get_board_rev() == 'C') {
+ setup_eth_rev_c(srds_s1);
+ goto next;
+ }
+
switch (srds_s1) {
case 19:
wriop_set_phy_address(WRIOP1_DPMAC2, 0,
@@ -181,6 +231,112 @@ void reset_phy(void)
}
#endif /* CONFIG_RESET_PHY_R */
+static int fdt_get_dpmac_node(void *fdt, int dpmac_id)
+{
+ char dpmac_str[11] = "dpmacs@00";
+ int offset, dpmacs_offset;
+
+ /* get the dpmac offset */
+ dpmacs_offset = fdt_path_offset(fdt, "/soc/fsl-mc/dpmacs");
+ if (dpmacs_offset < 0)
+ dpmacs_offset = fdt_path_offset(fdt, "/fsl-mc/dpmacs");
+
+ if (dpmacs_offset < 0) {
+ printf("dpmacs node not found in device tree\n");
+ return dpmacs_offset;
+ }
+
+ sprintf(dpmac_str, "dpmac@%x", dpmac_id);
+ offset = fdt_subnode_offset(fdt, dpmacs_offset, dpmac_str);
+ if (offset < 0) {
+ sprintf(dpmac_str, "ethernet@%x", dpmac_id);
+ offset = fdt_subnode_offset(fdt, dpmacs_offset, dpmac_str);
+ if (offset < 0) {
+ printf("dpmac@%x/ethernet@%x node not found in device tree\n",
+ dpmac_id, dpmac_id);
+ return offset;
+ }
+ }
+
+ return offset;
+}
+
+static int fdt_update_phy_addr(void *fdt, int dpmac_id, int phy_addr)
+{
+ char dpmac_str[] = "dpmacs@00";
+ const u32 *phyhandle;
+ int offset;
+ int err;
+
+ /* get the dpmac offset */
+ offset = fdt_get_dpmac_node(fdt, dpmac_id);
+ if (offset < 0)
+ return offset;
+
+ /* get dpmac phy-handle */
+ sprintf(dpmac_str, "dpmac@%x", dpmac_id);
+ phyhandle = (u32 *)fdt_getprop(fdt, offset, "phy-handle", NULL);
+ if (!phyhandle) {
+ printf("%s node not found in device tree\n", dpmac_str);
+ return offset;
+ }
+
+ offset = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*phyhandle));
+ if (offset < 0) {
+ printf("Could not get the ph node offset for dpmac %d\n",
+ dpmac_id);
+ return offset;
+ }
+
+ phy_addr = cpu_to_fdt32(phy_addr);
+ err = fdt_setprop(fdt, offset, "reg", &phy_addr, sizeof(phy_addr));
+ if (err < 0) {
+ printf("Could not set phy node's reg for dpmac %d: %s.\n",
+ dpmac_id, fdt_strerror(err));
+ return err;
+ }
+
+ return 0;
+}
+
+static int fdt_delete_phy_handle(void *fdt, int dpmac_id)
+{
+ const u32 *phyhandle;
+ int offset;
+
+ /* get the dpmac offset */
+ offset = fdt_get_dpmac_node(fdt, dpmac_id);
+ if (offset < 0)
+ return offset;
+
+ /* verify if the node has a phy-handle */
+ phyhandle = (u32 *)fdt_getprop(fdt, offset, "phy-handle", NULL);
+ if (!phyhandle)
+ return 0;
+
+ return fdt_delprop(fdt, offset, "phy-handle");
+}
+
+int fdt_fixup_board_phy_revc(void *fdt)
+{
+ int ret;
+
+ if (get_board_rev() != 'C')
+ return 0;
+
+ /* DPMACs 3,4 have their Aquantia PHYs at new addresses */
+ ret = fdt_update_phy_addr(fdt, 3, AQR113C_PHY_ADDR1);
+ if (ret)
+ return ret;
+
+ ret = fdt_update_phy_addr(fdt, 4, AQR113C_PHY_ADDR2);
+ if (ret)
+ return ret;
+
+ /* There is no PHY for the DPMAC2, so remove the phy-handle */
+ return fdt_delete_phy_handle(fdt, 2);
+}
+
int fdt_fixup_board_phy(void *fdt)
{
int mdio_offset;
@@ -210,5 +366,5 @@ int fdt_fixup_board_phy(void *fdt)
}
}
- return ret;
+ return fdt_fixup_board_phy_revc(fdt);
}
diff --git a/board/freescale/lx2160a/lx2160a.c b/board/freescale/lx2160a/lx2160a.c
index 49d96d3fa2..6bee724896 100644
--- a/board/freescale/lx2160a/lx2160a.c
+++ b/board/freescale/lx2160a/lx2160a.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+
/*
- * Copyright 2018-2021 NXP
+ * Copyright 2018-2022 NXP
*/
#include <common.h>
@@ -35,6 +35,8 @@
#include <fsl_immap.h>
#include <asm/arch-fsl-layerscape/fsl_icid.h>
#include "lx2160a.h"
+#include "../common/qsfp_eeprom.h"
+#include "../common/i2c_mux.h"
#ifdef CONFIG_EMC2305
#include "../common/emc2305.h"
@@ -166,6 +168,11 @@ int board_fix_fdt(void *fdt)
fdt_setprop(fdt, off, "reg-names", reg_names, names_len);
}
+ /* Fixup u-boot's DTS in case this is a revC board and
+ * we're using DM_ETH.
+ */
+ if (IS_ENABLED(CONFIG_TARGET_LX2160ARDB) && IS_ENABLED(CONFIG_DM_ETH))
+ fdt_fixup_board_phy_revc(fdt);
return 0;
}
#endif
@@ -541,6 +548,15 @@ int config_board_mux(void)
}
#endif
+#if CONFIG_IS_ENABLED(TARGET_LX2160ARDB)
+u8 get_board_rev(void)
+{
+ u8 board_rev = (QIXIS_READ(arch) & 0xf) - 1 + 'A';
+
+ return board_rev;
+}
+#endif
+
unsigned long get_board_sys_clk(void)
{
#if defined(CONFIG_TARGET_LX2160AQDS) || defined(CONFIG_TARGET_LX2162AQDS)
@@ -579,6 +595,32 @@ unsigned long get_board_ddr_clk(void)
#endif
}
+#if defined(CONFIG_TARGET_LX2160ARDB) && defined(CONFIG_QSFP_EEPROM) && defined(CONFIG_PHY_CORTINA)
+void qsfp_cortina_detect(void)
+{
+ u8 qsfp_compat_code;
+
+ /* read qsfp+ eeprom & update environment for cs4223 init */
+ select_i2c_ch_pca9547(I2C_MUX_CH_SEC, 0);
+ select_i2c_ch_pca9547_sec(I2C_MUX_CH_QSFP, 0);
+ qsfp_compat_code = get_qsfp_compat0();
+ switch (qsfp_compat_code) {
+ case QSFP_COMPAT_CR4:
+ env_set(CS4223_CONFIG_ENV, CS4223_CONFIG_CR4);
+ break;
+ case QSFP_COMPAT_XLPPI:
+ case QSFP_COMPAT_SR4:
+ env_set(CS4223_CONFIG_ENV, CS4223_CONFIG_SR4);
+ break;
+ default:
+ /* do nothing if detection fails or not supported*/
+ break;
+ }
+ select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT, 0);
+}
+
+#endif /* CONFIG_QSFP_EEPROM & CONFIG_PHY_CORTINA */
+
int board_init(void)
{
#if defined(CONFIG_FSL_MC_ENET) && defined(CONFIG_TARGET_LX2160ARDB)
@@ -590,6 +632,10 @@ int board_init(void)
#if defined(CONFIG_FSL_MC_ENET) && defined(CONFIG_TARGET_LX2160ARDB)
/* invert AQR107 IRQ pins polarity */
out_le32(irq_ccsr + IRQCR_OFFSET / 4, AQR107_IRQ_MASK);
+
+#if defined(CONFIG_QSFP_EEPROM) && defined(CONFIG_PHY_CORTINA)
+ qsfp_cortina_detect();
+#endif
#endif
#if !defined(CONFIG_SYS_EARLY_PCI_INIT) && defined(CONFIG_DM_ETH)
@@ -684,6 +730,9 @@ void fdt_fixup_board_enet(void *fdt)
fdt_status_okay(fdt, offset);
#ifndef CONFIG_DM_ETH
fdt_fixup_board_phy(fdt);
+#else
+ if (IS_ENABLED(CONFIG_TARGET_LX2160ARDB))
+ fdt_fixup_board_phy_revc(fdt);
#endif
} else {
fdt_status_fail(fdt, offset);
@@ -818,9 +867,6 @@ int ft_board_setup(void *blob, struct bd_info *bd)
u64 mc_memory_size = 0;
u16 total_memory_banks;
int err;
-#if CONFIG_IS_ENABLED(TARGET_LX2160ARDB)
- u8 board_rev;
-#endif
err = fdt_increase_size(blob, 512);
if (err) {
@@ -883,8 +929,7 @@ int ft_board_setup(void *blob, struct bd_info *bd)
fdt_fixup_icid(blob);
#if CONFIG_IS_ENABLED(TARGET_LX2160ARDB)
- board_rev = (QIXIS_READ(arch) & 0xf) - 1 + 'A';
- if (board_rev == 'C')
+ if (get_board_rev() >= 'C')
fdt_fixup_i2c_thermal_node(blob);
#endif
diff --git a/board/freescale/lx2160a/lx2160a.h b/board/freescale/lx2160a/lx2160a.h
index 52b020765d..40d4652dd6 100644
--- a/board/freescale/lx2160a/lx2160a.h
+++ b/board/freescale/lx2160a/lx2160a.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
- * Copyright 2020 NXP
+ * Copyright 2020-2022 NXP
*/
#ifndef __LX2160_H
@@ -58,4 +58,22 @@
#endif
#endif
+#if defined(CONFIG_QSFP_EEPROM) && defined(CONFIG_PHY_CORTINA)
+#define CS4223_CONFIG_ENV "cs4223_autoconfig"
+#define CS4223_CONFIG_CR4 "copper"
+#define CS4223_CONFIG_SR4 "optical"
+
+enum qsfp_compat_codes {
+ QSFP_COMPAT_XLPPI = 0x01,
+ QSFP_COMPAT_LR4 = 0x02,
+ QSFP_COMPAT_SR4 = 0x04,
+ QSFP_COMPAT_CR4 = 0x08,
+};
+#endif /* CONFIG_QSFP_EEPROM && CONFIG_PHY_CORTINA */
+
+#if CONFIG_IS_ENABLED(TARGET_LX2160ARDB)
+u8 get_board_rev(void);
+int fdt_fixup_board_phy_revc(void *fdt);
+#endif
+
#endif /* __LX2160_H */