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