Skip to content
Snippets Groups Projects
Commit e4310566 authored by Mugunthan V N's avatar Mugunthan V N Committed by Joe Hershberger
Browse files

drivers: net: cpsw: add support for reading mac address from efuse


Different TI platforms has to read with different combination to
get the mac address from efuse. So add support to read mac address
based on machine/device compatibles.

The code is taken from Linux drivers/net/ethernet/ti/cpsw-common.c
done by Tony Lindgren.

Signed-off-by: default avatarMugunthan V N <mugunthanvnm@ti.com>
Reviewed-by: default avatarTom Rini <trini@konsulko.com>
Acked-by: default avatarJoe Hershberger <joe.hershberger@ni.com>
parent 66e740cb
No related branches found
No related tags found
No related merge requests found
......@@ -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
......
/*
* 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;
}
......@@ -26,6 +26,7 @@
#include <phy.h>
#include <asm/arch/cpu.h>
#include <dm.h>
#include <fdt_support.h>
DECLARE_GLOBAL_DATA_PTR;
......@@ -1151,9 +1152,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;
......@@ -1250,20 +1250,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) {
......@@ -1284,6 +1275,7 @@ static int cpsw_eth_ofdata_to_platdata(struct udevice *dev)
writel(RGMII_MODE_ENABLE, priv->data.gmii_sel);
break;
}
return 0;
}
......
......@@ -51,5 +51,6 @@ struct cpsw_platform_data {
};
int cpsw_register(struct cpsw_platform_data *data);
int ti_cm_get_macid(struct udevice *dev, int slave, u8 *mac_addr);
#endif /* _CPSW_H_ */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment