blob: 4803196d49898211a538edba7f04a5b23859bf48 [file] [log] [blame]
Patrick Georgi02363b52020-05-05 20:48:50 +02001/* This file is part of the coreboot project. */
Patrick Georgiac959032020-05-05 22:49:26 +02002/* SPDX-License-Identifier: GPL-2.0-only */
T Michael Turney050be722019-10-22 06:25:09 -07003
T Michael Turney050be722019-10-22 06:25:09 -07004#include <stdlib.h>
5#include <console/console.h>
6#include <delay.h>
Patrick Georgib9d5b262019-12-05 19:56:53 +01007#include <device/mmio.h>
T Michael Turney050be722019-10-22 06:25:09 -07008#include <soc/usb.h>
9#include <soc/clock.h>
10#include <soc/addressmap.h>
11#include <soc/efuse.h>
12#include <timer.h>
13
14struct usb_qusb_phy_dig {
15 u8 rsvd1[16];
16 u32 pwr_ctrl1;
17 u32 pwr_ctrl2;
18 u8 rsvd2[8];
19 u32 imp_ctrl1;
20 u32 imp_ctrl2;
21 u8 rsvd3[20];
22 u32 chg_ctrl2;
23 u32 tune1;
24 u32 tune2;
25 u32 tune3;
26 u32 tune4;
27 u32 tune5;
28 u8 rsvd4[44];
29 u32 debug_ctrl2;
30 u8 rsvd5[28];
31 u32 debug_stat5;
32};
33check_member(usb_qusb_phy_dig, tune5, 0x50);
34check_member(usb_qusb_phy_dig, debug_ctrl2, 0x80);
35check_member(usb_qusb_phy_dig, debug_stat5, 0xA0);
36
37struct usb_qusb_phy_pll {
38 u8 rsvd0[4];
39 u32 analog_controls_two;
40 u8 rsvd1[36];
41 u32 cmode;
42 u8 rsvd2[132];
43 u32 dig_tim;
44 u8 rsvd3[204];
45 u32 lock_delay;
46 u8 rsvd4[4];
47 u32 clock_inverters;
48 u8 rsvd5[4];
49 u32 bias_ctrl_1;
50 u32 bias_ctrl_2;
51};
52check_member(usb_qusb_phy_pll, cmode, 0x2C);
53check_member(usb_qusb_phy_pll, bias_ctrl_2, 0x198);
54check_member(usb_qusb_phy_pll, dig_tim, 0xB4);
55
56/* Only for QMP V3 PHY - QSERDES COM registers */
57struct usb3_phy_qserdes_com_reg_layout {
58 u8 _reserved1[16];
59 u32 com_ssc_en_center;
60 u32 com_ssc_adj_per1;
61 u32 com_ssc_adj_per2;
62 u32 com_ssc_per1;
63 u32 com_ssc_per2;
64 u32 com_ssc_step_size1;
65 u32 com_ssc_step_size2;
66 u8 _reserved2[8];
67 u32 com_bias_en_clkbuflr_en;
68 u32 com_sys_clk_enable1;
69 u32 com_sys_clk_ctrl;
70 u32 com_sysclk_buf_enable;
71 u32 com_pll_en;
72 u32 com_pll_ivco;
73 u8 _reserved3[20];
74 u32 com_cp_ctrl_mode0;
75 u8 _reserved4[4];
76 u32 com_pll_rctrl_mode0;
77 u8 _reserved5[4];
78 u32 com_pll_cctrl_mode0;
79 u8 _reserved6[12];
80 u32 com_sysclk_en_sel;
81 u8 _reserved7[8];
82 u32 com_resetsm_ctrl2;
83 u32 com_lock_cmp_en;
84 u32 com_lock_cmp_cfg;
85 u32 com_lock_cmp1_mode0;
86 u32 com_lock_cmp2_mode0;
87 u32 com_lock_cmp3_mode0;
88 u8 _reserved8[12];
89 u32 com_dec_start_mode0;
90 u8 _reserved9[4];
91 u32 com_div_frac_start1_mode0;
92 u32 com_div_frac_start2_mode0;
93 u32 com_div_frac_start3_mode0;
94 u8 _reserved10[20];
95 u32 com_integloop_gain0_mode0;
96 u32 com_integloop_gain1_mode0;
97 u8 _reserved11[16];
98 u32 com_vco_tune_map;
99 u32 com_vco_tune1_mode0;
100 u32 com_vco_tune2_mode0;
101 u8 _reserved12[60];
102 u32 com_clk_select;
103 u32 com_hsclk_sel;
104 u8 _reserved13[8];
105 u32 com_coreclk_div_mode0;
106 u8 _reserved14[8];
107 u32 com_core_clk_en;
108 u32 com_c_ready_status;
109 u32 com_cmn_config;
110 u32 com_cmn_rate_override;
111 u32 com_svs_mode_clk_sel;
112};
113check_member(usb3_phy_qserdes_com_reg_layout, com_ssc_en_center, 0x010);
114check_member(usb3_phy_qserdes_com_reg_layout, com_ssc_adj_per1, 0x014);
115check_member(usb3_phy_qserdes_com_reg_layout, com_ssc_adj_per2, 0x018);
116check_member(usb3_phy_qserdes_com_reg_layout, com_ssc_per1, 0x01c);
117check_member(usb3_phy_qserdes_com_reg_layout, com_ssc_per2, 0x020);
118check_member(usb3_phy_qserdes_com_reg_layout, com_bias_en_clkbuflr_en, 0x034);
119check_member(usb3_phy_qserdes_com_reg_layout, com_pll_ivco, 0x048);
120check_member(usb3_phy_qserdes_com_reg_layout, com_cp_ctrl_mode0, 0x060);
121check_member(usb3_phy_qserdes_com_reg_layout, com_sysclk_en_sel, 0x080);
122check_member(usb3_phy_qserdes_com_reg_layout, com_resetsm_ctrl2, 0x08c);
123check_member(usb3_phy_qserdes_com_reg_layout, com_dec_start_mode0, 0x0b0);
124check_member(usb3_phy_qserdes_com_reg_layout, com_div_frac_start1_mode0, 0x0b8);
125check_member(usb3_phy_qserdes_com_reg_layout, com_integloop_gain0_mode0, 0x0d8);
126check_member(usb3_phy_qserdes_com_reg_layout, com_vco_tune_map, 0x0f0);
127check_member(usb3_phy_qserdes_com_reg_layout, com_clk_select, 0x138);
128check_member(usb3_phy_qserdes_com_reg_layout, com_coreclk_div_mode0, 0x148);
129check_member(usb3_phy_qserdes_com_reg_layout, com_core_clk_en, 0x154);
130check_member(usb3_phy_qserdes_com_reg_layout, com_svs_mode_clk_sel, 0x164);
131
132/* Only for QMP V3 PHY - TX registers */
133struct usb3_phy_qserdes_tx_reg_layout {
134 u8 _reserved1[68];
135 u32 tx_res_code_lane_offset_tx;
136 u32 tx_res_code_lane_offset_rx;
137 u8 _reserved2[20];
138 u32 tx_highz_drvr_en;
139 u8 _reserved3[40];
140 u32 tx_lane_mode_1;
141 u8 _reserved4[20];
142 u32 tx_rcv_detect_lvl_2;
143};
144check_member(usb3_phy_qserdes_tx_reg_layout, tx_res_code_lane_offset_tx, 0x044);
145check_member(usb3_phy_qserdes_tx_reg_layout, tx_res_code_lane_offset_rx, 0x048);
146check_member(usb3_phy_qserdes_tx_reg_layout, tx_highz_drvr_en, 0x060);
147check_member(usb3_phy_qserdes_tx_reg_layout, tx_lane_mode_1, 0x08c);
148check_member(usb3_phy_qserdes_tx_reg_layout, tx_rcv_detect_lvl_2, 0x0a4);
149
150/* Only for QMP V3 PHY - RX registers */
151struct usb3_phy_qserdes_rx_reg_layout {
152 u8 _reserved1[8];
153 u32 rx_ucdr_fo_gain;
154 u32 rx_ucdr_so_gain_half;
155 u8 _reserved2[32];
156 u32 rx_ucdr_fastlock_fo_gain;
157 u32 rx_ucdr_so_saturtn_and_en;
158 u8 _reserved3[12];
159 u32 rx_ucdr_pi_cntrls;
160 u8 _reserved4[120];
161 u32 rx_vga_cal_ctrl2;
162 u8 _reserved5[16];
163 u32 rx_rx_equ_adap_ctrl2;
164 u32 rx_rx_equ_adap_ctrl3;
165 u32 rx_rx_equ_adap_ctrl4;
166 u8 _reserved6[24];
167 u32 rx_rx_eq_offset_adap_ctrl1;
168 u32 rx_rx_offset_adap_ctrl2;
169 u32 rx_sigdet_enables;
170 u32 rx_sigdet_ctrl;
171 u8 _reserved7[4];
172 u32 rx_sigdet_deglitch_ctrl;
173 u32 rx_rx_band;
174 u8 _reserved8[80];
175 u32 rx_rx_mode_00;
176};
177check_member(usb3_phy_qserdes_rx_reg_layout, rx_ucdr_fo_gain, 0x008);
178check_member(usb3_phy_qserdes_rx_reg_layout, rx_ucdr_so_gain_half, 0x00c);
179check_member(usb3_phy_qserdes_rx_reg_layout, rx_ucdr_fastlock_fo_gain, 0x030);
180check_member(usb3_phy_qserdes_rx_reg_layout, rx_ucdr_so_saturtn_and_en, 0x034);
181check_member(usb3_phy_qserdes_rx_reg_layout, rx_ucdr_pi_cntrls, 0x044);
182check_member(usb3_phy_qserdes_rx_reg_layout, rx_vga_cal_ctrl2, 0x0c0);
183check_member(usb3_phy_qserdes_rx_reg_layout, rx_rx_equ_adap_ctrl2, 0x0d4);
184check_member(usb3_phy_qserdes_rx_reg_layout, rx_rx_equ_adap_ctrl3, 0x0d8);
185check_member(usb3_phy_qserdes_rx_reg_layout, rx_rx_equ_adap_ctrl4, 0x0dc);
186check_member(usb3_phy_qserdes_rx_reg_layout, rx_rx_eq_offset_adap_ctrl1, 0x0f8);
187check_member(usb3_phy_qserdes_rx_reg_layout, rx_rx_offset_adap_ctrl2, 0x0fc);
188check_member(usb3_phy_qserdes_rx_reg_layout, rx_sigdet_enables, 0x100);
189check_member(usb3_phy_qserdes_rx_reg_layout, rx_sigdet_ctrl, 0x104);
190check_member(usb3_phy_qserdes_rx_reg_layout, rx_sigdet_deglitch_ctrl, 0x10c);
191check_member(usb3_phy_qserdes_rx_reg_layout, rx_rx_band, 0x110);
192check_member(usb3_phy_qserdes_rx_reg_layout, rx_rx_mode_00, 0x164);
193
194/* Only for QMP V3 PHY - PCS registers */
195struct usb3_phy_pcs_reg_layout {
196 u32 pcs_sw_reset;
197 u32 pcs_power_down_control;
198 u32 pcs_start_control;
199 u32 pcs_txmgn_v0;
200 u32 pcs_txmgn_v1;
201 u32 pcs_txmgn_v2;
202 u32 pcs_txmgn_v3;
203 u32 pcs_txmgn_v4;
204 u32 pcs_txmgn_ls;
205 u32 pcs_txdeemph_m6db_v0;
206 u32 pcs_txdeemph_m3p5db_v0;
207 u32 pcs_txdeemph_m6db_v1;
208 u32 pcs_txdeemph_m3p5db_v1;
209 u32 pcs_txdeemph_m6db_v2;
210 u32 pcs_txdeemph_m3p5db_v2;
211 u32 pcs_txdeemph_m6db_v3;
212 u32 pcs_txdeemph_m3p5db_v3;
213 u32 pcs_txdeemph_m6db_v4;
214 u32 pcs_txdeemph_m3p5db_v4;
215 u32 pcs_txdeemph_m6db_ls;
216 u32 pcs_txdeemph_m3p5db_ls;
217 u8 _reserved1[8];
218 u32 pcs_rate_slew_cntrl;
219 u8 _reserved2[4];
220 u32 pcs_power_state_config2;
221 u8 _reserved3[8];
222 u32 pcs_rcvr_dtct_dly_p1u2_l;
223 u32 pcs_rcvr_dtct_dly_p1u2_h;
224 u32 pcs_rcvr_dtct_dly_u3_l;
225 u32 pcs_rcvr_dtct_dly_u3_h;
226 u32 pcs_lock_detect_config1;
227 u32 pcs_lock_detect_config2;
228 u32 pcs_lock_detect_config3;
229 u32 pcs_tsync_rsync_time;
230 u8 _reserved4[16];
231 u32 pcs_pwrup_reset_dly_time_auxclk;
232 u8 _reserved5[12];
233 u32 pcs_lfps_ecstart_eqtlock;
234 u8 _reserved6[4];
235 u32 pcs_rxeqtraining_wait_time;
236 u32 pcs_rxeqtraining_run_time;
237 u8 _reserved7[4];
238 u32 pcs_fll_ctrl1;
239 u32 pcs_fll_ctrl2;
240 u32 pcs_fll_cnt_val_l;
241 u32 pcs_fll_cnt_val_h_tol;
242 u32 pcs_fll_man_code;
243 u32 pcs_autonomous_mode_ctrl;
244 u8 _reserved8[152];
245 u32 pcs_ready_status;
246 u8 _reserved9[96];
247 u32 pcs_rx_sigdet_lvl;
248 u8 _reserved10[48];
249 u32 pcs_refgen_req_config1;
250 u32 pcs_refgen_req_config2;
251};
252check_member(usb3_phy_pcs_reg_layout, pcs_sw_reset, 0x000);
253check_member(usb3_phy_pcs_reg_layout, pcs_txmgn_v0, 0x00c);
254check_member(usb3_phy_pcs_reg_layout, pcs_txmgn_v1, 0x010);
255check_member(usb3_phy_pcs_reg_layout, pcs_txmgn_v2, 0x014);
256check_member(usb3_phy_pcs_reg_layout, pcs_txmgn_v3, 0x018);
257check_member(usb3_phy_pcs_reg_layout, pcs_txmgn_v4, 0x01c);
258check_member(usb3_phy_pcs_reg_layout, pcs_txmgn_ls, 0x020);
259check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m6db_v0, 0x024);
260check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m3p5db_v0, 0x028);
261check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m6db_v1, 0x02c);
262check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m3p5db_v1, 0x030);
263check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m6db_v2, 0x034);
264check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m3p5db_v2, 0x038);
265check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m6db_v3, 0x03c);
266check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m3p5db_v3, 0x040);
267check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m6db_v4, 0x044);
268check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m3p5db_v4, 0x048);
269check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m6db_ls, 0x04c);
270check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m3p5db_ls, 0x050);
271check_member(usb3_phy_pcs_reg_layout, pcs_rate_slew_cntrl, 0x05c);
272check_member(usb3_phy_pcs_reg_layout, pcs_power_state_config2, 0x064);
273check_member(usb3_phy_pcs_reg_layout, pcs_rcvr_dtct_dly_p1u2_l, 0x070);
274check_member(usb3_phy_pcs_reg_layout, pcs_rcvr_dtct_dly_p1u2_h, 0x074);
275check_member(usb3_phy_pcs_reg_layout, pcs_rcvr_dtct_dly_u3_l, 0x078);
276check_member(usb3_phy_pcs_reg_layout, pcs_rcvr_dtct_dly_u3_h, 0x07c);
277check_member(usb3_phy_pcs_reg_layout, pcs_lock_detect_config1, 0x080);
278check_member(usb3_phy_pcs_reg_layout, pcs_lock_detect_config2, 0x084);
279check_member(usb3_phy_pcs_reg_layout, pcs_lock_detect_config3, 0x088);
280check_member(usb3_phy_pcs_reg_layout, pcs_pwrup_reset_dly_time_auxclk, 0x0a0);
281check_member(usb3_phy_pcs_reg_layout, pcs_rxeqtraining_wait_time, 0x0b8);
282check_member(usb3_phy_pcs_reg_layout, pcs_fll_cnt_val_h_tol, 0x0d0);
283check_member(usb3_phy_pcs_reg_layout, pcs_autonomous_mode_ctrl, 0x0d8);
284check_member(usb3_phy_pcs_reg_layout, pcs_ready_status, 0x174);
285check_member(usb3_phy_pcs_reg_layout, pcs_refgen_req_config2, 0x210);
286
287static struct usb3_phy_qserdes_com_reg_layout *const qserdes_com_reg_layout =
288 (void *)QMP_PHY_QSERDES_COM_REG_BASE;
289static struct usb3_phy_qserdes_tx_reg_layout *const qserdes_tx_reg_layout =
290 (void *)QMP_PHY_QSERDES_TX_REG_BASE;
291static struct usb3_phy_qserdes_rx_reg_layout *const qserdes_rx_reg_layout =
292 (void *)QMP_PHY_QSERDES_RX_REG_BASE;
293static struct usb3_phy_pcs_reg_layout *const pcs_reg_layout =
294 (void *)QMP_PHY_PCS_REG_BASE;
295
296
297
298struct usb_dwc3 {
299 u32 sbuscfg0;
300 u32 sbuscfg1;
301 u32 txthrcfg;
302 u32 rxthrcfg;
303 u32 ctl;
304 u32 pmsts;
305 u32 sts;
306 u32 uctl1;
307 u32 snpsid;
308 u32 gpio;
309 u32 uid;
310 u32 uctl;
311 u64 buserraddr;
312 u64 prtbimap;
313 u8 reserved1[32];
314 u32 dbgfifospace;
315 u32 dbgltssm;
316 u32 dbglnmcc;
317 u32 dbgbmu;
318 u32 dbglspmux;
319 u32 dbglsp;
320 u32 dbgepinfo0;
321 u32 dbgepinfo1;
322 u64 prtbimap_hs;
323 u64 prtbimap_fs;
324 u8 reserved2[112];
325 u32 usb2phycfg;
326 u8 reserved3[124];
327 u32 usb2phyacc;
328 u8 reserved4[60];
329 u32 usb3pipectl;
330 u8 reserved5[60];
331};
332check_member(usb_dwc3, usb3pipectl, 0x1c0);
333
334static const struct qmp_phy_init_tbl qmp_v3_usb3_serdes_tbl[] = {
335 {&qserdes_com_reg_layout->com_pll_ivco, 0x07},
336 {&qserdes_com_reg_layout->com_sysclk_en_sel, 0x14},
337 {&qserdes_com_reg_layout->com_bias_en_clkbuflr_en, 0x08},
338 {&qserdes_com_reg_layout->com_clk_select, 0x30},
339 {&qserdes_com_reg_layout->com_sys_clk_ctrl, 0x02},
340 {&qserdes_com_reg_layout->com_resetsm_ctrl2, 0x08},
341 {&qserdes_com_reg_layout->com_cmn_config, 0x16},
342 {&qserdes_com_reg_layout->com_svs_mode_clk_sel, 0x01},
343 {&qserdes_com_reg_layout->com_hsclk_sel, 0x80},
344 {&qserdes_com_reg_layout->com_dec_start_mode0, 0x82},
345 {&qserdes_com_reg_layout->com_div_frac_start1_mode0, 0xab},
346 {&qserdes_com_reg_layout->com_div_frac_start2_mode0, 0xea},
347 {&qserdes_com_reg_layout->com_div_frac_start3_mode0, 0x02},
348 {&qserdes_com_reg_layout->com_cp_ctrl_mode0, 0x06},
349 {&qserdes_com_reg_layout->com_pll_rctrl_mode0, 0x16},
350 {&qserdes_com_reg_layout->com_pll_cctrl_mode0, 0x36},
351 {&qserdes_com_reg_layout->com_integloop_gain1_mode0, 0x00},
352 {&qserdes_com_reg_layout->com_integloop_gain0_mode0, 0x3f},
353 {&qserdes_com_reg_layout->com_vco_tune2_mode0, 0x01},
354 {&qserdes_com_reg_layout->com_vco_tune1_mode0, 0xc9},
355 {&qserdes_com_reg_layout->com_coreclk_div_mode0, 0x0a},
356 {&qserdes_com_reg_layout->com_lock_cmp3_mode0, 0x00},
357 {&qserdes_com_reg_layout->com_lock_cmp2_mode0, 0x34},
358 {&qserdes_com_reg_layout->com_lock_cmp1_mode0, 0x15},
359 {&qserdes_com_reg_layout->com_lock_cmp_en, 0x04},
360 {&qserdes_com_reg_layout->com_core_clk_en, 0x00},
361 {&qserdes_com_reg_layout->com_lock_cmp_cfg, 0x00},
362 {&qserdes_com_reg_layout->com_vco_tune_map, 0x00},
363 {&qserdes_com_reg_layout->com_sysclk_buf_enable, 0x0a},
364 {&qserdes_com_reg_layout->com_ssc_en_center, 0x01},
365 {&qserdes_com_reg_layout->com_ssc_per1, 0x31},
366 {&qserdes_com_reg_layout->com_ssc_per2, 0x01},
367 {&qserdes_com_reg_layout->com_ssc_adj_per1, 0x00},
368 {&qserdes_com_reg_layout->com_ssc_adj_per2, 0x00},
369 {&qserdes_com_reg_layout->com_ssc_step_size1, 0x85},
370 {&qserdes_com_reg_layout->com_ssc_step_size2, 0x07},
371};
372
373static const struct qmp_phy_init_tbl qmp_v3_usb3_tx_tbl[] = {
374 {&qserdes_tx_reg_layout->tx_highz_drvr_en, 0x10},
375 {&qserdes_tx_reg_layout->tx_rcv_detect_lvl_2, 0x12},
376 {&qserdes_tx_reg_layout->tx_lane_mode_1, 0x16},
377 {&qserdes_tx_reg_layout->tx_res_code_lane_offset_rx, 0x09},
378 {&qserdes_tx_reg_layout->tx_res_code_lane_offset_tx, 0x06},
379};
380
381static const struct qmp_phy_init_tbl qmp_v3_usb3_rx_tbl[] = {
382 {&qserdes_rx_reg_layout->rx_ucdr_fastlock_fo_gain, 0x0b},
383 {&qserdes_rx_reg_layout->rx_rx_equ_adap_ctrl2, 0x0f},
384 {&qserdes_rx_reg_layout->rx_rx_equ_adap_ctrl3, 0x4e},
385 {&qserdes_rx_reg_layout->rx_rx_equ_adap_ctrl4, 0x18},
386 {&qserdes_rx_reg_layout->rx_rx_eq_offset_adap_ctrl1, 0x77},
387 {&qserdes_rx_reg_layout->rx_rx_offset_adap_ctrl2, 0x80},
388 {&qserdes_rx_reg_layout->rx_sigdet_ctrl, 0x03},
389 {&qserdes_rx_reg_layout->rx_sigdet_deglitch_ctrl, 0x16},
390 {&qserdes_rx_reg_layout->rx_ucdr_so_saturtn_and_en, 0x75},
391 {&qserdes_rx_reg_layout->rx_ucdr_pi_cntrls, 0x80},
392 {&qserdes_rx_reg_layout->rx_ucdr_fo_gain, 0x0a},
393 {&qserdes_rx_reg_layout->rx_ucdr_so_gain_half, 0x06},
394 {&qserdes_rx_reg_layout->rx_sigdet_enables, 0x00},
395};
396
397static const struct qmp_phy_init_tbl qmp_v3_usb3_pcs_tbl[] = {
398 /* FLL settings */
399 {&pcs_reg_layout->pcs_fll_ctrl2, 0x83},
400 {&pcs_reg_layout->pcs_fll_cnt_val_l, 0x09},
401 {&pcs_reg_layout->pcs_fll_cnt_val_h_tol, 0xa2},
402 {&pcs_reg_layout->pcs_fll_man_code, 0x40},
403 {&pcs_reg_layout->pcs_fll_ctrl1, 0x02},
404
405 /* Lock Det settings */
406 {&pcs_reg_layout->pcs_lock_detect_config1, 0xd1},
407 {&pcs_reg_layout->pcs_lock_detect_config2, 0x1f},
408 {&pcs_reg_layout->pcs_lock_detect_config3, 0x47},
409 {&pcs_reg_layout->pcs_power_state_config2, 0x1b},
410
411 {&pcs_reg_layout->pcs_rx_sigdet_lvl, 0xba},
412 {&pcs_reg_layout->pcs_txmgn_v0, 0x9f},
413 {&pcs_reg_layout->pcs_txmgn_v1, 0x9f},
414 {&pcs_reg_layout->pcs_txmgn_v2, 0xb7},
415 {&pcs_reg_layout->pcs_txmgn_v3, 0x4e},
416 {&pcs_reg_layout->pcs_txmgn_v4, 0x65},
417 {&pcs_reg_layout->pcs_txmgn_ls, 0x6b},
418 {&pcs_reg_layout->pcs_txdeemph_m6db_v0, 0x15},
419 {&pcs_reg_layout->pcs_txdeemph_m3p5db_v0, 0x0d},
420 {&pcs_reg_layout->pcs_txdeemph_m6db_v1, 0x15},
421 {&pcs_reg_layout->pcs_txdeemph_m3p5db_v1, 0x0d},
422 {&pcs_reg_layout->pcs_txdeemph_m6db_v2, 0x15},
423 {&pcs_reg_layout->pcs_txdeemph_m3p5db_v2, 0x0d},
424 {&pcs_reg_layout->pcs_txdeemph_m6db_v3, 0x15},
425 {&pcs_reg_layout->pcs_txdeemph_m3p5db_v3, 0x1d},
426 {&pcs_reg_layout->pcs_txdeemph_m6db_v4, 0x15},
427 {&pcs_reg_layout->pcs_txdeemph_m3p5db_v4, 0x0d},
428 {&pcs_reg_layout->pcs_txdeemph_m6db_ls, 0x15},
429 {&pcs_reg_layout->pcs_txdeemph_m3p5db_ls, 0x0d},
430 {&pcs_reg_layout->pcs_rate_slew_cntrl, 0x02},
431 {&pcs_reg_layout->pcs_pwrup_reset_dly_time_auxclk, 0x04},
432 {&pcs_reg_layout->pcs_tsync_rsync_time, 0x44},
433 {&pcs_reg_layout->pcs_rcvr_dtct_dly_p1u2_l, 0xe7},
434 {&pcs_reg_layout->pcs_rcvr_dtct_dly_p1u2_h, 0x03},
435 {&pcs_reg_layout->pcs_rcvr_dtct_dly_u3_l, 0x40},
436 {&pcs_reg_layout->pcs_rcvr_dtct_dly_u3_h, 0x00},
437 {&pcs_reg_layout->pcs_rxeqtraining_wait_time, 0x75},
438 {&pcs_reg_layout->pcs_lfps_ecstart_eqtlock, 0x86},
439 {&pcs_reg_layout->pcs_rxeqtraining_run_time, 0x13},
440};
441
442
443
444struct usb_dwc3_cfg {
445 struct usb_dwc3 *usb_host_dwc3;
446 struct usb_qusb_phy_pll *qusb_phy_pll;
447 struct usb_qusb_phy_dig *qusb_phy_dig;
448 /* Init sequence for QMP PHY blocks - serdes, tx, rx, pcs */
449 const struct qmp_phy_init_tbl *serdes_tbl;
450 int serdes_tbl_num;
451 const struct qmp_phy_init_tbl *tx_tbl;
452 int tx_tbl_num;
453 const struct qmp_phy_init_tbl *rx_tbl;
454 int rx_tbl_num;
455 const struct qmp_phy_init_tbl *pcs_tbl;
456 int pcs_tbl_num;
457 struct usb3_phy_pcs_reg_layout *qmp_pcs_reg;
458
459 u32 *usb3_bcr;
460 u32 *qusb2phy_bcr;
461 u32 *gcc_usb3phy_bcr_reg;
462 u32 *gcc_qmpphy_bcr_reg;
463 struct usb_board_data *board_data;
464 u32 efuse_offset;
465};
466
467static struct usb_dwc3_cfg usb_port0 = {
468 .usb_host_dwc3 = (void *)USB_HOST_DWC3_BASE,
469 .qusb_phy_pll = (void *)QUSB_PRIM_PHY_BASE,
470 .qusb_phy_dig = (void *)QUSB_PRIM_PHY_DIG_BASE,
471 .serdes_tbl = qmp_v3_usb3_serdes_tbl,
472 .serdes_tbl_num = ARRAY_SIZE(qmp_v3_usb3_serdes_tbl),
473 .tx_tbl = qmp_v3_usb3_tx_tbl,
474 .tx_tbl_num = ARRAY_SIZE(qmp_v3_usb3_tx_tbl),
475 .rx_tbl = qmp_v3_usb3_rx_tbl,
476 .rx_tbl_num = ARRAY_SIZE(qmp_v3_usb3_rx_tbl),
477 .pcs_tbl = qmp_v3_usb3_pcs_tbl,
478 .pcs_tbl_num = ARRAY_SIZE(qmp_v3_usb3_pcs_tbl),
479 .qmp_pcs_reg = (void *)QMP_PHY_PCS_REG_BASE,
480 .usb3_bcr = &gcc->usb30_prim_bcr,
481 .qusb2phy_bcr = &gcc->qusb2phy_prim_bcr,
482 .gcc_usb3phy_bcr_reg = &gcc->usb3_dp_phy_prim_bcr,
483 .gcc_qmpphy_bcr_reg = &gcc->usb3_phy_prim_bcr,
484 .efuse_offset = 25,
485};
486
487
488static struct qfprom_corr * const qfprom_corr_efuse = (void *)QFPROM_BASE;
489
490static void reset_usb(struct usb_dwc3_cfg *dwc3)
491{
492 /* Assert Core reset */
493 clock_reset_bcr(dwc3->usb3_bcr, 1);
494
495 /* Assert QUSB PHY reset */
496 clock_reset_bcr(dwc3->qusb2phy_bcr, 1);
497
498 /* Assert QMP PHY reset */
499 clock_reset_bcr(dwc3->gcc_usb3phy_bcr_reg, 1);
500 clock_reset_bcr(dwc3->gcc_qmpphy_bcr_reg, 1);
501}
502
503void reset_usb0(void)
504{
505 /* Before Resetting PHY, put Core in Reset */
506 printk(BIOS_INFO, "Starting DWC3 and PHY resets for USB(0)\n");
507
508 reset_usb(&usb_port0);
509}
510
511
512/*
513 * Update board specific PHY tuning override values that specified from
514 * board file.
515 */
516static void qusb2_phy_override_phy_params(struct usb_dwc3_cfg *dwc3)
517{
518 /* Override preemphasis value */
519 write32(&dwc3->qusb_phy_dig->tune1,
520 dwc3->board_data->port_tune1);
521
522 /* Override BIAS_CTRL_2 to reduce the TX swing overshooting. */
523 write32(&dwc3->qusb_phy_pll->bias_ctrl_2,
524 dwc3->board_data->pll_bias_control_2);
525
526 /* Override IMP_RES_OFFSET value */
527 write32(&dwc3->qusb_phy_dig->imp_ctrl1,
528 dwc3->board_data->imp_ctrl1);
529}
530
531/*
532 * Fetches HS Tx tuning value from efuse register and sets the
533 * QUSB2PHY_PORT_TUNE1/2 register.
534 * For error case, skip setting the value and use the default value.
535 */
536static void qusb2_phy_set_tune_param(struct usb_dwc3_cfg *dwc3)
537{
538 /*
539 * Efuse registers 3 bit value specifies tuning for HSTX
540 * output current in TUNE1 Register. Hence Extract 3 bits from
541 * EFUSE at correct position.
542 */
543
544 const int efuse_bits = 3;
545 int bit_pos = dwc3->efuse_offset;
546
547 u32 bit_mask = (1 << efuse_bits) - 1;
548 u32 tune_val =
549 (read32(&qfprom_corr_efuse->qusb_hstx_trim_lsb) >> bit_pos)
550 & bit_mask;
551 /*
552 * if efuse reg is updated (i.e non-zero) then use it to program
553 * tune parameters.
554 */
555 if (tune_val)
Patrick Georgib9d5b262019-12-05 19:56:53 +0100556 clrsetbits32(&dwc3->qusb_phy_dig->tune1,
T Michael Turney050be722019-10-22 06:25:09 -0700557 PORT_TUNE1_MASK, tune_val << 4);
558}
559
560static void tune_phy(struct usb_dwc3_cfg *dwc3, struct usb_qusb_phy_dig *phy)
561{
562 write32(&phy->pwr_ctrl2, QUSB2PHY_PWR_CTRL2);
563 /* IMP_CTRL1: Control the impedance reduction */
564 write32(&phy->imp_ctrl1, QUSB2PHY_IMP_CTRL1);
565 /* IMP_CTRL2: Impedance offset/mapping slope */
566 write32(&phy->imp_ctrl2, QUSB2PHY_IMP_CTRL1);
567 write32(&phy->chg_ctrl2, QUSB2PHY_IMP_CTRL2);
568 /*
569 * TUNE1: Sets HS Impedance to approx 45 ohms
570 * then override with efuse value.
571 */
572 write32(&phy->tune1, QUSB2PHY_PORT_TUNE1);
573 /* TUNE2: Tuning for HS Disconnect Level */
574 write32(&phy->tune2, QUSB2PHY_PORT_TUNE2);
575 /* TUNE3: Tune squelch range */
576 write32(&phy->tune3, QUSB2PHY_PORT_TUNE3);
577 /* TUNE4: Sets EOP_DLY(Squelch rising edge to linestate falling edge) */
578 write32(&phy->tune4, QUSB2PHY_PORT_TUNE4);
579 write32(&phy->tune5, QUSB2PHY_PORT_TUNE5);
580
581 if (dwc3->board_data) {
582 /* Override board specific PHY tuning values */
583 qusb2_phy_override_phy_params(dwc3);
584
585 /* Set efuse value for tuning the PHY */
586 qusb2_phy_set_tune_param(dwc3);
587 }
588}
589
590static void hs_qusb_phy_init(struct usb_dwc3_cfg *dwc3)
591{
592 /* PWR_CTRL: set the power down bit to disable the PHY */
Patrick Georgib9d5b262019-12-05 19:56:53 +0100593 setbits32(&dwc3->qusb_phy_dig->pwr_ctrl1, POWER_DOWN);
T Michael Turney050be722019-10-22 06:25:09 -0700594
595 write32(&dwc3->qusb_phy_pll->analog_controls_two,
596 QUSB2PHY_PLL_ANALOG_CONTROLS_TWO);
597 write32(&dwc3->qusb_phy_pll->clock_inverters,
598 QUSB2PHY_PLL_CLOCK_INVERTERS);
599 write32(&dwc3->qusb_phy_pll->cmode,
600 QUSB2PHY_PLL_CMODE);
601 write32(&dwc3->qusb_phy_pll->lock_delay,
602 QUSB2PHY_PLL_LOCK_DELAY);
603 write32(&dwc3->qusb_phy_pll->dig_tim,
604 QUSB2PHY_PLL_DIGITAL_TIMERS_TWO);
605 write32(&dwc3->qusb_phy_pll->bias_ctrl_1,
606 QUSB2PHY_PLL_BIAS_CONTROL_1);
607 write32(&dwc3->qusb_phy_pll->bias_ctrl_2,
608 QUSB2PHY_PLL_BIAS_CONTROL_2);
609
610 tune_phy(dwc3, dwc3->qusb_phy_dig);
611
612 /* PWR_CTRL1: Clear the power down bit to enable the PHY */
Patrick Georgib9d5b262019-12-05 19:56:53 +0100613 clrbits32(&dwc3->qusb_phy_dig->pwr_ctrl1, POWER_DOWN);
T Michael Turney050be722019-10-22 06:25:09 -0700614
615 write32(&dwc3->qusb_phy_dig->debug_ctrl2,
616 DEBUG_CTRL2_MUX_PLL_LOCK_STATUS);
617
618 /*
619 * DEBUG_STAT5: wait for 160uS for PLL lock;
620 * vstatus[0] changes from 0 to 1.
621 */
622 long lock_us = wait_us(160, read32(&dwc3->qusb_phy_dig->debug_stat5) &
623 VSTATUS_PLL_LOCK_STATUS_MASK);
624 if (!lock_us)
625 printk(BIOS_ERR, "ERROR: QUSB PHY PLL LOCK fails\n");
626 else
627 printk(BIOS_DEBUG, "QUSB PHY initialized and locked in %ldus\n",
628 lock_us);
629}
630
631static void qcom_qmp_phy_configure(const struct qmp_phy_init_tbl tbl[],
632 int num)
633{
634 int i;
635 const struct qmp_phy_init_tbl *t = tbl;
636
637 if (!t)
638 return;
639
640 for (i = 0; i < num; i++, t++)
641 write32(t->address, t->val);
642}
643
644static void ss_qmp_phy_init(struct usb_dwc3_cfg *dwc3)
645{
646 /* power up USB3 PHY */
647 write32(&dwc3->qmp_pcs_reg->pcs_power_down_control, 0x01);
648
649 /* Serdes configuration */
650 qcom_qmp_phy_configure(dwc3->serdes_tbl, dwc3->serdes_tbl_num);
651 /* Tx, Rx, and PCS configurations */
652 qcom_qmp_phy_configure(dwc3->tx_tbl, dwc3->tx_tbl_num);
653 qcom_qmp_phy_configure(dwc3->rx_tbl, dwc3->rx_tbl_num);
654 qcom_qmp_phy_configure(dwc3->pcs_tbl, dwc3->pcs_tbl_num);
655
656 /* perform software reset of PCS/Serdes */
657 write32(&dwc3->qmp_pcs_reg->pcs_sw_reset, 0x00);
658 /* start PCS/Serdes to operation mode */
659 write32(&dwc3->qmp_pcs_reg->pcs_start_control, 0x03);
660
661 /*
662 * Wait for PHY initialization to be done
663 * PCS_STATUS: wait for 1ms for PHY STATUS;
664 * SW can continuously check for PHYSTATUS = 1.b0.
665 */
666 long lock_us = wait_us(1000,
667 !(read32(&dwc3->qmp_pcs_reg->pcs_ready_status) &
668 USB3_PCS_PHYSTATUS));
669 if (!lock_us)
670 printk(BIOS_ERR, "ERROR: QMP PHY PLL LOCK fails:\n");
671 else
672 printk(BIOS_DEBUG, "QMP PHY initialized and locked in %ldus\n",
673 lock_us);
674}
675
676static void setup_dwc3(struct usb_dwc3 *dwc3)
677{
678 /* core exits U1/U2/U3 only in PHY power state P1/P2/P3 respectively */
Patrick Georgib9d5b262019-12-05 19:56:53 +0100679 clrsetbits32(&dwc3->usb3pipectl,
T Michael Turney050be722019-10-22 06:25:09 -0700680 DWC3_GUSB3PIPECTL_DELAYP1TRANS,
681 DWC3_GUSB3PIPECTL_UX_EXIT_IN_PX);
682
683 /*
684 * Configure USB phy interface of DWC3 core.
685 * 1. Select UTMI+ PHY with 16-bit interface.
686 * 2. Set USBTRDTIM to the corresponding value
687 * according to the UTMI+ PHY interface.
688 */
Patrick Georgib9d5b262019-12-05 19:56:53 +0100689 clrsetbits32(&dwc3->usb2phycfg,
T Michael Turney050be722019-10-22 06:25:09 -0700690 (DWC3_GUSB2PHYCFG_USB2TRDTIM_MASK |
691 DWC3_GUSB2PHYCFG_PHYIF_MASK),
692 (DWC3_GUSB2PHYCFG_PHYIF(UTMI_PHYIF_8_BIT) |
693 DWC3_GUSB2PHYCFG_USBTRDTIM(USBTRDTIM_UTMI_8_BIT)));
694
Patrick Georgib9d5b262019-12-05 19:56:53 +0100695 clrsetbits32(&dwc3->ctl, (DWC3_GCTL_SCALEDOWN_MASK |
T Michael Turney050be722019-10-22 06:25:09 -0700696 DWC3_GCTL_DISSCRAMBLE),
697 DWC3_GCTL_U2EXIT_LFPS | DWC3_GCTL_DSBLCLKGTNG);
698
699 /* configure controller in Host mode */
Patrick Georgib9d5b262019-12-05 19:56:53 +0100700 clrsetbits32(&dwc3->ctl, (DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG)),
T Michael Turney050be722019-10-22 06:25:09 -0700701 DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_HOST));
702 printk(BIOS_SPEW, "Configure USB in Host mode\n");
703}
704
705/* Initialization of DWC3 Core and PHY */
706static void setup_usb_host(struct usb_dwc3_cfg *dwc3,
707 struct usb_board_data *board_data)
708{
709 dwc3->board_data = board_data;
710
711 /* Clear core reset. */
712 clock_reset_bcr(dwc3->usb3_bcr, 0);
713
714 /* Clear QUSB PHY reset. */
715 clock_reset_bcr(dwc3->qusb2phy_bcr, 0);
716
717 /* Initialize QUSB PHY */
718 hs_qusb_phy_init(dwc3);
719
720 /* Clear QMP PHY resets. */
721 clock_reset_bcr(dwc3->gcc_usb3phy_bcr_reg, 0);
722 clock_reset_bcr(dwc3->gcc_qmpphy_bcr_reg, 0);
723
724 /* Initialize QMP PHY */
725 ss_qmp_phy_init(dwc3);
726
727 setup_dwc3(dwc3->usb_host_dwc3);
728
729 printk(BIOS_INFO, "DWC3 and PHY setup finished\n");
730}
731
732void setup_usb_host0(struct usb_board_data *board_data)
733{
734 printk(BIOS_INFO, "Setting up USB HOST0 controller.\n");
735 setup_usb_host(&usb_port0, board_data);
736}