From: Florin Chiculita <[email protected]>

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 or
newer. 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.

Use the newly fdt_fixup_board_phy_revc() function introduced to
update both kernel's DTS and u-boot's DTS.

Signed-off-by: Florin Chiculita <[email protected]>
Signed-off-by: Ioana Ciornei <[email protected]>
---
 board/freescale/lx2160a/eth_lx2160ardb.c | 107 +++++++++++++++++++++++
 board/freescale/lx2160a/lx2160a.c        |   7 ++
 board/freescale/lx2160a/lx2160a.h        |   1 +
 include/configs/lx2160ardb.h             |   5 ++
 4 files changed, 120 insertions(+)

diff --git a/board/freescale/lx2160a/eth_lx2160ardb.c 
b/board/freescale/lx2160a/eth_lx2160ardb.c
index 533f606effa7..c5dfefe1f342 100644
--- a/board/freescale/lx2160a/eth_lx2160ardb.c
+++ b/board/freescale/lx2160a/eth_lx2160ardb.c
@@ -8,6 +8,7 @@
 #include <netdev.h>
 #include <exports.h>
 #include <fsl-mc/fsl_mc.h>
+#include "lx2160a.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -36,3 +37,109 @@ void reset_phy(void)
 #endif
 }
 #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);
+}
diff --git a/board/freescale/lx2160a/lx2160a.c 
b/board/freescale/lx2160a/lx2160a.c
index 4d406ac8f1c6..d631a11ff667 100644
--- a/board/freescale/lx2160a/lx2160a.c
+++ b/board/freescale/lx2160a/lx2160a.c
@@ -133,6 +133,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
@@ -636,6 +641,8 @@ void fdt_fixup_board_enet(void *fdt)
        if (get_mc_boot_status() == 0 &&
            (is_lazy_dpl_addr_valid() || get_dpl_apply_status() == 0)) {
                fdt_status_okay(fdt, offset);
+               if (IS_ENABLED(CONFIG_TARGET_LX2160ARDB))
+                       fdt_fixup_board_phy_revc(fdt);
        } else {
                fdt_status_fail(fdt, offset);
        }
diff --git a/board/freescale/lx2160a/lx2160a.h 
b/board/freescale/lx2160a/lx2160a.h
index 4aac99e576a4..1cd0af538168 100644
--- a/board/freescale/lx2160a/lx2160a.h
+++ b/board/freescale/lx2160a/lx2160a.h
@@ -60,6 +60,7 @@
 
 #if IS_ENABLED(CONFIG_TARGET_LX2160ARDB)
 u8 get_board_rev(void);
+int fdt_fixup_board_phy_revc(void *fdt);
 #endif
 
 #endif /* __LX2160_H */
diff --git a/include/configs/lx2160ardb.h b/include/configs/lx2160ardb.h
index 8cc4e0db03f0..6404b359111f 100644
--- a/include/configs/lx2160ardb.h
+++ b/include/configs/lx2160ardb.h
@@ -11,6 +11,11 @@
 /* RTC */
 #define CFG_SYS_RTC_BUS_NUM            4
 
+#if defined(CONFIG_FSL_MC_ENET)
+#define AQR113C_PHY_ADDR1              0x0
+#define AQR113C_PHY_ADDR2              0x08
+#endif
+
 /* EMC2305 */
 #define I2C_MUX_CH_EMC2305             0x09
 #define I2C_EMC2305_ADDR               0x4D
-- 
2.25.1

Reply via email to