// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2015 Stefan Roese <sr@denx.de>
 */

#include <common.h>
#include <i2c.h>
#include <miiphy.h>
#include <net.h>
#include <netdev.h>
#include <asm/io.h>
#include <asm/arch/cpu.h>
#include <asm/arch/soc.h>
#include "../common/tlv_data.h"

#include "../drivers/ddr/marvell/a38x/ddr3_init.h"
#include <../serdes/a38x/high_speed_env_spec.h>

DECLARE_GLOBAL_DATA_PTR;

/*
 * Those values and defines are taken from the Marvell U-Boot version
 * "u-boot-2013.01-15t1-clearfog"
 */
#define BOARD_GPP_OUT_ENA_LOW	0xffffffff
#define BOARD_GPP_OUT_ENA_MID	0xffffffff

#define BOARD_GPP_OUT_VAL_LOW	0x0
#define BOARD_GPP_OUT_VAL_MID	0x0
#define BOARD_GPP_POL_LOW	0x0
#define BOARD_GPP_POL_MID	0x0

static struct tlv_data cf_tlv_data;

static void cf_read_tlv_data(void)
{
	static bool read_once;

	if (read_once)
		return;
	read_once = true;

	read_tlv_data(&cf_tlv_data);
}

/* The starting board_serdes_map reflects original Clearfog Pro usage */
static struct serdes_map board_serdes_map[] = {
	{SATA0, SERDES_SPEED_3_GBPS, SERDES_DEFAULT_MODE, 0, 0},
	{SGMII1, SERDES_SPEED_1_25_GBPS, SERDES_DEFAULT_MODE, 0, 0},
	{PEX1, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
	{USB3_HOST1, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0},
	{PEX2, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
	{SGMII2, SERDES_SPEED_1_25_GBPS, SERDES_DEFAULT_MODE, 0, 0},
};

void config_cfbase_serdes_map(void)
{
	board_serdes_map[4].serdes_type = USB3_HOST0;
	board_serdes_map[4].serdes_speed = SERDES_SPEED_5_GBPS;
	board_serdes_map[4].serdes_mode = SERDES_DEFAULT_MODE;
}

int hws_board_topology_load(struct serdes_map **serdes_map_array, u8 *count)
{
	cf_read_tlv_data();

	/* Apply build configuration options before runtime configuration */
	if (IS_ENABLED(CONFIG_CLEARFOG_SFP_25GB))
		board_serdes_map[5].serdes_speed = SERDES_SPEED_3_125_GBPS;

	if (IS_ENABLED(CONFIG_CLEARFOG_CON2_SATA)) {
		board_serdes_map[4].serdes_type = SATA2;
		board_serdes_map[4].serdes_speed = SERDES_SPEED_3_GBPS;
		board_serdes_map[4].serdes_mode = SERDES_DEFAULT_MODE;
		board_serdes_map[4].swap_rx = 1;
	}

	if (IS_ENABLED(CONFIG_CLEARFOG_CON3_SATA)) {
		board_serdes_map[2].serdes_type = SATA1;
		board_serdes_map[2].serdes_speed = SERDES_SPEED_3_GBPS;
		board_serdes_map[2].serdes_mode = SERDES_DEFAULT_MODE;
		board_serdes_map[2].swap_rx = 1;
	}

	/* Apply runtime detection changes */
	if (sr_product_is(&cf_tlv_data, "Clearfog GTR")) {
		board_serdes_map[0].serdes_type = PEX0;
		board_serdes_map[0].serdes_speed = SERDES_SPEED_5_GBPS;
		board_serdes_map[0].serdes_mode = PEX_ROOT_COMPLEX_X1;
	} else if (sr_product_is(&cf_tlv_data, "Clearfog Pro")) {
		/* handle recognized product as noop, no adjustment required */
	} else if (sr_product_is(&cf_tlv_data, "Clearfog Base")) {
		config_cfbase_serdes_map();
	} else {
		/*
		 * Fallback to static default. EEPROM TLV support is not
		 * enabled, runtime detection failed, hardware support is not
		 * present, EEPROM is corrupt, or an unrecognized product name
		 * is present.
		 */
		if (IS_ENABLED(CONFIG_SPL_CMD_TLV_EEPROM))
			puts("EEPROM TLV detection failed: ");
		puts("Using static config for ");
		if (IS_ENABLED(CONFIG_TARGET_CLEARFOG_BASE)) {
			puts("Clearfog Base.\n");
			config_cfbase_serdes_map();
		} else {
			puts("Clearfog Pro.\n");
		}
	}

	*serdes_map_array = board_serdes_map;
	*count = ARRAY_SIZE(board_serdes_map);
	return 0;
}

/*
 * 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 board_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_800,		/* 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 */
	{ {0} },			/* raw spd data */
	{0},				/* timing parameters */
	{ {0} },			/* electrical configuration */
	{0,},				/* electrical parameters */
	0x3,				/* clock enable mask */
};

struct mv_ddr_topology_map *mv_ddr_topology_map_get(void)
{
	struct if_params *ifp = &board_topology_map.interface_params[0];

