uboot/board/freescale/common/sgmii_riser.c
<<
>>
Prefs
   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 <linux/libfdt.h>
  19#include <tsec.h>
  20#include <fdt_support.h>
  21
  22void 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
  31void 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}
 130