]> git.sur5r.net Git - u-boot/blobdiff - board/freescale/common/sgmii_riser.c
libfdt: move headers to <linux/libfdt.h> and <linux/libfdt_env.h>
[u-boot] / board / freescale / common / sgmii_riser.c
index aeacb91bc13875c2e874d205c8b2ab4742a3cb18..f3e0fb2cd5e4e06f68684236e75e63d68a03f756 100644 (file)
@@ -15,8 +15,9 @@
 #include <config.h>
 #include <common.h>
 #include <net.h>
-#include <libfdt.h>
+#include <linux/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,17 +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;
 
-               printf("Updating PHY address for %s\n", dev->name);
                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) {
@@ -64,7 +87,6 @@ void fsl_sgmii_riser_fdt_fixup(void *fdt)
 
                model = fdt_getprop(fdt, enet_node, "model", NULL);
 
-               printf("%s's model is %s\n", enet, model);
                /*
                 * We only want to do this to eTSECs.  On some platforms
                 * there are more than one type of gianfar-style ethernet
@@ -76,16 +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;
 
-               printf("Device flags are %x\n", priv->flags);
-               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));
+               }
        }
 }