Patrick Georgi | 02363b5 | 2020-05-05 20:48:50 +0200 | [diff] [blame] | 1 | /* This file is part of the coreboot project. */ |
Patrick Georgi | ac95903 | 2020-05-05 22:49:26 +0200 | [diff] [blame^] | 2 | /* SPDX-License-Identifier: GPL-2.0-only */ |
T Michael Turney | 050be72 | 2019-10-22 06:25:09 -0700 | [diff] [blame] | 3 | |
T Michael Turney | 050be72 | 2019-10-22 06:25:09 -0700 | [diff] [blame] | 4 | #include <stdlib.h> |
| 5 | #include <console/console.h> |
| 6 | #include <delay.h> |
Patrick Georgi | b9d5b26 | 2019-12-05 19:56:53 +0100 | [diff] [blame] | 7 | #include <device/mmio.h> |
T Michael Turney | 050be72 | 2019-10-22 06:25:09 -0700 | [diff] [blame] | 8 | #include <soc/usb.h> |
| 9 | #include <soc/clock.h> |
| 10 | #include <soc/addressmap.h> |
| 11 | #include <soc/efuse.h> |
| 12 | #include <timer.h> |
| 13 | |
| 14 | struct 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 | }; |
| 33 | check_member(usb_qusb_phy_dig, tune5, 0x50); |
| 34 | check_member(usb_qusb_phy_dig, debug_ctrl2, 0x80); |
| 35 | check_member(usb_qusb_phy_dig, debug_stat5, 0xA0); |
| 36 | |
| 37 | struct 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 | }; |
| 52 | check_member(usb_qusb_phy_pll, cmode, 0x2C); |
| 53 | check_member(usb_qusb_phy_pll, bias_ctrl_2, 0x198); |
| 54 | check_member(usb_qusb_phy_pll, dig_tim, 0xB4); |
| 55 | |
| 56 | /* Only for QMP V3 PHY - QSERDES COM registers */ |
| 57 | struct 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 | }; |
| 113 | check_member(usb3_phy_qserdes_com_reg_layout, com_ssc_en_center, 0x010); |
| 114 | check_member(usb3_phy_qserdes_com_reg_layout, com_ssc_adj_per1, 0x014); |
| 115 | check_member(usb3_phy_qserdes_com_reg_layout, com_ssc_adj_per2, 0x018); |
| 116 | check_member(usb3_phy_qserdes_com_reg_layout, com_ssc_per1, 0x01c); |
| 117 | check_member(usb3_phy_qserdes_com_reg_layout, com_ssc_per2, 0x020); |
| 118 | check_member(usb3_phy_qserdes_com_reg_layout, com_bias_en_clkbuflr_en, 0x034); |
| 119 | check_member(usb3_phy_qserdes_com_reg_layout, com_pll_ivco, 0x048); |
| 120 | check_member(usb3_phy_qserdes_com_reg_layout, com_cp_ctrl_mode0, 0x060); |
| 121 | check_member(usb3_phy_qserdes_com_reg_layout, com_sysclk_en_sel, 0x080); |
| 122 | check_member(usb3_phy_qserdes_com_reg_layout, com_resetsm_ctrl2, 0x08c); |
| 123 | check_member(usb3_phy_qserdes_com_reg_layout, com_dec_start_mode0, 0x0b0); |
| 124 | check_member(usb3_phy_qserdes_com_reg_layout, com_div_frac_start1_mode0, 0x0b8); |
| 125 | check_member(usb3_phy_qserdes_com_reg_layout, com_integloop_gain0_mode0, 0x0d8); |
| 126 | check_member(usb3_phy_qserdes_com_reg_layout, com_vco_tune_map, 0x0f0); |
| 127 | check_member(usb3_phy_qserdes_com_reg_layout, com_clk_select, 0x138); |
| 128 | check_member(usb3_phy_qserdes_com_reg_layout, com_coreclk_div_mode0, 0x148); |
| 129 | check_member(usb3_phy_qserdes_com_reg_layout, com_core_clk_en, 0x154); |
| 130 | check_member(usb3_phy_qserdes_com_reg_layout, com_svs_mode_clk_sel, 0x164); |
| 131 | |
| 132 | /* Only for QMP V3 PHY - TX registers */ |
| 133 | struct 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 | }; |
| 144 | check_member(usb3_phy_qserdes_tx_reg_layout, tx_res_code_lane_offset_tx, 0x044); |
| 145 | check_member(usb3_phy_qserdes_tx_reg_layout, tx_res_code_lane_offset_rx, 0x048); |
| 146 | check_member(usb3_phy_qserdes_tx_reg_layout, tx_highz_drvr_en, 0x060); |
| 147 | check_member(usb3_phy_qserdes_tx_reg_layout, tx_lane_mode_1, 0x08c); |
| 148 | check_member(usb3_phy_qserdes_tx_reg_layout, tx_rcv_detect_lvl_2, 0x0a4); |
| 149 | |
| 150 | /* Only for QMP V3 PHY - RX registers */ |
| 151 | struct 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 | }; |
| 177 | check_member(usb3_phy_qserdes_rx_reg_layout, rx_ucdr_fo_gain, 0x008); |
| 178 | check_member(usb3_phy_qserdes_rx_reg_layout, rx_ucdr_so_gain_half, 0x00c); |
| 179 | check_member(usb3_phy_qserdes_rx_reg_layout, rx_ucdr_fastlock_fo_gain, 0x030); |
| 180 | check_member(usb3_phy_qserdes_rx_reg_layout, rx_ucdr_so_saturtn_and_en, 0x034); |
| 181 | check_member(usb3_phy_qserdes_rx_reg_layout, rx_ucdr_pi_cntrls, 0x044); |
| 182 | check_member(usb3_phy_qserdes_rx_reg_layout, rx_vga_cal_ctrl2, 0x0c0); |
| 183 | check_member(usb3_phy_qserdes_rx_reg_layout, rx_rx_equ_adap_ctrl2, 0x0d4); |
| 184 | check_member(usb3_phy_qserdes_rx_reg_layout, rx_rx_equ_adap_ctrl3, 0x0d8); |
| 185 | check_member(usb3_phy_qserdes_rx_reg_layout, rx_rx_equ_adap_ctrl4, 0x0dc); |
| 186 | check_member(usb3_phy_qserdes_rx_reg_layout, rx_rx_eq_offset_adap_ctrl1, 0x0f8); |
| 187 | check_member(usb3_phy_qserdes_rx_reg_layout, rx_rx_offset_adap_ctrl2, 0x0fc); |
| 188 | check_member(usb3_phy_qserdes_rx_reg_layout, rx_sigdet_enables, 0x100); |
| 189 | check_member(usb3_phy_qserdes_rx_reg_layout, rx_sigdet_ctrl, 0x104); |
| 190 | check_member(usb3_phy_qserdes_rx_reg_layout, rx_sigdet_deglitch_ctrl, 0x10c); |
| 191 | check_member(usb3_phy_qserdes_rx_reg_layout, rx_rx_band, 0x110); |
| 192 | check_member(usb3_phy_qserdes_rx_reg_layout, rx_rx_mode_00, 0x164); |
| 193 | |
| 194 | /* Only for QMP V3 PHY - PCS registers */ |
| 195 | struct 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 | }; |
| 252 | check_member(usb3_phy_pcs_reg_layout, pcs_sw_reset, 0x000); |
| 253 | check_member(usb3_phy_pcs_reg_layout, pcs_txmgn_v0, 0x00c); |
| 254 | check_member(usb3_phy_pcs_reg_layout, pcs_txmgn_v1, 0x010); |
| 255 | check_member(usb3_phy_pcs_reg_layout, pcs_txmgn_v2, 0x014); |
| 256 | check_member(usb3_phy_pcs_reg_layout, pcs_txmgn_v3, 0x018); |
| 257 | check_member(usb3_phy_pcs_reg_layout, pcs_txmgn_v4, 0x01c); |
| 258 | check_member(usb3_phy_pcs_reg_layout, pcs_txmgn_ls, 0x020); |
| 259 | check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m6db_v0, 0x024); |
| 260 | check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m3p5db_v0, 0x028); |
| 261 | check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m6db_v1, 0x02c); |
| 262 | check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m3p5db_v1, 0x030); |
| 263 | check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m6db_v2, 0x034); |
| 264 | check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m3p5db_v2, 0x038); |
| 265 | check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m6db_v3, 0x03c); |
| 266 | check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m3p5db_v3, 0x040); |
| 267 | check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m6db_v4, 0x044); |
| 268 | check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m3p5db_v4, 0x048); |
| 269 | check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m6db_ls, 0x04c); |
| 270 | check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m3p5db_ls, 0x050); |
| 271 | check_member(usb3_phy_pcs_reg_layout, pcs_rate_slew_cntrl, 0x05c); |
| 272 | check_member(usb3_phy_pcs_reg_layout, pcs_power_state_config2, 0x064); |
| 273 | check_member(usb3_phy_pcs_reg_layout, pcs_rcvr_dtct_dly_p1u2_l, 0x070); |
| 274 | check_member(usb3_phy_pcs_reg_layout, pcs_rcvr_dtct_dly_p1u2_h, 0x074); |
| 275 | check_member(usb3_phy_pcs_reg_layout, pcs_rcvr_dtct_dly_u3_l, 0x078); |
| 276 | check_member(usb3_phy_pcs_reg_layout, pcs_rcvr_dtct_dly_u3_h, 0x07c); |
| 277 | check_member(usb3_phy_pcs_reg_layout, pcs_lock_detect_config1, 0x080); |
| 278 | check_member(usb3_phy_pcs_reg_layout, pcs_lock_detect_config2, 0x084); |
| 279 | check_member(usb3_phy_pcs_reg_layout, pcs_lock_detect_config3, 0x088); |
| 280 | check_member(usb3_phy_pcs_reg_layout, pcs_pwrup_reset_dly_time_auxclk, 0x0a0); |
| 281 | check_member(usb3_phy_pcs_reg_layout, pcs_rxeqtraining_wait_time, 0x0b8); |
| 282 | check_member(usb3_phy_pcs_reg_layout, pcs_fll_cnt_val_h_tol, 0x0d0); |
| 283 | check_member(usb3_phy_pcs_reg_layout, pcs_autonomous_mode_ctrl, 0x0d8); |
| 284 | check_member(usb3_phy_pcs_reg_layout, pcs_ready_status, 0x174); |
| 285 | check_member(usb3_phy_pcs_reg_layout, pcs_refgen_req_config2, 0x210); |
| 286 | |
| 287 | static struct usb3_phy_qserdes_com_reg_layout *const qserdes_com_reg_layout = |
| 288 | (void *)QMP_PHY_QSERDES_COM_REG_BASE; |
| 289 | static struct usb3_phy_qserdes_tx_reg_layout *const qserdes_tx_reg_layout = |
| 290 | (void *)QMP_PHY_QSERDES_TX_REG_BASE; |
| 291 | static struct usb3_phy_qserdes_rx_reg_layout *const qserdes_rx_reg_layout = |
| 292 | (void *)QMP_PHY_QSERDES_RX_REG_BASE; |
| 293 | static struct usb3_phy_pcs_reg_layout *const pcs_reg_layout = |
| 294 | (void *)QMP_PHY_PCS_REG_BASE; |
| 295 | |
| 296 | |
| 297 | |
| 298 | struct 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 | }; |
| 332 | check_member(usb_dwc3, usb3pipectl, 0x1c0); |
| 333 | |
| 334 | static 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 | |
| 373 | static 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 | |
| 381 | static 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 | |
| 397 | static 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 | |
| 444 | struct 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 | |
| 467 | static 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 | |
| 488 | static struct qfprom_corr * const qfprom_corr_efuse = (void *)QFPROM_BASE; |
| 489 | |
| 490 | static 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 | |
| 503 | void 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 | */ |
| 516 | static 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 | */ |
| 536 | static 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 Georgi | b9d5b26 | 2019-12-05 19:56:53 +0100 | [diff] [blame] | 556 | clrsetbits32(&dwc3->qusb_phy_dig->tune1, |
T Michael Turney | 050be72 | 2019-10-22 06:25:09 -0700 | [diff] [blame] | 557 | PORT_TUNE1_MASK, tune_val << 4); |
| 558 | } |
| 559 | |
| 560 | static 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 | |
| 590 | static void hs_qusb_phy_init(struct usb_dwc3_cfg *dwc3) |
| 591 | { |
| 592 | /* PWR_CTRL: set the power down bit to disable the PHY */ |
Patrick Georgi | b9d5b26 | 2019-12-05 19:56:53 +0100 | [diff] [blame] | 593 | setbits32(&dwc3->qusb_phy_dig->pwr_ctrl1, POWER_DOWN); |
T Michael Turney | 050be72 | 2019-10-22 06:25:09 -0700 | [diff] [blame] | 594 | |
| 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 Georgi | b9d5b26 | 2019-12-05 19:56:53 +0100 | [diff] [blame] | 613 | clrbits32(&dwc3->qusb_phy_dig->pwr_ctrl1, POWER_DOWN); |
T Michael Turney | 050be72 | 2019-10-22 06:25:09 -0700 | [diff] [blame] | 614 | |
| 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 | |
| 631 | static 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 | |
| 644 | static 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 | |
| 676 | static void setup_dwc3(struct usb_dwc3 *dwc3) |
| 677 | { |
| 678 | /* core exits U1/U2/U3 only in PHY power state P1/P2/P3 respectively */ |
Patrick Georgi | b9d5b26 | 2019-12-05 19:56:53 +0100 | [diff] [blame] | 679 | clrsetbits32(&dwc3->usb3pipectl, |
T Michael Turney | 050be72 | 2019-10-22 06:25:09 -0700 | [diff] [blame] | 680 | 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 Georgi | b9d5b26 | 2019-12-05 19:56:53 +0100 | [diff] [blame] | 689 | clrsetbits32(&dwc3->usb2phycfg, |
T Michael Turney | 050be72 | 2019-10-22 06:25:09 -0700 | [diff] [blame] | 690 | (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 Georgi | b9d5b26 | 2019-12-05 19:56:53 +0100 | [diff] [blame] | 695 | clrsetbits32(&dwc3->ctl, (DWC3_GCTL_SCALEDOWN_MASK | |
T Michael Turney | 050be72 | 2019-10-22 06:25:09 -0700 | [diff] [blame] | 696 | DWC3_GCTL_DISSCRAMBLE), |
| 697 | DWC3_GCTL_U2EXIT_LFPS | DWC3_GCTL_DSBLCLKGTNG); |
| 698 | |
| 699 | /* configure controller in Host mode */ |
Patrick Georgi | b9d5b26 | 2019-12-05 19:56:53 +0100 | [diff] [blame] | 700 | clrsetbits32(&dwc3->ctl, (DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG)), |
T Michael Turney | 050be72 | 2019-10-22 06:25:09 -0700 | [diff] [blame] | 701 | 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 */ |
| 706 | static 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 | |
| 732 | void 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 | } |