// SPDX-License-Identifier: GPL-2.0+
/*
 * U-Boot board functions for CompuLab CL-SOM-iMX7 module
 *
 * (C) Copyright 2017 CompuLab, Ltd. http://www.compulab.com
 *
 * Author: Uri Mashiach <uri.mashiach@compulab.co.il>
 */

#include <common.h>
#include <env.h>
#include <init.h>
#include <mmc.h>
#include <net.h>
#include <phy.h>
#include <netdev.h>
#include <fsl_esdhc_imx.h>
#include <linux/delay.h>
#include <power/pmic.h>
#include <power/pfuze3000_pmic.h>
#include <asm/mach-imx/mxc_i2c.h>
#include <asm/mach-imx/iomux-v3.h>
#include <asm/arch-mx7/mx7-pins.h>
#include <asm/arch-mx7/sys_proto.h>
#include <asm/arch-mx7/clock.h>
#include "../common/eeprom.h"
#include "common.h"

DECLARE_GLOBAL_DATA_PTR;

#ifdef CONFIG_SYS_I2C_MXC

#define I2C_PAD_CTRL		(PAD_CTL_DSE_3P3V_32OHM | PAD_CTL_SRE_SLOW | \
				PAD_CTL_HYS)

#define CL_SOM_IMX7_GPIO_I2C2_SCL	IMX_GPIO_NR(1, 6)
#define CL_SOM_IMX7_GPIO_I2C2_SDA	IMX_GPIO_NR(1, 7)

static struct i2c_pads_info cl_som_imx7_i2c_pad_info2 = {
	.scl = {
		.i2c_mode = MX7D_PAD_GPIO1_IO06__I2C2_SCL |
			MUX_PAD_CTRL(I2C_PAD_CTRL),
		.gpio_mode = MX7D_PAD_GPIO1_IO06__GPIO1_IO6 |
			MUX_PAD_CTRL(I2C_PAD_CTRL),
		.gp = CL_SOM_IMX7_GPIO_I2C2_SCL,
	},
	.sda = {
		.i2c_mode = MX7D_PAD_GPIO1_IO07__I2C2_SDA |
			MUX_PAD_CTRL(I2C_PAD_CTRL),
		.gpio_mode = MX7D_PAD_GPIO1_IO07__GPIO1_IO7 |
			MUX_PAD_CTRL(I2C_PAD_CTRL),
		.gp = CL_SOM_IMX7_GPIO_I2C2_SDA,
	},
};

/*
 * cl_som_imx7_setup_i2c() - I2C  pinmux configuration.
 */
static void cl_som_imx7_setup_i2c(void)
{
	setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &cl_som_imx7_i2c_pad_info2);
}
#else /* !CONFIG_SYS_I2C_MXC */
static void cl_som_imx7_setup_i2c(void) {}
#endif /* CONFIG_SYS_I2C_MXC */

int dram_init(void)
{
	gd->ram_size = imx_ddr_size();

	return 0;
}

#ifdef CONFIG_FSL_ESDHC_IMX

#define CL_SOM_IMX7_GPIO_USDHC3_PWR	IMX_GPIO_NR(6, 11)

static struct fsl_esdhc_cfg cl_som_imx7_usdhc_cfg[3] = {
	{USDHC1_BASE_ADDR, 0, 4},
	{USDHC3_BASE_ADDR},
};

int board_mmc_init(bd_t *bis)
{
	int i, ret;
	/*
	 * According to the board_mmc_init() the following map is done:
	 * (U-boot device node)    (Physical Port)
	 * mmc0                    USDHC1
	 * mmc2                    USDHC3 (eMMC)
	 */
	for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) {
		switch (i) {
		case 0:
			cl_som_imx7_usdhc1_pads_set();
			gpio_request(CL_SOM_IMX7_GPIO_USDHC1_CD, "usdhc1_cd");
			cl_som_imx7_usdhc_cfg[0].sdhc_clk =
				mxc_get_clock(MXC_ESDHC_CLK);
			break;
		case 1:
			cl_som_imx7_usdhc3_emmc_pads_set();
			gpio_request(CL_SOM_IMX7_GPIO_USDHC3_PWR, "usdhc3_pwr");
			gpio_direction_output(CL_SOM_IMX7_GPIO_USDHC3_PWR, 0);
			udelay(500);
			gpio_direction_output(CL_SOM_IMX7_GPIO_USDHC3_PWR, 1);
			cl_som_imx7_usdhc_cfg[1].sdhc_clk =
				mxc_get_clock(MXC_ESDHC3_CLK);
			break;
		default:
			printf("Warning: you configured more USDHC controllers "
				"(%d) than supported by the board\n", i + 1);
			return -EINVAL;
		}

		ret = fsl_esdhc_initialize(bis, &cl_som_imx7_usdhc_cfg[i]);
		if (ret)
			return ret;
	}

	return 0;
}
#endif /* CONFIG_FSL_ESDHC_IMX */

#ifdef CONFIG_FEC_MXC

#define CL_SOM_IMX7_ETH1_PHY_NRST	IMX_GPIO_NR(1, 4)

/*
 * cl_som_imx7_rgmii_rework() - Ethernet PHY configuration.
 */
static void cl_som_imx7_rgmii_rework(struct phy_device *phydev)
{
	unsigned short val;

	/* Ar8031 phy SmartEEE feature cause link status generates glitch,
	 * which cause ethernet link down/up issue, so disable SmartEEE
	 */
	phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x3);
	phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x805d);
	phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4003);
	val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
	val &= ~(0x1 << 8);
	phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val);

	/* To enable AR8031 ouput a 125MHz clk from CLK_25M */
	phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x7);
	phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016);
	phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007);

	val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
	val &= 0xffe3;
	val |= 0x18;
	phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val);

	/* introduce tx clock delay */
	phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5);
	val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
	val |= 0x0100;
	phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val);
}

