• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <device/mmio.h>
4 #include <console/console.h>
5 #include <delay.h>
6 #include <soc/clock.h>
7 #include <soc/iomap.h>
8 #include <soc/usb.h>
9 
10 /**
11  *  USB Hardware registers
12  */
13 #define PHY_CTRL0_ADDR	0x000
14 #define PHY_CTRL1_ADDR	0x004
15 #define PHY_CTRL2_ADDR	0x008
16 #define PHY_CTRL3_ADDR	0x00C
17 #define PHY_CTRL4_ADDR	0x010
18 #define PHY_MISC_ADDR	0x024
19 #define PHY_IPG_ADDR	0x030
20 
21 #define PHY_CTRL0_VAL	0xA4600015
22 #define PHY_CTRL1_VAL	0x09500000
23 #define PHY_CTRL2_VAL	0x00058180
24 #define PHY_CTRL3_VAL	0x6DB6DCD6
25 #define PHY_CTRL4_VAL	0x836DB6DB
26 #define PHY_MISC_VAL	0x3803FB0C
27 #define PHY_IPG_VAL	0x47323232
28 
29 #define	USB_HOST3_PHY_BASE		((void *)0x8a00000)
30 #define	USB_HOST3_BALDUR_PHY_BASE	((void *)0xa6000)
31 #define	GCC_USB3_RST_CTRL		((void *)0x0181E038)
32 
33 #define DWC3_GCTL			0xc110
34 #define DWC3_GUSB3PIPECTL(n)		(0xc2c0 + (n * 0x04))
35 #define DWC3_GUSB2PHYCFG(n)		(0xc200 + (n * 0x04))
36 
37 /* Global USB3 PIPE Control Register */
38 #define DWC3_GUSB3PIPECTL_PHYSOFTRST	(1 << 31)
39 #define DWC3_GUSB3PIPECTL_SUSPHY	(1 << 17)
40 #define DWC3_GCTL_CORESOFTRESET		(1 << 11)
41 #define DWC3_GCTL_PRTCAPDIR(n)		((n) << 12)
42 #define DWC3_GCTL_PRTCAP_OTG		3
43 #define DWC3_DCTL_CSFTRST		(1 << 30)
44 #define DWC3_GSNPSID			0xc120
45 #define DWC3_DCTL			0xc704
46 
47 /* Global USB2 PHY Configuration Register */
48 #define DWC3_GUSB2PHYCFG_PHYSOFTRST	(1 << 31)
49 #define DWC3_GUSB2PHYCFG_SUSPHY		(1 << 6)
50 #define DWC3_GSNPSID_MASK		0xffff0000
51 #define DWC3_GEVTEN			0xc114
52 
53 #define DWC3_GCTL_SCALEDOWN(n)		((n) << 4)
54 #define DWC3_GCTL_SCALEDOWN_MASK	DWC3_GCTL_SCALEDOWN(3)
55 #define DWC3_GCTL_DISSCRAMBLE		(1 << 3)
56 #define DWC3_GCTL_DSBLCLKGTNG		(1 << 0)
57 #define DWC3_GCTL_U2RSTECN		(1 << 16)
58 #define DWC3_REVISION_190A		0x5533190a
59 
60 #define USB30_HS_PHY_CTRL		0x00000010
61 #define SW_SESSVLD			(0x01 << 0x1C)
62 #define UTMI_OTG_VBUS_VALID		(0x01 << 0x14)
63 
64 #define USB30_SS_PHY_CTRL		0x00000030
65 #define LANE0_PWR_PRESENT		(0x01 << 0x18)
66 
67 static void setup_dwc3(void);
68 
69 /**
70  * Write register.
71  *
72  * @param base - PHY base virtual address.
73  * @param offset - register offset.
74  * @param val - value to write.
75  */
qscratch_write(void * base,u32 offset,u32 val)76 static inline void qscratch_write(void *base, u32 offset, u32 val)
77 {
78 	write32(base + offset, val);
79 }
80 
81 /**
82  * Write register and read back masked value to confirm it is written
83  *
84  * @param base - base virtual address.
85  * @param offset - register offset.
86  * @param mask - register bitmask specifying what should be updated
87  * @param val - value to write.
88  */
qscratch_write_readback(void * base,u32 offset,const u32 mask,u32 val)89 static inline void qscratch_write_readback(void *base, u32 offset,
90 						const u32 mask, u32 val)
91 {
92 	u32 write_val, tmp = read32(base + offset);
93 
94 	tmp &= ~mask;       /* retain other bits */
95 	write_val = tmp | val;
96 
97 	write32(base + offset, write_val);
98 
99 	/* Read back to see if val was written */
100 	tmp = read32(base + offset);
101 	tmp &= mask;        /* clear other bits */
102 
103 	if (tmp != val) {
104 		printk(BIOS_INFO, "write: %x to QSCRATCH: %x FAILED\n",
105 			val, offset);
106 	}
107 }
108 
dwc3_ipq40xx_enable_vbus_valid(void)109 static void dwc3_ipq40xx_enable_vbus_valid(void)
110 {
111 	/* Enable VBUS valid for HS PHY*/
112 	qscratch_write_readback((void *)0x8af8800, USB30_HS_PHY_CTRL,
113 				SW_SESSVLD, SW_SESSVLD);
114 	qscratch_write_readback((void *)0x8af8800, USB30_HS_PHY_CTRL,
115 				UTMI_OTG_VBUS_VALID, UTMI_OTG_VBUS_VALID);
116 
117 	/* Enable VBUS valid for SS PHY*/
118 	qscratch_write_readback((void *)0x8af8800, USB30_SS_PHY_CTRL,
119 				LANE0_PWR_PRESENT, LANE0_PWR_PRESENT);
120 }
121 
qcom_baldur_hs_phy_init(void)122 static void qcom_baldur_hs_phy_init(void)
123 {
124 	u32 reg;
125 
126 	/* assert HS PHY POR reset */
127 	reg = read32(GCC_USB3_RST_CTRL);
128 	reg = reg | 0x10;
129 	write32(GCC_USB3_RST_CTRL, reg);
130 	mdelay(10);
131 
132 	/* assert HS PHY SRIF reset */
133 	reg = read32(GCC_USB3_RST_CTRL);
134 	reg = reg | 0x4;
135 	write32(GCC_USB3_RST_CTRL, reg);
136 	mdelay(10);
137 
138 	/* deassert HS PHY SRIF reset and program HS PHY registers */
139 	reg = read32(GCC_USB3_RST_CTRL);
140 	reg = reg & ~0x4;
141 	write32(GCC_USB3_RST_CTRL, reg);
142 
143 	mdelay(10);
144 
145 	/* perform PHY register writes */
146 	write32(USB_HOST3_BALDUR_PHY_BASE + PHY_CTRL0_ADDR, PHY_CTRL0_VAL);
147 	write32(USB_HOST3_BALDUR_PHY_BASE + PHY_CTRL1_ADDR, PHY_CTRL1_VAL);
148 	write32(USB_HOST3_BALDUR_PHY_BASE + PHY_CTRL2_ADDR, PHY_CTRL2_VAL);
149 	write32(USB_HOST3_BALDUR_PHY_BASE + PHY_CTRL3_ADDR, PHY_CTRL3_VAL);
150 	write32(USB_HOST3_BALDUR_PHY_BASE + PHY_CTRL4_ADDR, PHY_CTRL4_VAL);
151 	write32(USB_HOST3_BALDUR_PHY_BASE + PHY_MISC_ADDR, PHY_MISC_VAL);
152 	write32(USB_HOST3_BALDUR_PHY_BASE + PHY_IPG_ADDR, PHY_IPG_VAL);
153 
154 	mdelay(10);
155 
156 	/* de-assert USB3 HS PHY POR reset */
157 	reg = read32(GCC_USB3_RST_CTRL);
158 	reg = reg & ~0x10;
159 	write32(GCC_USB3_RST_CTRL, reg);
160 }
161 
qcom_uni_ss_phy_init(void)162 static void qcom_uni_ss_phy_init(void)
163 {
164 	u32 reg;
165 
166 	/* assert SS PHY POR reset */
167 	reg = read32(GCC_USB3_RST_CTRL);
168 	reg = reg | 0x20;
169 	write32(GCC_USB3_RST_CTRL, reg);
170 
171 	mdelay(100);
172 
173 	/* deassert SS PHY POR reset */
174 	reg = read32(GCC_USB3_RST_CTRL);
175 	reg = reg  & ~0x20;
176 	write32(GCC_USB3_RST_CTRL, reg);
177 }
178 
setup_dwc3(void)179 void setup_dwc3(void)
180 {
181 	u32 reg;
182 	u32 revision;
183 
184 	revision = read32(USB_HOST3_PHY_BASE + DWC3_GSNPSID);
185 	/* This should read as U3 followed by revision number */
186 	if ((revision & DWC3_GSNPSID_MASK) != 0x55330000)
187 		printk(BIOS_INFO, "Error in reading Version\n");
188 
189 	printk(BIOS_INFO, "Version = %x\n", revision);
190 
191 	/* issue device SoftReset too */
192 	write32(USB_HOST3_PHY_BASE + DWC3_DCTL, DWC3_DCTL_CSFTRST);
193 	do {
194 		reg = read32(USB_HOST3_PHY_BASE + DWC3_DCTL);
195 		if (!(reg & DWC3_DCTL_CSFTRST))
196 			break;
197 
198 		udelay(10);
199 	} while (true);
200 	printk(BIOS_INFO, "software reset done\n");
201 
202 	/* Before Resetting PHY, put Core in Reset */
203 	reg = read32(USB_HOST3_PHY_BASE + DWC3_GCTL);
204 	reg |= DWC3_GCTL_CORESOFTRESET;
205 	write32(USB_HOST3_PHY_BASE + DWC3_GCTL, reg);
206 
207 	/* Assert USB3 PHY reset */
208 	reg = read32(USB_HOST3_PHY_BASE + DWC3_GUSB3PIPECTL(0));
209 	reg |= DWC3_GUSB3PIPECTL_PHYSOFTRST;
210 	write32(USB_HOST3_PHY_BASE + DWC3_GUSB3PIPECTL(0), reg);
211 
212 	/* Assert USB2 PHY reset */
213 	reg = read32(USB_HOST3_PHY_BASE + DWC3_GUSB2PHYCFG(0));
214 	reg |= DWC3_GUSB2PHYCFG_PHYSOFTRST;
215 	write32(USB_HOST3_PHY_BASE + DWC3_GUSB2PHYCFG(0), reg);
216 
217 	qcom_baldur_hs_phy_init();
218 	qcom_uni_ss_phy_init();
219 	mdelay(100);
220 
221 	/* Clear USB3 PHY reset */
222 	reg = read32(USB_HOST3_PHY_BASE + DWC3_GUSB3PIPECTL(0));
223 	reg &= ~DWC3_GUSB3PIPECTL_PHYSOFTRST;
224 	write32(USB_HOST3_PHY_BASE + DWC3_GUSB3PIPECTL(0), reg);
225 
226 	/* Clear USB2 PHY reset */
227 	reg = read32(USB_HOST3_PHY_BASE + DWC3_GUSB2PHYCFG(0));
228 	reg &= ~DWC3_GUSB2PHYCFG_PHYSOFTRST;
229 	write32(USB_HOST3_PHY_BASE + DWC3_GUSB2PHYCFG(0), reg);
230 
231 	mdelay(100);
232 
233 	/* After PHYs are stable we can take Core out of reset state */
234 	reg = read32(USB_HOST3_PHY_BASE + DWC3_GCTL);
235 	reg &= ~DWC3_GCTL_CORESOFTRESET;
236 	write32(USB_HOST3_PHY_BASE + DWC3_GCTL, reg);
237 
238 #if 0
239 	/* Enable Suspend USB2.0 HS/FS/LS PHY (SusPHY) */
240 	reg = read32(USB_HOST3_PHY_BASE + DWC3_GUSB2PHYCFG(0));
241 	reg |= DWC3_GUSB2PHYCFG_SUSPHY;
242 	write32(USB_HOST3_PHY_BASE + DWC3_GUSB2PHYCFG(0), reg);
243 
244 	/* Enable Suspend USB3.0 SS PHY (Suspend_en) */
245 	reg = read32(USB_HOST3_PHY_BASE + DWC3_GUSB3PIPECTL(0));
246 	reg |= DWC3_GUSB3PIPECTL_SUSPHY;
247 	write32(USB_HOST3_PHY_BASE + DWC3_GUSB3PIPECTL(0), reg);
248 #endif
249 
250 	/* configure controller in Host mode */
251 	reg = read32(USB_HOST3_PHY_BASE + DWC3_GCTL);
252 	reg &= ~(DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG));
253 	reg |= DWC3_GCTL_PRTCAPDIR(0x1); /* host mode */
254 	write32(USB_HOST3_PHY_BASE + DWC3_GCTL, reg);
255 	printk(BIOS_INFO, "USB Host mode reg = %x\n", reg);
256 
257 	reg = read32(USB_HOST3_PHY_BASE + DWC3_GCTL);
258 	reg &= ~DWC3_GCTL_SCALEDOWN_MASK;
259 	reg &= ~DWC3_GCTL_DISSCRAMBLE;
260 
261 	reg &= ~DWC3_GCTL_DSBLCLKGTNG;
262 	/*
263 	 * WORKAROUND: DWC3 revisions <1.90a have a bug
264 	 * where the device can fail to connect at SuperSpeed
265 	 * and falls back to high-speed mode which causes
266 	 * the device to enter a Connect/Disconnect loop
267 	 */
268 	if (revision < DWC3_REVISION_190A)
269 		reg |= DWC3_GCTL_U2RSTECN;
270 
271 	write32(USB_HOST3_PHY_BASE + DWC3_GCTL, reg);
272 }
273 
setup_usb_host1(void)274 void setup_usb_host1(void)
275 {
276 	printk(BIOS_INFO, "Setting up USB HOST1 controller.\n");
277 	setup_dwc3();
278 	dwc3_ipq40xx_enable_vbus_valid();
279 }
280