1e4310566SMugunthan V N /* 2e4310566SMugunthan V N * CPSW common - libs used across TI ethernet devices. 3e4310566SMugunthan V N * 4e4310566SMugunthan V N * Copyright (C) 2016, Texas Instruments, Incorporated 5e4310566SMugunthan V N * 6e4310566SMugunthan V N * SPDX-License-Identifier: GPL-2.0+ 7e4310566SMugunthan V N */ 8e4310566SMugunthan V N 9e4310566SMugunthan V N #include <common.h> 10e4310566SMugunthan V N #include <dm.h> 11e4310566SMugunthan V N #include <fdt_support.h> 12e4310566SMugunthan V N #include <asm/io.h> 13e4310566SMugunthan V N #include <cpsw.h> 14e4310566SMugunthan V N 15e4310566SMugunthan V N DECLARE_GLOBAL_DATA_PTR; 16e4310566SMugunthan V N 17e4310566SMugunthan V N #define CTRL_MAC_REG(offset, id) ((offset) + 0x8 * (id)) 18e4310566SMugunthan V N 19e4310566SMugunthan V N static int davinci_emac_3517_get_macid(struct udevice *dev, u16 offset, 20e4310566SMugunthan V N int slave, u8 *mac_addr) 21e4310566SMugunthan V N { 22e4310566SMugunthan V N void *fdt = (void *)gd->fdt_blob; 23*e160f7d4SSimon Glass int node = dev_of_offset(dev); 24e4310566SMugunthan V N u32 macid_lsb; 25e4310566SMugunthan V N u32 macid_msb; 26e4310566SMugunthan V N fdt32_t gmii = 0; 27e4310566SMugunthan V N int syscon; 28e4310566SMugunthan V N u32 addr; 29e4310566SMugunthan V N 30e4310566SMugunthan V N syscon = fdtdec_lookup_phandle(fdt, node, "syscon"); 31e4310566SMugunthan V N if (syscon < 0) { 32e4310566SMugunthan V N error("Syscon offset not found\n"); 33e4310566SMugunthan V N return -ENOENT; 34e4310566SMugunthan V N } 35e4310566SMugunthan V N 36e4310566SMugunthan V N addr = (u32)map_physmem(fdt_translate_address(fdt, syscon, &gmii), 37e4310566SMugunthan V N sizeof(u32), MAP_NOCACHE); 38e4310566SMugunthan V N if (addr == FDT_ADDR_T_NONE) { 39e4310566SMugunthan V N error("Not able to get syscon address to get mac efuse address\n"); 40e4310566SMugunthan V N return -ENOENT; 41e4310566SMugunthan V N } 42e4310566SMugunthan V N 43e4310566SMugunthan V N addr += CTRL_MAC_REG(offset, slave); 44e4310566SMugunthan V N 45e4310566SMugunthan V N /* try reading mac address from efuse */ 46e4310566SMugunthan V N macid_lsb = readl(addr); 47e4310566SMugunthan V N macid_msb = readl(addr + 4); 48e4310566SMugunthan V N 49e4310566SMugunthan V N mac_addr[0] = (macid_msb >> 16) & 0xff; 50e4310566SMugunthan V N mac_addr[1] = (macid_msb >> 8) & 0xff; 51e4310566SMugunthan V N mac_addr[2] = macid_msb & 0xff; 52e4310566SMugunthan V N mac_addr[3] = (macid_lsb >> 16) & 0xff; 53e4310566SMugunthan V N mac_addr[4] = (macid_lsb >> 8) & 0xff; 54e4310566SMugunthan V N mac_addr[5] = macid_lsb & 0xff; 55e4310566SMugunthan V N 56e4310566SMugunthan V N return 0; 57e4310566SMugunthan V N } 58e4310566SMugunthan V N 59e4310566SMugunthan V N static int cpsw_am33xx_cm_get_macid(struct udevice *dev, u16 offset, int slave, 60e4310566SMugunthan V N u8 *mac_addr) 61e4310566SMugunthan V N { 62e4310566SMugunthan V N void *fdt = (void *)gd->fdt_blob; 63*e160f7d4SSimon Glass int node = dev_of_offset(dev); 64e4310566SMugunthan V N u32 macid_lo; 65e4310566SMugunthan V N u32 macid_hi; 66e4310566SMugunthan V N fdt32_t gmii = 0; 67e4310566SMugunthan V N int syscon; 68e4310566SMugunthan V N u32 addr; 69e4310566SMugunthan V N 70e4310566SMugunthan V N syscon = fdtdec_lookup_phandle(fdt, node, "syscon"); 71e4310566SMugunthan V N if (syscon < 0) { 72e4310566SMugunthan V N error("Syscon offset not found\n"); 73e4310566SMugunthan V N return -ENOENT; 74e4310566SMugunthan V N } 75e4310566SMugunthan V N 76e4310566SMugunthan V N addr = (u32)map_physmem(fdt_translate_address(fdt, syscon, &gmii), 77e4310566SMugunthan V N sizeof(u32), MAP_NOCACHE); 78e4310566SMugunthan V N if (addr == FDT_ADDR_T_NONE) { 79e4310566SMugunthan V N error("Not able to get syscon address to get mac efuse address\n"); 80e4310566SMugunthan V N return -ENOENT; 81e4310566SMugunthan V N } 82e4310566SMugunthan V N 83e4310566SMugunthan V N addr += CTRL_MAC_REG(offset, slave); 84e4310566SMugunthan V N 85e4310566SMugunthan V N /* try reading mac address from efuse */ 86e4310566SMugunthan V N macid_lo = readl(addr); 87e4310566SMugunthan V N macid_hi = readl(addr + 4); 88e4310566SMugunthan V N 89e4310566SMugunthan V N mac_addr[5] = (macid_lo >> 8) & 0xff; 90e4310566SMugunthan V N mac_addr[4] = macid_lo & 0xff; 91e4310566SMugunthan V N mac_addr[3] = (macid_hi >> 24) & 0xff; 92e4310566SMugunthan V N mac_addr[2] = (macid_hi >> 16) & 0xff; 93e4310566SMugunthan V N mac_addr[1] = (macid_hi >> 8) & 0xff; 94e4310566SMugunthan V N mac_addr[0] = macid_hi & 0xff; 95e4310566SMugunthan V N 96e4310566SMugunthan V N return 0; 97e4310566SMugunthan V N } 98e4310566SMugunthan V N 99e4310566SMugunthan V N int ti_cm_get_macid(struct udevice *dev, int slave, u8 *mac_addr) 100e4310566SMugunthan V N { 101e4310566SMugunthan V N if (of_machine_is_compatible("ti,dm8148")) 102e4310566SMugunthan V N return cpsw_am33xx_cm_get_macid(dev, 0x630, slave, mac_addr); 103e4310566SMugunthan V N 104e4310566SMugunthan V N if (of_machine_is_compatible("ti,am33xx")) 105e4310566SMugunthan V N return cpsw_am33xx_cm_get_macid(dev, 0x630, slave, mac_addr); 106e4310566SMugunthan V N 107e4310566SMugunthan V N if (of_device_is_compatible(dev, "ti,am3517-emac")) 108e4310566SMugunthan V N return davinci_emac_3517_get_macid(dev, 0x110, slave, mac_addr); 109e4310566SMugunthan V N 110e4310566SMugunthan V N if (of_device_is_compatible(dev, "ti,dm816-emac")) 111e4310566SMugunthan V N return cpsw_am33xx_cm_get_macid(dev, 0x30, slave, mac_addr); 112e4310566SMugunthan V N 113e4310566SMugunthan V N if (of_machine_is_compatible("ti,am4372")) 114e4310566SMugunthan V N return cpsw_am33xx_cm_get_macid(dev, 0x630, slave, mac_addr); 115e4310566SMugunthan V N 116e4310566SMugunthan V N if (of_machine_is_compatible("ti,dra7")) 117e4310566SMugunthan V N return davinci_emac_3517_get_macid(dev, 0x514, slave, mac_addr); 118e4310566SMugunthan V N 119e4310566SMugunthan V N dev_err(dev, "incompatible machine/device type for reading mac address\n"); 120e4310566SMugunthan V N return -ENOENT; 121e4310566SMugunthan V N } 122