mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-18 10:48:51 +00:00
c0e66793c4
This adds necessary config options and a new build target, am335x_evm_usbspl, to enable usb booting and fixes board_eth_init() function to take into account that we may have USB ether support in SPL now. This uses the same MAC for both cpsw and USB, in order to match ROM behavior. The usbspl build target does not contain UART SPL, CPSW SPL or extra environment settings, so that we may fit within our binary size constraint. Signed-off-by: Ilya Yanok <ilya.yanok@cogentembedded.com> Signed-off-by: Tom Rini <trini@ti.com>
511 lines
14 KiB
C
511 lines
14 KiB
C
/*
|
|
* board.c
|
|
*
|
|
* Board functions for TI AM335X based boards
|
|
*
|
|
* Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License as
|
|
* published by the Free Software Foundation; either version 2 of
|
|
* the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*/
|
|
|
|
#include <common.h>
|
|
#include <errno.h>
|
|
#include <spl.h>
|
|
#include <asm/arch/cpu.h>
|
|
#include <asm/arch/hardware.h>
|
|
#include <asm/arch/omap.h>
|
|
#include <asm/arch/ddr_defs.h>
|
|
#include <asm/arch/clock.h>
|
|
#include <asm/arch/gpio.h>
|
|
#include <asm/arch/mmc_host_def.h>
|
|
#include <asm/arch/sys_proto.h>
|
|
#include <asm/io.h>
|
|
#include <asm/emif.h>
|
|
#include <asm/gpio.h>
|
|
#include <i2c.h>
|
|
#include <miiphy.h>
|
|
#include <cpsw.h>
|
|
#include "board.h"
|
|
|
|
DECLARE_GLOBAL_DATA_PTR;
|
|
|
|
static struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE;
|
|
#ifdef CONFIG_SPL_BUILD
|
|
static struct uart_sys *uart_base = (struct uart_sys *)DEFAULT_UART_BASE;
|
|
#endif
|
|
|
|
/* MII mode defines */
|
|
#define MII_MODE_ENABLE 0x0
|
|
#define RGMII_MODE_ENABLE 0x3A
|
|
|
|
/* GPIO that controls power to DDR on EVM-SK */
|
|
#define GPIO_DDR_VTT_EN 7
|
|
|
|
static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
|
|
|
|
static struct am335x_baseboard_id __attribute__((section (".data"))) header;
|
|
|
|
static inline int board_is_bone(void)
|
|
{
|
|
return !strncmp(header.name, "A335BONE", HDR_NAME_LEN);
|
|
}
|
|
|
|
static inline int board_is_bone_lt(void)
|
|
{
|
|
return !strncmp(header.name, "A335BNLT", HDR_NAME_LEN);
|
|
}
|
|
|
|
static inline int board_is_evm_sk(void)
|
|
{
|
|
return !strncmp("A335X_SK", header.name, HDR_NAME_LEN);
|
|
}
|
|
|
|
static inline int board_is_idk(void)
|
|
{
|
|
return !strncmp(header.config, "SKU#02", 6);
|
|
}
|
|
|
|
static int board_is_gp_evm(void)
|
|
{
|
|
return !strncmp("A33515BB", header.name, 8);
|
|
}
|
|
|
|
int board_is_evm_15_or_later(void)
|
|
{
|
|
return (!strncmp("A33515BB", header.name, 8) &&
|
|
strncmp("1.5", header.version, 3) <= 0);
|
|
}
|
|
|
|
/*
|
|
* Read header information from EEPROM into global structure.
|
|
*/
|
|
static int read_eeprom(void)
|
|
{
|
|
/* Check if baseboard eeprom is available */
|
|
if (i2c_probe(CONFIG_SYS_I2C_EEPROM_ADDR)) {
|
|
puts("Could not probe the EEPROM; something fundamentally "
|
|
"wrong on the I2C bus.\n");
|
|
return -ENODEV;
|
|
}
|
|
|
|
/* read the eeprom using i2c */
|
|
if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, 2, (uchar *)&header,
|
|
sizeof(header))) {
|
|
puts("Could not read the EEPROM; something fundamentally"
|
|
" wrong on the I2C bus.\n");
|
|
return -EIO;
|
|
}
|
|
|
|
if (header.magic != 0xEE3355AA) {
|
|
/*
|
|
* read the eeprom using i2c again,
|
|
* but use only a 1 byte address
|
|
*/
|
|
if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, 1,
|
|
(uchar *)&header, sizeof(header))) {
|
|
puts("Could not read the EEPROM; something "
|
|
"fundamentally wrong on the I2C bus.\n");
|
|
return -EIO;
|
|
}
|
|
|
|
if (header.magic != 0xEE3355AA) {
|
|
printf("Incorrect magic number (0x%x) in EEPROM\n",
|
|
header.magic);
|
|
return -EINVAL;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* UART Defines */
|
|
#ifdef CONFIG_SPL_BUILD
|
|
#define UART_RESET (0x1 << 1)
|
|
#define UART_CLK_RUNNING_MASK 0x1
|
|
#define UART_SMART_IDLE_EN (0x1 << 0x3)
|
|
|
|
static void rtc32k_enable(void)
|
|
{
|
|
struct rtc_regs *rtc = (struct rtc_regs *)AM335X_RTC_BASE;
|
|
|
|
/*
|
|
* Unlock the RTC's registers. For more details please see the
|
|
* RTC_SS section of the TRM. In order to unlock we need to
|
|
* write these specific values (keys) in this order.
|
|
*/
|
|
writel(0x83e70b13, &rtc->kick0r);
|
|
writel(0x95a4f1e0, &rtc->kick1r);
|
|
|
|
/* Enable the RTC 32K OSC by setting bits 3 and 6. */
|
|
writel((1 << 3) | (1 << 6), &rtc->osc);
|
|
}
|
|
|
|
static const struct ddr_data ddr2_data = {
|
|
.datardsratio0 = ((MT47H128M16RT25E_RD_DQS<<30) |
|
|
(MT47H128M16RT25E_RD_DQS<<20) |
|
|
(MT47H128M16RT25E_RD_DQS<<10) |
|
|
(MT47H128M16RT25E_RD_DQS<<0)),
|
|
.datawdsratio0 = ((MT47H128M16RT25E_WR_DQS<<30) |
|
|
(MT47H128M16RT25E_WR_DQS<<20) |
|
|
(MT47H128M16RT25E_WR_DQS<<10) |
|
|
(MT47H128M16RT25E_WR_DQS<<0)),
|
|
.datawiratio0 = ((MT47H128M16RT25E_PHY_WRLVL<<30) |
|
|
(MT47H128M16RT25E_PHY_WRLVL<<20) |
|
|
(MT47H128M16RT25E_PHY_WRLVL<<10) |
|
|
(MT47H128M16RT25E_PHY_WRLVL<<0)),
|
|
.datagiratio0 = ((MT47H128M16RT25E_PHY_GATELVL<<30) |
|
|
(MT47H128M16RT25E_PHY_GATELVL<<20) |
|
|
(MT47H128M16RT25E_PHY_GATELVL<<10) |
|
|
(MT47H128M16RT25E_PHY_GATELVL<<0)),
|
|
.datafwsratio0 = ((MT47H128M16RT25E_PHY_FIFO_WE<<30) |
|
|
(MT47H128M16RT25E_PHY_FIFO_WE<<20) |
|
|
(MT47H128M16RT25E_PHY_FIFO_WE<<10) |
|
|
(MT47H128M16RT25E_PHY_FIFO_WE<<0)),
|
|
.datawrsratio0 = ((MT47H128M16RT25E_PHY_WR_DATA<<30) |
|
|
(MT47H128M16RT25E_PHY_WR_DATA<<20) |
|
|
(MT47H128M16RT25E_PHY_WR_DATA<<10) |
|
|
(MT47H128M16RT25E_PHY_WR_DATA<<0)),
|
|
.datauserank0delay = MT47H128M16RT25E_PHY_RANK0_DELAY,
|
|
.datadldiff0 = PHY_DLL_LOCK_DIFF,
|
|
};
|
|
|
|
static const struct cmd_control ddr2_cmd_ctrl_data = {
|
|
.cmd0csratio = MT47H128M16RT25E_RATIO,
|
|
.cmd0dldiff = MT47H128M16RT25E_DLL_LOCK_DIFF,
|
|
.cmd0iclkout = MT47H128M16RT25E_INVERT_CLKOUT,
|
|
|
|
.cmd1csratio = MT47H128M16RT25E_RATIO,
|
|
.cmd1dldiff = MT47H128M16RT25E_DLL_LOCK_DIFF,
|
|
.cmd1iclkout = MT47H128M16RT25E_INVERT_CLKOUT,
|
|
|
|
.cmd2csratio = MT47H128M16RT25E_RATIO,
|
|
.cmd2dldiff = MT47H128M16RT25E_DLL_LOCK_DIFF,
|
|
.cmd2iclkout = MT47H128M16RT25E_INVERT_CLKOUT,
|
|
};
|
|
|
|
static const struct emif_regs ddr2_emif_reg_data = {
|
|
.sdram_config = MT47H128M16RT25E_EMIF_SDCFG,
|
|
.ref_ctrl = MT47H128M16RT25E_EMIF_SDREF,
|
|
.sdram_tim1 = MT47H128M16RT25E_EMIF_TIM1,
|
|
.sdram_tim2 = MT47H128M16RT25E_EMIF_TIM2,
|
|
.sdram_tim3 = MT47H128M16RT25E_EMIF_TIM3,
|
|
.emif_ddr_phy_ctlr_1 = MT47H128M16RT25E_EMIF_READ_LATENCY,
|
|
};
|
|
|
|
static const struct ddr_data ddr3_data = {
|
|
.datardsratio0 = MT41J128MJT125_RD_DQS,
|
|
.datawdsratio0 = MT41J128MJT125_WR_DQS,
|
|
.datafwsratio0 = MT41J128MJT125_PHY_FIFO_WE,
|
|
.datawrsratio0 = MT41J128MJT125_PHY_WR_DATA,
|
|
.datadldiff0 = PHY_DLL_LOCK_DIFF,
|
|
};
|
|
|
|
static const struct ddr_data ddr3_evm_data = {
|
|
.datardsratio0 = MT41J512M8RH125_RD_DQS,
|
|
.datawdsratio0 = MT41J512M8RH125_WR_DQS,
|
|
.datafwsratio0 = MT41J512M8RH125_PHY_FIFO_WE,
|
|
.datawrsratio0 = MT41J512M8RH125_PHY_WR_DATA,
|
|
.datadldiff0 = PHY_DLL_LOCK_DIFF,
|
|
};
|
|
|
|
static const struct cmd_control ddr3_cmd_ctrl_data = {
|
|
.cmd0csratio = MT41J128MJT125_RATIO,
|
|
.cmd0dldiff = MT41J128MJT125_DLL_LOCK_DIFF,
|
|
.cmd0iclkout = MT41J128MJT125_INVERT_CLKOUT,
|
|
|
|
.cmd1csratio = MT41J128MJT125_RATIO,
|
|
.cmd1dldiff = MT41J128MJT125_DLL_LOCK_DIFF,
|
|
.cmd1iclkout = MT41J128MJT125_INVERT_CLKOUT,
|
|
|
|
.cmd2csratio = MT41J128MJT125_RATIO,
|
|
.cmd2dldiff = MT41J128MJT125_DLL_LOCK_DIFF,
|
|
.cmd2iclkout = MT41J128MJT125_INVERT_CLKOUT,
|
|
};
|
|
|
|
static const struct cmd_control ddr3_evm_cmd_ctrl_data = {
|
|
.cmd0csratio = MT41J512M8RH125_RATIO,
|
|
.cmd0dldiff = MT41J512M8RH125_DLL_LOCK_DIFF,
|
|
.cmd0iclkout = MT41J512M8RH125_INVERT_CLKOUT,
|
|
|
|
.cmd1csratio = MT41J512M8RH125_RATIO,
|
|
.cmd1dldiff = MT41J512M8RH125_DLL_LOCK_DIFF,
|
|
.cmd1iclkout = MT41J512M8RH125_INVERT_CLKOUT,
|
|
|
|
.cmd2csratio = MT41J512M8RH125_RATIO,
|
|
.cmd2dldiff = MT41J512M8RH125_DLL_LOCK_DIFF,
|
|
.cmd2iclkout = MT41J512M8RH125_INVERT_CLKOUT,
|
|
};
|
|
|
|
static struct emif_regs ddr3_emif_reg_data = {
|
|
.sdram_config = MT41J128MJT125_EMIF_SDCFG,
|
|
.ref_ctrl = MT41J128MJT125_EMIF_SDREF,
|
|
.sdram_tim1 = MT41J128MJT125_EMIF_TIM1,
|
|
.sdram_tim2 = MT41J128MJT125_EMIF_TIM2,
|
|
.sdram_tim3 = MT41J128MJT125_EMIF_TIM3,
|
|
.zq_config = MT41J128MJT125_ZQ_CFG,
|
|
.emif_ddr_phy_ctlr_1 = MT41J128MJT125_EMIF_READ_LATENCY,
|
|
};
|
|
|
|
static struct emif_regs ddr3_evm_emif_reg_data = {
|
|
.sdram_config = MT41J512M8RH125_EMIF_SDCFG,
|
|
.ref_ctrl = MT41J512M8RH125_EMIF_SDREF,
|
|
.sdram_tim1 = MT41J512M8RH125_EMIF_TIM1,
|
|
.sdram_tim2 = MT41J512M8RH125_EMIF_TIM2,
|
|
.sdram_tim3 = MT41J512M8RH125_EMIF_TIM3,
|
|
.zq_config = MT41J512M8RH125_ZQ_CFG,
|
|
.emif_ddr_phy_ctlr_1 = MT41J512M8RH125_EMIF_READ_LATENCY,
|
|
};
|
|
#endif
|
|
|
|
/*
|
|
* early system init of muxing and clocks.
|
|
*/
|
|
void s_init(void)
|
|
{
|
|
/* WDT1 is already running when the bootloader gets control
|
|
* Disable it to avoid "random" resets
|
|
*/
|
|
writel(0xAAAA, &wdtimer->wdtwspr);
|
|
while (readl(&wdtimer->wdtwwps) != 0x0)
|
|
;
|
|
writel(0x5555, &wdtimer->wdtwspr);
|
|
while (readl(&wdtimer->wdtwwps) != 0x0)
|
|
;
|
|
|
|
#ifdef CONFIG_SPL_BUILD
|
|
/* Setup the PLLs and the clocks for the peripherals */
|
|
pll_init();
|
|
|
|
/* Enable RTC32K clock */
|
|
rtc32k_enable();
|
|
|
|
/* UART softreset */
|
|
u32 regVal;
|
|
|
|
#ifdef CONFIG_SERIAL1
|
|
enable_uart0_pin_mux();
|
|
#endif /* CONFIG_SERIAL1 */
|
|
#ifdef CONFIG_SERIAL2
|
|
enable_uart1_pin_mux();
|
|
#endif /* CONFIG_SERIAL2 */
|
|
#ifdef CONFIG_SERIAL3
|
|
enable_uart2_pin_mux();
|
|
#endif /* CONFIG_SERIAL3 */
|
|
#ifdef CONFIG_SERIAL4
|
|
enable_uart3_pin_mux();
|
|
#endif /* CONFIG_SERIAL4 */
|
|
#ifdef CONFIG_SERIAL5
|
|
enable_uart4_pin_mux();
|
|
#endif /* CONFIG_SERIAL5 */
|
|
#ifdef CONFIG_SERIAL6
|
|
enable_uart5_pin_mux();
|
|
#endif /* CONFIG_SERIAL6 */
|
|
|
|
regVal = readl(&uart_base->uartsyscfg);
|
|
regVal |= UART_RESET;
|
|
writel(regVal, &uart_base->uartsyscfg);
|
|
while ((readl(&uart_base->uartsyssts) &
|
|
UART_CLK_RUNNING_MASK) != UART_CLK_RUNNING_MASK)
|
|
;
|
|
|
|
/* Disable smart idle */
|
|
regVal = readl(&uart_base->uartsyscfg);
|
|
regVal |= UART_SMART_IDLE_EN;
|
|
writel(regVal, &uart_base->uartsyscfg);
|
|
|
|
gd = &gdata;
|
|
|
|
preloader_console_init();
|
|
|
|
/* Initalize the board header */
|
|
enable_i2c0_pin_mux();
|
|
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
|
|
if (read_eeprom() < 0)
|
|
puts("Could not get board ID.\n");
|
|
|
|
enable_board_pin_mux(&header);
|
|
if (board_is_evm_sk()) {
|
|
/*
|
|
* EVM SK 1.2A and later use gpio0_7 to enable DDR3.
|
|
* This is safe enough to do on older revs.
|
|
*/
|
|
gpio_request(GPIO_DDR_VTT_EN, "ddr_vtt_en");
|
|
gpio_direction_output(GPIO_DDR_VTT_EN, 1);
|
|
}
|
|
|
|
if (board_is_evm_sk() || board_is_bone_lt())
|
|
config_ddr(303, MT41J128MJT125_IOCTRL_VALUE, &ddr3_data,
|
|
&ddr3_cmd_ctrl_data, &ddr3_emif_reg_data);
|
|
else if (board_is_evm_15_or_later())
|
|
config_ddr(303, MT41J512M8RH125_IOCTRL_VALUE, &ddr3_evm_data,
|
|
&ddr3_evm_cmd_ctrl_data, &ddr3_evm_emif_reg_data);
|
|
else
|
|
config_ddr(266, MT47H128M16RT25E_IOCTRL_VALUE, &ddr2_data,
|
|
&ddr2_cmd_ctrl_data, &ddr2_emif_reg_data);
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
* Basic board specific setup. Pinmux has been handled already.
|
|
*/
|
|
int board_init(void)
|
|
{
|
|
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
|
|
if (read_eeprom() < 0)
|
|
puts("Could not get board ID.\n");
|
|
|
|
gd->bd->bi_boot_params = PHYS_DRAM_1 + 0x100;
|
|
|
|
gpmc_init();
|
|
|
|
return 0;
|
|
}
|
|
|
|
#ifdef CONFIG_BOARD_LATE_INIT
|
|
int board_late_init(void)
|
|
{
|
|
#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
|
|
char safe_string[HDR_NAME_LEN + 1];
|
|
|
|
/* Now set variables based on the header. */
|
|
strncpy(safe_string, (char *)header.name, sizeof(header.name));
|
|
safe_string[sizeof(header.name)] = 0;
|
|
setenv("board_name", safe_string);
|
|
|
|
strncpy(safe_string, (char *)header.version, sizeof(header.version));
|
|
safe_string[sizeof(header.version)] = 0;
|
|
setenv("board_rev", safe_string);
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
#if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) || \
|
|
(defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD))
|
|
static void cpsw_control(int enabled)
|
|
{
|
|
/* VTP can be added here */
|
|
|
|
return;
|
|
}
|
|
|
|
static struct cpsw_slave_data cpsw_slaves[] = {
|
|
{
|
|
.slave_reg_ofs = 0x208,
|
|
.sliver_reg_ofs = 0xd80,
|
|
.phy_id = 0,
|
|
},
|
|
{
|
|
.slave_reg_ofs = 0x308,
|
|
.sliver_reg_ofs = 0xdc0,
|
|
.phy_id = 1,
|
|
},
|
|
};
|
|
|
|
static struct cpsw_platform_data cpsw_data = {
|
|
.mdio_base = AM335X_CPSW_MDIO_BASE,
|
|
.cpsw_base = AM335X_CPSW_BASE,
|
|
.mdio_div = 0xff,
|
|
.channels = 8,
|
|
.cpdma_reg_ofs = 0x800,
|
|
.slaves = 1,
|
|
.slave_data = cpsw_slaves,
|
|
.ale_reg_ofs = 0xd00,
|
|
.ale_entries = 1024,
|
|
.host_port_reg_ofs = 0x108,
|
|
.hw_stats_reg_ofs = 0x900,
|
|
.mac_control = (1 << 5),
|
|
.control = cpsw_control,
|
|
.host_port_num = 0,
|
|
.version = CPSW_CTRL_VERSION_2,
|
|
};
|
|
#endif
|
|
|
|
#if defined(CONFIG_DRIVER_TI_CPSW) || \
|
|
(defined(CONFIG_USB_ETHER) && defined(CONFIG_MUSB_GADGET))
|
|
int board_eth_init(bd_t *bis)
|
|
{
|
|
int rv, n = 0;
|
|
uint8_t mac_addr[6];
|
|
uint32_t mac_hi, mac_lo;
|
|
|
|
/* try reading mac address from efuse */
|
|
mac_lo = readl(&cdev->macid0l);
|
|
mac_hi = readl(&cdev->macid0h);
|
|
mac_addr[0] = mac_hi & 0xFF;
|
|
mac_addr[1] = (mac_hi & 0xFF00) >> 8;
|
|
mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
|
|
mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
|
|
mac_addr[4] = mac_lo & 0xFF;
|
|
mac_addr[5] = (mac_lo & 0xFF00) >> 8;
|
|
|
|
#if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) || \
|
|
(defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD))
|
|
if (!getenv("ethaddr")) {
|
|
printf("<ethaddr> not set. Validating first E-fuse MAC\n");
|
|
|
|
if (is_valid_ether_addr(mac_addr))
|
|
eth_setenv_enetaddr("ethaddr", mac_addr);
|
|
}
|
|
|
|
if (board_is_bone() || board_is_bone_lt() || board_is_idk()) {
|
|
writel(MII_MODE_ENABLE, &cdev->miisel);
|
|
cpsw_slaves[0].phy_if = cpsw_slaves[1].phy_if =
|
|
PHY_INTERFACE_MODE_MII;
|
|
} else {
|
|
writel(RGMII_MODE_ENABLE, &cdev->miisel);
|
|
cpsw_slaves[0].phy_if = cpsw_slaves[1].phy_if =
|
|
PHY_INTERFACE_MODE_RGMII;
|
|
}
|
|
|
|
rv = cpsw_register(&cpsw_data);
|
|
if (rv < 0)
|
|
printf("Error %d registering CPSW switch\n", rv);
|
|
else
|
|
n += rv;
|
|
|
|
/*
|
|
*
|
|
* CPSW RGMII Internal Delay Mode is not supported in all PVT
|
|
* operating points. So we must set the TX clock delay feature
|
|
* in the AR8051 PHY. Since we only support a single ethernet
|
|
* device in U-Boot, we only do this for the first instance.
|
|
*/
|
|
#define AR8051_PHY_DEBUG_ADDR_REG 0x1d
|
|
#define AR8051_PHY_DEBUG_DATA_REG 0x1e
|
|
#define AR8051_DEBUG_RGMII_CLK_DLY_REG 0x5
|
|
#define AR8051_RGMII_TX_CLK_DLY 0x100
|
|
|
|
if (board_is_evm_sk() || board_is_gp_evm()) {
|
|
const char *devname;
|
|
devname = miiphy_get_current_dev();
|
|
|
|
miiphy_write(devname, 0x0, AR8051_PHY_DEBUG_ADDR_REG,
|
|
AR8051_DEBUG_RGMII_CLK_DLY_REG);
|
|
miiphy_write(devname, 0x0, AR8051_PHY_DEBUG_DATA_REG,
|
|
AR8051_RGMII_TX_CLK_DLY);
|
|
}
|
|
#endif
|
|
#if defined(CONFIG_USB_ETHER) && \
|
|
(!defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_USBETH_SUPPORT))
|
|
if (is_valid_ether_addr(mac_addr))
|
|
eth_setenv_enetaddr("usbnet_devaddr", mac_addr);
|
|
|
|
rv = usb_eth_initialize(bis);
|
|
if (rv < 0)
|
|
printf("Error %d registering USB_ETHER\n", rv);
|
|
else
|
|
n += rv;
|
|
#endif
|
|
return n;
|
|
}
|
|
#endif
|