[PATCH 3/4] board: fsl: lx2160ardb: add dts fixup function for RevC
Ioana Ciornei
ioana.ciornei at nxp.com
Wed Apr 21 12:36:54 CEST 2021
From: Florin Chiculita <florinlaurentiu.chiculita at nxp.com>
Since the new RevC LX2160A-RDB board has its 10G Aquantia PHYs at
different MDIO bus addresses, we must update both the kernel DTS and
u-boot's DTS (in case of DM_ETH) in case the board is indeed RevC.
Use the newly introduced get_board_rev() function to trigger a fixup
of the kernel DTS to properly match the actual PHY addresses.
All this is encapsulated in the fdt_fixup_board_phy_revc() function
which will be used in the next patch.
Signed-off-by: Florin Chiculita <florinlaurentiu.chiculita at nxp.com>
Signed-off-by: Ioana Ciornei <ioana.ciornei at nxp.com>
---
board/freescale/lx2160a/eth_lx2160ardb.c | 106 +++++++++++++++++++++++
board/freescale/lx2160a/lx2160a.h | 1 +
2 files changed, 107 insertions(+)
diff --git a/board/freescale/lx2160a/eth_lx2160ardb.c b/board/freescale/lx2160a/eth_lx2160ardb.c
index cc4c94702c2b..1add00687a31 100644
--- a/board/freescale/lx2160a/eth_lx2160ardb.c
+++ b/board/freescale/lx2160a/eth_lx2160ardb.c
@@ -231,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[] = "dpmacs at 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 at 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;
diff --git a/board/freescale/lx2160a/lx2160a.h b/board/freescale/lx2160a/lx2160a.h
index 26a94e4c176a..43f96597c3a7 100644
--- a/board/freescale/lx2160a/lx2160a.h
+++ b/board/freescale/lx2160a/lx2160a.h
@@ -60,6 +60,7 @@
#if CONFIG_IS_ENABLED(TARGET_LX2160ARDB)
u8 get_board_rev(void);
+int fdt_fixup_board_phy_revc(void *fdt);
#endif
#endif /* __LX2160_H */
--
2.17.1
More information about the U-Boot
mailing list