// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2015 Stefan Roese <sr@denx.de>
 * Copyright (C) 2016 Mario Six <mario.six@gdsys.cc>
 */

#include <common.h>
#include <command.h>
#include <dm.h>
#include <event.h>
#include <init.h>
#include <miiphy.h>
#include <net.h>
#include <tpm-v1.h>
#include <asm/global_data.h>
#include <asm/io.h>
#include <asm/arch/cpu.h>
#include <asm-generic/gpio.h>
#include <linux/delay.h>

#include "../drivers/ddr/marvell/a38x/ddr3_init.h"
#include "../arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.h"

#include "keyprogram.h"
#include "dt_helpers.h"
#include "hydra.h"
#include "ihs_phys.h"

DECLARE_GLOBAL_DATA_PTR;

#define DB_GP_88F68XX_GPP_OUT_ENA_LOW	0x7fffffff
#define DB_GP_88F68XX_GPP_OUT_ENA_MID	0xffffefff

#define DB_GP_88F68XX_GPP_OUT_VAL_LOW	0x0
#define DB_GP_88F68XX_GPP_OUT_VAL_MID	0x00001000
#define DB_GP_88F68XX_GPP_POL_LOW	0x0
#define DB_GP_88F68XX_GPP_POL_MID	0x0

/*
 * Define the DDR layout / topology here in the board file. This will
 * be used by the DDR3 init code in the SPL U-Boot version to configure
 * the DDR3 controller.
 */
static struct mv_ddr_topology_map ddr_topology_map = {
	DEBUG_LEVEL_ERROR,
	0x1, /* active interfaces */
	/* cs_mask, mirror, dqs_swap, ck_swap X PUPs */
	{ { { {0x1, 0, 0, 0},
	      {0x1, 0, 0, 0},
	      {0x1, 0, 0, 0},
	      {0x1, 0, 0, 0},
	      {0x1, 0, 0, 0} },
	    SPEED_BIN_DDR_1600K,	/* speed_bin */
	    MV_DDR_DEV_WIDTH_16BIT,	/* memory_width */
	    MV_DDR_DIE_CAP_4GBIT,	/* mem_size */
	    MV_DDR_FREQ_533,		/* frequency */
	    0, 0,			/* cas_wl cas_l */
	    MV_DDR_TEMP_LOW,		/* temperature */
	    MV_DDR_TIM_DEFAULT} },	/* timing */
	BUS_MASK_32BIT,			/* Busses mask */
	MV_DDR_CFG_DEFAULT,		/* ddr configuration data source */
	NOT_COMBINED,			/* ddr twin-die combined */
	{ {0} },			/* raw spd data */
	{0}				/* timing parameters */

};

static struct serdes_map serdes_topology_map[] = {
	{SGMII0, SERDES_SPEED_1_25_GBPS, SERDES_DEFAULT_MODE, 0, 0},
	{USB3_HOST0, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0},
	/* SATA tx polarity is inverted */
	{SATA1, SERDES_SPEED_3_GBPS, SERDES_DEFAULT_MODE, 0, 1},
	{SGMII2, SERDES_SPEED_1_25_GBPS, SERDES_DEFAULT_MODE, 0, 0},
	{DEFAULT_SERDES, SERDES_SPEED_3_GBPS, SERDES_DEFAULT_MODE, 0, 0},
	{PEX2, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0}
};

int hws_board_topology_load(struct serdes_map **serdes_map_array, u8 *count)
{
	*serdes_map_array = serdes_topology_map;
	*count = ARRAY_SIZE(serdes_topology_map);
	return 0;
}

void spl_board_init(void)
{
#ifdef CONFIG_SPL_BUILD
	uint k;
	struct gpio_desc gpio = {};

	/* Enable PCIe link 2 */
	setbits_32(MVEBU_REGISTER(0x18204), BIT(2));
	mdelay(10);

	if (!request_gpio_by_name(&gpio, "pca9698@22", 31, "fpga-program-gpio")) {
		/* prepare FPGA reconfiguration */
		dm_gpio_set_dir_flags(&gpio, GPIOD_IS_OUT);
		dm_gpio_set_value(&gpio, 0);

		/* give lunatic PCIe clock some time to stabilize */
		mdelay(500);

		/* start FPGA reconfiguration */
		dm_gpio_set_dir_flags(&gpio, GPIOD_IS_IN);
	}

	/* wait for FPGA done */
	if (!request_gpio_by_name(&gpio, "pca9698@22", 19, "fpga-done-gpio")) {
		for (k = 0; k < 20; ++k) {
			if (dm_gpio_get_value(&gpio)) {
				printf("FPGA done after %u rounds\n", k);
				break;
			}
			mdelay(100);
		}
	}

	/* disable FPGA reset */
	if (!request_gpio_by_name(&gpio, "gpio@18100", 6, "cpu-to-fpga-reset")) {
		dm_gpio_set_dir_flags(&gpio, GPIOD_IS_OUT);
		dm_gpio_set_value(&gpio, 1);
	}

	/* wait for FPGA ready */
	if (!request_gpio_by_name(&gpio, "pca9698@22", 27, "fpga-ready-gpio")) {
		for (k = 0; k < 2; ++k) {
			if (!dm_gpio_get_value(&gpio))
				break;
			mdelay(100);
		}
	}
#endif
}

