/*
 * Copyright (C) Marvell International Ltd. and its affiliates
 *
 * SPDX-License-Identifier:	GPL-2.0
 */

#include <common.h>
#include <spl.h>
#include <asm/io.h>
#include <asm/arch/cpu.h>
#include <asm/arch/soc.h>

#include "high_speed_env_spec.h"
#include "sys_env_lib.h"

#define SERDES_VERION	"2.0"

u8 selectors_serdes_rev1_map[LAST_SERDES_TYPE][MAX_SERDES_LANES] = {
	/* 0  1    2    3    4    5 */
	{0x1, 0x1, NA,  NA,  NA,  NA},		/* PEX0 */
	{NA,  0x2, 0x1, NA,  0x1, NA},		/* PEX1 */
	{NA,  NA,  0x2, NA,  NA,  0x1},		/* PEX2 */
	{NA,  NA,  NA,  0x1, NA,  NA},		/* PEX3 */
	{0x2, 0x3, NA,  NA,  NA,  NA},		/* SATA0 */
	{NA,  NA,  0x3, NA,  0x2, NA},		/* SATA1 */
	{NA,  NA,  NA,  NA,  0x6, 0x2},		/* SATA2 */
	{NA,  NA,  NA,  0x3, NA,  NA},		/* SATA3 */
	{0x3, 0x4, NA,  NA,  NA,  NA},		/* SGMII0 */
	{NA,  0x5, 0x4, NA,  0x3, NA},		/* SGMII1 */
	{NA,  NA,  NA,  0x4, NA,  0x3},		/* SGMII2 */
	{NA,  0x7, NA,  NA,  NA,  NA},		/* QSGMII */
	{NA,  0x6, NA,  NA,  0x4, NA},		/* USB3_HOST0 */
	{NA,  NA,  NA,  0x5, NA,  0x4},		/* USB3_HOST1 */
	{NA,  NA,  NA,  0x6, 0x5, 0x5},		/* USB3_DEVICE */
	{0x0, 0x0, 0x0, 0x0, 0x0, 0x0}		/* DEFAULT_SERDES */
};

int hws_serdes_seq_init(void)
{
	DEBUG_INIT_FULL_S("\n### serdes_seq_init ###\n");

	if (hws_serdes_seq_db_init() != MV_OK) {
		printf("hws_serdes_seq_init: Error: Serdes initialization fail\n");
		return MV_FAIL;
	}

	return MV_OK;
}

int serdes_power_up_ctrl_ext(u32 serdes_num, int serdes_power_up,
			     enum serdes_type serdes_type,
			     enum serdes_speed baud_rate,
			     enum serdes_mode serdes_mode,
			     enum ref_clock ref_clock)
{
	return MV_NOT_SUPPORTED;
}

u32 hws_serdes_silicon_ref_clock_get(void)
{
	DEBUG_INIT_FULL_S("\n### hws_serdes_silicon_ref_clock_get ###\n");

	return REF_CLOCK_25MHZ;
}

u32 hws_serdes_get_max_lane(void)
{
	switch (sys_env_device_id_get()) {
	case MV_6811:		/* A381/A3282: 6811/6821: single/dual cpu */
		return 4;
	case MV_6810:
		return 5;
	case MV_6820:
	case MV_6828:
		return 6;
	default:		/* not the right module */
		printf("%s: Device ID Error, using 4 SerDes lanes\n",
		       __func__);
		return 4;
	}
	return 6;
}

int hws_is_serdes_active(u8 lane_num)
{
	int ret = 1;

	/* Maximum lane count for A388 (6828) is 6 */
	if (lane_num > 6)
		ret = 0;

	/* 4th Lane (#4 on Device 6810 is not Active */
	if (sys_env_device_id_get() == MV_6810 && lane_num == 4) {
		printf("%s: Error: Lane#4 on Device 6810 is not Active.\n",
		       __func__);
		return 0;
	}

	/*
	 * 6th Lane (#5) on Device 6810 is Active, even though 6810
	 * has only 5 lanes
	 */
	if (sys_env_device_id_get() == MV_6810 && lane_num == 5)
		return 1;

	if (lane_num >= hws_serdes_get_max_lane())
		ret = 0;

	return ret;
}

int hws_get_ext_base_addr(u32 serdes_num, u32 base_addr, u32 unit_base_offset,
			  u32 *unit_base_reg, u32 *unit_offset)
{
	*unit_base_reg = base_addr;
	*unit_offset = unit_base_offset;

	return MV_OK;
}

/*
 * hws_serdes_get_phy_selector_val
 *
 * DESCRIPTION: Get the mapping of Serdes Selector values according to the
 *              Serdes revision number
 * INPUT:    serdes_num - Serdes number
 *           serdes_type - Serdes type
 * OUTPUT: None
 * RETURN:
 *       Mapping of Serdes Selector values
 */
u32 hws_serdes_get_phy_selector_val(int serdes_num,
				    enum serdes_type serdes_type)
{
	if (serdes_type >= LAST_SERDES_TYPE)
		return 0xff;

	if (hws_ctrl_serdes_rev_get() == MV_SERDES_REV_1_2) {
		return selectors_serdes_rev1_map
			[serdes_type][serdes_num];
	} else
		return selectors_serdes_rev2_map
			[serdes_type][serdes_num];
}

u32 hws_get_physical_serdes_num(u32 serdes_num)
{
	if ((serdes_num == 4) && (sys_env_device_id_get() == MV_6810)) {
		/*
		 * For 6810, there are 5 Serdes and Serdes Num 4 doesn't
		 * exist. Instead Serdes Num 5 is connected.
		 */
		return 5;
	} else {
		return serdes_num;
	}
}
