Home | History | Annotate | Download | only in a38x
      1 // SPDX-License-Identifier: GPL-2.0
      2 /*
      3  * Copyright (C) Marvell International Ltd. and its affiliates
      4  */
      5 
      6 #include <common.h>
      7 #include <spl.h>
      8 #include <asm/io.h>
      9 #include <asm/arch/cpu.h>
     10 #include <asm/arch/soc.h>
     11 
     12 #include "high_speed_env_spec.h"
     13 #include "sys_env_lib.h"
     14 
     15 u8 selectors_serdes_rev1_map[LAST_SERDES_TYPE][MAX_SERDES_LANES] = {
     16 	/* 0  1    2    3    4    5 */
     17 	{0x1, 0x1, NA,  NA,  NA,  NA},		/* PEX0 */
     18 	{NA,  0x2, 0x1, NA,  0x1, NA},		/* PEX1 */
     19 	{NA,  NA,  0x2, NA,  NA,  0x1},		/* PEX2 */
     20 	{NA,  NA,  NA,  0x1, NA,  NA},		/* PEX3 */
     21 	{0x2, 0x3, NA,  NA,  NA,  NA},		/* SATA0 */
     22 	{NA,  NA,  0x3, NA,  0x2, NA},		/* SATA1 */
     23 	{NA,  NA,  NA,  NA,  0x6, 0x2},		/* SATA2 */
     24 	{NA,  NA,  NA,  0x3, NA,  NA},		/* SATA3 */
     25 	{0x3, 0x4, NA,  NA,  NA,  NA},		/* SGMII0 */
     26 	{NA,  0x5, 0x4, NA,  0x3, NA},		/* SGMII1 */
     27 	{NA,  NA,  NA,  0x4, NA,  0x3},		/* SGMII2 */
     28 	{NA,  0x7, NA,  NA,  NA,  NA},		/* QSGMII */
     29 	{NA,  0x6, NA,  NA,  0x4, NA},		/* USB3_HOST0 */
     30 	{NA,  NA,  NA,  0x5, NA,  0x4},		/* USB3_HOST1 */
     31 	{NA,  NA,  NA,  0x6, 0x5, 0x5},		/* USB3_DEVICE */
     32 	{0x0, 0x0, 0x0, 0x0, 0x0, 0x0}		/* DEFAULT_SERDES */
     33 };
     34 
     35 int hws_serdes_seq_init(void)
     36 {
     37 	DEBUG_INIT_FULL_S("\n### serdes_seq_init ###\n");
     38 
     39 	if (hws_serdes_seq_db_init() != MV_OK) {
     40 		printf("hws_serdes_seq_init: Error: Serdes initialization fail\n");
     41 		return MV_FAIL;
     42 	}
     43 
     44 	return MV_OK;
     45 }
     46 
     47 int serdes_power_up_ctrl_ext(u32 serdes_num, int serdes_power_up,
     48 			     enum serdes_type serdes_type,
     49 			     enum serdes_speed baud_rate,
     50 			     enum serdes_mode serdes_mode,
     51 			     enum ref_clock ref_clock)
     52 {
     53 	return MV_NOT_SUPPORTED;
     54 }
     55 
     56 u32 hws_serdes_silicon_ref_clock_get(void)
     57 {
     58 	DEBUG_INIT_FULL_S("\n### hws_serdes_silicon_ref_clock_get ###\n");
     59 
     60 	return REF_CLOCK_25MHZ;
     61 }
     62 
     63 u32 hws_serdes_get_max_lane(void)
     64 {
     65 	switch (sys_env_device_id_get()) {
     66 	case MV_6811:		/* A381/A3282: 6811/6821: single/dual cpu */
     67 		return 4;
     68 	case MV_6810:
     69 		return 5;
     70 	case MV_6820:
     71 	case MV_6828:
     72 		return 6;
     73 	default:		/* not the right module */
     74 		printf("%s: Device ID Error, using 4 SerDes lanes\n",
     75 		       __func__);
     76 		return 4;
     77 	}
     78 	return 6;
     79 }
     80 
     81 int hws_is_serdes_active(u8 lane_num)
     82 {
     83 	int ret = 1;
     84 
     85 	/* Maximum lane count for A388 (6828) is 6 */
     86 	if (lane_num > 6)
     87 		ret = 0;
     88 
     89 	/* 4th Lane (#4 on Device 6810 is not Active */
     90 	if (sys_env_device_id_get() == MV_6810 && lane_num == 4) {
     91 		printf("%s: Error: Lane#4 on Device 6810 is not Active.\n",
     92 		       __func__);
     93 		return 0;
     94 	}
     95 
     96 	/*
     97 	 * 6th Lane (#5) on Device 6810 is Active, even though 6810
     98 	 * has only 5 lanes
     99 	 */
    100 	if (sys_env_device_id_get() == MV_6810 && lane_num == 5)
    101 		return 1;
    102 
    103 	if (lane_num >= hws_serdes_get_max_lane())
    104 		ret = 0;
    105 
    106 	return ret;
    107 }
    108 
    109 int hws_get_ext_base_addr(u32 serdes_num, u32 base_addr, u32 unit_base_offset,
    110 			  u32 *unit_base_reg, u32 *unit_offset)
    111 {
    112 	*unit_base_reg = base_addr;
    113 	*unit_offset = unit_base_offset;
    114 
    115 	return MV_OK;
    116 }
    117 
    118 /*
    119  * hws_serdes_get_phy_selector_val
    120  *
    121  * DESCRIPTION: Get the mapping of Serdes Selector values according to the
    122  *              Serdes revision number
    123  * INPUT:    serdes_num - Serdes number
    124  *           serdes_type - Serdes type
    125  * OUTPUT: None
    126  * RETURN:
    127  *       Mapping of Serdes Selector values
    128  */
    129 u32 hws_serdes_get_phy_selector_val(int serdes_num,
    130 				    enum serdes_type serdes_type)
    131 {
    132 	if (serdes_type >= LAST_SERDES_TYPE)
    133 		return 0xff;
    134 
    135 	if (hws_ctrl_serdes_rev_get() == MV_SERDES_REV_1_2) {
    136 		return selectors_serdes_rev1_map
    137 			[serdes_type][serdes_num];
    138 	} else
    139 		return selectors_serdes_rev2_map
    140 			[serdes_type][serdes_num];
    141 }
    142 
    143 u32 hws_get_physical_serdes_num(u32 serdes_num)
    144 {
    145 	if ((serdes_num == 4) && (sys_env_device_id_get() == MV_6810)) {
    146 		/*
    147 		 * For 6810, there are 5 Serdes and Serdes Num 4 doesn't
    148 		 * exist. Instead Serdes Num 5 is connected.
    149 		 */
    150 		return 5;
    151 	} else {
    152 		return serdes_num;
    153 	}
    154 }
    155