Merge git://git.denx.de/u-boot-fdt
authorTom Rini <trini@konsulko.com>
Fri, 14 Oct 2016 00:03:33 +0000 (20:03 -0400)
committerTom Rini <trini@konsulko.com>
Fri, 14 Oct 2016 00:03:33 +0000 (20:03 -0400)
1  2 
drivers/net/cpsw.c

diff --combined drivers/net/cpsw.c
@@@ -225,18 -225,6 +225,18 @@@ struct cpdma_chan 
        void                    *hdp, *cp, *rxfree;
  };
  
 +/* AM33xx SoC specific definitions for the CONTROL port */
 +#define AM33XX_GMII_SEL_MODE_MII      0
 +#define AM33XX_GMII_SEL_MODE_RMII     1
 +#define AM33XX_GMII_SEL_MODE_RGMII    2
 +
 +#define AM33XX_GMII_SEL_RGMII1_IDMODE BIT(4)
 +#define AM33XX_GMII_SEL_RGMII2_IDMODE BIT(5)
 +#define AM33XX_GMII_SEL_RMII1_IO_CLK_EN       BIT(6)
 +#define AM33XX_GMII_SEL_RMII2_IO_CLK_EN       BIT(7)
 +
 +#define GMII_SEL_MODE_MASK            0x3
 +
  #define desc_write(desc, fld, val)    __raw_writel((u32)(val), &(desc)->fld)
  #define desc_read(desc, fld)          __raw_readl(&(desc)->fld)
  #define desc_read_ptr(desc, fld)      ((void *)__raw_readl(&(desc)->fld))