int board_phy_config(struct phy_device *phydev)
{
	cl_som_imx7_rgmii_rework(phydev);

	if (phydev->drv->config)
		phydev->drv->config(phydev);

	return 0;
}

/*
 * cl_som_imx7_handle_mac_address() - set Ethernet MAC address environment.
 *
 * @env_var: MAC address environment variable
 * @eeprom_bus: I2C bus of the environment EEPROM
 *
 * @return: 0 on success, < 0 on failure
 */
static int cl_som_imx7_handle_mac_address(char *env_var, uint eeprom_bus)
{
	int ret;
	unsigned char enetaddr[6];

	ret = eth_env_get_enetaddr(env_var, enetaddr);
	if (ret)
		return 0;

	ret = cl_eeprom_read_mac_addr(enetaddr, eeprom_bus);
	if (ret)
		return ret;

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

	return eth_env_set_enetaddr(env_var, enetaddr);
}

#define CL_SOM_IMX7_FEC_DEV_ID_PRI 0

int board_eth_init(bd_t *bis)
{
	/* set Ethernet MAC address environment */
	cl_som_imx7_handle_mac_address("ethaddr", CONFIG_SYS_I2C_EEPROM_BUS);
	/* Ethernet interface pinmux configuration  */
	cl_som_imx7_phy1_rst_pads_set();
	cl_som_imx7_fec1_pads_set();
	/* PHY reset */
	gpio_request(CL_SOM_IMX7_ETH1_PHY_NRST, "eth1_phy_nrst");
	gpio_direction_output(CL_SOM_IMX7_ETH1_PHY_NRST, 0);
	mdelay(10);
	gpio_set_value(CL_SOM_IMX7_ETH1_PHY_NRST, 1);
	/* MAC initialization */
	return fecmxc_initialize_multi(bis, CL_SOM_IMX7_FEC_DEV_ID_PRI,
				       CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE);
}

/*
 * cl_som_imx7_setup_fec() - Ethernet MAC 1 clock configuration.
 * - ENET1 reference clock mode select.
 * - ENET1_TX_CLK output driver is disabled when configured for ALT1.
 */
static void cl_som_imx7_setup_fec(void)
{
	struct iomuxc_gpr_base_regs *const iomuxc_gpr_regs
		= (struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR;

	/* Use 125M anatop REF_CLK1 for ENET1, clear gpr1[13], gpr1[17]*/
	clrsetbits_le32(&iomuxc_gpr_regs->gpr[1],
			(IOMUXC_GPR_GPR1_GPR_ENET1_TX_CLK_SEL_MASK |
			 IOMUXC_GPR_GPR1_GPR_ENET1_CLK_DIR_MASK), 0);

	set_clk_enet(ENET_125MHZ);
}
#else /* !CONFIG_FEC_MXC */
static void cl_som_imx7_setup_fec(void) {}
#endif /* CONFIG_FEC_MXC */

#ifdef CONFIG_SPI

static void cl_som_imx7_spi_init(void)
{
	cl_som_imx7_espi1_pads_set();
}
#else /* !CONFIG_SPI */
static void cl_som_imx7_spi_init(void) {}
#endif /* CONFIG_SPI */

int board_early_init_f(void)
{
	cl_som_imx7_uart1_pads_set();
	cl_som_imx7_usb_otg1_pads_set();

	return 0;
}

int board_init(void)
{
	/* address of boot parameters */
	gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
	cl_som_imx7_setup_i2c();
	cl_som_imx7_setup_fec();
	cl_som_imx7_spi_init();

	return 0;
}

#ifdef CONFIG_POWER
#define I2C_PMIC	0
int power_init_board(void)
{
	struct pmic *p;
	int ret;
	unsigned int reg, rev_id;

	ret = power_pfuze3000_init(I2C_PMIC);
	if (ret)
		return ret;

	p = pmic_get("PFUZE3000");
	ret = pmic_probe(p);
	if (ret)
		return ret;

	pmic_reg_read(p, PFUZE3000_DEVICEID, &reg);
	pmic_reg_read(p, PFUZE3000_REVID, &rev_id);
	printf("PMIC: PFUZE3000 DEV_ID=0x%x REV_ID=0x%x\n", reg, rev_id);

	/* disable Low Power Mode during standby mode */
	pmic_reg_write(p, PFUZE3000_LDOGCTL, 0x1);

	return 0;
}
#endif /* CONFIG_POWER */

/*
 * cl_som_imx7_setup_wdog() - watchdog configuration.
 * - Output WDOG_B signal to reset external pmic.
 * - Suspend the watchdog timer during low-power modes.
 */
void cl_som_imx7_setup_wdog(void)
{
	struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR;

	cl_som_imx7_wdog_pads_set();
	set_wdog_reset(wdog);
       /*
	* Do not assert internal WDOG_RESET_B_DEB(controlled by bit 4),
	* since we use PMIC_PWRON to reset the board.
	*/
	clrsetbits_le16(&wdog->wcr, 0, 0x10);
}

int board_late_init(void)
{
	env_set("board_name", "CL-SOM-iMX7");
	cl_som_imx7_setup_wdog();
	return 0;
}

int checkboard(void)
{
	char *mode;

	if (IS_ENABLED(CONFIG_ARMV7_BOOT_SEC_DEFAULT))
		mode = "secure";
	else
		mode = "non-secure";

	printf("Board: CL-SOM-iMX7 in %s mode\n", mode);

	return 0;
}
