1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <device/mmio.h>
4 #include <console/console.h>
11 * USB Hardware registers
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
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
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)
33 #define DWC3_GCTL 0xc110
34 #define DWC3_GUSB3PIPECTL(n) (0xc2c0 + (n * 0x04))
35 #define DWC3_GUSB2PHYCFG(n) (0xc200 + (n * 0x04))
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
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
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
60 #define USB30_HS_PHY_CTRL 0x00000010
61 #define SW_SESSVLD (0x01 << 0x1C)
62 #define UTMI_OTG_VBUS_VALID (0x01 << 0x14)
64 #define USB30_SS_PHY_CTRL 0x00000030
65 #define LANE0_PWR_PRESENT (0x01 << 0x18)
67 static void setup_dwc3(void);
72 * @param base - PHY base virtual address.
73 * @param offset - register offset.
74 * @param val - value to write.
76 static inline void qscratch_write(void *base
, u32 offset
, u32 val
)
78 write32(base
+ offset
, val
);
82 * Write register and read back masked value to confirm it is written
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.
89 static inline void qscratch_write_readback(void *base
, u32 offset
,
90 const u32 mask
, u32 val
)
92 u32 write_val
, tmp
= read32(base
+ offset
);
94 tmp
&= ~mask
; /* retain other bits */
95 write_val
= tmp
| val
;
97 write32(base
+ offset
, write_val
);
99 /* Read back to see if val was written */
100 tmp
= read32(base
+ offset
);
101 tmp
&= mask
; /* clear other bits */
104 printk(BIOS_INFO
, "write: %x to QSCRATCH: %x FAILED\n",
109 static void dwc3_ipq40xx_enable_vbus_valid(void)
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
);
117 /* Enable VBUS valid for SS PHY*/
118 qscratch_write_readback((void *)0x8af8800, USB30_SS_PHY_CTRL
,
119 LANE0_PWR_PRESENT
, LANE0_PWR_PRESENT
);
122 static void qcom_baldur_hs_phy_init(void)
126 /* assert HS PHY POR reset */
127 reg
= read32(GCC_USB3_RST_CTRL
);
129 write32(GCC_USB3_RST_CTRL
, reg
);
132 /* assert HS PHY SRIF reset */
133 reg
= read32(GCC_USB3_RST_CTRL
);
135 write32(GCC_USB3_RST_CTRL
, reg
);
138 /* deassert HS PHY SRIF reset and program HS PHY registers */
139 reg
= read32(GCC_USB3_RST_CTRL
);
141 write32(GCC_USB3_RST_CTRL
, reg
);
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
);
156 /* de-assert USB3 HS PHY POR reset */
157 reg
= read32(GCC_USB3_RST_CTRL
);
159 write32(GCC_USB3_RST_CTRL
, reg
);
162 static void qcom_uni_ss_phy_init(void)
166 /* assert SS PHY POR reset */
167 reg
= read32(GCC_USB3_RST_CTRL
);
169 write32(GCC_USB3_RST_CTRL
, reg
);
173 /* deassert SS PHY POR reset */
174 reg
= read32(GCC_USB3_RST_CTRL
);
176 write32(GCC_USB3_RST_CTRL
, reg
);
179 void setup_dwc3(void)
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");
189 printk(BIOS_INFO
, "Version = %x\n", revision
);
191 /* issue device SoftReset too */
192 write32(USB_HOST3_PHY_BASE
+ DWC3_DCTL
, DWC3_DCTL_CSFTRST
);
194 reg
= read32(USB_HOST3_PHY_BASE
+ DWC3_DCTL
);
195 if (!(reg
& DWC3_DCTL_CSFTRST
))
200 printk(BIOS_INFO
, "software reset done\n");
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
);
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
);
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
);
217 qcom_baldur_hs_phy_init();
218 qcom_uni_ss_phy_init();
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
);
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
);
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
);
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
);
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
);
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
);
257 reg
= read32(USB_HOST3_PHY_BASE
+ DWC3_GCTL
);
258 reg
&= ~DWC3_GCTL_SCALEDOWN_MASK
;
259 reg
&= ~DWC3_GCTL_DISSCRAMBLE
;
261 reg
&= ~DWC3_GCTL_DSBLCLKGTNG
;
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
268 if (revision
< DWC3_REVISION_190A
)
269 reg
|= DWC3_GCTL_U2RSTECN
;
271 write32(USB_HOST3_PHY_BASE
+ DWC3_GCTL
, reg
);
274 void setup_usb_host1(void)
276 printk(BIOS_INFO
, "Setting up USB HOST1 controller.\n");
278 dwc3_ipq40xx_enable_vbus_valid();