@@@ -1162,129 -1150,12 +1162,129 @@@ static inline fdt_addr_t cpsw_get_addr_
                                                  false);
  }
  
 +static void cpsw_gmii_sel_am3352(struct cpsw_priv *priv,
 +                               phy_interface_t phy_mode)
 +{
 +      u32 reg;
 +      u32 mask;
 +      u32 mode = 0;
 +      bool rgmii_id = false;
 +      int slave = priv->data.active_slave;
 +
 +      reg = readl(priv->data.gmii_sel);
 +
 +      switch (phy_mode) {
 +      case PHY_INTERFACE_MODE_RMII:
 +              mode = AM33XX_GMII_SEL_MODE_RMII;
 +              break;
 +
 +      case PHY_INTERFACE_MODE_RGMII:
 +              mode = AM33XX_GMII_SEL_MODE_RGMII;
 +              break;
 +      case PHY_INTERFACE_MODE_RGMII_ID:
 +      case PHY_INTERFACE_MODE_RGMII_RXID:
 +      case PHY_INTERFACE_MODE_RGMII_TXID:
 +              mode = AM33XX_GMII_SEL_MODE_RGMII;
 +              rgmii_id = true;
 +              break;
 +
 +      case PHY_INTERFACE_MODE_MII:
 +      default:
 +              mode = AM33XX_GMII_SEL_MODE_MII;
 +              break;
 +      };
 +
 +      mask = GMII_SEL_MODE_MASK << (slave * 2) | BIT(slave + 6);
 +      mode <<= slave * 2;
 +
 +      if (priv->data.rmii_clock_external) {
 +              if (slave == 0)
 +                      mode |= AM33XX_GMII_SEL_RMII1_IO_CLK_EN;
 +              else
 +                      mode |= AM33XX_GMII_SEL_RMII2_IO_CLK_EN;
 +      }
 +
 +      if (rgmii_id) {
 +              if (slave == 0)
 +                      mode |= AM33XX_GMII_SEL_RGMII1_IDMODE;
 +              else
 +                      mode |= AM33XX_GMII_SEL_RGMII2_IDMODE;
 +      }
 +
 +      reg &= ~mask;
 +      reg |= mode;
 +
 +      writel(reg, priv->data.gmii_sel);
 +}
 +
 +static void cpsw_gmii_sel_dra7xx(struct cpsw_priv *priv,
 +                               phy_interface_t phy_mode)
 +{
 +      u32 reg;
 +      u32 mask;
 +      u32 mode = 0;
 +      int slave = priv->data.active_slave;
 +
 +      reg = readl(priv->data.gmii_sel);
 +
 +      switch (phy_mode) {
 +      case PHY_INTERFACE_MODE_RMII:
 +              mode = AM33XX_GMII_SEL_MODE_RMII;
 +              break;
 +
 +      case PHY_INTERFACE_MODE_RGMII:
 +      case PHY_INTERFACE_MODE_RGMII_ID:
 +      case PHY_INTERFACE_MODE_RGMII_RXID:
 +      case PHY_INTERFACE_MODE_RGMII_TXID:
 +              mode = AM33XX_GMII_SEL_MODE_RGMII;
 +              break;
 +
 +      case PHY_INTERFACE_MODE_MII:
 +      default:
 +              mode = AM33XX_GMII_SEL_MODE_MII;
 +              break;
 +      };
 +
 +      switch (slave) {
 +      case 0:
 +              mask = GMII_SEL_MODE_MASK;
 +              break;
 +      case 1:
 +              mask = GMII_SEL_MODE_MASK << 4;
 +              mode <<= 4;
 +              break;
 +      default:
 +              dev_err(priv->dev, "invalid slave number...\n");
 +              return;
 +      }
 +
 +      if (priv->data.rmii_clock_external)
 +              dev_err(priv->dev, "RMII External clock is not supported\n");
 +
 +      reg &= ~mask;
 +      reg |= mode;
 +
 +      writel(reg, priv->data.gmii_sel);
 +}
 +
 +static void cpsw_phy_sel(struct cpsw_priv *priv, const char *compat,
 +                       phy_interface_t phy_mode)
 +{
 +      if (!strcmp(compat, "ti,am3352-cpsw-phy-sel"))
 +              cpsw_gmii_sel_am3352(priv, phy_mode);
 +      if (!strcmp(compat, "ti,am43xx-cpsw-phy-sel"))
 +              cpsw_gmii_sel_am3352(priv, phy_mode);
 +      else if (!strcmp(compat, "ti,dra7xx-cpsw-phy-sel"))
 +              cpsw_gmii_sel_dra7xx(priv, phy_mode);
 +}
 +
  static int cpsw_eth_ofdata_to_platdata(struct udevice *dev)
  {
        struct eth_pdata *pdata = dev_get_platdata(dev);
        struct cpsw_priv *priv = dev_get_priv(dev);
        struct gpio_desc *mode_gpios;
        const char *phy_mode;
 +      const char *phy_sel_compat = NULL;
        const void *fdt = gd->fdt_blob;
        int node = dev->of_offset;
        int subnode;
        active_slave = fdtdec_get_int(fdt, node, "active_slave", 0);
        priv->data.active_slave = active_slave;
  
-       fdt_for_each_subnode(fdt, subnode, node) {
+       fdt_for_each_subnode(subnode, fdt, node) {
                int len;
                const char *name;
  
                                error("Not able to get gmii_sel reg address\n");
                                return -ENOENT;
                        }
 +
 +                      if (fdt_get_property(fdt, subnode, "rmii-clock-ext",
 +                                           NULL))
 +                              priv->data.rmii_clock_external = true;
 +
 +                      phy_sel_compat = fdt_getprop(fdt, subnode, "compatible",
 +                                                   NULL);
 +                      if (!phy_sel_compat) {
 +                              error("Not able to get gmii_sel compatible\n");
 +                              return -ENOENT;
 +                      }
                }
        }
  
                debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode);
                return -EINVAL;
        }
 -      switch (pdata->phy_interface) {
 -      case PHY_INTERFACE_MODE_MII:
 -              writel(MII_MODE_ENABLE, priv->data.gmii_sel);
 -              break;
 -      case PHY_INTERFACE_MODE_RMII:
 -              writel(RMII_MODE_ENABLE, priv->data.gmii_sel);
 -              break;
 -      case PHY_INTERFACE_MODE_RGMII:
 -      case PHY_INTERFACE_MODE_RGMII_ID:
 -      case PHY_INTERFACE_MODE_RGMII_RXID:
 -      case PHY_INTERFACE_MODE_RGMII_TXID:
 -              writel(RGMII_MODE_ENABLE, priv->data.gmii_sel);
 -              break;
 -      }
 +
 +      /* Select phy interface in control module */
 +      cpsw_phy_sel(priv, phy_sel_compat, pdata->phy_interface);
  
        return 0;
  }