struct mv_ddr_topology_map *mv_ddr_topology_map_get(void)
{
	return &ddr_topology_map;
}

int board_early_init_f(void)
{
#ifdef CONFIG_SPL_BUILD
	/* Configure MPP */
	writel(0x00111111, MVEBU_MPP_BASE + 0x00);
	writel(0x40040000, MVEBU_MPP_BASE + 0x04);
	writel(0x00466444, MVEBU_MPP_BASE + 0x08);
	writel(0x00043300, MVEBU_MPP_BASE + 0x0c);
	writel(0x44400000, MVEBU_MPP_BASE + 0x10);
	writel(0x20000334, MVEBU_MPP_BASE + 0x14);
	writel(0x40000000, MVEBU_MPP_BASE + 0x18);
	writel(0x00004444, MVEBU_MPP_BASE + 0x1c);

	/* Set GPP Out value */
	writel(DB_GP_88F68XX_GPP_OUT_VAL_LOW, MVEBU_GPIO0_BASE + 0x00);
	writel(DB_GP_88F68XX_GPP_OUT_VAL_MID, MVEBU_GPIO1_BASE + 0x00);

	/* Set GPP Polarity */
	writel(DB_GP_88F68XX_GPP_POL_LOW, MVEBU_GPIO0_BASE + 0x0c);
	writel(DB_GP_88F68XX_GPP_POL_MID, MVEBU_GPIO1_BASE + 0x0c);

	/* Set GPP Out Enable */
	writel(DB_GP_88F68XX_GPP_OUT_ENA_LOW, MVEBU_GPIO0_BASE + 0x04);
	writel(DB_GP_88F68XX_GPP_OUT_ENA_MID, MVEBU_GPIO1_BASE + 0x04);
#endif

	return 0;
}

int board_init(void)
{
	/* Address of boot parameters */
	gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;

	return 0;
}

#ifndef CONFIG_SPL_BUILD
void init_host_phys(struct mii_dev *bus)
{
	uint k;

	for (k = 0; k < 2; ++k) {
		struct phy_device *phydev;

		phydev = phy_find_by_mask(bus, 1 << k);

		if (phydev) {
			phydev->interface = PHY_INTERFACE_MODE_SGMII;
			phy_config(phydev);
		}
	}
}

int ccdc_eth_init(void)
{
	uint k;
	uint octo_phy_mask = 0;
	int ret;
	struct mii_dev *bus;

	/* Init SoC's phys */
	bus = miiphy_get_dev_by_name("ethernet@34000");

	if (bus)
		init_host_phys(bus);

	bus = miiphy_get_dev_by_name("ethernet@70000");

	if (bus)
		init_host_phys(bus);

	/* Init octo phys */
	octo_phy_mask = calculate_octo_phy_mask();

	printf("IHS PHYS: %08x", octo_phy_mask);

	ret = init_octo_phys(octo_phy_mask);

	if (ret)
		return ret;

	printf("\n");

	if (!get_fpga()) {
		puts("fpga was NULL\n");
		return 1;
	}

	/* reset all FPGA-QSGMII instances */
	for (k = 0; k < 80; ++k)
		writel(1 << 31, get_fpga()->qsgmii_port_state[k]);

	udelay(100);

	for (k = 0; k < 80; ++k)
		writel(0, get_fpga()->qsgmii_port_state[k]);
	return 0;
}

#endif

int board_late_init(void)
{
#ifndef CONFIG_SPL_BUILD
	hydra_initialize();
#endif
	return 0;
}

int board_fix_fdt(void *rw_fdt_blob)
{
	struct udevice *bus = NULL;
	uint k;
	char name[64];
	int err;

	err = uclass_get_device_by_name(UCLASS_I2C, "i2c@11000", &bus);

	if (err) {
		printf("Could not get I2C bus.\n");
		return err;
	}

	for (k = 0x21; k <= 0x26; k++) {
		snprintf(name, 64,
			 "/soc/internal-regs/i2c@11000/pca9698@%02x", k);

		if (!dm_i2c_simple_probe(bus, k))
			fdt_disable_by_ofname(rw_fdt_blob, name);
	}

	return 0;
}

#ifndef CONFIG_SPL_BUILD
static int last_stage_init(void)
{
	struct udevice *tpm;
	int ret;

	if (IS_ENABLED(CONFIG_SPL_BUILD))
		return 0;
	ccdc_eth_init();

	ret = uclass_first_device_err(UCLASS_TPM, &tpm);
	if (ret) {
		printf("Could not find TPM (ret=%d)\n", ret);
		return ret;
	}

	if (ret || tpm_init(tpm) || tpm1_startup(tpm, TPM_ST_CLEAR) ||
	    tpm1_continue_self_test(tpm)) {
		return 1;
	}

	mdelay(37);

	flush_keys(tpm);
	load_and_run_keyprog(tpm);

	return 0;
}
EVENT_SPY_SIMPLE(EVT_LAST_STAGE_INIT, last_stage_init);
#endif
