1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <device/mmio.h>
5 #include <console/console.h>
11 /* SuperSpeed over Type-C is hard. We don't care about speed in firmware: just
12 * gate off the SuperSpeed lines to have an unimpaired USB 2.0 connection. */
13 static void isolate_tcphy(struct rk3399_tcphy
*tcphy
)
15 write32(&tcphy
->isolation_ctrl
,
16 TCPHY_ISOLATION_CTRL_EN
|
17 TCPHY_ISOLATION_CTRL_CMN_EN
|
18 TCPHY_ISOLATION_CTRL_MODE_SEL
|
19 TCPHY_ISOLATION_CTRL_LN_EN(7) |
20 TCPHY_ISOLATION_CTRL_LN_EN(6) |
21 TCPHY_ISOLATION_CTRL_LN_EN(5) |
22 TCPHY_ISOLATION_CTRL_LN_EN(4) |
23 TCPHY_ISOLATION_CTRL_LN_EN(3) |
24 TCPHY_ISOLATION_CTRL_LN_EN(2) |
25 TCPHY_ISOLATION_CTRL_LN_EN(1) |
26 TCPHY_ISOLATION_CTRL_LN_EN(0));
29 static void tcphy_cfg_24m(struct rk3399_tcphy
*tcphy
)
33 /* cmn_ref_clk_sel = 3, select the 24Mhz for clk parent
34 * cmn_psm_clk_dig_div = 2, set the clk division to 2 */
35 write32(&tcphy
->pma_cmn_ctrl1
, 2 << 10 | 3 << 4);
36 for (i
= 0; i
< 4; i
++) {
37 /* The following PHY configuration assumes a
38 * 24 MHz reference clock */
39 write32(&tcphy
->lane
[i
].xcvr_diag_lane_fcm_en_mgn
, 0x90);
40 write32(&tcphy
->lane
[i
].tx_rcvdet_en_tmr
, 0x960);
41 write32(&tcphy
->lane
[i
].tx_rcvdet_st_tmr
, 0x30);
44 clrsetbits32(&tcphy
->cmn_diag_hsclk_sel
,
45 TCPHY_CMN_HSCLK_PLL_MASK
, TCPHY_CMN_HSCLK_PLL_CONFIG
);
48 static void tcphy_phy_init(struct rk3399_tcphy
*tcphy
)
54 for (i
= 0; i
< 4; i
++) {
55 /* Enable transmitter reset pull down override for all lanes*/
56 write32(&tcphy
->lane
[i
].tx_diag_tx_drv
, 0x2000);
57 /* Disable transmitter low current mode, disable TX
58 * driver common mode, disable TX post-emphasis*/
59 write32(&tcphy
->lane
[i
].tx_psc_a2
, 0x0000);
65 static void reset_dwc3(struct rockchip_usb_dwc3
*dwc3
)
67 /* Before Resetting PHY, put Core in Reset */
68 setbits32(&dwc3
->ctl
, DWC3_GCTL_CORESOFTRESET
);
69 /* Assert USB3 PHY reset */
70 setbits32(&dwc3
->usb3pipectl
, DWC3_GUSB3PIPECTL_PHYSOFTRST
);
71 /* Assert USB2 PHY reset */
72 setbits32(&dwc3
->usb2phycfg
, DWC3_GUSB2PHYCFG_PHYSOFTRST
);
75 static void setup_dwc3(struct rockchip_usb_dwc3
*dwc3
)
77 u32 usb2phycfg
= read32(&dwc3
->usb2phycfg
);
78 u32 ctl
= read32(&dwc3
->ctl
);
80 /* Ensure reset_dwc3() has been called before this. */
81 assert(ctl
& DWC3_GCTL_CORESOFTRESET
);
83 /* Clear USB3 PHY reset (oddly enough, this is really necessary). */
84 clrbits32(&dwc3
->usb3pipectl
, DWC3_GUSB3PIPECTL_PHYSOFTRST
);
86 /* Clear USB2 PHY and core reset. */
87 usb2phycfg
&= ~DWC3_GUSB2PHYCFG_PHYSOFTRST
;
88 ctl
&= ~DWC3_GCTL_CORESOFTRESET
;
90 /* We are hard-coding DWC3 core to Host Mode */
91 ctl
&= ~DWC3_GCTL_PRTCAP_MASK
;
92 ctl
|= DWC3_GCTL_PRTCAP_HOST
;
95 * Configure USB phy interface of DWC3 core.
96 * For Rockchip rk3399 SOC DWC3 core:
97 * 1. Clear U2_FREECLK_EXITS.
98 * 2. Select UTMI+ PHY with 16-bit interface.
99 * 3. Set USBTRDTIM to the corresponding value
100 * according to the UTMI+ PHY interface.
102 usb2phycfg
&= ~(DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS
|
103 DWC3_GUSB2PHYCFG_USB2TRDTIM_MASK
|
104 DWC3_GUSB2PHYCFG_PHYIF_MASK
);
105 usb2phycfg
|= DWC3_GUSB2PHYCFG_PHYIF(1) |
106 DWC3_GUSB2PHYCFG_USBTRDTIM(USBTRDTIM_UTMI_16_BIT
);
108 write32(&dwc3
->usb2phycfg
, usb2phycfg
);
109 write32(&dwc3
->ctl
, ctl
);
112 void reset_usb_otg0(void)
114 printk(BIOS_DEBUG
, "Starting DWC3 and TCPHY reset for USB OTG0\n");
116 /* Keep whole USB OTG0 controller in reset, then
117 * configure controller to work in USB 2.0 only mode. */
118 write32(&cru_ptr
->softrst_con
[18], RK_SETBITS(1 << 5));
119 write32(&rk3399_grf
->usb3otg0_con1
, RK_CLRSETBITS(0xf << 12, 1 << 0));
120 write32(&cru_ptr
->softrst_con
[18], RK_CLRBITS(1 << 5));
122 tcphy_phy_init(rockchip_usb_otg0_phy
);
124 /* Clear TCPHY0 reset */
125 write32(&cru_ptr
->softrst_con
[9], RK_CLRBITS(1 << 5));
127 reset_dwc3(rockchip_usb_otg0_dwc3
);
130 void reset_usb_otg1(void)
132 printk(BIOS_DEBUG
, "Starting DWC3 and TCPHY reset for USB OTG1\n");
134 /* Keep whole USB OTG1 controller in reset, then
135 * configure controller to work in USB 2.0 only mode. */
136 write32(&cru_ptr
->softrst_con
[18], RK_SETBITS(1 << 6));
137 write32(&rk3399_grf
->usb3otg1_con1
, RK_CLRSETBITS(0xf << 12, 1 << 0));
138 write32(&cru_ptr
->softrst_con
[18], RK_CLRBITS(1 << 6));
140 tcphy_phy_init(rockchip_usb_otg1_phy
);
142 /* Clear TCPHY1 reset */
143 write32(&cru_ptr
->softrst_con
[9], RK_CLRBITS(1 << 13));
145 reset_dwc3(rockchip_usb_otg1_dwc3
);
148 void setup_usb_otg0(void)
150 /* Clear pipe reset */
151 write32(&cru_ptr
->softrst_con
[9], RK_CLRBITS(1 << 4));
153 setup_dwc3(rockchip_usb_otg0_dwc3
);
154 printk(BIOS_DEBUG
, "DWC3 and TCPHY setup for USB OTG0 finished\n");
157 void setup_usb_otg1(void)
159 /* Clear pipe reset */
160 write32(&cru_ptr
->softrst_con
[9], RK_CLRBITS(1 << 12));
162 setup_dwc3(rockchip_usb_otg1_dwc3
);
163 printk(BIOS_DEBUG
, "DWC3 and TCPHY setup for USB OTG1 finished\n");