diff options
Diffstat (limited to 'board/freescale/common')
-rw-r--r-- | board/freescale/common/sgmii_riser.c | 57 |
1 files changed, 49 insertions, 8 deletions
diff --git a/board/freescale/common/sgmii_riser.c b/board/freescale/common/sgmii_riser.c index 4f40a1d6d4..5c3c59375c 100644 --- a/board/freescale/common/sgmii_riser.c +++ b/board/freescale/common/sgmii_riser.c @@ -17,6 +17,7 @@ #include <net.h> #include <libfdt.h> #include <tsec.h> +#include <fdt_support.h> void fsl_sgmii_riser_init(struct tsec_info_struct *tsec_info, int num) { @@ -31,6 +32,7 @@ void fsl_sgmii_riser_fdt_fixup(void *fdt) { struct eth_device *dev; int node; + int mdio_node; int i = -1; int etsec_num = 0; @@ -40,16 +42,38 @@ void fsl_sgmii_riser_fdt_fixup(void *fdt) while ((dev = eth_get_dev_by_index(++i)) != NULL) { struct tsec_private *priv; + int phy_node; int enet_node; + uint32_t ph; + char sgmii_phy[16]; char enet[16]; const u32 *phyh; - int phynode; const char *model; const char *path; if (!strstr(dev->name, "eTSEC")) continue; + priv = dev->priv; + if (!(priv->flags & TSEC_SGMII)) { + etsec_num++; + continue; + } + + mdio_node = fdt_node_offset_by_compatible(fdt, -1, + "fsl,gianfar-mdio"); + if (mdio_node < 0) + return; + + sprintf(sgmii_phy, "sgmii-phy@%d", etsec_num); + phy_node = fdt_subnode_offset(fdt, mdio_node, sgmii_phy); + if (phy_node > 0) { + fdt_increase_size(fdt, 32); + ph = fdt_create_phandle(fdt, phy_node); + if (!ph) + continue; + } + sprintf(enet, "ethernet%d", etsec_num++); path = fdt_getprop(fdt, node, enet, NULL); if (!path) { @@ -74,15 +98,32 @@ void fsl_sgmii_riser_fdt_fixup(void *fdt) if (!strstr(model, "TSEC")) continue; - phyh = fdt_getprop(fdt, enet_node, "phy-handle", NULL); - if (!phyh) - continue; + if (phy_node < 0) { + /* + * This part is only for old device tree without + * sgmii_phy nodes. It's kept just for compatible + * reason. Soon to be deprecated if all device tree + * get updated. + */ + phyh = fdt_getprop(fdt, enet_node, "phy-handle", NULL); + if (!phyh) + continue; - phynode = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*phyh)); + phy_node = fdt_node_offset_by_phandle(fdt, + fdt32_to_cpu(*phyh)); - priv = dev->priv; + priv = dev->priv; - if (priv->flags & TSEC_SGMII) - fdt_setprop_cell(fdt, phynode, "reg", priv->phyaddr); + if (priv->flags & TSEC_SGMII) + fdt_setprop_cell(fdt, phy_node, "reg", + priv->phyaddr); + } else { + fdt_setprop(fdt, enet_node, "phy-handle", &ph, + sizeof(ph)); + fdt_setprop_string(fdt, enet_node, + "phy-connection-type", + phy_string_for_interface( + PHY_INTERFACE_MODE_SGMII)); + } } } |