Merge branch 'master' of git://git.denx.de/u-boot-net

Signed-off-by: Tom Rini <trini@konsulko.com>

Conflicts:
	drivers/net/zynq_gem.c
This commit is contained in:
Tom Rini
2016-05-24 11:59:02 -04:00
22 changed files with 1341 additions and 631 deletions

View File

@@ -59,7 +59,7 @@ obj-$(CONFIG_SMC91111) += smc91111.o
obj-$(CONFIG_SMC911X) += smc911x.o
obj-$(CONFIG_DRIVER_TI_EMAC) += davinci_emac.o
obj-$(CONFIG_TSEC_ENET) += tsec.o fsl_mdio.o
obj-$(CONFIG_DRIVER_TI_CPSW) += cpsw.o
obj-$(CONFIG_DRIVER_TI_CPSW) += cpsw.o cpsw-common.o
obj-$(CONFIG_FMAN_ENET) += fsl_mdio.o
obj-$(CONFIG_TSI108_ETH) += tsi108_eth.o
obj-$(CONFIG_ULI526X) += uli526x.o

121
drivers/net/cpsw-common.c Normal file
View File

@@ -0,0 +1,121 @@
/*
* CPSW common - libs used across TI ethernet devices.
*
* Copyright (C) 2016, Texas Instruments, Incorporated
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <dm.h>
#include <fdt_support.h>
#include <asm/io.h>
#include <cpsw.h>
DECLARE_GLOBAL_DATA_PTR;
#define CTRL_MAC_REG(offset, id) ((offset) + 0x8 * (id))
static int davinci_emac_3517_get_macid(struct udevice *dev, u16 offset,
int slave, u8 *mac_addr)
{
void *fdt = (void *)gd->fdt_blob;
int node = dev->of_offset;
u32 macid_lsb;
u32 macid_msb;
fdt32_t gmii = 0;
int syscon;
u32 addr;
syscon = fdtdec_lookup_phandle(fdt, node, "syscon");
if (syscon < 0) {
error("Syscon offset not found\n");
return -ENOENT;
}
addr = (u32)map_physmem(fdt_translate_address(fdt, syscon, &gmii),
sizeof(u32), MAP_NOCACHE);
if (addr == FDT_ADDR_T_NONE) {
error("Not able to get syscon address to get mac efuse address\n");
return -ENOENT;
}
addr += CTRL_MAC_REG(offset, slave);
/* try reading mac address from efuse */
macid_lsb = readl(addr);
macid_msb = readl(addr + 4);
mac_addr[0] = (macid_msb >> 16) & 0xff;
mac_addr[1] = (macid_msb >> 8) & 0xff;
mac_addr[2] = macid_msb & 0xff;
mac_addr[3] = (macid_lsb >> 16) & 0xff;
mac_addr[4] = (macid_lsb >> 8) & 0xff;
mac_addr[5] = macid_lsb & 0xff;
return 0;
}
static int cpsw_am33xx_cm_get_macid(struct udevice *dev, u16 offset, int slave,
u8 *mac_addr)
{
void *fdt = (void *)gd->fdt_blob;
int node = dev->of_offset;
u32 macid_lo;
u32 macid_hi;
fdt32_t gmii = 0;
int syscon;
u32 addr;
syscon = fdtdec_lookup_phandle(fdt, node, "syscon");
if (syscon < 0) {
error("Syscon offset not found\n");
return -ENOENT;
}
addr = (u32)map_physmem(fdt_translate_address(fdt, syscon, &gmii),
sizeof(u32), MAP_NOCACHE);
if (addr == FDT_ADDR_T_NONE) {
error("Not able to get syscon address to get mac efuse address\n");
return -ENOENT;
}
addr += CTRL_MAC_REG(offset, slave);
/* try reading mac address from efuse */
macid_lo = readl(addr);
macid_hi = readl(addr + 4);
mac_addr[5] = (macid_lo >> 8) & 0xff;
mac_addr[4] = macid_lo & 0xff;
mac_addr[3] = (macid_hi >> 24) & 0xff;
mac_addr[2] = (macid_hi >> 16) & 0xff;
mac_addr[1] = (macid_hi >> 8) & 0xff;
mac_addr[0] = macid_hi & 0xff;
return 0;
}
int ti_cm_get_macid(struct udevice *dev, int slave, u8 *mac_addr)
{
if (of_machine_is_compatible("ti,dm8148"))
return cpsw_am33xx_cm_get_macid(dev, 0x630, slave, mac_addr);
if (of_machine_is_compatible("ti,am33xx"))
return cpsw_am33xx_cm_get_macid(dev, 0x630, slave, mac_addr);
if (of_device_is_compatible(dev, "ti,am3517-emac"))
return davinci_emac_3517_get_macid(dev, 0x110, slave, mac_addr);
if (of_device_is_compatible(dev, "ti,dm816-emac"))
return cpsw_am33xx_cm_get_macid(dev, 0x30, slave, mac_addr);
if (of_machine_is_compatible("ti,am4372"))
return cpsw_am33xx_cm_get_macid(dev, 0x630, slave, mac_addr);
if (of_machine_is_compatible("ti,dra7"))
return davinci_emac_3517_get_macid(dev, 0x514, slave, mac_addr);
dev_err(dev, "incompatible machine/device type for reading mac address\n");
return -ENOENT;
}

