Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / u-boot / board / freescale / common / sgmii_riser.c
1 /*
2  * Freescale SGMII Riser Card
3  *
4  * This driver supports the SGMII Riser card found on the
5  * "DS" style of development board from Freescale.
6  *
7  * This software may be used and distributed according to the
8  * terms of the GNU Public License, Version 2, incorporated
9  * herein by reference.
10  *
11  * Copyright 2008 Freescale Semiconductor, Inc.
12  *
13  */
14
15 #include <config.h>
16 #include <common.h>
17 #include <net.h>
18 #include <libfdt.h>
19 #include <tsec.h>
20 #include <fdt_support.h>
21
22 void fsl_sgmii_riser_init(struct tsec_info_struct *tsec_info, int num)
23 {
24         int i;
25
26         for (i = 0; i < num; i++)
27                 if (tsec_info[i].flags & TSEC_SGMII)
28                         tsec_info[i].phyaddr += SGMII_RISER_PHY_OFFSET;
29 }
30
31 void fsl_sgmii_riser_fdt_fixup(void *fdt)
32 {
33         struct eth_device *dev;
34         int node;
35         int mdio_node;
36         int i = -1;
37         int etsec_num = 0;
38
39         node = fdt_path_offset(fdt, "/aliases");
40         if (node < 0)
41                 return;
42
43         while ((dev = eth_get_dev_by_index(++i)) != NULL) {
44                 struct tsec_private *priv;
45                 int phy_node;
46                 int enet_node;
47                 uint32_t ph;
48                 char sgmii_phy[16];
49                 char enet[16];
50                 const u32 *phyh;
51                 const char *model;
52                 const char *path;
53
54                 if (!strstr(dev->name, "eTSEC"))
55                         continue;
56
57                 priv = dev->priv;
58                 if (!(priv->flags & TSEC_SGMII)) {
59                         etsec_num++;
60                         continue;
61                 }
62
63                 mdio_node = fdt_node_offset_by_compatible(fdt, -1,
64                                 "fsl,gianfar-mdio");
65                 if (mdio_node < 0)
66                         return;
67
68                 sprintf(sgmii_phy, "sgmii-phy@%d", etsec_num);
69                 phy_node = fdt_subnode_offset(fdt, mdio_node, sgmii_phy);
70                 if (phy_node > 0) {
71                         fdt_increase_size(fdt, 32);
72                         ph = fdt_create_phandle(fdt, phy_node);
73                         if (!ph)
74                                 continue;
75                 }
76
77                 sprintf(enet, "ethernet%d", etsec_num++);
78                 path = fdt_getprop(fdt, node, enet, NULL);
79                 if (!path) {
80                         debug("No alias for %s\n", enet);
81                         continue;
82                 }
83
84                 enet_node = fdt_path_offset(fdt, path);
85                 if (enet_node < 0)
86                         continue;
87
88                 model = fdt_getprop(fdt, enet_node, "model", NULL);
89
90                 /*
91                  * We only want to do this to eTSECs.  On some platforms
92                  * there are more than one type of gianfar-style ethernet
93                  * controller, and as we are creating an implicit connection
94                  * between ethernet nodes and eTSEC devices, it is best to
95                  * make the connection use as much explicit information
96                  * as exists.
97                  */
98                 if (!strstr(model, "TSEC"))
99                         continue;
100
101                 if (phy_node < 0) {
102                         /*
103                          * This part is only for old device tree without
104                          * sgmii_phy nodes. It's kept just for compatible
105                          * reason. Soon to be deprecated if all device tree
106                          * get updated.
107                          */
108                         phyh = fdt_getprop(fdt, enet_node, "phy-handle", NULL);
109                         if (!phyh)
110                                 continue;
111
112                         phy_node = fdt_node_offset_by_phandle(fdt,
113                                         fdt32_to_cpu(*phyh));
114
115                         priv = dev->priv;
116
117                         if (priv->flags & TSEC_SGMII)
118                                 fdt_setprop_cell(fdt, phy_node, "reg",
119                                                 priv->phyaddr);
120                 } else {
121                         fdt_setprop(fdt, enet_node, "phy-handle", &ph,
122                                         sizeof(ph));
123                         fdt_setprop_string(fdt, enet_node,
124                                         "phy-connection-type",
125                                         phy_string_for_interface(
126                                                 PHY_INTERFACE_MODE_SGMII));
127                 }
128         }
129 }