diff options
author | Dmitry Lifshitz | 2016-12-28 18:28:35 +0200 |
---|---|---|
committer | Tom Rini | 2017-01-02 11:14:07 -0500 |
commit | fc300e2c5d9b6217400d89a58e35a69b362ad288 (patch) | |
tree | c612e3719583bff2e349799e69acac409cd9805d /board/compulab/cl-som-am57x | |
parent | 965c509f0a06ea506432e1f90fdd43a0faff6c23 (diff) |
arm: am57xx: cl-som-am57x: add ETH support
Add MAC support.
Use PHY, connected to RGMII1 as a default Eth adapter,
by appropriate setting of 'cpsw_data.active_slave'.
'cpsw_phy' env variable can override this setting.
Set the MAC addresses in the U-Boot environment.
The addresses are retrieved from the on-board EEPROM or from the SOC's
MAC fuses.
Set the following PHYs RGMII clock delays:
- Enable RX delay
- Disable TX delay
Signed-off-by: Dmitry Lifshitz <lifshitz@compulab.co.il>
[uri.mashiach@compulab.co.il: add RGMII clock delays]
Signed-off-by: Uri Mashiach <uri.mashiach@compulab.co.il>
Acked-by: Igor Grinberg <grinberg@compulab.co.il>
Reviewed-by: Tom Rini <trini@konsulko.com>
Diffstat (limited to 'board/compulab/cl-som-am57x')
-rw-r--r-- | board/compulab/cl-som-am57x/Makefile | 2 | ||||
-rw-r--r-- | board/compulab/cl-som-am57x/eth.c | 198 | ||||
-rw-r--r-- | board/compulab/cl-som-am57x/mux.c | 23 |
3 files changed, 223 insertions, 0 deletions
diff --git a/board/compulab/cl-som-am57x/Makefile b/board/compulab/cl-som-am57x/Makefile index 0c59781a8b8..566366bf6e3 100644 --- a/board/compulab/cl-som-am57x/Makefile +++ b/board/compulab/cl-som-am57x/Makefile @@ -13,3 +13,5 @@ obj-y += spl.o mux.o else obj-y += cl-som-am57x.o mux.o endif + +obj-$(CONFIG_DRIVER_TI_CPSW) += eth.o diff --git a/board/compulab/cl-som-am57x/eth.c b/board/compulab/cl-som-am57x/eth.c new file mode 100644 index 00000000000..0c4bf91c130 --- /dev/null +++ b/board/compulab/cl-som-am57x/eth.c @@ -0,0 +1,198 @@ +/* + * Ethernet specific code for CompuLab CL-SOM-AM57x module + * + * (C) Copyright 2016 CompuLab, Ltd. http://compulab.co.il/ + * + * Author: Uri Mashiach <uri.mashiach@compulab.co.il> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <cpsw.h> +#include <miiphy.h> +#include <asm/gpio.h> +#include <asm/arch/sys_proto.h> +#include "../common/eeprom.h" + +static void cpsw_control(int enabled) +{ + /* VTP can be added here */ +} + +static struct cpsw_slave_data cl_som_am57x_cpsw_slaves[] = { + { + .slave_reg_ofs = 0x208, + .sliver_reg_ofs = 0xd80, + .phy_addr = 0, + .phy_if = PHY_INTERFACE_MODE_RMII, + }, + { + .slave_reg_ofs = 0x308, + .sliver_reg_ofs = 0xdc0, + .phy_addr = 1, + .phy_if = PHY_INTERFACE_MODE_RMII, + + }, +}; + +static struct cpsw_platform_data cl_som_am57_cpsw_data = { + .mdio_base = CPSW_MDIO_BASE, + .cpsw_base = CPSW_BASE, + .mdio_div = 0xff, + .channels = 8, + .cpdma_reg_ofs = 0x800, + .slaves = 2, + .slave_data = cl_som_am57x_cpsw_slaves, + .ale_reg_ofs = 0xd00, + .ale_entries = 1024, + .host_port_reg_ofs = 0x108, + .hw_stats_reg_ofs = 0x900, + .bd_ram_ofs = 0x2000, + .mac_control = (1 << 5), + .control = cpsw_control, + .host_port_num = 0, + .version = CPSW_CTRL_VERSION_2, +}; + +/* + * cl_som_am57x_efuse_read_mac_addr() - read Ethernet port MAC address. + * The information is retrieved from the SOC's registers. + * @buff: read buffer. + * @port_num: port number. + */ +static void cl_som_am57x_efuse_read_mac_addr(uchar *buff, uint port_num) +{ + uint32_t mac_hi, mac_lo; + + if (port_num) { + mac_lo = readl((*ctrl)->control_core_mac_id_1_lo); + mac_hi = readl((*ctrl)->control_core_mac_id_1_hi); + } else { + mac_lo = readl((*ctrl)->control_core_mac_id_0_lo); + mac_hi = readl((*ctrl)->control_core_mac_id_0_hi); + } + + buff[0] = (mac_hi & 0xFF0000) >> 16; + buff[1] = (mac_hi & 0xFF00) >> 8; + buff[2] = mac_hi & 0xFF; + buff[3] = (mac_lo & 0xFF0000) >> 16; + buff[4] = (mac_lo & 0xFF00) >> 8; + buff[5] = mac_lo & 0xFF; +} + +/* + * cl_som_am57x_handle_mac_address() - set MAC address in the U-Boot + * environment. + * The address is retrieved retrieved from an EEPROM field or from the + * SOC's registers. + * @env_name: U-Boot environment name. + * @field_name: EEPROM field name. + * @port_num: SOC's port number. + */ +static int cl_som_am57x_handle_mac_address(char *env_name, uint port_num) +{ + int ret; + uint8_t enetaddr[6]; + + ret = eth_getenv_enetaddr(env_name, enetaddr); + if (ret) + return 0; + + ret = cl_eeprom_read_mac_addr(enetaddr, CONFIG_SYS_I2C_EEPROM_BUS); + + if (ret || !is_valid_ethaddr(enetaddr)) + cl_som_am57x_efuse_read_mac_addr(enetaddr, port_num); + + if (!is_valid_ethaddr(enetaddr)) + return -1; + + ret = eth_setenv_enetaddr(env_name, enetaddr); + if (ret) + printf("cl-som-am57x: Failed to set Eth port %d MAC address\n", + port_num); + + return ret; +} + +#define CL_SOM_AM57X_PHY_ADDR2 0x01 +#define AR8033_PHY_DEBUG_ADDR_REG 0x1d +#define AR8033_PHY_DEBUG_DATA_REG 0x1e +#define AR8033_DEBUG_RGMII_RX_CLK_DLY_REG 0x00 +#define AR8033_DEBUG_RGMII_TX_CLK_DLY_REG 0x05 +#define AR8033_DEBUG_RGMII_RX_CLK_DLY_MASK (1 << 15) +#define AR8033_DEBUG_RGMII_TX_CLK_DLY_MASK (1 << 8) + +/* + * cl_som_am57x_rgmii_clk_delay() - Set RGMII clock delay. + * Enable RX delay, disable TX delay. + */ +static void cl_som_am57x_rgmii_clk_delay(void) +{ + uint16_t mii_reg_val; + const char *devname; + + devname = miiphy_get_current_dev(); + /* PHY 2 */ + miiphy_write(devname, CL_SOM_AM57X_PHY_ADDR2, AR8033_PHY_DEBUG_ADDR_REG, + AR8033_DEBUG_RGMII_RX_CLK_DLY_REG); + miiphy_read(devname, CL_SOM_AM57X_PHY_ADDR2, AR8033_PHY_DEBUG_DATA_REG, + &mii_reg_val); + mii_reg_val |= AR8033_DEBUG_RGMII_RX_CLK_DLY_MASK; + miiphy_write(devname, CL_SOM_AM57X_PHY_ADDR2, AR8033_PHY_DEBUG_DATA_REG, + mii_reg_val); + + miiphy_write(devname, CL_SOM_AM57X_PHY_ADDR2, AR8033_PHY_DEBUG_ADDR_REG, + AR8033_DEBUG_RGMII_TX_CLK_DLY_REG); + miiphy_read(devname, CL_SOM_AM57X_PHY_ADDR2, AR8033_PHY_DEBUG_DATA_REG, + &mii_reg_val); + mii_reg_val &= ~AR8033_DEBUG_RGMII_TX_CLK_DLY_MASK; + miiphy_write(devname, CL_SOM_AM57X_PHY_ADDR2, AR8033_PHY_DEBUG_DATA_REG, + mii_reg_val); +} + +#define CL_SOM_AM57X_GPIO_PHY1_RST 92 /* GPIO3_28 */ +#define CL_SOM_AM57X_RGMII_PORT1 1 + +int board_eth_init(bd_t *bis) +{ + int ret; + uint32_t ctrl_val; + char *cpsw_phy_envval; + int cpsw_act_phy = 1; + + /* SB-SOM-AM57x primary Eth (P21) is routed to RGMII1 */ + ret = cl_som_am57x_handle_mac_address("ethaddr", + CL_SOM_AM57X_RGMII_PORT1); + + if (ret) + return -1; + + /* Select RGMII for GMII1_SEL */ + ctrl_val = readl((*ctrl)->control_core_control_io1) & (~0x33); + ctrl_val |= 0x22; + writel(ctrl_val, (*ctrl)->control_core_control_io1); + mdelay(10); + + gpio_request(CL_SOM_AM57X_GPIO_PHY1_RST, "phy1_rst"); + gpio_direction_output(CL_SOM_AM57X_GPIO_PHY1_RST, 0); + mdelay(20); + + gpio_set_value(CL_SOM_AM57X_GPIO_PHY1_RST, 1); + mdelay(20); + + cpsw_phy_envval = getenv("cpsw_phy"); + if (cpsw_phy_envval != NULL) + cpsw_act_phy = simple_strtoul(cpsw_phy_envval, NULL, 0); + + cl_som_am57_cpsw_data.active_slave = cpsw_act_phy; + + ret = cpsw_register(&cl_som_am57_cpsw_data); + if (ret < 0) + printf("Error %d registering CPSW switch\n", ret); + + /* Set RGMII clock delay */ + cl_som_am57x_rgmii_clk_delay(); + + return ret; +} diff --git a/board/compulab/cl-som-am57x/mux.c b/board/compulab/cl-som-am57x/mux.c index 625cbc1dbdb..5b7197578cc 100644 --- a/board/compulab/cl-som-am57x/mux.c +++ b/board/compulab/cl-som-am57x/mux.c @@ -83,6 +83,28 @@ static const struct pad_conf_entry cl_som_am57x_padconf_usb[] = { {USB1_DRVVBUS, (M0 | FSC) }, /* USB1_DRVVBUS.USB1_DRVVBUS */ }; +/* Ethernet */ +static const struct pad_conf_entry cl_som_am57x_padconf_ethernet[] = { + /* MDIO bus */ + {VIN2A_D10, (PDIS | PTU | M3) }, /* VIN2A_D10.MDIO_MCLK */ + {VIN2A_D11, (IEN | PDIS | PTU | M3) }, /* VIN2A_D11.MDIO_D */ + /* EMAC Slave 1 at addr 0x1 - Default interface */ + {VIN2A_D12, (IDIS | PEN | M3) }, /* VIN2A_D12.RGMII1_TXC */ + {VIN2A_D13, (IDIS | PEN | M3) }, /* VIN2A_D13.RGMII1_TXCTL */ + {VIN2A_D14, (IDIS | PEN | M3) }, /* VIN2A_D14.RGMII1_TXD3 */ + {VIN2A_D15, (IDIS | PEN | M3) }, /* VIN2A_D15.RGMII1_TXD2 */ + {VIN2A_D16, (IDIS | PEN | M3) }, /* VIN2A_D16.RGMII1_TXD1 */ + {VIN2A_D17, (IDIS | PEN | M3) }, /* VIN2A_D17.RGMII1_TXD0 */ + {VIN2A_D18, (IEN | PDIS | PTD | M3) }, /* VIN2A_D18.RGMII1_RXC */ + {VIN2A_D19, (IEN | PDIS | PTD | M3) }, /* VIN2A_D19.RGMII1_RXCTL */ + {VIN2A_D20, (IEN | PDIS | PTD | M3) }, /* VIN2A_D20.RGMII1_RXD3 */ + {VIN2A_D21, (IEN | PDIS | PTD | M3) }, /* VIN2A_D21.RGMII1_RXD2 */ + {VIN2A_D22, (IEN | PDIS | PTD | M3) }, /* VIN2A_D22.RGMII1_RXD1 */ + {VIN2A_D23, (IEN | PDIS | PTD | M3) }, /* VIN2A_D23.RGMII1_RXD0 */ + /* Eth PHY1 reset GPIOs*/ + {VIN1B_CLK1, (IDIS | PDIS | PTD | M14)}, /* VIN1B_CLK1.GPIO2_31 */ +}; + #define SET_MUX(mux_array) do_set_mux32((*ctrl)->control_padconf_core_base, \ mux_array, ARRAY_SIZE(mux_array)) @@ -97,4 +119,5 @@ void set_muxconf_regs(void) SET_MUX(cl_som_am57x_padconf_i2c_gpio); SET_MUX(cl_som_am57x_padconf_emmc); SET_MUX(cl_som_am57x_padconf_usb); + SET_MUX(cl_som_am57x_padconf_ethernet); } |