View File

@@ -26,6 +26,7 @@
#include <phy.h>
#include <asm/arch/cpu.h>
#include <dm.h>
#include <fdt_support.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -965,6 +966,11 @@ static int cpsw_phy_init(struct cpsw_priv *priv, struct cpsw_slave *slave)
phydev->supported &= supported;
phydev->advertising = phydev->supported;
#ifdef CONFIG_DM_ETH
if (slave->data->phy_of_handle)
phydev->dev->of_offset = slave->data->phy_of_handle;
#endif
priv->phydev = phydev;
phy_config(phydev);
@@ -1137,6 +1143,11 @@ static const struct eth_ops cpsw_eth_ops = {
.stop = cpsw_eth_stop,
};
static inline fdt_addr_t cpsw_get_addr_by_node(const void *fdt, int node)
{
return fdtdec_get_addr_size_auto_noparent(fdt, node, "reg", 0, NULL);
}
static int cpsw_eth_ofdata_to_platdata(struct udevice *dev)
{
struct eth_pdata *pdata = dev_get_platdata(dev);
@@ -1146,9 +1157,8 @@ static int cpsw_eth_ofdata_to_platdata(struct udevice *dev)
int node = dev->of_offset;
int subnode;
int slave_index = 0;
uint32_t mac_hi, mac_lo;
fdt32_t gmii = 0;
int active_slave;
int ret;
pdata->iobase = dev_get_addr(dev);
priv->data.version = CPSW_CTRL_VERSION_2;
@@ -1202,29 +1212,52 @@ static int cpsw_eth_ofdata_to_platdata(struct udevice *dev)
name = fdt_get_name(fdt, subnode, &len);
if (!strncmp(name, "mdio", 4)) {
priv->data.mdio_base = fdtdec_get_addr(fdt, subnode,
"reg");
u32 mdio_base;
mdio_base = cpsw_get_addr_by_node(fdt, subnode);
if (mdio_base == FDT_ADDR_T_NONE) {
error("Not able to get MDIO address space\n");
return -ENOENT;
}
priv->data.mdio_base = mdio_base;
}
if (!strncmp(name, "slave", 5)) {
u32 phy_id[2];
if (slave_index >= priv->data.slaves) {
printf("error: num slaves and slave nodes did not match\n");
return -EINVAL;
}
if (slave_index >= priv->data.slaves)
continue;
phy_mode = fdt_getprop(fdt, subnode, "phy-mode", NULL);
if (phy_mode)
priv->data.slave_data[slave_index].phy_if =
phy_get_interface_by_name(phy_mode);
fdtdec_get_int_array(fdt, subnode, "phy_id", phy_id, 2);
priv->data.slave_data[slave_index].phy_addr = phy_id[1];
priv->data.slave_data[slave_index].phy_of_handle =
fdtdec_lookup_phandle(fdt, subnode,
"phy-handle");
if (priv->data.slave_data[slave_index].phy_of_handle >= 0) {
priv->data.slave_data[slave_index].phy_addr =
fdtdec_get_int(gd->fdt_blob,
priv->data.slave_data[slave_index].phy_of_handle,
"reg", -1);
} else {
fdtdec_get_int_array(fdt, subnode, "phy_id",
phy_id, 2);
priv->data.slave_data[slave_index].phy_addr =
phy_id[1];
}
slave_index++;
}
if (!strncmp(name, "cpsw-phy-sel", 12)) {
priv->data.gmii_sel = fdtdec_get_addr(fdt, subnode,
"reg");
priv->data.gmii_sel = cpsw_get_addr_by_node(fdt,
subnode);
if (priv->data.gmii_sel == FDT_ADDR_T_NONE) {
error("Not able to get gmii_sel reg address\n");
return -ENOENT;
}
}
}
@@ -1236,20 +1269,11 @@ static int cpsw_eth_ofdata_to_platdata(struct udevice *dev)
priv->data.slave_data[1].sliver_reg_ofs = CPSW_SLIVER1_OFFSET;
}
subnode = fdtdec_lookup_phandle(fdt, node, "syscon");
priv->data.mac_id = fdt_translate_address((void *)fdt, subnode, &gmii);
priv->data.mac_id += AM335X_GMII_SEL_OFFSET;
priv->data.mac_id += active_slave * 8;
/* try reading mac address from efuse */
mac_lo = readl(priv->data.mac_id);
mac_hi = readl(priv->data.mac_id + 4);
pdata->enetaddr[0] = mac_hi & 0xFF;
pdata->enetaddr[1] = (mac_hi & 0xFF00) >> 8;
pdata->enetaddr[2] = (mac_hi & 0xFF0000) >> 16;
pdata->enetaddr[3] = (mac_hi & 0xFF000000) >> 24;
pdata->enetaddr[4] = mac_lo & 0xFF;
pdata->enetaddr[5] = (mac_lo & 0xFF00) >> 8;
ret = ti_cm_get_macid(dev, active_slave, pdata->enetaddr);
if (ret < 0) {
error("cpsw read efuse mac failed\n");
return ret;
}
pdata->phy_interface = priv->data.slave_data[active_slave].phy_if;
if (pdata->phy_interface == -1) {
@@ -1270,6 +1294,7 @@ static int cpsw_eth_ofdata_to_platdata(struct udevice *dev)
writel(RGMII_MODE_ENABLE, priv->data.gmii_sel);
break;
}
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,61 +0,0 @@
/*
* (C) Copyright 2009
* Marvell Semiconductor <www.marvell.com>
* Prafulla Wadaskar <prafulla@marvell.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _MV88E61XX_H
#define _MV88E61XX_H
#include <miiphy.h>
#define MV88E61XX_CPU_PORT 0x5
#define MV88E61XX_PHY_TIMEOUT 100000
/* port dev-addr (= port + 0x10) */
#define MV88E61XX_PRT_OFST 0x10
/* port registers */
#define MV88E61XX_PCS_CTRL_REG 0x1
#define MV88E61XX_PRT_CTRL_REG 0x4
#define MV88E61XX_PRT_VMAP_REG 0x6
#define MV88E61XX_PRT_VID_REG 0x7
#define MV88E61XX_RGMII_TIMECTRL_REG 0x1A
/* global registers dev-addr */
#define MV88E61XX_GLBREG_DEVADR 0x1B
/* global registers */
#define MV88E61XX_SGSR 0x00
#define MV88E61XX_SGCR 0x04
/* global 2 registers dev-addr */
#define MV88E61XX_GLB2REG_DEVADR 0x1C
/* global 2 registers */
#define MV88E61XX_PHY_CMD 0x18
#define MV88E61XX_PHY_DATA 0x19
/* global 2 phy commands */
#define MV88E61XX_PHY_WRITE_CMD 0x9400
#define MV88E61XX_PHY_READ_CMD 0x9800
#define MV88E61XX_BUSY_OFST 15
#define MV88E61XX_MODE_OFST 12
#define MV88E61XX_OP_OFST 10
#define MV88E61XX_ADDR_OFST 5
#ifdef CONFIG_MV88E61XX_MULTICHIP_ADRMODE
static int mv88e61xx_busychk_multic(char *name, u32 devaddr);
static void mv88e61xx_switch_write(char *name, u32 phy_adr,
u32 reg_ofs, u16 data);
static void mv88e61xx_switch_read(char *name, u32 phy_adr,
u32 reg_ofs, u16 *data);
#define wr_switch_reg mv88e61xx_switch_write
#define rd_switch_reg mv88e61xx_switch_read
#else
/* switch appears a s simple PHY and can thus use miiphy */
#define wr_switch_reg miiphy_write
#define rd_switch_reg miiphy_read
#endif /* CONFIG_MV88E61XX_MULTICHIP_ADRMODE */
#endif /* _MV88E61XX_H */

