1 /* SPDX-License-Identifier: GPL-2.0-only */
2
3 #include <console/console.h>
4 #include <timer.h>
5 #include <soc/usb/qmp_usb_phy.h>
6 #include <soc/addressmap.h>
7
8 /* Only for QMP V3 PHY - QSERDES COM registers */
9 struct usb3_phy_qserdes_com_reg_layout {
10 u8 _reserved1[16];
11 u32 com_ssc_en_center;
12 u32 com_ssc_adj_per1;
13 u32 com_ssc_adj_per2;
14 u32 com_ssc_per1;
15 u32 com_ssc_per2;
16 u32 com_ssc_step_size1;
17 u32 com_ssc_step_size2;
18 u8 _reserved2[8];
19 u32 com_bias_en_clkbuflr_en;
20 u32 com_sys_clk_enable1;
21 u32 com_sys_clk_ctrl;
22 u32 com_sysclk_buf_enable;
23 u32 com_pll_en;
24 u32 com_pll_ivco;
25 u8 _reserved3[20];
26 u32 com_cp_ctrl_mode0;
27 u8 _reserved4[4];
28 u32 com_pll_rctrl_mode0;
29 u8 _reserved5[4];
30 u32 com_pll_cctrl_mode0;
31 u8 _reserved6[12];
32 u32 com_sysclk_en_sel;
33 u8 _reserved7[8];
34 u32 com_resetsm_ctrl2;
35 u32 com_lock_cmp_en;
36 u32 com_lock_cmp_cfg;
37 u32 com_lock_cmp1_mode0;
38 u32 com_lock_cmp2_mode0;
39 u32 com_lock_cmp3_mode0;
40 u8 _reserved8[12];
41 u32 com_dec_start_mode0;
42 u8 _reserved9[4];
43 u32 com_div_frac_start1_mode0;
44 u32 com_div_frac_start2_mode0;
45 u32 com_div_frac_start3_mode0;
46 u8 _reserved10[20];
47 u32 com_integloop_gain0_mode0;
48 u32 com_integloop_gain1_mode0;
49 u8 _reserved11[16];
50 u32 com_vco_tune_map;
51 u32 com_vco_tune1_mode0;
52 u32 com_vco_tune2_mode0;
53 u8 _reserved12[60];
54 u32 com_clk_select;
55 u32 com_hsclk_sel;
56 u8 _reserved13[8];
57 u32 com_coreclk_div_mode0;
58 u8 _reserved14[8];
59 u32 com_core_clk_en;
60 u32 com_c_ready_status;
61 u32 com_cmn_config;
62 u32 com_cmn_rate_override;
63 u32 com_svs_mode_clk_sel;
64 };
65 check_member(usb3_phy_qserdes_com_reg_layout, com_ssc_en_center, 0x010);
66 check_member(usb3_phy_qserdes_com_reg_layout, com_ssc_adj_per1, 0x014);
67 check_member(usb3_phy_qserdes_com_reg_layout, com_ssc_adj_per2, 0x018);
68 check_member(usb3_phy_qserdes_com_reg_layout, com_ssc_per1, 0x01c);
69 check_member(usb3_phy_qserdes_com_reg_layout, com_ssc_per2, 0x020);
70 check_member(usb3_phy_qserdes_com_reg_layout, com_bias_en_clkbuflr_en, 0x034);
71 check_member(usb3_phy_qserdes_com_reg_layout, com_pll_ivco, 0x048);
72 check_member(usb3_phy_qserdes_com_reg_layout, com_cp_ctrl_mode0, 0x060);
73 check_member(usb3_phy_qserdes_com_reg_layout, com_sysclk_en_sel, 0x080);
74 check_member(usb3_phy_qserdes_com_reg_layout, com_resetsm_ctrl2, 0x08c);
75 check_member(usb3_phy_qserdes_com_reg_layout, com_dec_start_mode0, 0x0b0);
76 check_member(usb3_phy_qserdes_com_reg_layout, com_div_frac_start1_mode0, 0x0b8);
77 check_member(usb3_phy_qserdes_com_reg_layout, com_integloop_gain0_mode0, 0x0d8);
78 check_member(usb3_phy_qserdes_com_reg_layout, com_vco_tune_map, 0x0f0);
79 check_member(usb3_phy_qserdes_com_reg_layout, com_clk_select, 0x138);
80 check_member(usb3_phy_qserdes_com_reg_layout, com_coreclk_div_mode0, 0x148);
81 check_member(usb3_phy_qserdes_com_reg_layout, com_core_clk_en, 0x154);
82 check_member(usb3_phy_qserdes_com_reg_layout, com_svs_mode_clk_sel, 0x164);
83
84 /* Only for QMP V3 PHY - TX registers */
85 struct usb3_phy_qserdes_tx_reg_layout {
86 u8 _reserved1[68];
87 u32 tx_res_code_lane_offset_tx;
88 u32 tx_res_code_lane_offset_rx;
89 u8 _reserved2[20];
90 u32 tx_highz_drvr_en;
91 u8 _reserved3[40];
92 u32 tx_lane_mode_1;
93 u8 _reserved4[20];
94 u32 tx_rcv_detect_lvl_2;
95 };
96 check_member(usb3_phy_qserdes_tx_reg_layout, tx_res_code_lane_offset_tx, 0x044);
97 check_member(usb3_phy_qserdes_tx_reg_layout, tx_res_code_lane_offset_rx, 0x048);
98 check_member(usb3_phy_qserdes_tx_reg_layout, tx_highz_drvr_en, 0x060);
99 check_member(usb3_phy_qserdes_tx_reg_layout, tx_lane_mode_1, 0x08c);
100 check_member(usb3_phy_qserdes_tx_reg_layout, tx_rcv_detect_lvl_2, 0x0a4);
101
102 /* Only for QMP V3 PHY - RX registers */
103 struct usb3_phy_qserdes_rx_reg_layout {
104 u8 _reserved1[8];
105 u32 rx_ucdr_fo_gain;
106 u32 rx_ucdr_so_gain_half;
107 u8 _reserved2[32];
108 u32 rx_ucdr_fastlock_fo_gain;
109 u32 rx_ucdr_so_saturtn_and_en;
110 u8 _reserved3[12];
111 u32 rx_ucdr_pi_cntrls;
112 u8 _reserved4[120];
113 u32 rx_vga_cal_ctrl2;
114 u8 _reserved5[16];
115 u32 rx_rx_equ_adap_ctrl2;
116 u32 rx_rx_equ_adap_ctrl3;
117 u32 rx_rx_equ_adap_ctrl4;
118 u8 _reserved6[24];
119 u32 rx_rx_eq_offset_adap_ctrl1;
120 u32 rx_rx_offset_adap_ctrl2;
121 u32 rx_sigdet_enables;
122 u32 rx_sigdet_ctrl;
123 u8 _reserved7[4];
124 u32 rx_sigdet_deglitch_ctrl;
125 u32 rx_rx_band;
126 u8 _reserved8[80];
127 u32 rx_rx_mode_00;
128 };
129 check_member(usb3_phy_qserdes_rx_reg_layout, rx_ucdr_fo_gain, 0x008);
130 check_member(usb3_phy_qserdes_rx_reg_layout, rx_ucdr_so_gain_half, 0x00c);
131 check_member(usb3_phy_qserdes_rx_reg_layout, rx_ucdr_fastlock_fo_gain, 0x030);
132 check_member(usb3_phy_qserdes_rx_reg_layout, rx_ucdr_so_saturtn_and_en, 0x034);
133 check_member(usb3_phy_qserdes_rx_reg_layout, rx_ucdr_pi_cntrls, 0x044);
134 check_member(usb3_phy_qserdes_rx_reg_layout, rx_vga_cal_ctrl2, 0x0c0);
135 check_member(usb3_phy_qserdes_rx_reg_layout, rx_rx_equ_adap_ctrl2, 0x0d4);
136 check_member(usb3_phy_qserdes_rx_reg_layout, rx_rx_equ_adap_ctrl3, 0x0d8);
137 check_member(usb3_phy_qserdes_rx_reg_layout, rx_rx_equ_adap_ctrl4, 0x0dc);
138 check_member(usb3_phy_qserdes_rx_reg_layout, rx_rx_eq_offset_adap_ctrl1, 0x0f8);
139 check_member(usb3_phy_qserdes_rx_reg_layout, rx_rx_offset_adap_ctrl2, 0x0fc);
140 check_member(usb3_phy_qserdes_rx_reg_layout, rx_sigdet_enables, 0x100);
141 check_member(usb3_phy_qserdes_rx_reg_layout, rx_sigdet_ctrl, 0x104);
142 check_member(usb3_phy_qserdes_rx_reg_layout, rx_sigdet_deglitch_ctrl, 0x10c);
143 check_member(usb3_phy_qserdes_rx_reg_layout, rx_rx_band, 0x110);
144 check_member(usb3_phy_qserdes_rx_reg_layout, rx_rx_mode_00, 0x164);
145
146 /* Only for QMP V3 PHY - PCS registers */
147 struct usb3_phy_pcs_reg_layout {
148 u32 pcs_sw_reset;
149 u32 pcs_power_down_control;
150 u32 pcs_start_control;
151 u32 pcs_txmgn_v0;
152 u32 pcs_txmgn_v1;
153 u32 pcs_txmgn_v2;
154 u32 pcs_txmgn_v3;
155 u32 pcs_txmgn_v4;
156 u32 pcs_txmgn_ls;
157 u32 pcs_txdeemph_m6db_v0;
158 u32 pcs_txdeemph_m3p5db_v0;
159 u32 pcs_txdeemph_m6db_v1;
160 u32 pcs_txdeemph_m3p5db_v1;
161 u32 pcs_txdeemph_m6db_v2;
162 u32 pcs_txdeemph_m3p5db_v2;
163 u32 pcs_txdeemph_m6db_v3;
164 u32 pcs_txdeemph_m3p5db_v3;
165 u32 pcs_txdeemph_m6db_v4;
166 u32 pcs_txdeemph_m3p5db_v4;
167 u32 pcs_txdeemph_m6db_ls;
168 u32 pcs_txdeemph_m3p5db_ls;
169 u8 _reserved1[8];
170 u32 pcs_rate_slew_cntrl;
171 u8 _reserved2[4];
172 u32 pcs_power_state_config2;
173 u8 _reserved3[8];
174 u32 pcs_rcvr_dtct_dly_p1u2_l;
175 u32 pcs_rcvr_dtct_dly_p1u2_h;
176 u32 pcs_rcvr_dtct_dly_u3_l;
177 u32 pcs_rcvr_dtct_dly_u3_h;
178 u32 pcs_lock_detect_config1;
179 u32 pcs_lock_detect_config2;
180 u32 pcs_lock_detect_config3;
181 u32 pcs_tsync_rsync_time;
182 u8 _reserved4[16];
183 u32 pcs_pwrup_reset_dly_time_auxclk;
184 u8 _reserved5[12];
185 u32 pcs_lfps_ecstart_eqtlock;
186 u8 _reserved6[4];
187 u32 pcs_rxeqtraining_wait_time;
188 u32 pcs_rxeqtraining_run_time;
189 u8 _reserved7[4];
190 u32 pcs_fll_ctrl1;
191 u32 pcs_fll_ctrl2;
192 u32 pcs_fll_cnt_val_l;
193 u32 pcs_fll_cnt_val_h_tol;
194 u32 pcs_fll_man_code;
195 u32 pcs_autonomous_mode_ctrl;
196 u8 _reserved8[152];
197 u32 pcs_ready_status;
198 u8 _reserved9[96];
199 u32 pcs_rx_sigdet_lvl;
200 u8 _reserved10[48];
201 u32 pcs_refgen_req_config1;
202 u32 pcs_refgen_req_config2;
203 };
204 check_member(usb3_phy_pcs_reg_layout, pcs_sw_reset, 0x000);
205 check_member(usb3_phy_pcs_reg_layout, pcs_txmgn_v0, 0x00c);
206 check_member(usb3_phy_pcs_reg_layout, pcs_txmgn_v1, 0x010);
207 check_member(usb3_phy_pcs_reg_layout, pcs_txmgn_v2, 0x014);
208 check_member(usb3_phy_pcs_reg_layout, pcs_txmgn_v3, 0x018);
209 check_member(usb3_phy_pcs_reg_layout, pcs_txmgn_v4, 0x01c);
210 check_member(usb3_phy_pcs_reg_layout, pcs_txmgn_ls, 0x020);
211 check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m6db_v0, 0x024);
212 check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m3p5db_v0, 0x028);
213 check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m6db_v1, 0x02c);
214 check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m3p5db_v1, 0x030);
215 check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m6db_v2, 0x034);
216 check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m3p5db_v2, 0x038);
217 check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m6db_v3, 0x03c);
218 check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m3p5db_v3, 0x040);
219 check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m6db_v4, 0x044);
220 check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m3p5db_v4, 0x048);
221 check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m6db_ls, 0x04c);
222 check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m3p5db_ls, 0x050);
223 check_member(usb3_phy_pcs_reg_layout, pcs_rate_slew_cntrl, 0x05c);
224 check_member(usb3_phy_pcs_reg_layout, pcs_power_state_config2, 0x064);
225 check_member(usb3_phy_pcs_reg_layout, pcs_rcvr_dtct_dly_p1u2_l, 0x070);
226 check_member(usb3_phy_pcs_reg_layout, pcs_rcvr_dtct_dly_p1u2_h, 0x074);
227 check_member(usb3_phy_pcs_reg_layout, pcs_rcvr_dtct_dly_u3_l, 0x078);
228 check_member(usb3_phy_pcs_reg_layout, pcs_rcvr_dtct_dly_u3_h, 0x07c);
229 check_member(usb3_phy_pcs_reg_layout, pcs_lock_detect_config1, 0x080);
230 check_member(usb3_phy_pcs_reg_layout, pcs_lock_detect_config2, 0x084);
231 check_member(usb3_phy_pcs_reg_layout, pcs_lock_detect_config3, 0x088);
232 check_member(usb3_phy_pcs_reg_layout, pcs_pwrup_reset_dly_time_auxclk, 0x0a0);
233 check_member(usb3_phy_pcs_reg_layout, pcs_rxeqtraining_wait_time, 0x0b8);
234 check_member(usb3_phy_pcs_reg_layout, pcs_fll_cnt_val_h_tol, 0x0d0);
235 check_member(usb3_phy_pcs_reg_layout, pcs_autonomous_mode_ctrl, 0x0d8);
236 check_member(usb3_phy_pcs_reg_layout, pcs_ready_status, 0x174);
237 check_member(usb3_phy_pcs_reg_layout, pcs_refgen_req_config2, 0x210);
238
239 static struct usb3_phy_qserdes_com_reg_layout *const qserdes_com_reg_layout =
240 (void *)QMP_PHY_QSERDES_COM_REG_BASE;
241 static struct usb3_phy_qserdes_tx_reg_layout *const qserdes_tx_reg_layout =
242 (void *)QMP_PHY_QSERDES_TX_REG_BASE;
243 static struct usb3_phy_qserdes_rx_reg_layout *const qserdes_rx_reg_layout =
244 (void *)QMP_PHY_QSERDES_RX_REG_BASE;
245 static struct usb3_phy_pcs_reg_layout *const pcs_reg_layout =
246 (void *)QMP_PHY_PCS_REG_BASE;
247
248
249 static const struct qmp_phy_init_tbl qmp_v3_usb3_serdes_tbl[] = {
250 {&qserdes_com_reg_layout->com_pll_ivco, 0x07},
251 {&qserdes_com_reg_layout->com_sysclk_en_sel, 0x14},
252 {&qserdes_com_reg_layout->com_bias_en_clkbuflr_en, 0x08},
253 {&qserdes_com_reg_layout->com_clk_select, 0x30},
254 {&qserdes_com_reg_layout->com_sys_clk_ctrl, 0x02},
255 {&qserdes_com_reg_layout->com_resetsm_ctrl2, 0x08},
256 {&qserdes_com_reg_layout->com_cmn_config, 0x16},
257 {&qserdes_com_reg_layout->com_svs_mode_clk_sel, 0x01},
258 {&qserdes_com_reg_layout->com_hsclk_sel, 0x80},
259 {&qserdes_com_reg_layout->com_dec_start_mode0, 0x82},
260 {&qserdes_com_reg_layout->com_div_frac_start1_mode0, 0xab},
261 {&qserdes_com_reg_layout->com_div_frac_start2_mode0, 0xea},
262 {&qserdes_com_reg_layout->com_div_frac_start3_mode0, 0x02},
263 {&qserdes_com_reg_layout->com_cp_ctrl_mode0, 0x06},
264 {&qserdes_com_reg_layout->com_pll_rctrl_mode0, 0x16},
265 {&qserdes_com_reg_layout->com_pll_cctrl_mode0, 0x36},
266 {&qserdes_com_reg_layout->com_integloop_gain1_mode0, 0x00},
267 {&qserdes_com_reg_layout->com_integloop_gain0_mode0, 0x3f},
268 {&qserdes_com_reg_layout->com_vco_tune2_mode0, 0x01},
269 {&qserdes_com_reg_layout->com_vco_tune1_mode0, 0xc9},
270 {&qserdes_com_reg_layout->com_coreclk_div_mode0, 0x0a},
271 {&qserdes_com_reg_layout->com_lock_cmp3_mode0, 0x00},
272 {&qserdes_com_reg_layout->com_lock_cmp2_mode0, 0x34},
273 {&qserdes_com_reg_layout->com_lock_cmp1_mode0, 0x15},
274 {&qserdes_com_reg_layout->com_lock_cmp_en, 0x04},
275 {&qserdes_com_reg_layout->com_core_clk_en, 0x00},
276 {&qserdes_com_reg_layout->com_lock_cmp_cfg, 0x00},
277 {&qserdes_com_reg_layout->com_vco_tune_map, 0x00},
278 {&qserdes_com_reg_layout->com_sysclk_buf_enable, 0x0a},
279 {&qserdes_com_reg_layout->com_ssc_en_center, 0x01},
280 {&qserdes_com_reg_layout->com_ssc_per1, 0x31},
281 {&qserdes_com_reg_layout->com_ssc_per2, 0x01},
282 {&qserdes_com_reg_layout->com_ssc_adj_per1, 0x00},
283 {&qserdes_com_reg_layout->com_ssc_adj_per2, 0x00},
284 {&qserdes_com_reg_layout->com_ssc_step_size1, 0x85},
285 {&qserdes_com_reg_layout->com_ssc_step_size2, 0x07},
286 };
287
288 static const struct qmp_phy_init_tbl qmp_v3_usb3_tx_tbl[] = {
289 {&qserdes_tx_reg_layout->tx_highz_drvr_en, 0x10},
290 {&qserdes_tx_reg_layout->tx_rcv_detect_lvl_2, 0x12},
291 {&qserdes_tx_reg_layout->tx_lane_mode_1, 0x16},
292 {&qserdes_tx_reg_layout->tx_res_code_lane_offset_rx, 0x09},
293 {&qserdes_tx_reg_layout->tx_res_code_lane_offset_tx, 0x06},
294 };
295
296 static const struct qmp_phy_init_tbl qmp_v3_usb3_rx_tbl[] = {
297 {&qserdes_rx_reg_layout->rx_ucdr_fastlock_fo_gain, 0x0b},
298 {&qserdes_rx_reg_layout->rx_rx_equ_adap_ctrl2, 0x0f},
299 {&qserdes_rx_reg_layout->rx_rx_equ_adap_ctrl3, 0x4e},
300 {&qserdes_rx_reg_layout->rx_rx_equ_adap_ctrl4, 0x18},
301 {&qserdes_rx_reg_layout->rx_rx_eq_offset_adap_ctrl1, 0x77},
302 {&qserdes_rx_reg_layout->rx_rx_offset_adap_ctrl2, 0x80},
303 {&qserdes_rx_reg_layout->rx_sigdet_ctrl, 0x03},
304 {&qserdes_rx_reg_layout->rx_sigdet_deglitch_ctrl, 0x16},
305 {&qserdes_rx_reg_layout->rx_ucdr_so_saturtn_and_en, 0x75},
306 {&qserdes_rx_reg_layout->rx_ucdr_pi_cntrls, 0x80},
307 {&qserdes_rx_reg_layout->rx_ucdr_fo_gain, 0x0a},
308 {&qserdes_rx_reg_layout->rx_ucdr_so_gain_half, 0x06},
309 {&qserdes_rx_reg_layout->rx_sigdet_enables, 0x00},
310 };
311
312 static const struct qmp_phy_init_tbl qmp_v3_usb3_pcs_tbl[] = {
313 /* FLL settings */
314 {&pcs_reg_layout->pcs_fll_ctrl2, 0x83},
315 {&pcs_reg_layout->pcs_fll_cnt_val_l, 0x09},
316 {&pcs_reg_layout->pcs_fll_cnt_val_h_tol, 0xa2},
317 {&pcs_reg_layout->pcs_fll_man_code, 0x40},
318 {&pcs_reg_layout->pcs_fll_ctrl1, 0x02},
319
320 /* Lock Det settings */
321 {&pcs_reg_layout->pcs_lock_detect_config1, 0xd1},
322 {&pcs_reg_layout->pcs_lock_detect_config2, 0x1f},
323 {&pcs_reg_layout->pcs_lock_detect_config3, 0x47},
324 {&pcs_reg_layout->pcs_power_state_config2, 0x1b},
325
326 {&pcs_reg_layout->pcs_rx_sigdet_lvl, 0xba},
327 {&pcs_reg_layout->pcs_txmgn_v0, 0x9f},
328 {&pcs_reg_layout->pcs_txmgn_v1, 0x9f},
329 {&pcs_reg_layout->pcs_txmgn_v2, 0xb7},
330 {&pcs_reg_layout->pcs_txmgn_v3, 0x4e},
331 {&pcs_reg_layout->pcs_txmgn_v4, 0x65},
332 {&pcs_reg_layout->pcs_txmgn_ls, 0x6b},
333 {&pcs_reg_layout->pcs_txdeemph_m6db_v0, 0x15},
334 {&pcs_reg_layout->pcs_txdeemph_m3p5db_v0, 0x0d},
335 {&pcs_reg_layout->pcs_txdeemph_m6db_v1, 0x15},
336 {&pcs_reg_layout->pcs_txdeemph_m3p5db_v1, 0x0d},
337 {&pcs_reg_layout->pcs_txdeemph_m6db_v2, 0x15},
338 {&pcs_reg_layout->pcs_txdeemph_m3p5db_v2, 0x0d},
339 {&pcs_reg_layout->pcs_txdeemph_m6db_v3, 0x15},
340 {&pcs_reg_layout->pcs_txdeemph_m3p5db_v3, 0x1d},
341 {&pcs_reg_layout->pcs_txdeemph_m6db_v4, 0x15},
342 {&pcs_reg_layout->pcs_txdeemph_m3p5db_v4, 0x0d},
343 {&pcs_reg_layout->pcs_txdeemph_m6db_ls, 0x15},
344 {&pcs_reg_layout->pcs_txdeemph_m3p5db_ls, 0x0d},
345 {&pcs_reg_layout->pcs_rate_slew_cntrl, 0x02},
346 {&pcs_reg_layout->pcs_pwrup_reset_dly_time_auxclk, 0x04},
347 {&pcs_reg_layout->pcs_tsync_rsync_time, 0x44},
348 {&pcs_reg_layout->pcs_rcvr_dtct_dly_p1u2_l, 0xe7},
349 {&pcs_reg_layout->pcs_rcvr_dtct_dly_p1u2_h, 0x03},
350 {&pcs_reg_layout->pcs_rcvr_dtct_dly_u3_l, 0x40},
351 {&pcs_reg_layout->pcs_rcvr_dtct_dly_u3_h, 0x00},
352 {&pcs_reg_layout->pcs_rxeqtraining_wait_time, 0x75},
353 {&pcs_reg_layout->pcs_lfps_ecstart_eqtlock, 0x86},
354 {&pcs_reg_layout->pcs_rxeqtraining_run_time, 0x13},
355 };
356
357 struct ss_usb_phy_reg qmp_v3_usb_phy = {
358 .serdes_tbl = qmp_v3_usb3_serdes_tbl,
359 .serdes_tbl_num = ARRAY_SIZE(qmp_v3_usb3_serdes_tbl),
360 .tx_tbl = qmp_v3_usb3_tx_tbl,
361 .tx_tbl_num = ARRAY_SIZE(qmp_v3_usb3_tx_tbl),
362 .rx_tbl = qmp_v3_usb3_rx_tbl,
363 .rx_tbl_num = ARRAY_SIZE(qmp_v3_usb3_rx_tbl),
364 .pcs_tbl = qmp_v3_usb3_pcs_tbl,
365 .pcs_tbl_num = ARRAY_SIZE(qmp_v3_usb3_pcs_tbl),
366 .qmp_pcs_reg = (void *)QMP_PHY_PCS_REG_BASE,
367 };
368
qcom_qmp_phy_configure(const struct qmp_phy_init_tbl tbl[],int num)369 static void qcom_qmp_phy_configure(const struct qmp_phy_init_tbl tbl[],
370 int num)
371 {
372 int i;
373 const struct qmp_phy_init_tbl *t = tbl;
374
375 if (!t)
376 return;
377
378 for (i = 0; i < num; i++, t++)
379 write32(t->address, t->val);
380 }
381
ss_qmp_phy_init(void)382 void ss_qmp_phy_init(void)
383 {
384 struct ss_usb_phy_reg *ss_phy_reg;
385
386 ss_phy_reg = &qmp_v3_usb_phy;
387 /* power up USB3 PHY */
388 write32(&ss_phy_reg->qmp_pcs_reg->pcs_power_down_control, 0x01);
389
390 /* Serdes configuration */
391 qcom_qmp_phy_configure(ss_phy_reg->serdes_tbl,
392 ss_phy_reg->serdes_tbl_num);
393 /* Tx, Rx, and PCS configurations */
394 qcom_qmp_phy_configure(ss_phy_reg->tx_tbl, ss_phy_reg->tx_tbl_num);
395 qcom_qmp_phy_configure(ss_phy_reg->rx_tbl, ss_phy_reg->rx_tbl_num);
396 qcom_qmp_phy_configure(ss_phy_reg->pcs_tbl, ss_phy_reg->pcs_tbl_num);
397
398 /* perform software reset of PCS/Serdes */
399 write32(&ss_phy_reg->qmp_pcs_reg->pcs_sw_reset, 0x00);
400 /* start PCS/Serdes to operation mode */
401 write32(&ss_phy_reg->qmp_pcs_reg->pcs_start_control, 0x03);
402
403 /*
404 * Wait for PHY initialization to be done
405 * PCS_STATUS: wait for 1ms for PHY STATUS;
406 * SW can continuously check for PHYSTATUS = 1.b0.
407 */
408 long lock_us = wait_us(10000,
409 !(read32(&ss_phy_reg->qmp_pcs_reg->pcs_ready_status) &
410 USB3_PCS_PHYSTATUS));
411 if (!lock_us)
412 printk(BIOS_ERR, "QMP PHY PLL LOCK fails:\n");
413 else
414 printk(BIOS_DEBUG, "QMP PHY initialized and locked in %ldus\n",
415 lock_us);
416 }
417