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 <device/device.h>
7 #include <soc/gpio.h>
8 #include <soc/power.h>
9 #include <soc/sysreg.h>
10 #include <soc/usb.h>
11 
12 static void reset_dwc3(struct exynos5_usb_drd_dwc3 *dwc3)
13 {
14  setbits32(&dwc3->ctl, 0x1 << 11); /* core soft reset */
15  setbits32(&dwc3->usb3pipectl, 0x1 << 31); /* PHY soft reset */
16  setbits32(&dwc3->usb2phycfg, 0x1 << 31); /* PHY soft reset */
17 }
18 
20 {
21  printk(BIOS_DEBUG, "Starting DWC3 reset for USB DRD0\n");
23 }
24 
26 {
27  printk(BIOS_DEBUG, "Starting DWC3 reset for USB DRD1\n");
29 }
30 
31 static void setup_dwc3(struct exynos5_usb_drd_dwc3 *dwc3)
32 {
33  if (!(dwc3->ctl & 0x1 << 11) ||
34  !(dwc3->usb3pipectl & 0x1 << 31) ||
35  !(dwc3->usb2phycfg & 0x1 << 31)) {
36  printk(BIOS_ERR, "DWC3 at %p not in reset (you need to call "
37  "reset_usb_drdX_dwc3() first)!\n", dwc3);
38  }
39 
40  /* Set relevant registers to default values (clearing all reset bits) */
41 
42  write32(&dwc3->usb3pipectl,
43  0x1 << 24 | /* activate PHY low power states */
44  0x4 << 19 | /* low power delay value */
45  0x1 << 18 | /* activate PHY low power delay */
46  0x1 << 17 | /* enable SuperSpeed PHY suspend */
47  0x1 << 1); /* default Tx deemphasis value */
48 
49  /* Configure PHY clock turnaround for 8-bit UTMI+, disable suspend */
50  write32(&dwc3->usb2phycfg,
51  0x9 << 10 | /* PHY clock turnaround for 8-bit UTMI+ */
52  0x1 << 8 | /* enable PHY sleep in L1 */
53  0x1 << 6); /* enable PHY suspend */
54 
55  write32(&dwc3->ctl,
56  0x5dc << 19 | /* suspend clock scale for 24MHz */
57  0x1 << 16 | /* retry SS three times (bugfix from U-Boot) */
58  0x1 << 12); /* port capability HOST */
59 }
60 
62 {
64  printk(BIOS_DEBUG, "DWC3 setup for USB DRD0 finished\n");
65 }
66 
68 {
70  printk(BIOS_DEBUG, "DWC3 setup for USB DRD1 finished\n");
71 }
72 
73 static void setup_drd_phy(struct exynos5_usb_drd_phy *phy)
74 {
75  /* Set all PHY registers to default values */
76 
77  /* XHCI Version 1.0, Frame Length adjustment 30 MHz */
78  setbits32(&phy->linksystem, 0x1 << 27 | 0x20 << 1);
79 
80  /* Disable OTG, ID0 and DRVVBUS, do not force sleep/suspend */
81  write32(&phy->utmi, 1 << 6);
82 
83  write32(&phy->clkrst,
84  0x88 << 23 | /* spread spectrum refclk selector */
85  0x1 << 20 | /* enable spread spectrum */
86  0x1 << 19 | /* enable prescaler refclk */
87  0x68 << 11 | /* multiplier for 24MHz refclk */
88  0x5 << 5 | /* select 24MHz refclk (weird, from U-Boot) */
89  0x1 << 4 | /* power supply in normal operating mode */
90  0x3 << 2 | /* use external refclk (undocumented on 5420?)*/
91  0x1 << 1 | /* force port reset */
92  0x1 << 0); /* normal operating mode */
93 
94  write32(&phy->param0,
95  0x9 << 26 | /* LOS level */
96  0x3 << 22 | /* TX VREF tune */
97  0x1 << 20 | /* TX rise tune */
98  0x1 << 18 | /* TX res tune */
99  0x3 << 13 | /* TX HS X Vtune */
100  0x3 << 9 | /* TX FS/LS tune */
101  0x3 << 6 | /* SQRX tune */
102  0x4 << 3 | /* OTG tune */
103  0x4 << 0); /* comp disc tune */
104 
105  write32(&phy->param1,
106  0x7f << 19 | /* reserved */
107  0x7f << 12 | /* Tx launch amplitude */
108  0x20 << 6 | /* Tx deemphasis 6dB */
109  0x1c << 0); /* Tx deemphasis 3.5dB (value from U-Boot) */
110 
111  /* disable all test features */
112  write32(&phy->test, 0);
113 
114  /* UTMI clock select? ("must be 0x1") */
115  write32(&phy->utmiclksel, 0x1 << 2);
116 
117  /* Samsung magic, undocumented (from U-Boot) */
118  write32(&phy->resume, 0x0);
119 
120  udelay(10);
121  clrbits32(&phy->clkrst, 0x1 << 1); /* deassert port reset */
122 }
123 
125 {
126  printk(BIOS_DEBUG, "Powering up USB DRD0 PHY\n");
129 }
130 
132 {
133  printk(BIOS_DEBUG, "Powering up USB DRD1 PHY\n");
136 }
137 
138 void setup_usb_host_phy(int hsic_gpio)
139 {
140  unsigned int hostphy_ctrl0;
141 
144 
145  printk(BIOS_DEBUG, "Powering up USB HOST PHY (%s HSIC)\n",
146  hsic_gpio ? "with" : "without");
147 
148  hostphy_ctrl0 = read32(&exynos_usb_host_phy->usbphyctrl0);
149  hostphy_ctrl0 &= ~(HOST_CTRL0_FSEL_MASK |
151  /* HOST Phy setting */
157  hostphy_ctrl0 |= (/* Setting up the ref freq */
158  CLK_24MHZ << 16 |
159  /* HOST Phy setting */
162  write32(&exynos_usb_host_phy->usbphyctrl0, hostphy_ctrl0);
163  udelay(10);
167  udelay(20);
168 
169  /* EHCI Ctrl setting */
175 
176  /* HSIC USB Hub initialization. */
177  if (hsic_gpio) {
178  gpio_direction_output(hsic_gpio, 0);
179  udelay(100);
180  gpio_direction_output(hsic_gpio, 1);
181  udelay(5000);
182 
189  udelay(10);
192  }
193 
194  /* At this point we need to wait for 50ms before talking to
195  * the USB controller (PHY clock and power setup time)
196  * By the time we are actually in the payload, these 50ms
197  * will have passed.
198  */
199 }
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
#define setbits32(addr, set)
Definition: mmio.h:21
#define clrbits32(addr, clear)
Definition: mmio.h:26
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
static struct exynos5_sysreg *const exynos_sysreg
Definition: sysreg.h:20
#define USB20_PHY_CFG_EN
Definition: sysreg.h:24
#define POWER_USB_PHY_CTRL_EN
Definition: power.h:16
static struct exynos5_power *const exynos_power
Definition: power.h:52
int gpio_direction_output(unsigned int gpio, int value)
Make a GPIO an output, and set its value.
Definition: gpio.c:151
#define HOST_CTRL0_UTMISWRST
Definition: usb.h:16
static struct exynos5_usb_host_phy *const exynos_usb_host_phy
Definition: usb.h:46
#define CLK_24MHZ
Definition: usb.h:8
#define EHCICTRL_ENAINCR16
Definition: usb.h:25
#define EHCICTRL_ENAINCRXALIGN
Definition: usb.h:22
#define HOST_CTRL0_COMMONON_N
Definition: usb.h:11
#define HOST_CTRL0_SIDDQ
Definition: usb.h:12
#define HOST_CTRL0_LINKSWRST
Definition: usb.h:17
#define HOST_CTRL0_FORCESLEEP
Definition: usb.h:13
#define EHCICTRL_ENAINCR8
Definition: usb.h:24
#define HOST_CTRL0_FORCESUSPEND
Definition: usb.h:14
#define HOST_CTRL0_PHYSWRST
Definition: usb.h:18
#define HOST_CTRL0_FSEL_MASK
Definition: usb.h:20
#define HOST_CTRL0_PHYSWRSTALL
Definition: usb.h:10
#define EHCICTRL_ENAINCR4
Definition: usb.h:23
void setup_usb_host_phy(int hsic_gpio)
Definition: usb.c:119
static struct exynos5_usb_drd_phy *const exynos_usb_drd1_phy
Definition: usb.h:72
static struct exynos5_usb_drd_dwc3 *const exynos_usb_drd1_dwc3
Definition: usb.h:115
static struct exynos5_usb_drd_phy *const exynos_usb_drd0_phy
Definition: usb.h:70
static struct exynos5_usb_drd_dwc3 *const exynos_usb_drd0_dwc3
Definition: usb.h:113
void setup_usb_drd1_dwc3(void)
Definition: usb.c:67
void setup_usb_drd0_dwc3(void)
Definition: usb.c:61
static void reset_dwc3(struct exynos5_usb_drd_dwc3 *dwc3)
Definition: usb.c:12
void setup_usb_drd0_phy(void)
Definition: usb.c:124
static void setup_dwc3(struct exynos5_usb_drd_dwc3 *dwc3)
Definition: usb.c:31
void reset_usb_drd0_dwc3(void)
Definition: usb.c:19
void setup_usb_drd1_phy(void)
Definition: usb.c:131
void reset_usb_drd1_dwc3(void)
Definition: usb.c:25
static void setup_drd_phy(struct exynos5_usb_drd_phy *phy)
Definition: usb.c:73
uint32_t usb_drd0_phy_ctrl
Definition: power.h:34
uint32_t usb_host_phy_ctrl
Definition: power.h:35
uint32_t usb_drd1_phy_ctrl
Definition: power.h:35
unsigned int usb20_phy_cfg
Definition: sysreg.h:16
uint32_t ctl
Definition: usb.h:78
uint32_t usb3pipectl
Definition: usb.h:106
uint32_t usb2phycfg
Definition: usb.h:100
uint32_t utmiclksel
Definition: usb.h:62
uint32_t param0
Definition: usb.h:57
uint32_t test
Definition: usb.h:60
uint32_t param1
Definition: usb.h:58
uint32_t resume
Definition: usb.h:63
uint32_t utmi
Definition: usb.h:52
uint32_t clkrst
Definition: usb.h:54
uint32_t linksystem
Definition: usb.h:51
uint32_t ehcictrl
Definition: usb.h:38
uint32_t hsicphyctrl1
Definition: usb.h:32
uint32_t usbphyctrl0
Definition: usb.h:29
void udelay(uint32_t us)
Definition: udelay.c:15