View File

@@ -461,6 +461,9 @@ static LIST_HEAD(phy_drivers);
int phy_init(void)
{
#ifdef CONFIG_MV88E61XX_SWITCH
phy_mv88e61xx_init();
#endif
#ifdef CONFIG_PHY_AQUANTIA
phy_aquantia_init();
#endif

View File

@@ -6,6 +6,14 @@
*/
#include <common.h>
#include <phy.h>
#include <linux/compat.h>
#include <malloc.h>
#include <fdtdec.h>
#include <dm.h>
#include <dt-bindings/net/ti-dp83867.h>
DECLARE_GLOBAL_DATA_PTR;
/* TI DP83867 */
#define DP83867_DEVADDR 0x1f
@@ -71,6 +79,17 @@
#define MII_MMD_CTRL_INCR_RDWT 0x8000 /* post increment on reads & writes */
#define MII_MMD_CTRL_INCR_ON_WT 0xC000 /* post increment on writes only */
/* User setting - can be taken from DTS */
#define DEFAULT_RX_ID_DELAY DP83867_RGMIIDCTL_2_25_NS
#define DEFAULT_TX_ID_DELAY DP83867_RGMIIDCTL_2_75_NS
#define DEFAULT_FIFO_DEPTH DP83867_PHYCR_FIFO_DEPTH_4_B_NIB
struct dp83867_private {
int rx_id_delay;
int tx_id_delay;
int fifo_depth;
};
/**
* phy_read_mmd_indirect - reads data from the MMD registers
* @phydev: The PHY device bus
@@ -137,27 +156,60 @@ void phy_write_mmd_indirect(struct phy_device *phydev, int prtad,
phy_write(phydev, addr, MII_MMD_DATA, data);
}
#if defined(CONFIG_DM_ETH)
/**
* phy_interface_is_rgmii - Convenience function for testing if a PHY interface
* is RGMII (all variants)
* dp83867_data_init - Convenience function for setting PHY specific data
*
* @phydev: the phy_device struct
*/
static inline bool phy_interface_is_rgmii(struct phy_device *phydev)
static int dp83867_of_init(struct phy_device *phydev)
{
return phydev->interface >= PHY_INTERFACE_MODE_RGMII &&
phydev->interface <= PHY_INTERFACE_MODE_RGMII_TXID;
}
struct dp83867_private *dp83867 = phydev->priv;
struct udevice *dev = phydev->dev;
/* User setting - can be taken from DTS */
#define RX_ID_DELAY 8
#define TX_ID_DELAY 0xa
#define FIFO_DEPTH 1
dp83867->rx_id_delay = fdtdec_get_uint(gd->fdt_blob, dev->of_offset,
"ti,rx-internal-delay", -1);
dp83867->tx_id_delay = fdtdec_get_uint(gd->fdt_blob, dev->of_offset,
"ti,tx-internal-delay", -1);
dp83867->fifo_depth = fdtdec_get_uint(gd->fdt_blob, dev->of_offset,
"ti,fifo-depth", -1);
return 0;
}
#else
static int dp83867_of_init(struct phy_device *phydev)
{
struct dp83867_private *dp83867 = phydev->priv;
dp83867->rx_id_delay = DEFAULT_RX_ID_DELAY;
dp83867->tx_id_delay = DEFAULT_TX_ID_DELAY;
dp83867->fifo_depth = DEFAULT_FIFO_DEPTH;
return 0;
}
#endif
static int dp83867_config(struct phy_device *phydev)
{
struct dp83867_private *dp83867;
unsigned int val, delay, cfg2;
int ret;
if (!phydev->priv) {
dp83867 = kzalloc(sizeof(*dp83867), GFP_KERNEL);
if (!dp83867)
return -ENOMEM;
phydev->priv = dp83867;
ret = dp83867_of_init(phydev);
if (ret)
goto err_out;
} else {
dp83867 = (struct dp83867_private *)phydev->priv;
}
/* Restart the PHY. */
val = phy_read(phydev, MDIO_DEVAD_NONE, DP83867_CTRL);
phy_write(phydev, MDIO_DEVAD_NONE, DP83867_CTRL,
@@ -166,10 +218,10 @@ static int dp83867_config(struct phy_device *phydev)
if (phy_interface_is_rgmii(phydev)) {
ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83867_PHYCTRL,
(DP83867_MDI_CROSSOVER_AUTO << DP83867_MDI_CROSSOVER) |
(FIFO_DEPTH << DP83867_PHYCR_FIFO_DEPTH_SHIFT));
(dp83867->fifo_depth << DP83867_PHYCR_FIFO_DEPTH_SHIFT));
if (ret)
return ret;
} else {
goto err_out;
} else if (phy_interface_is_sgmii(phydev)) {
phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR,
(BMCR_ANENABLE | BMCR_FULLDPLX | BMCR_SPEED1000));
@@ -189,8 +241,8 @@ static int dp83867_config(struct phy_device *phydev)
DP83867_PHYCTRL_SGMIIEN |
(DP83867_MDI_CROSSOVER_MDIX <<
DP83867_MDI_CROSSOVER) |
(FIFO_DEPTH << DP83867_PHYCTRL_RXFIFO_SHIFT) |
(FIFO_DEPTH << DP83867_PHYCTRL_TXFIFO_SHIFT));
(dp83867->fifo_depth << DP83867_PHYCTRL_RXFIFO_SHIFT) |
(dp83867->fifo_depth << DP83867_PHYCTRL_TXFIFO_SHIFT));
phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83867_BISCR, 0x0);
}
@@ -212,8 +264,8 @@ static int dp83867_config(struct phy_device *phydev)
phy_write_mmd_indirect(phydev, DP83867_RGMIICTL,
DP83867_DEVADDR, phydev->addr, val);
delay = (RX_ID_DELAY |
(TX_ID_DELAY << DP83867_RGMII_TX_CLK_DELAY_SHIFT));
delay = (dp83867->rx_id_delay |
(dp83867->tx_id_delay << DP83867_RGMII_TX_CLK_DELAY_SHIFT));
phy_write_mmd_indirect(phydev, DP83867_RGMIIDCTL,
DP83867_DEVADDR, phydev->addr, delay);
@@ -221,6 +273,10 @@ static int dp83867_config(struct phy_device *phydev)
genphy_config_aneg(phydev);
return 0;
err_out:
kfree(dp83867);
return ret;
}
static struct phy_driver DP83867_driver = {

View File

@@ -179,6 +179,7 @@ struct zynq_gem_priv {
struct zynq_gem_regs *iobase;
phy_interface_t interface;
struct phy_device *phydev;
int phy_of_handle;
struct mii_dev *bus;
};
@@ -353,6 +354,9 @@ static int zynq_phy_init(struct udevice *dev)
ADVERTISED_Asym_Pause;
priv->phydev->advertising = priv->phydev->supported;
if (priv->phy_of_handle > 0)
priv->phydev->dev->of_offset = priv->phy_of_handle;
return phy_config(priv->phydev);
}
@@ -677,7 +681,6 @@ static int zynq_gem_ofdata_to_platdata(struct udevice *dev)
{
struct eth_pdata *pdata = dev_get_platdata(dev);
struct zynq_gem_priv *priv = dev_get_priv(dev);
int offset = 0;
const char *phy_mode;
pdata->iobase = (phys_addr_t)dev_get_addr(dev);
@@ -686,10 +689,11 @@ static int zynq_gem_ofdata_to_platdata(struct udevice *dev)
priv->emio = 0;
priv->phyaddr = -1;
offset = fdtdec_lookup_phandle(gd->fdt_blob, dev->of_offset,
"phy-handle");
if (offset > 0)
priv->phyaddr = fdtdec_get_int(gd->fdt_blob, offset, "reg", -1);
priv->phy_of_handle = fdtdec_lookup_phandle(gd->fdt_blob,
dev->of_offset, "phy-handle");
if (priv->phy_of_handle > 0)
priv->phyaddr = fdtdec_get_int(gd->fdt_blob,
priv->phy_of_handle, "reg", -1);
phy_mode = fdt_getprop(gd->fdt_blob, dev->of_offset, "phy-mode", NULL);
if (phy_mode)