blob: 12596ec2d8bdd1987aefd535e30071a2f181417b [file] [log] [blame]
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) Marvell International Ltd. and its affiliates
*/
#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"
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;
}
}