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