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

#include <common.h>
#include <i2c.h>
#include <miiphy.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");

	return 0;
}
