1fc300e2cSDmitry Lifshitz /* 2fc300e2cSDmitry Lifshitz * Ethernet specific code for CompuLab CL-SOM-AM57x module 3fc300e2cSDmitry Lifshitz * 4fc300e2cSDmitry Lifshitz * (C) Copyright 2016 CompuLab, Ltd. http://compulab.co.il/ 5fc300e2cSDmitry Lifshitz * 6fc300e2cSDmitry Lifshitz * Author: Uri Mashiach <uri.mashiach@compulab.co.il> 7fc300e2cSDmitry Lifshitz * 8fc300e2cSDmitry Lifshitz * SPDX-License-Identifier: GPL-2.0+ 9fc300e2cSDmitry Lifshitz */ 10fc300e2cSDmitry Lifshitz 11fc300e2cSDmitry Lifshitz #include <common.h> 12fc300e2cSDmitry Lifshitz #include <cpsw.h> 13fc300e2cSDmitry Lifshitz #include <miiphy.h> 14fc300e2cSDmitry Lifshitz #include <asm/gpio.h> 15fc300e2cSDmitry Lifshitz #include <asm/arch/sys_proto.h> 16fc300e2cSDmitry Lifshitz #include "../common/eeprom.h" 17fc300e2cSDmitry Lifshitz 18fc300e2cSDmitry Lifshitz static void cpsw_control(int enabled) 19fc300e2cSDmitry Lifshitz { 20fc300e2cSDmitry Lifshitz /* VTP can be added here */ 21fc300e2cSDmitry Lifshitz } 22fc300e2cSDmitry Lifshitz 23fc300e2cSDmitry Lifshitz static struct cpsw_slave_data cl_som_am57x_cpsw_slaves[] = { 24fc300e2cSDmitry Lifshitz { 25fc300e2cSDmitry Lifshitz .slave_reg_ofs = 0x208, 26fc300e2cSDmitry Lifshitz .sliver_reg_ofs = 0xd80, 27fc300e2cSDmitry Lifshitz .phy_addr = 0, 28fc300e2cSDmitry Lifshitz .phy_if = PHY_INTERFACE_MODE_RMII, 29fc300e2cSDmitry Lifshitz }, 30fc300e2cSDmitry Lifshitz { 31fc300e2cSDmitry Lifshitz .slave_reg_ofs = 0x308, 32fc300e2cSDmitry Lifshitz .sliver_reg_ofs = 0xdc0, 33fc300e2cSDmitry Lifshitz .phy_addr = 1, 34fc300e2cSDmitry Lifshitz .phy_if = PHY_INTERFACE_MODE_RMII, 35fc300e2cSDmitry Lifshitz 36fc300e2cSDmitry Lifshitz }, 37fc300e2cSDmitry Lifshitz }; 38fc300e2cSDmitry Lifshitz 39fc300e2cSDmitry Lifshitz static struct cpsw_platform_data cl_som_am57_cpsw_data = { 40fc300e2cSDmitry Lifshitz .mdio_base = CPSW_MDIO_BASE, 41fc300e2cSDmitry Lifshitz .cpsw_base = CPSW_BASE, 42fc300e2cSDmitry Lifshitz .mdio_div = 0xff, 43fc300e2cSDmitry Lifshitz .channels = 8, 44fc300e2cSDmitry Lifshitz .cpdma_reg_ofs = 0x800, 45fc300e2cSDmitry Lifshitz .slaves = 2, 46fc300e2cSDmitry Lifshitz .slave_data = cl_som_am57x_cpsw_slaves, 47fc300e2cSDmitry Lifshitz .ale_reg_ofs = 0xd00, 48fc300e2cSDmitry Lifshitz .ale_entries = 1024, 49fc300e2cSDmitry Lifshitz .host_port_reg_ofs = 0x108, 50fc300e2cSDmitry Lifshitz .hw_stats_reg_ofs = 0x900, 51fc300e2cSDmitry Lifshitz .bd_ram_ofs = 0x2000, 52fc300e2cSDmitry Lifshitz .mac_control = (1 << 5), 53fc300e2cSDmitry Lifshitz .control = cpsw_control, 54fc300e2cSDmitry Lifshitz .host_port_num = 0, 55fc300e2cSDmitry Lifshitz .version = CPSW_CTRL_VERSION_2, 56fc300e2cSDmitry Lifshitz }; 57fc300e2cSDmitry Lifshitz 58fc300e2cSDmitry Lifshitz /* 59fc300e2cSDmitry Lifshitz * cl_som_am57x_efuse_read_mac_addr() - read Ethernet port MAC address. 60fc300e2cSDmitry Lifshitz * The information is retrieved from the SOC's registers. 61fc300e2cSDmitry Lifshitz * @buff: read buffer. 62fc300e2cSDmitry Lifshitz * @port_num: port number. 63fc300e2cSDmitry Lifshitz */ 64fc300e2cSDmitry Lifshitz static void cl_som_am57x_efuse_read_mac_addr(uchar *buff, uint port_num) 65fc300e2cSDmitry Lifshitz { 66fc300e2cSDmitry Lifshitz uint32_t mac_hi, mac_lo; 67fc300e2cSDmitry Lifshitz 68fc300e2cSDmitry Lifshitz if (port_num) { 69fc300e2cSDmitry Lifshitz mac_lo = readl((*ctrl)->control_core_mac_id_1_lo); 70fc300e2cSDmitry Lifshitz mac_hi = readl((*ctrl)->control_core_mac_id_1_hi); 71fc300e2cSDmitry Lifshitz } else { 72fc300e2cSDmitry Lifshitz mac_lo = readl((*ctrl)->control_core_mac_id_0_lo); 73fc300e2cSDmitry Lifshitz mac_hi = readl((*ctrl)->control_core_mac_id_0_hi); 74fc300e2cSDmitry Lifshitz } 75fc300e2cSDmitry Lifshitz 76fc300e2cSDmitry Lifshitz buff[0] = (mac_hi & 0xFF0000) >> 16; 77fc300e2cSDmitry Lifshitz buff[1] = (mac_hi & 0xFF00) >> 8; 78fc300e2cSDmitry Lifshitz buff[2] = mac_hi & 0xFF; 79fc300e2cSDmitry Lifshitz buff[3] = (mac_lo & 0xFF0000) >> 16; 80fc300e2cSDmitry Lifshitz buff[4] = (mac_lo & 0xFF00) >> 8; 81fc300e2cSDmitry Lifshitz buff[5] = mac_lo & 0xFF; 82fc300e2cSDmitry Lifshitz } 83fc300e2cSDmitry Lifshitz 84fc300e2cSDmitry Lifshitz /* 85fc300e2cSDmitry Lifshitz * cl_som_am57x_handle_mac_address() - set MAC address in the U-Boot 86fc300e2cSDmitry Lifshitz * environment. 87fc300e2cSDmitry Lifshitz * The address is retrieved retrieved from an EEPROM field or from the 88fc300e2cSDmitry Lifshitz * SOC's registers. 89fc300e2cSDmitry Lifshitz * @env_name: U-Boot environment name. 90fc300e2cSDmitry Lifshitz * @field_name: EEPROM field name. 91fc300e2cSDmitry Lifshitz * @port_num: SOC's port number. 92fc300e2cSDmitry Lifshitz */ 93fc300e2cSDmitry Lifshitz static int cl_som_am57x_handle_mac_address(char *env_name, uint port_num) 94fc300e2cSDmitry Lifshitz { 95fc300e2cSDmitry Lifshitz int ret; 96fc300e2cSDmitry Lifshitz uint8_t enetaddr[6]; 97fc300e2cSDmitry Lifshitz 98fc300e2cSDmitry Lifshitz ret = eth_getenv_enetaddr(env_name, enetaddr); 99fc300e2cSDmitry Lifshitz if (ret) 100fc300e2cSDmitry Lifshitz return 0; 101fc300e2cSDmitry Lifshitz 102fc300e2cSDmitry Lifshitz ret = cl_eeprom_read_mac_addr(enetaddr, CONFIG_SYS_I2C_EEPROM_BUS); 103fc300e2cSDmitry Lifshitz 104fc300e2cSDmitry Lifshitz if (ret || !is_valid_ethaddr(enetaddr)) 105fc300e2cSDmitry Lifshitz cl_som_am57x_efuse_read_mac_addr(enetaddr, port_num); 106fc300e2cSDmitry Lifshitz 107fc300e2cSDmitry Lifshitz if (!is_valid_ethaddr(enetaddr)) 108fc300e2cSDmitry Lifshitz return -1; 109fc300e2cSDmitry Lifshitz 110*fd1e959eSSimon Glass ret = eth_env_set_enetaddr(env_name, enetaddr); 111fc300e2cSDmitry Lifshitz if (ret) 112fc300e2cSDmitry Lifshitz printf("cl-som-am57x: Failed to set Eth port %d MAC address\n", 113fc300e2cSDmitry Lifshitz port_num); 114fc300e2cSDmitry Lifshitz 115fc300e2cSDmitry Lifshitz return ret; 116fc300e2cSDmitry Lifshitz } 117fc300e2cSDmitry Lifshitz 118fc300e2cSDmitry Lifshitz #define CL_SOM_AM57X_PHY_ADDR2 0x01 119fc300e2cSDmitry Lifshitz #define AR8033_PHY_DEBUG_ADDR_REG 0x1d 120fc300e2cSDmitry Lifshitz #define AR8033_PHY_DEBUG_DATA_REG 0x1e 121fc300e2cSDmitry Lifshitz #define AR8033_DEBUG_RGMII_RX_CLK_DLY_REG 0x00 122fc300e2cSDmitry Lifshitz #define AR8033_DEBUG_RGMII_TX_CLK_DLY_REG 0x05 123fc300e2cSDmitry Lifshitz #define AR8033_DEBUG_RGMII_RX_CLK_DLY_MASK (1 << 15) 124fc300e2cSDmitry Lifshitz #define AR8033_DEBUG_RGMII_TX_CLK_DLY_MASK (1 << 8) 125fc300e2cSDmitry Lifshitz 126fc300e2cSDmitry Lifshitz /* 127fc300e2cSDmitry Lifshitz * cl_som_am57x_rgmii_clk_delay() - Set RGMII clock delay. 128fc300e2cSDmitry Lifshitz * Enable RX delay, disable TX delay. 129fc300e2cSDmitry Lifshitz */ 130fc300e2cSDmitry Lifshitz static void cl_som_am57x_rgmii_clk_delay(void) 131fc300e2cSDmitry Lifshitz { 132fc300e2cSDmitry Lifshitz uint16_t mii_reg_val; 133fc300e2cSDmitry Lifshitz const char *devname; 134fc300e2cSDmitry Lifshitz 135fc300e2cSDmitry Lifshitz devname = miiphy_get_current_dev(); 136fc300e2cSDmitry Lifshitz /* PHY 2 */ 137fc300e2cSDmitry Lifshitz miiphy_write(devname, CL_SOM_AM57X_PHY_ADDR2, AR8033_PHY_DEBUG_ADDR_REG, 138fc300e2cSDmitry Lifshitz AR8033_DEBUG_RGMII_RX_CLK_DLY_REG); 139fc300e2cSDmitry Lifshitz miiphy_read(devname, CL_SOM_AM57X_PHY_ADDR2, AR8033_PHY_DEBUG_DATA_REG, 140fc300e2cSDmitry Lifshitz &mii_reg_val); 141fc300e2cSDmitry Lifshitz mii_reg_val |= AR8033_DEBUG_RGMII_RX_CLK_DLY_MASK; 142fc300e2cSDmitry Lifshitz miiphy_write(devname, CL_SOM_AM57X_PHY_ADDR2, AR8033_PHY_DEBUG_DATA_REG, 143fc300e2cSDmitry Lifshitz mii_reg_val); 144fc300e2cSDmitry Lifshitz 145fc300e2cSDmitry Lifshitz miiphy_write(devname, CL_SOM_AM57X_PHY_ADDR2, AR8033_PHY_DEBUG_ADDR_REG, 146fc300e2cSDmitry Lifshitz AR8033_DEBUG_RGMII_TX_CLK_DLY_REG); 147fc300e2cSDmitry Lifshitz miiphy_read(devname, CL_SOM_AM57X_PHY_ADDR2, AR8033_PHY_DEBUG_DATA_REG, 148fc300e2cSDmitry Lifshitz &mii_reg_val); 149fc300e2cSDmitry Lifshitz mii_reg_val &= ~AR8033_DEBUG_RGMII_TX_CLK_DLY_MASK; 150fc300e2cSDmitry Lifshitz miiphy_write(devname, CL_SOM_AM57X_PHY_ADDR2, AR8033_PHY_DEBUG_DATA_REG, 151fc300e2cSDmitry Lifshitz mii_reg_val); 152fc300e2cSDmitry Lifshitz } 153fc300e2cSDmitry Lifshitz 154fc300e2cSDmitry Lifshitz #define CL_SOM_AM57X_GPIO_PHY1_RST 92 /* GPIO3_28 */ 155fc300e2cSDmitry Lifshitz #define CL_SOM_AM57X_RGMII_PORT1 1 156fc300e2cSDmitry Lifshitz 157fc300e2cSDmitry Lifshitz int board_eth_init(bd_t *bis) 158fc300e2cSDmitry Lifshitz { 159fc300e2cSDmitry Lifshitz int ret; 160fc300e2cSDmitry Lifshitz uint32_t ctrl_val; 161fc300e2cSDmitry Lifshitz char *cpsw_phy_envval; 162fc300e2cSDmitry Lifshitz int cpsw_act_phy = 1; 163fc300e2cSDmitry Lifshitz 164fc300e2cSDmitry Lifshitz /* SB-SOM-AM57x primary Eth (P21) is routed to RGMII1 */ 165fc300e2cSDmitry Lifshitz ret = cl_som_am57x_handle_mac_address("ethaddr", 166fc300e2cSDmitry Lifshitz CL_SOM_AM57X_RGMII_PORT1); 167fc300e2cSDmitry Lifshitz 168fc300e2cSDmitry Lifshitz if (ret) 169fc300e2cSDmitry Lifshitz return -1; 170fc300e2cSDmitry Lifshitz 171fc300e2cSDmitry Lifshitz /* Select RGMII for GMII1_SEL */ 172fc300e2cSDmitry Lifshitz ctrl_val = readl((*ctrl)->control_core_control_io1) & (~0x33); 173fc300e2cSDmitry Lifshitz ctrl_val |= 0x22; 174fc300e2cSDmitry Lifshitz writel(ctrl_val, (*ctrl)->control_core_control_io1); 175fc300e2cSDmitry Lifshitz mdelay(10); 176fc300e2cSDmitry Lifshitz 177fc300e2cSDmitry Lifshitz gpio_request(CL_SOM_AM57X_GPIO_PHY1_RST, "phy1_rst"); 178fc300e2cSDmitry Lifshitz gpio_direction_output(CL_SOM_AM57X_GPIO_PHY1_RST, 0); 179fc300e2cSDmitry Lifshitz mdelay(20); 180fc300e2cSDmitry Lifshitz 181fc300e2cSDmitry Lifshitz gpio_set_value(CL_SOM_AM57X_GPIO_PHY1_RST, 1); 182fc300e2cSDmitry Lifshitz mdelay(20); 183fc300e2cSDmitry Lifshitz 184fc300e2cSDmitry Lifshitz cpsw_phy_envval = getenv("cpsw_phy"); 185fc300e2cSDmitry Lifshitz if (cpsw_phy_envval != NULL) 186fc300e2cSDmitry Lifshitz cpsw_act_phy = simple_strtoul(cpsw_phy_envval, NULL, 0); 187fc300e2cSDmitry Lifshitz 188fc300e2cSDmitry Lifshitz cl_som_am57_cpsw_data.active_slave = cpsw_act_phy; 189fc300e2cSDmitry Lifshitz 190fc300e2cSDmitry Lifshitz ret = cpsw_register(&cl_som_am57_cpsw_data); 191fc300e2cSDmitry Lifshitz if (ret < 0) 192fc300e2cSDmitry Lifshitz printf("Error %d registering CPSW switch\n", ret); 193fc300e2cSDmitry Lifshitz 194fc300e2cSDmitry Lifshitz /* Set RGMII clock delay */ 195fc300e2cSDmitry Lifshitz cl_som_am57x_rgmii_clk_delay(); 196fc300e2cSDmitry Lifshitz 197fc300e2cSDmitry Lifshitz return ret; 198fc300e2cSDmitry Lifshitz } 199