	cf_read_tlv_data();

	switch (cf_tlv_data.ram_size) {
	case 4:
	default:
		ifp->memory_size = MV_DDR_DIE_CAP_4GBIT;
		break;
	case 8:
		ifp->memory_size = MV_DDR_DIE_CAP_8GBIT;
		break;
	}

	/* Return the board topology as defined in the board code */
	return &board_topology_map;
}

int board_early_init_f(void)
{
	/* Configure MPP */
	writel(0x11111111, MVEBU_MPP_BASE + 0x00);
	writel(0x11111111, MVEBU_MPP_BASE + 0x04);
	writel(0x10400011, MVEBU_MPP_BASE + 0x08);
	writel(0x22043333, MVEBU_MPP_BASE + 0x0c);
	writel(0x44400002, MVEBU_MPP_BASE + 0x10);
	writel(0x41144004, MVEBU_MPP_BASE + 0x14);
	writel(0x40333333, MVEBU_MPP_BASE + 0x18);
	writel(0x00004444, MVEBU_MPP_BASE + 0x1c);

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

	/* Set GPP Polarity */
	writel(BOARD_GPP_POL_LOW, MVEBU_GPIO0_BASE + 0x0c);
	writel(BOARD_GPP_POL_MID, MVEBU_GPIO1_BASE + 0x0c);

	/* Set GPP Out Enable */
	writel(BOARD_GPP_OUT_ENA_LOW, MVEBU_GPIO0_BASE + 0x04);
	writel(BOARD_GPP_OUT_ENA_MID, MVEBU_GPIO1_BASE + 0x04);

	return 0;
}

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

	/* Toggle GPIO41 to reset onboard switch and phy */
	clrbits_le32(MVEBU_GPIO1_BASE + 0x0, BIT(9));
	clrbits_le32(MVEBU_GPIO1_BASE + 0x4, BIT(9));
	/* GPIO 19 on ClearFog rev 2.1 controls the uSOM onboard phy reset */
	clrbits_le32(MVEBU_GPIO0_BASE + 0x0, BIT(19));
	clrbits_le32(MVEBU_GPIO0_BASE + 0x4, BIT(19));
	mdelay(1);
	setbits_le32(MVEBU_GPIO1_BASE + 0x0, BIT(9));
	setbits_le32(MVEBU_GPIO0_BASE + 0x0, BIT(19));
	mdelay(10);

	return 0;
}

int checkboard(void)
{
	char *board = "Clearfog Pro";
	if (IS_ENABLED(CONFIG_TARGET_CLEARFOG_BASE))
		board = "Clearfog Base";

	cf_read_tlv_data();
	if (strlen(cf_tlv_data.tlv_product_name[0]) > 0)
		board = cf_tlv_data.tlv_product_name[0];

	printf("Board: SolidRun %s", board);
	if (strlen(cf_tlv_data.tlv_product_name[1]) > 0)
		printf(", %s", cf_tlv_data.tlv_product_name[1]);
	puts("\n");

	return 0;
}

int board_eth_init(bd_t *bis)
{
	cpu_eth_init(bis); /* Built in controller(s) come first */
	return pci_eth_init(bis);
}

int board_late_init(void)
{
	cf_read_tlv_data();

	if (sr_product_is(&cf_tlv_data, "Clearfog Base"))
		env_set("fdtfile", "armada-388-clearfog-base.dtb");
	else if (sr_product_is(&cf_tlv_data, "Clearfog GTR S4"))
		env_set("fdtfile", "armada-385-clearfog-gtr-s4.dtb");
	else if (sr_product_is(&cf_tlv_data, "Clearfog GTR L8"))
		env_set("fdtfile", "armada-385-clearfog-gtr-l8.dtb");
	else if (IS_ENABLED(CONFIG_TARGET_CLEARFOG_BASE))
		env_set("fdtfile", "armada-388-clearfog-base.dtb");
	else
		env_set("fdtfile", "armada-388-clearfog-pro.dtb");

	return 0;
}
