/*
 * Board functions for Compulab CM-T54 board
 *
 * Copyright (C) 2014, Compulab Ltd - http://compulab.co.il/
 *
 * Author: Dmitry Lifshitz <lifshitz@compulab.co.il>
 *
 * SPDX-License-Identifier:     GPL-2.0+
 */

#include <common.h>
#include <fdt_support.h>
#include <usb.h>
#include <mmc.h>
#include <palmas.h>
#include <spl.h>

#include <asm/gpio.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/mmc_host_def.h>
#include <asm/arch/clock.h>
#include <asm/arch/ehci.h>
#include <asm/ehci-omap.h>

#include "../common/eeprom.h"

#define DIE_ID_REG_BASE		(OMAP54XX_L4_CORE_BASE + 0x2000)
#define DIE_ID_REG_OFFSET	0x200

DECLARE_GLOBAL_DATA_PTR;

#if !defined(CONFIG_SPL_BUILD)
inline void set_muxconf_regs(void){};
#endif

const struct omap_sysinfo sysinfo = {
	"Board: CM-T54\n"
};

/*
 * Routine: board_init
 * Description: hardware init.
 */
int board_init(void)
{
	gd->bd->bi_boot_params = (CONFIG_SYS_SDRAM_BASE + 0x100);

	return 0;
}

/*
 * Routine: cm_t54_palmas_regulator_set
 * Description:  select voltage and turn on/off Palmas PMIC regulator.
 */
static int cm_t54_palmas_regulator_set(u8 vreg, u8 vval, u8 creg, u8 cval)
{
	int err;

	/* Setup voltage */
	err = palmas_i2c_write_u8(TWL603X_CHIP_P1, vreg, vval);
	if (err) {
		printf("cm_t54: could not set regulator 0x%02x voltage : %d\n",
		       vreg, err);
		return err;
	}

	/* Turn on/off regulator */
	err = palmas_i2c_write_u8(TWL603X_CHIP_P1, creg, cval);
	if (err) {
		printf("cm_t54: could not turn on/off regulator 0x%02x : %d\n",
		       creg, err);
		return err;
	}

	return 0;
}

/*
 * Routine: mmc_get_env_part
 * Description:  setup environment storage device partition.
 */
#ifdef CONFIG_SYS_MMC_ENV_PART
uint mmc_get_env_part(struct mmc *mmc)
{
	u32 bootmode = gd->arch.omap_boot_mode;
	uint bootpart = CONFIG_SYS_MMC_ENV_PART;

	/*
	 * If booted from eMMC boot partition then force eMMC
	 * FIRST boot partition to be env storage
	 */
	if (bootmode == BOOT_DEVICE_MMC2)
		bootpart = 1;

	return bootpart;
}
#endif

#if defined(CONFIG_GENERIC_MMC) && !defined(CONFIG_SPL_BUILD)
#define SB_T54_CD_GPIO 228
#define SB_T54_WP_GPIO 229

int board_mmc_init(bd_t *bis)
{
	int ret0, ret1;

	ret0 = omap_mmc_init(0, 0, 0, SB_T54_CD_GPIO, SB_T54_WP_GPIO);
	if (ret0)
		printf("cm_t54: failed to initialize mmc0\n");

	ret1 = omap_mmc_init(1, 0, 0, -1, -1);
	if (ret1)
		printf("cm_t54: failed to initialize mmc1\n");

	if (ret0 && ret1)
		return -1;

	return 0;
}
#endif

#ifdef CONFIG_USB_HOST_ETHER

int ft_board_setup(void *blob, bd_t *bd)
{
	uint8_t enetaddr[6];

	/* MAC addr */
	if (eth_getenv_enetaddr("usbethaddr", enetaddr)) {
		fdt_find_and_setprop(blob, "/smsc95xx@0", "mac-address",
				     enetaddr, 6, 1);
	}

	return 0;
}

static void generate_mac_addr(uint8_t *enetaddr)
{
	int reg;

	reg = DIE_ID_REG_BASE + DIE_ID_REG_OFFSET;

	/*
	 * create a fake MAC address from the processor ID code.
	 * first byte is 0x02 to signify locally administered.
	 */
	enetaddr[0] = 0x02;
	enetaddr[1] = readl(reg + 0x10) & 0xff;
	enetaddr[2] = readl(reg + 0xC) & 0xff;
	enetaddr[3] = readl(reg + 0x8) & 0xff;
	enetaddr[4] = readl(reg) & 0xff;
	enetaddr[5] = (readl(reg) >> 8) & 0xff;
}

