coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
usb.c
Go to the documentation of this file.
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  */
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  */
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 
110 {
111  /* Enable VBUS valid for HS PHY*/
112  qscratch_write_readback((void *)0x8af8800, USB30_HS_PHY_CTRL,
114  qscratch_write_readback((void *)0x8af8800, USB30_HS_PHY_CTRL,
116 
117  /* Enable VBUS valid for SS PHY*/
118  qscratch_write_readback((void *)0x8af8800, USB30_SS_PHY_CTRL,
120 }
121 
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;
130  mdelay(10);
131 
132  /* assert HS PHY SRIF reset */
133  reg = read32(GCC_USB3_RST_CTRL);
134  reg = reg | 0x4;
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;
142 
143  mdelay(10);
144 
145  /* perform PHY register writes */
153 
154  mdelay(10);
155 
156  /* de-assert USB3 HS PHY POR reset */
157  reg = read32(GCC_USB3_RST_CTRL);
158  reg = reg & ~0x10;
160 }
161 
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;
170 
171  mdelay(100);
172 
173  /* deassert SS PHY POR reset */
174  reg = read32(GCC_USB3_RST_CTRL);
175  reg = reg & ~0x20;
177 }
178 
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 */
193  do {
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 */
206 
207  /* Assert USB3 PHY reset */
211 
212  /* Assert USB2 PHY reset */
216 
219  mdelay(100);
220 
221  /* Clear USB3 PHY reset */
225 
226  /* Clear USB2 PHY reset */
230 
231  mdelay(100);
232 
233  /* After PHYs are stable we can take Core out of reset state */
235  reg &= ~DWC3_GCTL_CORESOFTRESET;
237 
238 #if 0
239  /* Enable Suspend USB2.0 HS/FS/LS PHY (SusPHY) */
243 
244  /* Enable Suspend USB3.0 SS PHY (Suspend_en) */
248 #endif
249 
250  /* configure controller in Host mode */
253  reg |= DWC3_GCTL_PRTCAPDIR(0x1); /* host mode */
255  printk(BIOS_INFO, "USB Host mode reg = %x\n", reg);
256 
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 
272 }
273 
274 void setup_usb_host1(void)
275 {
276  printk(BIOS_INFO, "Setting up USB HOST1 controller.\n");
277  setup_dwc3();
279 }
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
static uint32_t read32(const void *addr)
Definition: mmio.h:22
#define printk(level,...)
Definition: stdlib.h:16
void mdelay(unsigned int msecs)
Definition: delay.c:2
static size_t offset
Definition: flashconsole.c:16
#define BIOS_INFO
BIOS_INFO - Expected events.
Definition: loglevel.h:113
uintptr_t base
Definition: uart.c:17
static const int mask[4]
Definition: gpio.c:308
#define USB_HOST3_BALDUR_PHY_BASE
Definition: usb.c:30
#define LANE0_PWR_PRESENT
Definition: usb.c:65
#define PHY_CTRL3_ADDR
Definition: usb.c:16
#define PHY_MISC_VAL
Definition: usb.c:26
#define DWC3_REVISION_190A
Definition: usb.c:58
#define DWC3_GUSB2PHYCFG(n)
Definition: usb.c:35
#define GCC_USB3_RST_CTRL
Definition: usb.c:31
#define PHY_CTRL2_VAL
Definition: usb.c:23
#define PHY_CTRL4_ADDR
Definition: usb.c:17
#define DWC3_GCTL_PRTCAP_OTG
Definition: usb.c:42
#define DWC3_GUSB3PIPECTL_SUSPHY
Definition: usb.c:39
#define DWC3_GUSB2PHYCFG_PHYSOFTRST
Definition: usb.c:48
static void qcom_baldur_hs_phy_init(void)
Definition: usb.c:122
#define PHY_CTRL3_VAL
Definition: usb.c:24
#define PHY_MISC_ADDR
Definition: usb.c:18
#define USB30_HS_PHY_CTRL
Definition: usb.c:60
#define PHY_CTRL1_ADDR
Definition: usb.c:14
static void qscratch_write_readback(void *base, u32 offset, const u32 mask, u32 val)
Write register and read back masked value to confirm it is written.
Definition: usb.c:89
#define PHY_CTRL1_VAL
Definition: usb.c:22
#define DWC3_GCTL
Definition: usb.c:33
#define DWC3_GUSB2PHYCFG_SUSPHY
Definition: usb.c:49
#define PHY_IPG_VAL
Definition: usb.c:27
#define DWC3_GUSB3PIPECTL_PHYSOFTRST
Definition: usb.c:38
#define PHY_CTRL0_ADDR
USB Hardware registers.
Definition: usb.c:13
#define DWC3_DCTL
Definition: usb.c:45
#define DWC3_GCTL_SCALEDOWN_MASK
Definition: usb.c:54
static void qscratch_write(void *base, u32 offset, u32 val)
Write register.
Definition: usb.c:76
#define DWC3_GCTL_CORESOFTRESET
Definition: usb.c:40
#define USB30_SS_PHY_CTRL
Definition: usb.c:64
#define PHY_IPG_ADDR
Definition: usb.c:19
#define DWC3_DCTL_CSFTRST
Definition: usb.c:43
#define DWC3_GCTL_DISSCRAMBLE
Definition: usb.c:55
#define DWC3_GCTL_U2RSTECN
Definition: usb.c:57
#define PHY_CTRL4_VAL
Definition: usb.c:25
#define DWC3_GCTL_DSBLCLKGTNG
Definition: usb.c:56
#define UTMI_OTG_VBUS_VALID
Definition: usb.c:62
static void setup_dwc3(void)
Definition: usb.c:179
#define SW_SESSVLD
Definition: usb.c:61
#define DWC3_GSNPSID_MASK
Definition: usb.c:50
static void qcom_uni_ss_phy_init(void)
Definition: usb.c:162
#define PHY_CTRL2_ADDR
Definition: usb.c:15
#define DWC3_GSNPSID
Definition: usb.c:44
#define DWC3_GUSB3PIPECTL(n)
Definition: usb.c:34
#define DWC3_GCTL_PRTCAPDIR(n)
Definition: usb.c:41
void setup_usb_host1(void)
Definition: usb.c:274
#define PHY_CTRL0_VAL
Definition: usb.c:21
#define USB_HOST3_PHY_BASE
Definition: usb.c:29
static void dwc3_ipq40xx_enable_vbus_valid(void)
Definition: usb.c:109
uint32_t u32
Definition: stdint.h:51
u8 val
Definition: sys.c:300
void udelay(uint32_t us)
Definition: udelay.c:15