mb/google/brya/var/omnigul: Modify NVMe and UFS Storage support
[coreboot.git] / payloads / libpayload / drivers / usb / dwc2_rh.c
blobc0f25f907acf7028f0c2e83b0570687535f03e88
1 /*
3 * Copyright (C) 2014 Rockchip Electronics
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
15 #include <usb/usb.h>
16 #include "generic_hub.h"
17 #include "dwc2_private.h"
18 #include "dwc2.h"
20 static int
21 dwc2_rh_port_status_changed(usbdev_t *const dev, const int port)
23 hprt_t hprt;
24 int changed;
25 dwc_ctrl_t *const dwc2 = DWC2_INST(dev->controller);
27 hprt.d32 = readl(dwc2->hprt0);
28 changed = hprt.prtconndet;
30 /* Clear connect detect flag */
31 if (changed) {
32 hprt.d32 &= HPRT_W1C_MASK;
33 hprt.prtconndet = 1;
34 writel(hprt.d32, dwc2->hprt0);
36 return changed;
39 static int
40 dwc2_rh_port_connected(usbdev_t *const dev, const int port)
42 hprt_t hprt;
43 dwc_ctrl_t *const dwc2 = DWC2_INST(dev->controller);
45 hprt.d32 = readl(dwc2->hprt0);
46 return hprt.prtconnsts;
49 static int
50 dwc2_rh_port_in_reset(usbdev_t *const dev, const int port)
52 hprt_t hprt;
53 dwc_ctrl_t *const dwc2 = DWC2_INST(dev->controller);
55 hprt.d32 = readl(dwc2->hprt0);
56 return hprt.prtrst;
59 static int
60 dwc2_rh_port_enabled(usbdev_t *const dev, const int port)
62 hprt_t hprt;
63 dwc_ctrl_t *const dwc2 = DWC2_INST(dev->controller);
65 hprt.d32 = readl(dwc2->hprt0);
66 return hprt.prtena;
69 static usb_speed
70 dwc2_rh_port_speed(usbdev_t *const dev, const int port)
72 hprt_t hprt;
73 dwc_ctrl_t *const dwc2 = DWC2_INST(dev->controller);
75 hprt.d32 = readl(dwc2->hprt0);
76 if (hprt.prtena) {
77 switch (hprt.prtspd) {
78 case PRTSPD_HIGH:
79 return HIGH_SPEED;
80 case PRTSPD_FULL:
81 return FULL_SPEED;
82 case PRTSPD_LOW:
83 return LOW_SPEED;
86 return -1;
89 static int
90 dwc2_rh_reset_port(usbdev_t *const dev, const int port)
92 hprt_t hprt;
93 dwc_ctrl_t *const dwc2 = DWC2_INST(dev->controller);
95 hprt.d32 = readl(dwc2->hprt0);
96 hprt.d32 &= HPRT_W1C_MASK;
97 hprt.prtrst = 1;
98 writel(hprt.d32, dwc2->hprt0);
100 /* Wait a bit while reset is active. */
101 mdelay(50);
103 /* Deassert reset. */
104 hprt.prtrst = 0;
105 writel(hprt.d32, dwc2->hprt0);
108 * If reset and speed enum success the DWC2 core will set enable bit
109 * after port reset bit is deasserted
111 mdelay(1);
112 hprt.d32 = readl(dwc2->hprt0);
113 usb_debug("%s reset port ok, hprt = 0x%08x\n", __func__, hprt.d32);
115 if (!hprt.prtena) {
116 usb_debug("%s enable port fail! hprt = 0x%08x\n",
117 __func__, hprt.d32);
118 return -1;
121 return 0;
124 static int
125 dwc2_rh_enable_port(usbdev_t *const dev, const int port)
127 hprt_t hprt;
128 dwc_ctrl_t *const dwc2 = DWC2_INST(dev->controller);
130 /* Power on the port */
131 hprt.d32 = readl(dwc2->hprt0);
132 hprt.d32 &= HPRT_W1C_MASK;
133 hprt.prtpwr = 1;
134 writel(hprt.d32, dwc2->hprt0);
135 return 0;
138 static int
139 dwc2_rh_disable_port(usbdev_t *const dev, const int port)
141 hprt_t hprt;
142 dwc_ctrl_t *const dwc2 = DWC2_INST(dev->controller);
144 hprt.d32 = readl(dwc2->hprt0);
145 hprt.d32 &= HPRT_W1C_MASK;
146 /* Disable the port*/
147 hprt.prtena = 1;
148 /* Power off the port */
149 hprt.prtpwr = 0;
150 writel(hprt.d32, dwc2->hprt0);
151 return 0;
154 static const generic_hub_ops_t dwc2_rh_ops = {
155 .hub_status_changed = NULL,
156 .port_status_changed = dwc2_rh_port_status_changed,
157 .port_connected = dwc2_rh_port_connected,
158 .port_in_reset = dwc2_rh_port_in_reset,
159 .port_enabled = dwc2_rh_port_enabled,
160 .port_speed = dwc2_rh_port_speed,
161 .enable_port = dwc2_rh_enable_port,
162 .disable_port = dwc2_rh_disable_port,
163 .start_port_reset = NULL,
164 .reset_port = dwc2_rh_reset_port,
167 void
168 dwc2_rh_init(usbdev_t *dev)
170 dwc_ctrl_t *const dwc2 = DWC2_INST(dev->controller);
172 /* we can set them here because a root hub _really_ shouldn't
173 appear elsewhere */
174 dev->address = 0;
175 dev->hub = -1;
176 dev->port = -1;
178 generic_hub_init(dev, 1, &dwc2_rh_ops);
179 usb_debug("dwc2_rh_init HPRT 0x%08x p = %p\n ",
180 readl(dwc2->hprt0), dwc2->hprt0);
181 usb_debug("DWC2: root hub init done\n");