/*
 * Routine: handle_mac_address
 * Description: prepare MAC address for on-board Ethernet.
 */
static int handle_mac_address(void)
{
	uint8_t enetaddr[6];
	int ret;

	ret = eth_getenv_enetaddr("usbethaddr", enetaddr);
	if (ret)
		return 0;

	ret = cl_eeprom_read_mac_addr(enetaddr, CONFIG_SYS_I2C_EEPROM_BUS);
	if (ret || !is_valid_ethaddr(enetaddr))
		generate_mac_addr(enetaddr);

	if (!is_valid_ethaddr(enetaddr))
		return -1;

	return eth_setenv_enetaddr("usbethaddr", enetaddr);
}

int board_eth_init(bd_t *bis)
{
	return handle_mac_address();
}
#endif

#ifdef CONFIG_USB_EHCI
static struct omap_usbhs_board_data usbhs_bdata = {
	.port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
	.port_mode[1] = OMAP_EHCI_PORT_MODE_HSIC,
	.port_mode[2] = OMAP_EHCI_PORT_MODE_HSIC,
};

static void setup_host_clocks(bool enable)
{
	int usbhost_clk = OPTFCLKEN_HSIC60M_P3_CLK |
			  OPTFCLKEN_HSIC480M_P3_CLK |
			  OPTFCLKEN_HSIC60M_P2_CLK |
			  OPTFCLKEN_HSIC480M_P2_CLK |
			  OPTFCLKEN_UTMI_P3_CLK |
			  OPTFCLKEN_UTMI_P2_CLK;

	int usbtll_clk = OPTFCLKEN_USB_CH1_CLK_ENABLE |
			 OPTFCLKEN_USB_CH2_CLK_ENABLE;

	int usbhub_clk = CKOBUFFER_CLK_ENABLE_MASK;

	if (enable) {
		/* Enable port 2 and 3 clocks*/
		setbits_le32((*prcm)->cm_l3init_hsusbhost_clkctrl, usbhost_clk);
		/* Enable port 2 and 3 usb host ports tll clocks*/
		setbits_le32((*prcm)->cm_l3init_hsusbtll_clkctrl, usbtll_clk);
		/* Request FREF_XTAL_CLK clock for HSIC USB Hub */
		setbits_le32((*ctrl)->control_ckobuffer, usbhub_clk);
	} else {
		clrbits_le32((*ctrl)->control_ckobuffer, usbhub_clk);
		clrbits_le32((*prcm)->cm_l3init_hsusbtll_clkctrl, usbtll_clk);
		clrbits_le32((*prcm)->cm_l3init_hsusbhost_clkctrl, usbhost_clk);
	}
}

int ehci_hcd_init(int index, enum usb_init_type init,
		struct ehci_hccr **hccr, struct ehci_hcor **hcor)
{
	int ret;

	/* VCC_3V3_ETH */
	cm_t54_palmas_regulator_set(SMPS9_VOLTAGE, SMPS_VOLT_3V3, SMPS9_CTRL,
				    SMPS_MODE_SLP_AUTO | SMPS_MODE_ACT_AUTO);

	setup_host_clocks(true);

	ret = omap_ehci_hcd_init(index, &usbhs_bdata, hccr, hcor);
	if (ret < 0)
		printf("cm_t54: Failed to initialize ehci : %d\n", ret);

	return ret;
}

int ehci_hcd_stop(void)
{
	int ret = omap_ehci_hcd_stop();

	setup_host_clocks(false);

	cm_t54_palmas_regulator_set(SMPS9_VOLTAGE, SMPS_VOLT_OFF,
				    SMPS9_CTRL, SMPS_MODE_SLP_AUTO);

	return ret;
}

void usb_hub_reset_devices(int port)
{
	/* The LAN9730 needs to be reset after the port power has been set. */
	if (port == 3) {
		gpio_direction_output(CONFIG_OMAP_EHCI_PHY3_RESET_GPIO, 0);
		udelay(10);
		gpio_direction_output(CONFIG_OMAP_EHCI_PHY3_RESET_GPIO, 1);
	}
}
#endif

