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