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