/***********************************************************************
* OK335xS mac address hacking
* 声明:
* 在一般的嵌入式产品中,一般mac地址都是存在于CPU芯片中,不过有时候
* 我们也许会表示怀疑,因为我们可能更希望知道那些东西到底存在哪里,以一
* 种什么样的形式存在。
*
* 2016-2-1 深圳 南山平山村 曾剑锋
**********************************************************************/
MACHINE_START(AM335XEVM, "am335xevm")
/* Maintainer: Texas Instruments */
.atag_offset = 0x100,
.map_io = am335x_evm_map_io,
.init_early = am33xx_init_early,
.init_irq = ti81xx_init_irq,
.handle_irq = omap3_intc_handle_irq,
.timer = &omap3_am33xx_timer,
.init_machine = am335x_evm_init, -----------+
MACHINE_END |
|
MACHINE_START(AM335XIAEVM, "am335xiaevm") |
/* Maintainer: Texas Instruments */ |
.atag_offset = 0x100, |
.map_io = am335x_evm_map_io, |
.init_irq = ti81xx_init_irq, |
.init_early = am33xx_init_early, |
.timer = &omap3_am33xx_timer, |
.init_machine = am335x_evm_init, |
MACHINE_END |
|
|
static void __init am335x_evm_init(void) <----------+
{
am33xx_cpuidle_init();
am33xx_mux_init(board_mux);
omap_serial_init();
am335x_evm_i2c_init();
omap_sdrc_init(NULL, NULL);
usb_musb_init(&musb_board_data);
omap_board_config = am335x_evm_config;
omap_board_config_size = ARRAY_SIZE(am335x_evm_config);
_configure_device(EVM_SK, mfd_dev_cfg, PROFILE_NONE);
daughter_brd_detected = false;
setup_zengjf(); ------------------------------+
|
/*create /proc/boardname to export info to userspace*/ |
proc_init(); |
|
/* Create an alias for icss clock */ |
if (clk_add_alias("pruss", NULL, "pruss_uart_gclk", NULL)) |
pr_warn("failed to create an alias: icss_uart_gclk --> pruss\n"); |
/* Create an alias for gfx/sgx clock */ |
if (clk_add_alias("sgx_ck", NULL, "gfx_fclk", NULL)) |
pr_warn("failed to create an alias: gfx_fclk --> sgx_ck\n"); |
} |
|
/* sbc-zengjf */ |
#define TLK110_PHY_ID 0x2000a211 |
#define LAN8710A_PHY_ID 0x7c0f1 |
char sbc_zengjf_phy1[] = {"0:00"}; |
char sbc_zengjf_phy2[] = {"0:01"}; |
|
static void setup_zengjf(void) <--------------------------------+
{
pr_info("The board is a sbc-zengjf.\n");
/*which doesn't have Write Protect pin LAN8710A_PHY_ID */
am335x_mmc[].gpio_wp = -EINVAL;
int ret;
_configure_device(EVM_SK, sbc_zengjf_dev_cfg, PROFILE_NONE);
am33xx_cpsw_init(AM33XX_CPSW_MODE_MII, sbc_zengjf_phy1, sbc_zengjf_phy2); ---+
phy_register_fixup_for_uid(LAN8710A_PHY_ID , AM335X_EVM_PHY_MASK, |
am33xx_evm_tx_clk_dly_phy_fixup); |
} |
|
|
int am33xx_cpsw_init(enum am33xx_cpsw_mac_mode mode, unsigned char *phy_id0, <-+
unsigned char *phy_id1)
{
struct omap_hwmod *oh;
struct platform_device *pdev;
u32 mac_lo, mac_hi, gmii_sel;
u32 i;
mac_lo = omap_ctrl_readl(TI81XX_CONTROL_MAC_ID0_LO);
mac_hi = omap_ctrl_readl(TI81XX_CONTROL_MAC_ID0_HI); ------------+
am33xx_cpsw_slaves[].mac_addr[] = mac_hi & 0xFF; |
am33xx_cpsw_slaves[].mac_addr[] = (mac_hi & 0xFF00) >> ; |
am33xx_cpsw_slaves[].mac_addr[] = (mac_hi & 0xFF0000) >> ; |
am33xx_cpsw_slaves[].mac_addr[] = (mac_hi & 0xFF000000) >> ; |
am33xx_cpsw_slaves[].mac_addr[] = mac_lo & 0xFF; |
am33xx_cpsw_slaves[].mac_addr[] = (mac_lo & 0xFF00) >> ; |
|
/* Read MACID0 from eeprom if eFuse MACID is invalid */ |
if (!is_valid_ether_addr(am33xx_cpsw_slaves[].mac_addr)) { |
for (i = ; i < ETH_ALEN; i++) |
am33xx_cpsw_slaves[].mac_addr[i] = am33xx_macid0[i]; |
} |
|
mac_lo = omap_ctrl_readl(TI81XX_CONTROL_MAC_ID1_LO); |
mac_hi = omap_ctrl_readl(TI81XX_CONTROL_MAC_ID1_HI); |
am33xx_cpsw_slaves[].mac_addr[] = mac_hi & 0xFF; |
am33xx_cpsw_slaves[].mac_addr[] = (mac_hi & 0xFF00) >> ; |
am33xx_cpsw_slaves[].mac_addr[] = (mac_hi & 0xFF0000) >> ; |
am33xx_cpsw_slaves[].mac_addr[] = (mac_hi & 0xFF000000) >> ; |
am33xx_cpsw_slaves[].mac_addr[] = mac_lo & 0xFF; |
am33xx_cpsw_slaves[].mac_addr[] = (mac_lo & 0xFF00) >> ; |
// Read MACID1 from eeprom if eFuse MACID is invalid |
if (!is_valid_ether_addr(am33xx_cpsw_slaves[].mac_addr)) { |
for (i = ; i < ETH_ALEN; i++) |
am33xx_cpsw_slaves[].mac_addr[i] = am33xx_macid1[i]; |
} |
|
|
switch (mode) { |
case AM33XX_CPSW_MODE_MII: |
gmii_sel = AM33XX_MII_MODE_EN; |
break; |
case AM33XX_CPSW_MODE_RMII: |
gmii_sel = AM33XX_RMII_MODE_EN; |
break; |
case AM33XX_CPSW_MODE_RGMII: |
gmii_sel = AM33XX_RGMII_MODE_EN; |
am33xx_cpsw_slaves[].phy_if = PHY_INTERFACE_MODE_RGMII; |
am33xx_cpsw_slaves[].phy_if = PHY_INTERFACE_MODE_RGMII; |
break; |
default: |
return -EINVAL; |
} |
|
writel(gmii_sel, AM33XX_CTRL_REGADDR(AM33XX_CONTROL_GMII_SEL_OFFSET)); |
|
if (phy_id0 != NULL) |
am33xx_cpsw_slaves[].phy_id = phy_id0; |
|
if (phy_id1 != NULL) |
am33xx_cpsw_slaves[].phy_id = phy_id1; |
|
memcpy(am33xx_cpsw_pdata.mac_addr, |
am33xx_cpsw_slaves[].mac_addr, ETH_ALEN); |
|
oh = omap_hwmod_lookup("mdio"); |
if (!oh) { |
pr_err("could not find cpgmac0 hwmod data\n"); |
return -ENODEV; |
} |
|
pdev = omap_device_build("davinci_mdio", , oh, &am33xx_cpsw_mdiopdata, |
sizeof(am33xx_cpsw_mdiopdata), NULL, , ); |
if (IS_ERR(pdev)) |
pr_err("could not build omap_device for cpsw\n"); |
|
oh = omap_hwmod_lookup("cpgmac0"); |
if (!oh) { |
pr_err("could not find cpgmac0 hwmod data\n"); |
return -ENODEV; |
} |
|
pdev = omap_device_build("cpsw", -, oh, &am33xx_cpsw_pdata, |
sizeof(am33xx_cpsw_pdata), NULL, , ); |
if (IS_ERR(pdev)) |
pr_err("could not build omap_device for cpsw\n"); |
|
return ; |
} |
|
/* TI81XX spefic control submodules */ |
#define TI81XX_CONTROL_DEVCONF 0x600 <--------------------*---+
| |
/* TI81XX CONTROL_DEVCONF register offsets */ | |
#define TI81XX_CONTROL_MAC_ID0_LO (TI81XX_CONTROL_DEVCONF + 0x030) | |
// TI81XX_CONTROL_MAC_ID0_HI = 0x634 ---------------------------*---*-+
#define TI81XX_CONTROL_MAC_ID0_HI (TI81XX_CONTROL_DEVCONF + 0x034) <---+ --+ |
|
/* |
* 1. 参考文档: |
* AM335x ARM® Cortex™-A8 Microprocessors (MPUs) Technical Reference Manual |
* |
* 2. 确认寄存器: |
* Table 9-10. CONTROL_MODULE REGISTERS |
* +--------+------------------+-------------+----------------+ |
* | Offset | Acronym Register | Description | Section | |
* +--------+------------------+-------------+----------------+ |
* | 634h | mac_id0_hi | | Section 9.3.26 | <------------+
* +--------+------------------+-------------+----------------+
*
* 3. 寄存器说明:
* 26.1.8.4.1 Device Initialization
* ......
* • Device uses EFUSE registers mac_id0_lo and mac_id0_hi in the control module for Ethernet MAC address of the device.
* ......
*/