xref: /aosp_15_r20/external/coreboot/src/soc/qualcomm/common/usb/usb.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <console/console.h>
4 #include <device/mmio.h>
5 #include <soc/usb/usb_common.h>
6 #include <soc/addressmap.h>
7 #include <soc/clock.h>
8 
9 struct usb_dwc3 {
10 	u32 sbuscfg0;
11 	u32 sbuscfg1;
12 	u32 txthrcfg;
13 	u32 rxthrcfg;
14 	u32 ctl;
15 	u32 pmsts;
16 	u32 sts;
17 	u32 uctl1;
18 	u32 snpsid;
19 	u32 gpio;
20 	u32 uid;
21 	u32 uctl;
22 	u64 buserraddr;
23 	u64 prtbimap;
24 	u8 reserved1[32];
25 	u32 dbgfifospace;
26 	u32 dbgltssm;
27 	u32 dbglnmcc;
28 	u32 dbgbmu;
29 	u32 dbglspmux;
30 	u32 dbglsp;
31 	u32 dbgepinfo0;
32 	u32 dbgepinfo1;
33 	u64 prtbimap_hs;
34 	u64 prtbimap_fs;
35 	u8 reserved2[112];
36 	u32 usb2phycfg;
37 	u8 reserved3[124];
38 	u32 usb2phyacc;
39 	u8 reserved4[60];
40 	u32 usb3pipectl;
41 	u8 reserved5[60];
42 };
43 check_member(usb_dwc3, usb2phycfg, 0x100);
44 check_member(usb_dwc3, usb3pipectl, 0x1c0);
45 
46 struct usb_dwc3_cfg {
47 	struct usb_dwc3 *usb_host_dwc3;
48 	u32 *usb3_bcr;
49 	u32 *qusb2phy_bcr;
50 	u32 *gcc_usb3phy_bcr_reg;
51 	u32 *gcc_qmpphy_bcr_reg;
52 };
53 
54 static struct usb_dwc3_cfg usb_port0 = {
55 	.usb_host_dwc3 =	(void *)USB_HOST_DWC3_BASE,
56 	.usb3_bcr =		&gcc->usb30_prim_bcr,
57 	.qusb2phy_bcr =		&gcc->qusb2phy_prim_bcr,
58 	.gcc_usb3phy_bcr_reg =	&gcc->usb3_dp_phy_prim_bcr,
59 	.gcc_qmpphy_bcr_reg =	&gcc->usb3_phy_prim_bcr,
60 };
61 
reset_usb(struct usb_dwc3_cfg * dwc3)62 static void reset_usb(struct usb_dwc3_cfg *dwc3)
63 {
64 	/* Assert Core reset */
65 	clock_reset_bcr(dwc3->usb3_bcr, 1);
66 
67 	/* Assert HS PHY reset */
68 	clock_reset_bcr(dwc3->qusb2phy_bcr, 1);
69 
70 	/* Assert QMP PHY reset */
71 	clock_reset_bcr(dwc3->gcc_usb3phy_bcr_reg, 1);
72 	clock_reset_bcr(dwc3->gcc_qmpphy_bcr_reg, 1);
73 }
74 
reset_usb0(void)75 void reset_usb0(void)
76 {
77 	/* Before Resetting PHY, put Core in Reset */
78 	printk(BIOS_INFO, "Starting DWC3 and PHY resets for USB(0)\n");
79 
80 	reset_usb(&usb_port0);
81 }
82 
setup_dwc3(struct usb_dwc3 * dwc3)83 static void setup_dwc3(struct usb_dwc3 *dwc3)
84 {
85 	/* core exits U1/U2/U3 only in PHY power state P1/P2/P3 respectively */
86 	clrsetbits32(&dwc3->usb3pipectl,
87 		DWC3_GUSB3PIPECTL_DELAYP1TRANS,
88 		DWC3_GUSB3PIPECTL_UX_EXIT_IN_PX);
89 
90 	/*
91 	 * Configure USB phy interface of DWC3 core.
92 	 * 1. Select UTMI+ PHY with 16-bit interface.
93 	 * 2. Set USBTRDTIM to the corresponding value
94 	 * according to the UTMI+ PHY interface.
95 	 */
96 	clrsetbits32(&dwc3->usb2phycfg,
97 			(DWC3_GUSB2PHYCFG_USB2TRDTIM_MASK |
98 			DWC3_GUSB2PHYCFG_PHYIF_MASK),
99 			(DWC3_GUSB2PHYCFG_PHYIF(UTMI_PHYIF_8_BIT) |
100 			DWC3_GUSB2PHYCFG_USBTRDTIM(USBTRDTIM_UTMI_8_BIT)));
101 
102 	clrsetbits32(&dwc3->ctl, (DWC3_GCTL_SCALEDOWN_MASK |
103 			DWC3_GCTL_DISSCRAMBLE),
104 			DWC3_GCTL_U2EXIT_LFPS | DWC3_GCTL_DSBLCLKGTNG);
105 
106 	/* configure controller in Host mode */
107 	clrsetbits32(&dwc3->ctl, (DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG)),
108 			DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_HOST));
109 	printk(BIOS_SPEW, "Configure USB in Host mode\n");
110 }
111 
112 /* Initialization of DWC3 Core and PHY */
113 
setup_usb_host(struct usb_dwc3_cfg * dwc3,void * board_data)114 static void setup_usb_host(struct usb_dwc3_cfg *dwc3,
115 			void  *board_data)
116 {
117 	 /* Clear core reset. */
118 	clock_reset_bcr(dwc3->usb3_bcr, 0);
119 
120 	/* Clear QUSB PHY reset. */
121 	clock_reset_bcr(dwc3->qusb2phy_bcr, 0);
122 
123 	/* Initialize HS PHY */
124 	hs_usb_phy_init(board_data);
125 
126 	/* Clear QMP PHY resets. */
127 	clock_reset_bcr(dwc3->gcc_usb3phy_bcr_reg, 0);
128 	clock_reset_bcr(dwc3->gcc_qmpphy_bcr_reg, 0);
129 
130 	/* Initialize QMP PHY */
131 	ss_qmp_phy_init();
132 
133 	setup_dwc3(dwc3->usb_host_dwc3);
134 
135 	printk(BIOS_INFO, "DWC3 and PHY setup finished\n");
136 }
setup_usb_host0(void * board_data)137 void setup_usb_host0(void  *board_data)
138 {
139 	printk(BIOS_INFO, "Setting up USB HOST0 controller.\n");
140 	setup_usb_host(&usb_port0, board_data);
141 }
142