/*
 * 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_env_get_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_env_set_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 = env_get("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;
}
