1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <device/mmio.h>
4 #include <console/console.h>
5 #include <soc/addressmap.h>
9 #define USBTAG "[SSUSB] "
10 #define u3p_msg(fmt, arg...) printk(BIOS_INFO, USBTAG fmt, ##arg)
11 #define u3p_err(fmt, arg...) printk(BIOS_ERR, USBTAG fmt, ##arg)
13 static struct ssusb_ippc_regs
*ippc_regs
= (void *)(SSUSB_IPPC_BASE
);
14 static struct ssusb_sif_port
*phy_ports
= (void *)(SSUSB_SIF_BASE
);
16 void update_usb_base_regs(uintptr_t ippc_base
, uintptr_t sif_base
)
18 ippc_regs
= (void *)ippc_base
;
19 phy_ports
= (void *)sif_base
;
22 static void phy_index_power_on(int index
)
24 struct ssusb_sif_port
*phy
= phy_ports
+ index
;
27 /* Set RG_SSUSB_VUSB10_ON as 1 after VUSB10 ready */
28 setbits32(&phy
->u3phya
.phya_reg0
, P3A_RG_U3_VUSB10_ON
);
29 /* Disable power domain ISO */
30 clrbits32(&phy
->u2phy
.usbphyacr6
, PA6_RG_U2_ISO_EN
);
32 /* Switch system IP to USB mode */
33 clrbits32(&phy
->u2phy
.u2phydtm0
, P2C_FORCE_UART_EN
);
34 clrbits32(&phy
->u2phy
.u2phydtm1
, P2C_RG_UART_EN
);
36 clrbits32(&phy
->u2phy
.u2phyacr4
, P2C_U2_GPIO_CTR_MSK
);
38 /* Disable force settings */
39 clrbits32(&phy
->u2phy
.u2phydtm0
, P2C_FORCE_SUSPENDM
|
40 P2C_RG_XCVRSEL
| P2C_RG_DATAIN
| P2C_DTM0_PART_MASK
);
42 clrbits32(&phy
->u2phy
.usbphyacr6
, PA6_RG_U2_BC11_SW_EN
);
43 /* Improve Rx sensitivity */
44 clrsetbits32(&phy
->u2phy
.usbphyacr6
,
45 PA6_RG_U2_SQTH
, PA6_RG_U2_SQTH_VAL(2));
47 setbits32(&phy
->u2phy
.usbphyacr6
, PA6_RG_U2_OTG_VBUSCMP_EN
);
49 clrsetbits32(&phy
->u3phya_da
.reg0
,
50 P3A_RG_XTAL_EXT_EN_U3
, P3A_RG_XTAL_EXT_EN_U3_VAL(2));
52 clrsetbits32(&phy
->u3phya
.phya_reg9
,
53 P3A_RG_RX_DAC_MUX
, P3A_RG_RX_DAC_MUX_VAL(4));
56 clrbits32(&phy
->u2phy
.usbphyacr5
, PA5_RG_U2_HS_100U_U3_EN
);
58 clrsetbits32(&phy
->u3phya
.phya_reg6
,
59 P3A_RG_TX_EIDLE_CM
, P3A_RG_TX_EIDLE_CM_VAL(0xe));
61 clrsetbits32(&phy
->u3phyd
.phyd_cdr1
,
62 P3D_RG_CDR_BIR_LTD0
, P3D_RG_CDR_BIR_LTD0_VAL(0xc));
63 clrsetbits32(&phy
->u3phyd
.phyd_cdr1
,
64 P3D_RG_CDR_BIR_LTD1
, P3D_RG_CDR_BIR_LTD1_VAL(0x3));
66 clrsetbits32(&phy
->u2phy
.u2phydtm1
,
67 P2C_RG_SESSEND
, P2C_RG_VBUSVALID
| P2C_RG_AVALID
);
69 /* Set USB 2.0 slew rate value */
70 clrsetbits32(&phy
->u2phy
.usbphyacr5
,
71 PA5_RG_U2_HSTX_SRCTRL
, PA5_RG_U2_HSTX_SRCTRL_VAL(4));
73 /* Set USB 2.0 disconnect threshold */
74 clrsetbits32(&phy
->u2phy
.usbphyacr6
,
75 PA6_RG_U2_DISCTH
, PA6_RG_U2_DISCTH_VAL(15));
78 static void u3phy_power_on(void)
80 for (int i
= 0; i
< USB_PORT_NUMBER
; i
++)
81 phy_index_power_on(i
);
84 static int check_ip_clk_status(void)
91 u3_port_num
= CAP_U3_PORT_NUM(read32(&ippc_regs
->ip_xhci_cap
));
93 check_bits
= STS1_SYSPLL_STABLE
| STS1_REF_RST
| STS1_SYS125_RST
;
94 check_bits
|= (u3_port_num
? STS1_U3_MAC_RST
: 0);
96 stopwatch_init_usecs_expire(&sw
, 50000);
99 if (stopwatch_expired(&sw
)) {
100 u3p_err("USB clocks are not stable!!!\n");
104 sts1
= read32(&ippc_regs
->ip_pw_sts1
) & check_bits
;
105 sts2
= read32(&ippc_regs
->ip_pw_sts2
) & STS2_U2_MAC_RST
;
106 } while ((sts1
!= check_bits
) || !sts2
);
111 static int u3phy_ports_enable(void)
118 value
= read32(&ippc_regs
->ip_xhci_cap
);
119 u3_port_num
= CAP_U3_PORT_NUM(value
);
120 u2_port_num
= CAP_U2_PORT_NUM(value
);
121 u3p_msg("%s u2p:%d, u3p:%d\n", __func__
, u2_port_num
, u3_port_num
);
123 /* Power on host ip */
124 clrbits32(&ippc_regs
->ip_pw_ctr1
, CTRL1_IP_HOST_PDN
);
126 /* Power on and enable all u3 ports */
127 for (i
= 0; i
< u3_port_num
; i
++) {
128 clrsetbits32(&ippc_regs
->u3_ctrl_p
[i
],
129 CTRL_U3_PORT_PDN
| CTRL_U3_PORT_DIS
,
130 CTRL_U3_PORT_HOST_SEL
);
133 /* Power on and enable all u2 ports */
134 for (i
= 0; i
< u2_port_num
; i
++) {
135 clrsetbits32(&ippc_regs
->u2_ctrl_p
[i
],
136 CTRL_U2_PORT_PDN
| CTRL_U2_PORT_DIS
,
137 CTRL_U2_PORT_HOST_SEL
);
139 return check_ip_clk_status();
142 static inline void ssusb_soft_reset(void)
145 setbits32(&ippc_regs
->ip_pw_ctr0
, CTRL0_IP_SW_RST
);
146 clrbits32(&ippc_regs
->ip_pw_ctr0
, CTRL0_IP_SW_RST
);
149 __weak
void mtk_usb_prepare(void)
154 __weak
void mtk_usb_adjust_phy_shift(void)
159 void setup_usb_host_controller(void)
161 u3p_msg("Setting up USB HOST controller...\n");
165 if (u3phy_ports_enable()) {
166 u3p_err("%s fail to enable ports\n", __func__
);
170 mtk_usb_adjust_phy_shift();
171 u3p_msg("phy power-on done.\n");
174 void setup_usb_host(void)
176 update_usb_base_regs(SSUSB_IPPC_BASE
, SSUSB_SIF_BASE
);
177 setup_usb_host_controller();