blob: b3c0813fbbf2c796d9eaf7650c37d6a05df12b87 [file] [log] [blame]
Angel Pons7c1d70e2020-04-04 18:51:19 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Varadarajan Narayanana6935c22016-03-02 16:57:10 +05302
Kyösti Mälkki13f66502019-03-03 08:01:05 +02003#include <device/mmio.h>
Varadarajan Narayanana6935c22016-03-02 16:57:10 +05304#include <console/console.h>
5#include <delay.h>
6#include <soc/clock.h>
7#include <soc/iomap.h>
8#include <soc/usb.h>
9
Varadarajan Narayanan3939aca2015-11-03 14:42:21 +053010/**
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
Varadarajan Narayanana6935c22016-03-02 16:57:10 +053020
Varadarajan Narayanan3939aca2015-11-03 14:42:21 +053021#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
Varadarajan Narayanana6935c22016-03-02 16:57:10 +053028
Varadarajan Narayanan3939aca2015-11-03 14:42:21 +053029#define USB_HOST3_PHY_BASE ((void *)0x8a00000)
30#define USB_HOST3_BALDUR_PHY_BASE ((void *)0xa6000)
31#define GCC_USB3_RST_CTRL ((void *)0x0181E038)
Varadarajan Narayanana6935c22016-03-02 16:57:10 +053032
Varadarajan Narayanan3939aca2015-11-03 14:42:21 +053033#define DWC3_GCTL 0xc110
34#define DWC3_GUSB3PIPECTL(n) (0xc2c0 + (n * 0x04))
35#define DWC3_GUSB2PHYCFG(n) (0xc200 + (n * 0x04))
Varadarajan Narayanana6935c22016-03-02 16:57:10 +053036
Varadarajan Narayanan3939aca2015-11-03 14:42:21 +053037/* 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
Varadarajan Narayanana6935c22016-03-02 16:57:10 +053046
Varadarajan Narayanan3939aca2015-11-03 14:42:21 +053047/* 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
Varadarajan Narayanan3939aca2015-11-03 14:42:21 +053053#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
67static void setup_dwc3(void);
68
69/**
70 * Write register.
71 *
Martin Roth49348182016-07-06 10:17:19 -060072 * @param base - PHY base virtual address.
73 * @param offset - register offset.
74 * @param val - value to write.
Varadarajan Narayanan3939aca2015-11-03 14:42:21 +053075 */
76static inline void qscratch_write(void *base, u32 offset, u32 val)
Varadarajan Narayanana6935c22016-03-02 16:57:10 +053077{
Varadarajan Narayanan3939aca2015-11-03 14:42:21 +053078 write32(base + offset, val);
Varadarajan Narayanana6935c22016-03-02 16:57:10 +053079}
80
Varadarajan Narayanan3939aca2015-11-03 14:42:21 +053081/**
82 * Write register and read back masked value to confirm it is written
83 *
Martin Roth49348182016-07-06 10:17:19 -060084 * @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.
Varadarajan Narayanan3939aca2015-11-03 14:42:21 +053088 */
89static inline void qscratch_write_readback(void *base, u32 offset,
90 const u32 mask, u32 val)
Varadarajan Narayanana6935c22016-03-02 16:57:10 +053091{
Varadarajan Narayanan3939aca2015-11-03 14:42:21 +053092 u32 write_val, tmp = read32(base + offset);
Varadarajan Narayanana6935c22016-03-02 16:57:10 +053093
Varadarajan Narayanan3939aca2015-11-03 14:42:21 +053094 tmp &= ~mask; /* retain other bits */
95 write_val = tmp | val;
Varadarajan Narayanana6935c22016-03-02 16:57:10 +053096
Varadarajan Narayanan3939aca2015-11-03 14:42:21 +053097 write32(base + offset, write_val);
Varadarajan Narayanana6935c22016-03-02 16:57:10 +053098
Varadarajan Narayanan3939aca2015-11-03 14:42:21 +053099 /* Read back to see if val was written */
100 tmp = read32(base + offset);
101 tmp &= mask; /* clear other bits */
Varadarajan Narayanana6935c22016-03-02 16:57:10 +0530102
Varadarajan Narayanan3939aca2015-11-03 14:42:21 +0530103 if (tmp != val) {
104 printk(BIOS_INFO, "write: %x to QSCRATCH: %x FAILED\n",
105 val, offset);
106 }
Varadarajan Narayanana6935c22016-03-02 16:57:10 +0530107}
108
Varadarajan Narayanan3939aca2015-11-03 14:42:21 +0530109static void dwc3_ipq40xx_enable_vbus_valid(void)
Varadarajan Narayanana6935c22016-03-02 16:57:10 +0530110{
Varadarajan Narayanan3939aca2015-11-03 14:42:21 +0530111 /* 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);
Varadarajan Narayanana6935c22016-03-02 16:57:10 +0530116
Varadarajan Narayanan3939aca2015-11-03 14:42:21 +0530117 /* Enable VBUS valid for SS PHY*/
118 qscratch_write_readback((void *)0x8af8800, USB30_SS_PHY_CTRL,
119 LANE0_PWR_PRESENT, LANE0_PWR_PRESENT);
Varadarajan Narayanana6935c22016-03-02 16:57:10 +0530120}
121
Varadarajan Narayanan3939aca2015-11-03 14:42:21 +0530122static void qcom_baldur_hs_phy_init(void)
Varadarajan Narayanana6935c22016-03-02 16:57:10 +0530123{
Varadarajan Narayanan3939aca2015-11-03 14:42:21 +0530124 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);
Varadarajan Narayanana6935c22016-03-02 16:57:10 +0530160}
161
Varadarajan Narayanan3939aca2015-11-03 14:42:21 +0530162static void qcom_uni_ss_phy_init(void)
Varadarajan Narayanana6935c22016-03-02 16:57:10 +0530163{
Varadarajan Narayanan3939aca2015-11-03 14:42:21 +0530164 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
179void 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);
Varadarajan Narayanana6935c22016-03-02 16:57:10 +0530272}
273
274void setup_usb_host1(void)
275{
Varadarajan Narayanan3939aca2015-11-03 14:42:21 +0530276 printk(BIOS_INFO, "Setting up USB HOST1 controller.\n");
277 setup_dwc3();
278 dwc3_ipq40xx_enable_vbus_valid();
Varadarajan Narayanana6935c22016-03-02 16:57:10 +0530279}