[PATCH] ipcalc.sh CIDR notation
[openwrt.git] / target / linux / octeon / patches-2.6.30 / 018-dwc_otg.patch
1 Signed-off-by: David Daney <ddaney@caviumnetworks.com>
2 ---
3 arch/mips/cavium-octeon/octeon-platform.c | 105 ++
4 arch/mips/include/asm/octeon/cvmx-usbcx-defs.h | 1199 ++++++++++++++++++++++++
5 arch/mips/include/asm/octeon/cvmx-usbnx-defs.h | 760 +++++++++++++++
6 3 files changed, 2064 insertions(+), 0 deletions(-)
7 create mode 100644 arch/mips/include/asm/octeon/cvmx-usbcx-defs.h
8 create mode 100644 arch/mips/include/asm/octeon/cvmx-usbnx-defs.h
9
10 diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c
11 index cfdb4c2..20698a6 100644
12 --- a/arch/mips/cavium-octeon/octeon-platform.c
13 +++ b/arch/mips/cavium-octeon/octeon-platform.c
14 @@ -7,13 +7,19 @@
15 * Copyright (C) 2008 Wind River Systems
16 */
17
18 +#include <linux/delay.h>
19 #include <linux/init.h>
20 #include <linux/irq.h>
21 +#include <linux/kernel.h>
22 #include <linux/module.h>
23 #include <linux/platform_device.h>
24
25 +#include <asm/time.h>
26 +
27 #include <asm/octeon/octeon.h>
28 #include <asm/octeon/cvmx-rnm-defs.h>
29 +#include <asm/octeon/cvmx-usbnx-defs.h>
30 +#include <asm/octeon/cvmx-usbcx-defs.h>
31
32 static struct octeon_cf_data octeon_cf_data;
33
34 @@ -247,6 +253,105 @@ out:
35 }
36 device_initcall(octeon_mgmt_device_init);
37
38 +/* Octeon USB. */
39 +static int __init octeon_usb_device_init(void)
40 +{
41 + int p_rtype_ref_clk = 2;
42 + int number_usb_ports;
43 + int usb_port;
44 + int ret = 0;
45 +
46 + if (OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX)) {
47 + number_usb_ports = 0;
48 + } else if (OCTEON_IS_MODEL(OCTEON_CN52XX)) {
49 + number_usb_ports = 2;
50 + /* CN52XX encodes this field differently */
51 + p_rtype_ref_clk = 1;
52 + } else {
53 + number_usb_ports = 1;
54 + }
55 +
56 + for (usb_port = 0; usb_port < number_usb_ports; usb_port++) {
57 + int divisor;
58 + union cvmx_usbnx_clk_ctl usbn_clk_ctl;
59 + struct platform_device *pdev;
60 + struct resource usb_resource[2];
61 +
62 + /*
63 + * Divide the core clock down such that USB is as
64 + * close as possible to 125Mhz.
65 + */
66 + divisor = DIV_ROUND_UP(mips_hpt_frequency, 125000000);
67 + /* Lower than 4 doesn't seem to work properly */
68 + if (divisor < 4)
69 + divisor = 4;
70 +
71 + /* Fetch the value of the Register, and de-assert POR */
72 + usbn_clk_ctl.u64 = cvmx_read_csr(CVMX_USBNX_CLK_CTL(usb_port));
73 + usbn_clk_ctl.s.por = 0;
74 + if (OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
75 + usbn_clk_ctl.cn31xx.p_rclk = 1;
76 + usbn_clk_ctl.cn31xx.p_xenbn = 0;
77 + } else {
78 + if (cvmx_sysinfo_get()->board_type !=
79 + CVMX_BOARD_TYPE_BBGW_REF)
80 + usbn_clk_ctl.cn56xx.p_rtype = p_rtype_ref_clk;
81 + else
82 + usbn_clk_ctl.cn56xx.p_rtype = 0;
83 + }
84 + usbn_clk_ctl.s.divide = divisor;
85 + usbn_clk_ctl.s.divide2 = 0;
86 + cvmx_write_csr(CVMX_USBNX_CLK_CTL(usb_port), usbn_clk_ctl.u64);
87 +
88 + /* Wait for POR */
89 + udelay(850);
90 +
91 + usbn_clk_ctl.u64 = cvmx_read_csr(CVMX_USBNX_CLK_CTL(usb_port));
92 + usbn_clk_ctl.s.por = 0;
93 + if (OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
94 + usbn_clk_ctl.cn31xx.p_rclk = 1;
95 + usbn_clk_ctl.cn31xx.p_xenbn = 0;
96 + } else {
97 + if (cvmx_sysinfo_get()->board_type !=
98 + CVMX_BOARD_TYPE_BBGW_REF)
99 + usbn_clk_ctl.cn56xx.p_rtype = p_rtype_ref_clk;
100 + else
101 + usbn_clk_ctl.cn56xx.p_rtype = 0;
102 + }
103 + usbn_clk_ctl.s.prst = 1;
104 + cvmx_write_csr(CVMX_USBNX_CLK_CTL(usb_port), usbn_clk_ctl.u64);
105 +
106 + udelay(1);
107 +
108 + usbn_clk_ctl.s.hrst = 1;
109 + cvmx_write_csr(CVMX_USBNX_CLK_CTL(usb_port), usbn_clk_ctl.u64);
110 + udelay(1);
111 +
112 + memset(usb_resource, 0, sizeof(usb_resource));
113 + usb_resource[0].start =
114 + XKPHYS_TO_PHYS(CVMX_USBCX_GOTGCTL(usb_port));
115 + usb_resource[0].end = usb_resource[0].start + 0x10000;
116 + usb_resource[0].flags = IORESOURCE_MEM;
117 +
118 + usb_resource[1].start = (usb_port == 0) ?
119 + OCTEON_IRQ_USB0 : OCTEON_IRQ_USB1;
120 + usb_resource[1].end = usb_resource[1].start;
121 + usb_resource[1].flags = IORESOURCE_IRQ;
122 +
123 + pdev = platform_device_register_simple("dwc_otg",
124 + usb_port,
125 + usb_resource, 2);
126 + if (!pdev) {
127 + pr_err("dwc_otg: Failed to allocate platform device "
128 + "for USB%d\n", usb_port);
129 + ret = -ENOMEM;
130 + }
131 + }
132 +
133 + return ret;
134 +}
135 +device_initcall(octeon_usb_device_init);
136 +
137 MODULE_AUTHOR("David Daney <ddaney@caviumnetworks.com>");
138 MODULE_LICENSE("GPL");
139 MODULE_DESCRIPTION("Platform driver for Octeon SOC");
140 diff --git a/arch/mips/include/asm/octeon/cvmx-usbcx-defs.h b/arch/mips/include/asm/octeon/cvmx-usbcx-defs.h
141 new file mode 100644
142 index 0000000..c1e078e
143 --- /dev/null
144 +++ b/arch/mips/include/asm/octeon/cvmx-usbcx-defs.h
145 @@ -0,0 +1,1199 @@
146 +/***********************license start***************
147 + * Author: Cavium Networks
148 + *
149 + * Contact: support@caviumnetworks.com
150 + * This file is part of the OCTEON SDK
151 + *
152 + * Copyright (c) 2003-2008 Cavium Networks
153 + *
154 + * This file is free software; you can redistribute it and/or modify
155 + * it under the terms of the GNU General Public License, Version 2, as
156 + * published by the Free Software Foundation.
157 + *
158 + * This file is distributed in the hope that it will be useful, but
159 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
160 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
161 + * NONINFRINGEMENT. See the GNU General Public License for more
162 + * details.
163 + *
164 + * You should have received a copy of the GNU General Public License
165 + * along with this file; if not, write to the Free Software
166 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
167 + * or visit http://www.gnu.org/licenses/.
168 + *
169 + * This file may also be available under a different license from Cavium.
170 + * Contact Cavium Networks for more information
171 + ***********************license end**************************************/
172 +
173 +#ifndef __CVMX_USBCX_DEFS_H__
174 +#define __CVMX_USBCX_DEFS_H__
175 +
176 +#define CVMX_USBCX_DAINT(block_id) \
177 + CVMX_ADD_IO_SEG(0x00016F0010000818ull + (((block_id) & 1) * 0x100000000000ull))
178 +#define CVMX_USBCX_DAINTMSK(block_id) \
179 + CVMX_ADD_IO_SEG(0x00016F001000081Cull + (((block_id) & 1) * 0x100000000000ull))
180 +#define CVMX_USBCX_DCFG(block_id) \
181 + CVMX_ADD_IO_SEG(0x00016F0010000800ull + (((block_id) & 1) * 0x100000000000ull))
182 +#define CVMX_USBCX_DCTL(block_id) \
183 + CVMX_ADD_IO_SEG(0x00016F0010000804ull + (((block_id) & 1) * 0x100000000000ull))
184 +#define CVMX_USBCX_DIEPCTLX(offset, block_id) \
185 + CVMX_ADD_IO_SEG(0x00016F0010000900ull + (((offset) & 7) * 32) + (((block_id) & 1) * 0x100000000000ull))
186 +#define CVMX_USBCX_DIEPINTX(offset, block_id) \
187 + CVMX_ADD_IO_SEG(0x00016F0010000908ull + (((offset) & 7) * 32) + (((block_id) & 1) * 0x100000000000ull))
188 +#define CVMX_USBCX_DIEPMSK(block_id) \
189 + CVMX_ADD_IO_SEG(0x00016F0010000810ull + (((block_id) & 1) * 0x100000000000ull))
190 +#define CVMX_USBCX_DIEPTSIZX(offset, block_id) \
191 + CVMX_ADD_IO_SEG(0x00016F0010000910ull + (((offset) & 7) * 32) + (((block_id) & 1) * 0x100000000000ull))
192 +#define CVMX_USBCX_DOEPCTLX(offset, block_id) \
193 + CVMX_ADD_IO_SEG(0x00016F0010000B00ull + (((offset) & 7) * 32) + (((block_id) & 1) * 0x100000000000ull))
194 +#define CVMX_USBCX_DOEPINTX(offset, block_id) \
195 + CVMX_ADD_IO_SEG(0x00016F0010000B08ull + (((offset) & 7) * 32) + (((block_id) & 1) * 0x100000000000ull))
196 +#define CVMX_USBCX_DOEPMSK(block_id) \
197 + CVMX_ADD_IO_SEG(0x00016F0010000814ull + (((block_id) & 1) * 0x100000000000ull))
198 +#define CVMX_USBCX_DOEPTSIZX(offset, block_id) \
199 + CVMX_ADD_IO_SEG(0x00016F0010000B10ull + (((offset) & 7) * 32) + (((block_id) & 1) * 0x100000000000ull))
200 +#define CVMX_USBCX_DPTXFSIZX(offset, block_id) \
201 + CVMX_ADD_IO_SEG(0x00016F0010000100ull + (((offset) & 7) * 4) + (((block_id) & 1) * 0x100000000000ull))
202 +#define CVMX_USBCX_DSTS(block_id) \
203 + CVMX_ADD_IO_SEG(0x00016F0010000808ull + (((block_id) & 1) * 0x100000000000ull))
204 +#define CVMX_USBCX_DTKNQR1(block_id) \
205 + CVMX_ADD_IO_SEG(0x00016F0010000820ull + (((block_id) & 1) * 0x100000000000ull))
206 +#define CVMX_USBCX_DTKNQR2(block_id) \
207 + CVMX_ADD_IO_SEG(0x00016F0010000824ull + (((block_id) & 1) * 0x100000000000ull))
208 +#define CVMX_USBCX_DTKNQR3(block_id) \
209 + CVMX_ADD_IO_SEG(0x00016F0010000830ull + (((block_id) & 1) * 0x100000000000ull))
210 +#define CVMX_USBCX_DTKNQR4(block_id) \
211 + CVMX_ADD_IO_SEG(0x00016F0010000834ull + (((block_id) & 1) * 0x100000000000ull))
212 +#define CVMX_USBCX_GAHBCFG(block_id) \
213 + CVMX_ADD_IO_SEG(0x00016F0010000008ull + (((block_id) & 1) * 0x100000000000ull))
214 +#define CVMX_USBCX_GHWCFG1(block_id) \
215 + CVMX_ADD_IO_SEG(0x00016F0010000044ull + (((block_id) & 1) * 0x100000000000ull))
216 +#define CVMX_USBCX_GHWCFG2(block_id) \
217 + CVMX_ADD_IO_SEG(0x00016F0010000048ull + (((block_id) & 1) * 0x100000000000ull))
218 +#define CVMX_USBCX_GHWCFG3(block_id) \
219 + CVMX_ADD_IO_SEG(0x00016F001000004Cull + (((block_id) & 1) * 0x100000000000ull))
220 +#define CVMX_USBCX_GHWCFG4(block_id) \
221 + CVMX_ADD_IO_SEG(0x00016F0010000050ull + (((block_id) & 1) * 0x100000000000ull))
222 +#define CVMX_USBCX_GINTMSK(block_id) \
223 + CVMX_ADD_IO_SEG(0x00016F0010000018ull + (((block_id) & 1) * 0x100000000000ull))
224 +#define CVMX_USBCX_GINTSTS(block_id) \
225 + CVMX_ADD_IO_SEG(0x00016F0010000014ull + (((block_id) & 1) * 0x100000000000ull))
226 +#define CVMX_USBCX_GNPTXFSIZ(block_id) \
227 + CVMX_ADD_IO_SEG(0x00016F0010000028ull + (((block_id) & 1) * 0x100000000000ull))
228 +#define CVMX_USBCX_GNPTXSTS(block_id) \
229 + CVMX_ADD_IO_SEG(0x00016F001000002Cull + (((block_id) & 1) * 0x100000000000ull))
230 +#define CVMX_USBCX_GOTGCTL(block_id) \
231 + CVMX_ADD_IO_SEG(0x00016F0010000000ull + (((block_id) & 1) * 0x100000000000ull))
232 +#define CVMX_USBCX_GOTGINT(block_id) \
233 + CVMX_ADD_IO_SEG(0x00016F0010000004ull + (((block_id) & 1) * 0x100000000000ull))
234 +#define CVMX_USBCX_GRSTCTL(block_id) \
235 + CVMX_ADD_IO_SEG(0x00016F0010000010ull + (((block_id) & 1) * 0x100000000000ull))
236 +#define CVMX_USBCX_GRXFSIZ(block_id) \
237 + CVMX_ADD_IO_SEG(0x00016F0010000024ull + (((block_id) & 1) * 0x100000000000ull))
238 +#define CVMX_USBCX_GRXSTSPD(block_id) \
239 + CVMX_ADD_IO_SEG(0x00016F0010040020ull + (((block_id) & 1) * 0x100000000000ull))
240 +#define CVMX_USBCX_GRXSTSPH(block_id) \
241 + CVMX_ADD_IO_SEG(0x00016F0010000020ull + (((block_id) & 1) * 0x100000000000ull))
242 +#define CVMX_USBCX_GRXSTSRD(block_id) \
243 + CVMX_ADD_IO_SEG(0x00016F001004001Cull + (((block_id) & 1) * 0x100000000000ull))
244 +#define CVMX_USBCX_GRXSTSRH(block_id) \
245 + CVMX_ADD_IO_SEG(0x00016F001000001Cull + (((block_id) & 1) * 0x100000000000ull))
246 +#define CVMX_USBCX_GSNPSID(block_id) \
247 + CVMX_ADD_IO_SEG(0x00016F0010000040ull + (((block_id) & 1) * 0x100000000000ull))
248 +#define CVMX_USBCX_GUSBCFG(block_id) \
249 + CVMX_ADD_IO_SEG(0x00016F001000000Cull + (((block_id) & 1) * 0x100000000000ull))
250 +#define CVMX_USBCX_HAINT(block_id) \
251 + CVMX_ADD_IO_SEG(0x00016F0010000414ull + (((block_id) & 1) * 0x100000000000ull))
252 +#define CVMX_USBCX_HAINTMSK(block_id) \
253 + CVMX_ADD_IO_SEG(0x00016F0010000418ull + (((block_id) & 1) * 0x100000000000ull))
254 +#define CVMX_USBCX_HCCHARX(offset, block_id) \
255 + CVMX_ADD_IO_SEG(0x00016F0010000500ull + (((offset) & 7) * 32) + (((block_id) & 1) * 0x100000000000ull))
256 +#define CVMX_USBCX_HCFG(block_id) \
257 + CVMX_ADD_IO_SEG(0x00016F0010000400ull + (((block_id) & 1) * 0x100000000000ull))
258 +#define CVMX_USBCX_HCINTMSKX(offset, block_id) \
259 + CVMX_ADD_IO_SEG(0x00016F001000050Cull + (((offset) & 7) * 32) + (((block_id) & 1) * 0x100000000000ull))
260 +#define CVMX_USBCX_HCINTX(offset, block_id) \
261 + CVMX_ADD_IO_SEG(0x00016F0010000508ull + (((offset) & 7) * 32) + (((block_id) & 1) * 0x100000000000ull))
262 +#define CVMX_USBCX_HCSPLTX(offset, block_id) \
263 + CVMX_ADD_IO_SEG(0x00016F0010000504ull + (((offset) & 7) * 32) + (((block_id) & 1) * 0x100000000000ull))
264 +#define CVMX_USBCX_HCTSIZX(offset, block_id) \
265 + CVMX_ADD_IO_SEG(0x00016F0010000510ull + (((offset) & 7) * 32) + (((block_id) & 1) * 0x100000000000ull))
266 +#define CVMX_USBCX_HFIR(block_id) \
267 + CVMX_ADD_IO_SEG(0x00016F0010000404ull + (((block_id) & 1) * 0x100000000000ull))
268 +#define CVMX_USBCX_HFNUM(block_id) \
269 + CVMX_ADD_IO_SEG(0x00016F0010000408ull + (((block_id) & 1) * 0x100000000000ull))
270 +#define CVMX_USBCX_HPRT(block_id) \
271 + CVMX_ADD_IO_SEG(0x00016F0010000440ull + (((block_id) & 1) * 0x100000000000ull))
272 +#define CVMX_USBCX_HPTXFSIZ(block_id) \
273 + CVMX_ADD_IO_SEG(0x00016F0010000100ull + (((block_id) & 1) * 0x100000000000ull))
274 +#define CVMX_USBCX_HPTXSTS(block_id) \
275 + CVMX_ADD_IO_SEG(0x00016F0010000410ull + (((block_id) & 1) * 0x100000000000ull))
276 +#define CVMX_USBCX_NPTXDFIFOX(offset, block_id) \
277 + CVMX_ADD_IO_SEG(0x00016F0010001000ull + (((offset) & 7) * 4096) + (((block_id) & 1) * 0x100000000000ull))
278 +#define CVMX_USBCX_PCGCCTL(block_id) \
279 + CVMX_ADD_IO_SEG(0x00016F0010000E00ull + (((block_id) & 1) * 0x100000000000ull))
280 +
281 +union cvmx_usbcx_daint {
282 + uint32_t u32;
283 + struct cvmx_usbcx_daint_s {
284 + uint32_t outepint:16;
285 + uint32_t inepint:16;
286 + } s;
287 + struct cvmx_usbcx_daint_s cn30xx;
288 + struct cvmx_usbcx_daint_s cn31xx;
289 + struct cvmx_usbcx_daint_s cn50xx;
290 + struct cvmx_usbcx_daint_s cn52xx;
291 + struct cvmx_usbcx_daint_s cn52xxp1;
292 + struct cvmx_usbcx_daint_s cn56xx;
293 + struct cvmx_usbcx_daint_s cn56xxp1;
294 +};
295 +
296 +union cvmx_usbcx_daintmsk {
297 + uint32_t u32;
298 + struct cvmx_usbcx_daintmsk_s {
299 + uint32_t outepmsk:16;
300 + uint32_t inepmsk:16;
301 + } s;
302 + struct cvmx_usbcx_daintmsk_s cn30xx;
303 + struct cvmx_usbcx_daintmsk_s cn31xx;
304 + struct cvmx_usbcx_daintmsk_s cn50xx;
305 + struct cvmx_usbcx_daintmsk_s cn52xx;
306 + struct cvmx_usbcx_daintmsk_s cn52xxp1;
307 + struct cvmx_usbcx_daintmsk_s cn56xx;
308 + struct cvmx_usbcx_daintmsk_s cn56xxp1;
309 +};
310 +
311 +union cvmx_usbcx_dcfg {
312 + uint32_t u32;
313 + struct cvmx_usbcx_dcfg_s {
314 + uint32_t reserved_23_31:9;
315 + uint32_t epmiscnt:5;
316 + uint32_t reserved_13_17:5;
317 + uint32_t perfrint:2;
318 + uint32_t devaddr:7;
319 + uint32_t reserved_3_3:1;
320 + uint32_t nzstsouthshk:1;
321 + uint32_t devspd:2;
322 + } s;
323 + struct cvmx_usbcx_dcfg_s cn30xx;
324 + struct cvmx_usbcx_dcfg_s cn31xx;
325 + struct cvmx_usbcx_dcfg_s cn50xx;
326 + struct cvmx_usbcx_dcfg_s cn52xx;
327 + struct cvmx_usbcx_dcfg_s cn52xxp1;
328 + struct cvmx_usbcx_dcfg_s cn56xx;
329 + struct cvmx_usbcx_dcfg_s cn56xxp1;
330 +};
331 +
332 +union cvmx_usbcx_dctl {
333 + uint32_t u32;
334 + struct cvmx_usbcx_dctl_s {
335 + uint32_t reserved_12_31:20;
336 + uint32_t pwronprgdone:1;
337 + uint32_t cgoutnak:1;
338 + uint32_t sgoutnak:1;
339 + uint32_t cgnpinnak:1;
340 + uint32_t sgnpinnak:1;
341 + uint32_t tstctl:3;
342 + uint32_t goutnaksts:1;
343 + uint32_t gnpinnaksts:1;
344 + uint32_t sftdiscon:1;
345 + uint32_t rmtwkupsig:1;
346 + } s;
347 + struct cvmx_usbcx_dctl_s cn30xx;
348 + struct cvmx_usbcx_dctl_s cn31xx;
349 + struct cvmx_usbcx_dctl_s cn50xx;
350 + struct cvmx_usbcx_dctl_s cn52xx;
351 + struct cvmx_usbcx_dctl_s cn52xxp1;
352 + struct cvmx_usbcx_dctl_s cn56xx;
353 + struct cvmx_usbcx_dctl_s cn56xxp1;
354 +};
355 +
356 +union cvmx_usbcx_diepctlx {
357 + uint32_t u32;
358 + struct cvmx_usbcx_diepctlx_s {
359 + uint32_t epena:1;
360 + uint32_t epdis:1;
361 + uint32_t setd1pid:1;
362 + uint32_t setd0pid:1;
363 + uint32_t snak:1;
364 + uint32_t cnak:1;
365 + uint32_t txfnum:4;
366 + uint32_t stall:1;
367 + uint32_t reserved_20_20:1;
368 + uint32_t eptype:2;
369 + uint32_t naksts:1;
370 + uint32_t dpid:1;
371 + uint32_t usbactep:1;
372 + uint32_t nextep:4;
373 + uint32_t mps:11;
374 + } s;
375 + struct cvmx_usbcx_diepctlx_s cn30xx;
376 + struct cvmx_usbcx_diepctlx_s cn31xx;
377 + struct cvmx_usbcx_diepctlx_s cn50xx;
378 + struct cvmx_usbcx_diepctlx_s cn52xx;
379 + struct cvmx_usbcx_diepctlx_s cn52xxp1;
380 + struct cvmx_usbcx_diepctlx_s cn56xx;
381 + struct cvmx_usbcx_diepctlx_s cn56xxp1;
382 +};
383 +
384 +union cvmx_usbcx_diepintx {
385 + uint32_t u32;
386 + struct cvmx_usbcx_diepintx_s {
387 + uint32_t reserved_7_31:25;
388 + uint32_t inepnakeff:1;
389 + uint32_t intknepmis:1;
390 + uint32_t intkntxfemp:1;
391 + uint32_t timeout:1;
392 + uint32_t ahberr:1;
393 + uint32_t epdisbld:1;
394 + uint32_t xfercompl:1;
395 + } s;
396 + struct cvmx_usbcx_diepintx_s cn30xx;
397 + struct cvmx_usbcx_diepintx_s cn31xx;
398 + struct cvmx_usbcx_diepintx_s cn50xx;
399 + struct cvmx_usbcx_diepintx_s cn52xx;
400 + struct cvmx_usbcx_diepintx_s cn52xxp1;
401 + struct cvmx_usbcx_diepintx_s cn56xx;
402 + struct cvmx_usbcx_diepintx_s cn56xxp1;
403 +};
404 +
405 +union cvmx_usbcx_diepmsk {
406 + uint32_t u32;
407 + struct cvmx_usbcx_diepmsk_s {
408 + uint32_t reserved_7_31:25;
409 + uint32_t inepnakeffmsk:1;
410 + uint32_t intknepmismsk:1;
411 + uint32_t intkntxfempmsk:1;
412 + uint32_t timeoutmsk:1;
413 + uint32_t ahberrmsk:1;
414 + uint32_t epdisbldmsk:1;
415 + uint32_t xfercomplmsk:1;
416 + } s;
417 + struct cvmx_usbcx_diepmsk_s cn30xx;
418 + struct cvmx_usbcx_diepmsk_s cn31xx;
419 + struct cvmx_usbcx_diepmsk_s cn50xx;
420 + struct cvmx_usbcx_diepmsk_s cn52xx;
421 + struct cvmx_usbcx_diepmsk_s cn52xxp1;
422 + struct cvmx_usbcx_diepmsk_s cn56xx;
423 + struct cvmx_usbcx_diepmsk_s cn56xxp1;
424 +};
425 +
426 +union cvmx_usbcx_dieptsizx {
427 + uint32_t u32;
428 + struct cvmx_usbcx_dieptsizx_s {
429 + uint32_t reserved_31_31:1;
430 + uint32_t mc:2;
431 + uint32_t pktcnt:10;
432 + uint32_t xfersize:19;
433 + } s;
434 + struct cvmx_usbcx_dieptsizx_s cn30xx;
435 + struct cvmx_usbcx_dieptsizx_s cn31xx;
436 + struct cvmx_usbcx_dieptsizx_s cn50xx;
437 + struct cvmx_usbcx_dieptsizx_s cn52xx;
438 + struct cvmx_usbcx_dieptsizx_s cn52xxp1;
439 + struct cvmx_usbcx_dieptsizx_s cn56xx;
440 + struct cvmx_usbcx_dieptsizx_s cn56xxp1;
441 +};
442 +
443 +union cvmx_usbcx_doepctlx {
444 + uint32_t u32;
445 + struct cvmx_usbcx_doepctlx_s {
446 + uint32_t epena:1;
447 + uint32_t epdis:1;
448 + uint32_t setd1pid:1;
449 + uint32_t setd0pid:1;
450 + uint32_t snak:1;
451 + uint32_t cnak:1;
452 + uint32_t reserved_22_25:4;
453 + uint32_t stall:1;
454 + uint32_t snp:1;
455 + uint32_t eptype:2;
456 + uint32_t naksts:1;
457 + uint32_t dpid:1;
458 + uint32_t usbactep:1;
459 + uint32_t reserved_11_14:4;
460 + uint32_t mps:11;
461 + } s;
462 + struct cvmx_usbcx_doepctlx_s cn30xx;
463 + struct cvmx_usbcx_doepctlx_s cn31xx;
464 + struct cvmx_usbcx_doepctlx_s cn50xx;
465 + struct cvmx_usbcx_doepctlx_s cn52xx;
466 + struct cvmx_usbcx_doepctlx_s cn52xxp1;
467 + struct cvmx_usbcx_doepctlx_s cn56xx;
468 + struct cvmx_usbcx_doepctlx_s cn56xxp1;
469 +};
470 +
471 +union cvmx_usbcx_doepintx {
472 + uint32_t u32;
473 + struct cvmx_usbcx_doepintx_s {
474 + uint32_t reserved_5_31:27;
475 + uint32_t outtknepdis:1;
476 + uint32_t setup:1;
477 + uint32_t ahberr:1;
478 + uint32_t epdisbld:1;
479 + uint32_t xfercompl:1;
480 + } s;
481 + struct cvmx_usbcx_doepintx_s cn30xx;
482 + struct cvmx_usbcx_doepintx_s cn31xx;
483 + struct cvmx_usbcx_doepintx_s cn50xx;
484 + struct cvmx_usbcx_doepintx_s cn52xx;
485 + struct cvmx_usbcx_doepintx_s cn52xxp1;
486 + struct cvmx_usbcx_doepintx_s cn56xx;
487 + struct cvmx_usbcx_doepintx_s cn56xxp1;
488 +};
489 +
490 +union cvmx_usbcx_doepmsk {
491 + uint32_t u32;
492 + struct cvmx_usbcx_doepmsk_s {
493 + uint32_t reserved_5_31:27;
494 + uint32_t outtknepdismsk:1;
495 + uint32_t setupmsk:1;
496 + uint32_t ahberrmsk:1;
497 + uint32_t epdisbldmsk:1;
498 + uint32_t xfercomplmsk:1;
499 + } s;
500 + struct cvmx_usbcx_doepmsk_s cn30xx;
501 + struct cvmx_usbcx_doepmsk_s cn31xx;
502 + struct cvmx_usbcx_doepmsk_s cn50xx;
503 + struct cvmx_usbcx_doepmsk_s cn52xx;
504 + struct cvmx_usbcx_doepmsk_s cn52xxp1;
505 + struct cvmx_usbcx_doepmsk_s cn56xx;
506 + struct cvmx_usbcx_doepmsk_s cn56xxp1;
507 +};
508 +
509 +union cvmx_usbcx_doeptsizx {
510 + uint32_t u32;
511 + struct cvmx_usbcx_doeptsizx_s {
512 + uint32_t reserved_31_31:1;
513 + uint32_t mc:2;
514 + uint32_t pktcnt:10;
515 + uint32_t xfersize:19;
516 + } s;
517 + struct cvmx_usbcx_doeptsizx_s cn30xx;
518 + struct cvmx_usbcx_doeptsizx_s cn31xx;
519 + struct cvmx_usbcx_doeptsizx_s cn50xx;
520 + struct cvmx_usbcx_doeptsizx_s cn52xx;
521 + struct cvmx_usbcx_doeptsizx_s cn52xxp1;
522 + struct cvmx_usbcx_doeptsizx_s cn56xx;
523 + struct cvmx_usbcx_doeptsizx_s cn56xxp1;
524 +};
525 +
526 +union cvmx_usbcx_dptxfsizx {
527 + uint32_t u32;
528 + struct cvmx_usbcx_dptxfsizx_s {
529 + uint32_t dptxfsize:16;
530 + uint32_t dptxfstaddr:16;
531 + } s;
532 + struct cvmx_usbcx_dptxfsizx_s cn30xx;
533 + struct cvmx_usbcx_dptxfsizx_s cn31xx;
534 + struct cvmx_usbcx_dptxfsizx_s cn50xx;
535 + struct cvmx_usbcx_dptxfsizx_s cn52xx;
536 + struct cvmx_usbcx_dptxfsizx_s cn52xxp1;
537 + struct cvmx_usbcx_dptxfsizx_s cn56xx;
538 + struct cvmx_usbcx_dptxfsizx_s cn56xxp1;
539 +};
540 +
541 +union cvmx_usbcx_dsts {
542 + uint32_t u32;
543 + struct cvmx_usbcx_dsts_s {
544 + uint32_t reserved_22_31:10;
545 + uint32_t soffn:14;
546 + uint32_t reserved_4_7:4;
547 + uint32_t errticerr:1;
548 + uint32_t enumspd:2;
549 + uint32_t suspsts:1;
550 + } s;
551 + struct cvmx_usbcx_dsts_s cn30xx;
552 + struct cvmx_usbcx_dsts_s cn31xx;
553 + struct cvmx_usbcx_dsts_s cn50xx;
554 + struct cvmx_usbcx_dsts_s cn52xx;
555 + struct cvmx_usbcx_dsts_s cn52xxp1;
556 + struct cvmx_usbcx_dsts_s cn56xx;
557 + struct cvmx_usbcx_dsts_s cn56xxp1;
558 +};
559 +
560 +union cvmx_usbcx_dtknqr1 {
561 + uint32_t u32;
562 + struct cvmx_usbcx_dtknqr1_s {
563 + uint32_t eptkn:24;
564 + uint32_t wrapbit:1;
565 + uint32_t reserved_5_6:2;
566 + uint32_t intknwptr:5;
567 + } s;
568 + struct cvmx_usbcx_dtknqr1_s cn30xx;
569 + struct cvmx_usbcx_dtknqr1_s cn31xx;
570 + struct cvmx_usbcx_dtknqr1_s cn50xx;
571 + struct cvmx_usbcx_dtknqr1_s cn52xx;
572 + struct cvmx_usbcx_dtknqr1_s cn52xxp1;
573 + struct cvmx_usbcx_dtknqr1_s cn56xx;
574 + struct cvmx_usbcx_dtknqr1_s cn56xxp1;
575 +};
576 +
577 +union cvmx_usbcx_dtknqr2 {
578 + uint32_t u32;
579 + struct cvmx_usbcx_dtknqr2_s {
580 + uint32_t eptkn:32;
581 + } s;
582 + struct cvmx_usbcx_dtknqr2_s cn30xx;
583 + struct cvmx_usbcx_dtknqr2_s cn31xx;
584 + struct cvmx_usbcx_dtknqr2_s cn50xx;
585 + struct cvmx_usbcx_dtknqr2_s cn52xx;
586 + struct cvmx_usbcx_dtknqr2_s cn52xxp1;
587 + struct cvmx_usbcx_dtknqr2_s cn56xx;
588 + struct cvmx_usbcx_dtknqr2_s cn56xxp1;
589 +};
590 +
591 +union cvmx_usbcx_dtknqr3 {
592 + uint32_t u32;
593 + struct cvmx_usbcx_dtknqr3_s {
594 + uint32_t eptkn:32;
595 + } s;
596 + struct cvmx_usbcx_dtknqr3_s cn30xx;
597 + struct cvmx_usbcx_dtknqr3_s cn31xx;
598 + struct cvmx_usbcx_dtknqr3_s cn50xx;
599 + struct cvmx_usbcx_dtknqr3_s cn52xx;
600 + struct cvmx_usbcx_dtknqr3_s cn52xxp1;
601 + struct cvmx_usbcx_dtknqr3_s cn56xx;
602 + struct cvmx_usbcx_dtknqr3_s cn56xxp1;
603 +};
604 +
605 +union cvmx_usbcx_dtknqr4 {
606 + uint32_t u32;
607 + struct cvmx_usbcx_dtknqr4_s {
608 + uint32_t eptkn:32;
609 + } s;
610 + struct cvmx_usbcx_dtknqr4_s cn30xx;
611 + struct cvmx_usbcx_dtknqr4_s cn31xx;
612 + struct cvmx_usbcx_dtknqr4_s cn50xx;
613 + struct cvmx_usbcx_dtknqr4_s cn52xx;
614 + struct cvmx_usbcx_dtknqr4_s cn52xxp1;
615 + struct cvmx_usbcx_dtknqr4_s cn56xx;
616 + struct cvmx_usbcx_dtknqr4_s cn56xxp1;
617 +};
618 +
619 +union cvmx_usbcx_gahbcfg {
620 + uint32_t u32;
621 + struct cvmx_usbcx_gahbcfg_s {
622 + uint32_t reserved_9_31:23;
623 + uint32_t ptxfemplvl:1;
624 + uint32_t nptxfemplvl:1;
625 + uint32_t reserved_6_6:1;
626 + uint32_t dmaen:1;
627 + uint32_t hbstlen:4;
628 + uint32_t glblintrmsk:1;
629 + } s;
630 + struct cvmx_usbcx_gahbcfg_s cn30xx;
631 + struct cvmx_usbcx_gahbcfg_s cn31xx;
632 + struct cvmx_usbcx_gahbcfg_s cn50xx;
633 + struct cvmx_usbcx_gahbcfg_s cn52xx;
634 + struct cvmx_usbcx_gahbcfg_s cn52xxp1;
635 + struct cvmx_usbcx_gahbcfg_s cn56xx;
636 + struct cvmx_usbcx_gahbcfg_s cn56xxp1;
637 +};
638 +
639 +union cvmx_usbcx_ghwcfg1 {
640 + uint32_t u32;
641 + struct cvmx_usbcx_ghwcfg1_s {
642 + uint32_t epdir:32;
643 + } s;
644 + struct cvmx_usbcx_ghwcfg1_s cn30xx;
645 + struct cvmx_usbcx_ghwcfg1_s cn31xx;
646 + struct cvmx_usbcx_ghwcfg1_s cn50xx;
647 + struct cvmx_usbcx_ghwcfg1_s cn52xx;
648 + struct cvmx_usbcx_ghwcfg1_s cn52xxp1;
649 + struct cvmx_usbcx_ghwcfg1_s cn56xx;
650 + struct cvmx_usbcx_ghwcfg1_s cn56xxp1;
651 +};
652 +
653 +union cvmx_usbcx_ghwcfg2 {
654 + uint32_t u32;
655 + struct cvmx_usbcx_ghwcfg2_s {
656 + uint32_t reserved_31_31:1;
657 + uint32_t tknqdepth:5;
658 + uint32_t ptxqdepth:2;
659 + uint32_t nptxqdepth:2;
660 + uint32_t reserved_20_21:2;
661 + uint32_t dynfifosizing:1;
662 + uint32_t periosupport:1;
663 + uint32_t numhstchnl:4;
664 + uint32_t numdeveps:4;
665 + uint32_t fsphytype:2;
666 + uint32_t hsphytype:2;
667 + uint32_t singpnt:1;
668 + uint32_t otgarch:2;
669 + uint32_t otgmode:3;
670 + } s;
671 + struct cvmx_usbcx_ghwcfg2_s cn30xx;
672 + struct cvmx_usbcx_ghwcfg2_s cn31xx;
673 + struct cvmx_usbcx_ghwcfg2_s cn50xx;
674 + struct cvmx_usbcx_ghwcfg2_s cn52xx;
675 + struct cvmx_usbcx_ghwcfg2_s cn52xxp1;
676 + struct cvmx_usbcx_ghwcfg2_s cn56xx;
677 + struct cvmx_usbcx_ghwcfg2_s cn56xxp1;
678 +};
679 +
680 +union cvmx_usbcx_ghwcfg3 {
681 + uint32_t u32;
682 + struct cvmx_usbcx_ghwcfg3_s {
683 + uint32_t dfifodepth:16;
684 + uint32_t reserved_13_15:3;
685 + uint32_t ahbphysync:1;
686 + uint32_t rsttype:1;
687 + uint32_t optfeature:1;
688 + uint32_t vendor_control_interface_support:1;
689 + uint32_t i2c_selection:1;
690 + uint32_t otgen:1;
691 + uint32_t pktsizewidth:3;
692 + uint32_t xfersizewidth:4;
693 + } s;
694 + struct cvmx_usbcx_ghwcfg3_s cn30xx;
695 + struct cvmx_usbcx_ghwcfg3_s cn31xx;
696 + struct cvmx_usbcx_ghwcfg3_s cn50xx;
697 + struct cvmx_usbcx_ghwcfg3_s cn52xx;
698 + struct cvmx_usbcx_ghwcfg3_s cn52xxp1;
699 + struct cvmx_usbcx_ghwcfg3_s cn56xx;
700 + struct cvmx_usbcx_ghwcfg3_s cn56xxp1;
701 +};
702 +
703 +union cvmx_usbcx_ghwcfg4 {
704 + uint32_t u32;
705 + struct cvmx_usbcx_ghwcfg4_s {
706 + uint32_t reserved_30_31:2;
707 + uint32_t numdevmodinend:4;
708 + uint32_t endedtrfifo:1;
709 + uint32_t sessendfltr:1;
710 + uint32_t bvalidfltr:1;
711 + uint32_t avalidfltr:1;
712 + uint32_t vbusvalidfltr:1;
713 + uint32_t iddgfltr:1;
714 + uint32_t numctleps:4;
715 + uint32_t phydatawidth:2;
716 + uint32_t reserved_6_13:8;
717 + uint32_t ahbfreq:1;
718 + uint32_t enablepwropt:1;
719 + uint32_t numdevperioeps:4;
720 + } s;
721 + struct cvmx_usbcx_ghwcfg4_cn30xx {
722 + uint32_t reserved_25_31:7;
723 + uint32_t sessendfltr:1;
724 + uint32_t bvalidfltr:1;
725 + uint32_t avalidfltr:1;
726 + uint32_t vbusvalidfltr:1;
727 + uint32_t iddgfltr:1;
728 + uint32_t numctleps:4;
729 + uint32_t phydatawidth:2;
730 + uint32_t reserved_6_13:8;
731 + uint32_t ahbfreq:1;
732 + uint32_t enablepwropt:1;
733 + uint32_t numdevperioeps:4;
734 + } cn30xx;
735 + struct cvmx_usbcx_ghwcfg4_cn30xx cn31xx;
736 + struct cvmx_usbcx_ghwcfg4_s cn50xx;
737 + struct cvmx_usbcx_ghwcfg4_s cn52xx;
738 + struct cvmx_usbcx_ghwcfg4_s cn52xxp1;
739 + struct cvmx_usbcx_ghwcfg4_s cn56xx;
740 + struct cvmx_usbcx_ghwcfg4_s cn56xxp1;
741 +};
742 +
743 +union cvmx_usbcx_gintmsk {
744 + uint32_t u32;
745 + struct cvmx_usbcx_gintmsk_s {
746 + uint32_t wkupintmsk:1;
747 + uint32_t sessreqintmsk:1;
748 + uint32_t disconnintmsk:1;
749 + uint32_t conidstschngmsk:1;
750 + uint32_t reserved_27_27:1;
751 + uint32_t ptxfempmsk:1;
752 + uint32_t hchintmsk:1;
753 + uint32_t prtintmsk:1;
754 + uint32_t reserved_23_23:1;
755 + uint32_t fetsuspmsk:1;
756 + uint32_t incomplpmsk:1;
757 + uint32_t incompisoinmsk:1;
758 + uint32_t oepintmsk:1;
759 + uint32_t inepintmsk:1;
760 + uint32_t epmismsk:1;
761 + uint32_t reserved_16_16:1;
762 + uint32_t eopfmsk:1;
763 + uint32_t isooutdropmsk:1;
764 + uint32_t enumdonemsk:1;
765 + uint32_t usbrstmsk:1;
766 + uint32_t usbsuspmsk:1;
767 + uint32_t erlysuspmsk:1;
768 + uint32_t i2cint:1;
769 + uint32_t ulpickintmsk:1;
770 + uint32_t goutnakeffmsk:1;
771 + uint32_t ginnakeffmsk:1;
772 + uint32_t nptxfempmsk:1;
773 + uint32_t rxflvlmsk:1;
774 + uint32_t sofmsk:1;
775 + uint32_t otgintmsk:1;
776 + uint32_t modemismsk:1;
777 + uint32_t reserved_0_0:1;
778 + } s;
779 + struct cvmx_usbcx_gintmsk_s cn30xx;
780 + struct cvmx_usbcx_gintmsk_s cn31xx;
781 + struct cvmx_usbcx_gintmsk_s cn50xx;
782 + struct cvmx_usbcx_gintmsk_s cn52xx;
783 + struct cvmx_usbcx_gintmsk_s cn52xxp1;
784 + struct cvmx_usbcx_gintmsk_s cn56xx;
785 + struct cvmx_usbcx_gintmsk_s cn56xxp1;
786 +};
787 +
788 +union cvmx_usbcx_gintsts {
789 + uint32_t u32;
790 + struct cvmx_usbcx_gintsts_s {
791 + uint32_t wkupint:1;
792 + uint32_t sessreqint:1;
793 + uint32_t disconnint:1;
794 + uint32_t conidstschng:1;
795 + uint32_t reserved_27_27:1;
796 + uint32_t ptxfemp:1;
797 + uint32_t hchint:1;
798 + uint32_t prtint:1;
799 + uint32_t reserved_23_23:1;
800 + uint32_t fetsusp:1;
801 + uint32_t incomplp:1;
802 + uint32_t incompisoin:1;
803 + uint32_t oepint:1;
804 + uint32_t iepint:1;
805 + uint32_t epmis:1;
806 + uint32_t reserved_16_16:1;
807 + uint32_t eopf:1;
808 + uint32_t isooutdrop:1;
809 + uint32_t enumdone:1;
810 + uint32_t usbrst:1;
811 + uint32_t usbsusp:1;
812 + uint32_t erlysusp:1;
813 + uint32_t i2cint:1;
814 + uint32_t ulpickint:1;
815 + uint32_t goutnakeff:1;
816 + uint32_t ginnakeff:1;
817 + uint32_t nptxfemp:1;
818 + uint32_t rxflvl:1;
819 + uint32_t sof:1;
820 + uint32_t otgint:1;
821 + uint32_t modemis:1;
822 + uint32_t curmod:1;
823 + } s;
824 + struct cvmx_usbcx_gintsts_s cn30xx;
825 + struct cvmx_usbcx_gintsts_s cn31xx;
826 + struct cvmx_usbcx_gintsts_s cn50xx;
827 + struct cvmx_usbcx_gintsts_s cn52xx;
828 + struct cvmx_usbcx_gintsts_s cn52xxp1;
829 + struct cvmx_usbcx_gintsts_s cn56xx;
830 + struct cvmx_usbcx_gintsts_s cn56xxp1;
831 +};
832 +
833 +union cvmx_usbcx_gnptxfsiz {
834 + uint32_t u32;
835 + struct cvmx_usbcx_gnptxfsiz_s {
836 + uint32_t nptxfdep:16;
837 + uint32_t nptxfstaddr:16;
838 + } s;
839 + struct cvmx_usbcx_gnptxfsiz_s cn30xx;
840 + struct cvmx_usbcx_gnptxfsiz_s cn31xx;
841 + struct cvmx_usbcx_gnptxfsiz_s cn50xx;
842 + struct cvmx_usbcx_gnptxfsiz_s cn52xx;
843 + struct cvmx_usbcx_gnptxfsiz_s cn52xxp1;
844 + struct cvmx_usbcx_gnptxfsiz_s cn56xx;
845 + struct cvmx_usbcx_gnptxfsiz_s cn56xxp1;
846 +};
847 +
848 +union cvmx_usbcx_gnptxsts {
849 + uint32_t u32;
850 + struct cvmx_usbcx_gnptxsts_s {
851 + uint32_t reserved_31_31:1;
852 + uint32_t nptxqtop:7;
853 + uint32_t nptxqspcavail:8;
854 + uint32_t nptxfspcavail:16;
855 + } s;
856 + struct cvmx_usbcx_gnptxsts_s cn30xx;
857 + struct cvmx_usbcx_gnptxsts_s cn31xx;
858 + struct cvmx_usbcx_gnptxsts_s cn50xx;
859 + struct cvmx_usbcx_gnptxsts_s cn52xx;
860 + struct cvmx_usbcx_gnptxsts_s cn52xxp1;
861 + struct cvmx_usbcx_gnptxsts_s cn56xx;
862 + struct cvmx_usbcx_gnptxsts_s cn56xxp1;
863 +};
864 +
865 +union cvmx_usbcx_gotgctl {
866 + uint32_t u32;
867 + struct cvmx_usbcx_gotgctl_s {
868 + uint32_t reserved_20_31:12;
869 + uint32_t bsesvld:1;
870 + uint32_t asesvld:1;
871 + uint32_t dbnctime:1;
872 + uint32_t conidsts:1;
873 + uint32_t reserved_12_15:4;
874 + uint32_t devhnpen:1;
875 + uint32_t hstsethnpen:1;
876 + uint32_t hnpreq:1;
877 + uint32_t hstnegscs:1;
878 + uint32_t reserved_2_7:6;
879 + uint32_t sesreq:1;
880 + uint32_t sesreqscs:1;
881 + } s;
882 + struct cvmx_usbcx_gotgctl_s cn30xx;
883 + struct cvmx_usbcx_gotgctl_s cn31xx;
884 + struct cvmx_usbcx_gotgctl_s cn50xx;
885 + struct cvmx_usbcx_gotgctl_s cn52xx;
886 + struct cvmx_usbcx_gotgctl_s cn52xxp1;
887 + struct cvmx_usbcx_gotgctl_s cn56xx;
888 + struct cvmx_usbcx_gotgctl_s cn56xxp1;
889 +};
890 +
891 +union cvmx_usbcx_gotgint {
892 + uint32_t u32;
893 + struct cvmx_usbcx_gotgint_s {
894 + uint32_t reserved_20_31:12;
895 + uint32_t dbncedone:1;
896 + uint32_t adevtoutchg:1;
897 + uint32_t hstnegdet:1;
898 + uint32_t reserved_10_16:7;
899 + uint32_t hstnegsucstschng:1;
900 + uint32_t sesreqsucstschng:1;
901 + uint32_t reserved_3_7:5;
902 + uint32_t sesenddet:1;
903 + uint32_t reserved_0_1:2;
904 + } s;
905 + struct cvmx_usbcx_gotgint_s cn30xx;
906 + struct cvmx_usbcx_gotgint_s cn31xx;
907 + struct cvmx_usbcx_gotgint_s cn50xx;
908 + struct cvmx_usbcx_gotgint_s cn52xx;
909 + struct cvmx_usbcx_gotgint_s cn52xxp1;
910 + struct cvmx_usbcx_gotgint_s cn56xx;
911 + struct cvmx_usbcx_gotgint_s cn56xxp1;
912 +};
913 +
914 +union cvmx_usbcx_grstctl {
915 + uint32_t u32;
916 + struct cvmx_usbcx_grstctl_s {
917 + uint32_t ahbidle:1;
918 + uint32_t dmareq:1;
919 + uint32_t reserved_11_29:19;
920 + uint32_t txfnum:5;
921 + uint32_t txfflsh:1;
922 + uint32_t rxfflsh:1;
923 + uint32_t intknqflsh:1;
924 + uint32_t frmcntrrst:1;
925 + uint32_t hsftrst:1;
926 + uint32_t csftrst:1;
927 + } s;
928 + struct cvmx_usbcx_grstctl_s cn30xx;
929 + struct cvmx_usbcx_grstctl_s cn31xx;
930 + struct cvmx_usbcx_grstctl_s cn50xx;
931 + struct cvmx_usbcx_grstctl_s cn52xx;
932 + struct cvmx_usbcx_grstctl_s cn52xxp1;
933 + struct cvmx_usbcx_grstctl_s cn56xx;
934 + struct cvmx_usbcx_grstctl_s cn56xxp1;
935 +};
936 +
937 +union cvmx_usbcx_grxfsiz {
938 + uint32_t u32;
939 + struct cvmx_usbcx_grxfsiz_s {
940 + uint32_t reserved_16_31:16;
941 + uint32_t rxfdep:16;
942 + } s;
943 + struct cvmx_usbcx_grxfsiz_s cn30xx;
944 + struct cvmx_usbcx_grxfsiz_s cn31xx;
945 + struct cvmx_usbcx_grxfsiz_s cn50xx;
946 + struct cvmx_usbcx_grxfsiz_s cn52xx;
947 + struct cvmx_usbcx_grxfsiz_s cn52xxp1;
948 + struct cvmx_usbcx_grxfsiz_s cn56xx;
949 + struct cvmx_usbcx_grxfsiz_s cn56xxp1;
950 +};
951 +
952 +union cvmx_usbcx_grxstspd {
953 + uint32_t u32;
954 + struct cvmx_usbcx_grxstspd_s {
955 + uint32_t reserved_25_31:7;
956 + uint32_t fn:4;
957 + uint32_t pktsts:4;
958 + uint32_t dpid:2;
959 + uint32_t bcnt:11;
960 + uint32_t epnum:4;
961 + } s;
962 + struct cvmx_usbcx_grxstspd_s cn30xx;
963 + struct cvmx_usbcx_grxstspd_s cn31xx;
964 + struct cvmx_usbcx_grxstspd_s cn50xx;
965 + struct cvmx_usbcx_grxstspd_s cn52xx;
966 + struct cvmx_usbcx_grxstspd_s cn52xxp1;
967 + struct cvmx_usbcx_grxstspd_s cn56xx;
968 + struct cvmx_usbcx_grxstspd_s cn56xxp1;
969 +};
970 +
971 +union cvmx_usbcx_grxstsph {
972 + uint32_t u32;
973 + struct cvmx_usbcx_grxstsph_s {
974 + uint32_t reserved_21_31:11;
975 + uint32_t pktsts:4;
976 + uint32_t dpid:2;
977 + uint32_t bcnt:11;
978 + uint32_t chnum:4;
979 + } s;
980 + struct cvmx_usbcx_grxstsph_s cn30xx;
981 + struct cvmx_usbcx_grxstsph_s cn31xx;
982 + struct cvmx_usbcx_grxstsph_s cn50xx;
983 + struct cvmx_usbcx_grxstsph_s cn52xx;
984 + struct cvmx_usbcx_grxstsph_s cn52xxp1;
985 + struct cvmx_usbcx_grxstsph_s cn56xx;
986 + struct cvmx_usbcx_grxstsph_s cn56xxp1;
987 +};
988 +
989 +union cvmx_usbcx_grxstsrd {
990 + uint32_t u32;
991 + struct cvmx_usbcx_grxstsrd_s {
992 + uint32_t reserved_25_31:7;
993 + uint32_t fn:4;
994 + uint32_t pktsts:4;
995 + uint32_t dpid:2;
996 + uint32_t bcnt:11;
997 + uint32_t epnum:4;
998 + } s;
999 + struct cvmx_usbcx_grxstsrd_s cn30xx;
1000 + struct cvmx_usbcx_grxstsrd_s cn31xx;
1001 + struct cvmx_usbcx_grxstsrd_s cn50xx;
1002 + struct cvmx_usbcx_grxstsrd_s cn52xx;
1003 + struct cvmx_usbcx_grxstsrd_s cn52xxp1;
1004 + struct cvmx_usbcx_grxstsrd_s cn56xx;
1005 + struct cvmx_usbcx_grxstsrd_s cn56xxp1;
1006 +};
1007 +
1008 +union cvmx_usbcx_grxstsrh {
1009 + uint32_t u32;
1010 + struct cvmx_usbcx_grxstsrh_s {
1011 + uint32_t reserved_21_31:11;
1012 + uint32_t pktsts:4;
1013 + uint32_t dpid:2;
1014 + uint32_t bcnt:11;
1015 + uint32_t chnum:4;
1016 + } s;
1017 + struct cvmx_usbcx_grxstsrh_s cn30xx;
1018 + struct cvmx_usbcx_grxstsrh_s cn31xx;
1019 + struct cvmx_usbcx_grxstsrh_s cn50xx;
1020 + struct cvmx_usbcx_grxstsrh_s cn52xx;
1021 + struct cvmx_usbcx_grxstsrh_s cn52xxp1;
1022 + struct cvmx_usbcx_grxstsrh_s cn56xx;
1023 + struct cvmx_usbcx_grxstsrh_s cn56xxp1;
1024 +};
1025 +
1026 +union cvmx_usbcx_gsnpsid {
1027 + uint32_t u32;
1028 + struct cvmx_usbcx_gsnpsid_s {
1029 + uint32_t synopsysid:32;
1030 + } s;
1031 + struct cvmx_usbcx_gsnpsid_s cn30xx;
1032 + struct cvmx_usbcx_gsnpsid_s cn31xx;
1033 + struct cvmx_usbcx_gsnpsid_s cn50xx;
1034 + struct cvmx_usbcx_gsnpsid_s cn52xx;
1035 + struct cvmx_usbcx_gsnpsid_s cn52xxp1;
1036 + struct cvmx_usbcx_gsnpsid_s cn56xx;
1037 + struct cvmx_usbcx_gsnpsid_s cn56xxp1;
1038 +};
1039 +
1040 +union cvmx_usbcx_gusbcfg {
1041 + uint32_t u32;
1042 + struct cvmx_usbcx_gusbcfg_s {
1043 + uint32_t reserved_17_31:15;
1044 + uint32_t otgi2csel:1;
1045 + uint32_t phylpwrclksel:1;
1046 + uint32_t reserved_14_14:1;
1047 + uint32_t usbtrdtim:4;
1048 + uint32_t hnpcap:1;
1049 + uint32_t srpcap:1;
1050 + uint32_t ddrsel:1;
1051 + uint32_t physel:1;
1052 + uint32_t fsintf:1;
1053 + uint32_t ulpi_utmi_sel:1;
1054 + uint32_t phyif:1;
1055 + uint32_t toutcal:3;
1056 + } s;
1057 + struct cvmx_usbcx_gusbcfg_s cn30xx;
1058 + struct cvmx_usbcx_gusbcfg_s cn31xx;
1059 + struct cvmx_usbcx_gusbcfg_s cn50xx;
1060 + struct cvmx_usbcx_gusbcfg_s cn52xx;
1061 + struct cvmx_usbcx_gusbcfg_s cn52xxp1;
1062 + struct cvmx_usbcx_gusbcfg_s cn56xx;
1063 + struct cvmx_usbcx_gusbcfg_s cn56xxp1;
1064 +};
1065 +
1066 +union cvmx_usbcx_haint {
1067 + uint32_t u32;
1068 + struct cvmx_usbcx_haint_s {
1069 + uint32_t reserved_16_31:16;
1070 + uint32_t haint:16;
1071 + } s;
1072 + struct cvmx_usbcx_haint_s cn30xx;
1073 + struct cvmx_usbcx_haint_s cn31xx;
1074 + struct cvmx_usbcx_haint_s cn50xx;
1075 + struct cvmx_usbcx_haint_s cn52xx;
1076 + struct cvmx_usbcx_haint_s cn52xxp1;
1077 + struct cvmx_usbcx_haint_s cn56xx;
1078 + struct cvmx_usbcx_haint_s cn56xxp1;
1079 +};
1080 +
1081 +union cvmx_usbcx_haintmsk {
1082 + uint32_t u32;
1083 + struct cvmx_usbcx_haintmsk_s {
1084 + uint32_t reserved_16_31:16;
1085 + uint32_t haintmsk:16;
1086 + } s;
1087 + struct cvmx_usbcx_haintmsk_s cn30xx;
1088 + struct cvmx_usbcx_haintmsk_s cn31xx;
1089 + struct cvmx_usbcx_haintmsk_s cn50xx;
1090 + struct cvmx_usbcx_haintmsk_s cn52xx;
1091 + struct cvmx_usbcx_haintmsk_s cn52xxp1;
1092 + struct cvmx_usbcx_haintmsk_s cn56xx;
1093 + struct cvmx_usbcx_haintmsk_s cn56xxp1;
1094 +};
1095 +
1096 +union cvmx_usbcx_hccharx {
1097 + uint32_t u32;
1098 + struct cvmx_usbcx_hccharx_s {
1099 + uint32_t chena:1;
1100 + uint32_t chdis:1;
1101 + uint32_t oddfrm:1;
1102 + uint32_t devaddr:7;
1103 + uint32_t ec:2;
1104 + uint32_t eptype:2;
1105 + uint32_t lspddev:1;
1106 + uint32_t reserved_16_16:1;
1107 + uint32_t epdir:1;
1108 + uint32_t epnum:4;
1109 + uint32_t mps:11;
1110 + } s;
1111 + struct cvmx_usbcx_hccharx_s cn30xx;
1112 + struct cvmx_usbcx_hccharx_s cn31xx;
1113 + struct cvmx_usbcx_hccharx_s cn50xx;
1114 + struct cvmx_usbcx_hccharx_s cn52xx;
1115 + struct cvmx_usbcx_hccharx_s cn52xxp1;
1116 + struct cvmx_usbcx_hccharx_s cn56xx;
1117 + struct cvmx_usbcx_hccharx_s cn56xxp1;
1118 +};
1119 +
1120 +union cvmx_usbcx_hcfg {
1121 + uint32_t u32;
1122 + struct cvmx_usbcx_hcfg_s {
1123 + uint32_t reserved_3_31:29;
1124 + uint32_t fslssupp:1;
1125 + uint32_t fslspclksel:2;
1126 + } s;
1127 + struct cvmx_usbcx_hcfg_s cn30xx;
1128 + struct cvmx_usbcx_hcfg_s cn31xx;
1129 + struct cvmx_usbcx_hcfg_s cn50xx;
1130 + struct cvmx_usbcx_hcfg_s cn52xx;
1131 + struct cvmx_usbcx_hcfg_s cn52xxp1;
1132 + struct cvmx_usbcx_hcfg_s cn56xx;
1133 + struct cvmx_usbcx_hcfg_s cn56xxp1;
1134 +};
1135 +
1136 +union cvmx_usbcx_hcintx {
1137 + uint32_t u32;
1138 + struct cvmx_usbcx_hcintx_s {
1139 + uint32_t reserved_11_31:21;
1140 + uint32_t datatglerr:1;
1141 + uint32_t frmovrun:1;
1142 + uint32_t bblerr:1;
1143 + uint32_t xacterr:1;
1144 + uint32_t nyet:1;
1145 + uint32_t ack:1;
1146 + uint32_t nak:1;
1147 + uint32_t stall:1;
1148 + uint32_t ahberr:1;
1149 + uint32_t chhltd:1;
1150 + uint32_t xfercompl:1;
1151 + } s;
1152 + struct cvmx_usbcx_hcintx_s cn30xx;
1153 + struct cvmx_usbcx_hcintx_s cn31xx;
1154 + struct cvmx_usbcx_hcintx_s cn50xx;
1155 + struct cvmx_usbcx_hcintx_s cn52xx;
1156 + struct cvmx_usbcx_hcintx_s cn52xxp1;
1157 + struct cvmx_usbcx_hcintx_s cn56xx;
1158 + struct cvmx_usbcx_hcintx_s cn56xxp1;
1159 +};
1160 +
1161 +union cvmx_usbcx_hcintmskx {
1162 + uint32_t u32;
1163 + struct cvmx_usbcx_hcintmskx_s {
1164 + uint32_t reserved_11_31:21;
1165 + uint32_t datatglerrmsk:1;
1166 + uint32_t frmovrunmsk:1;
1167 + uint32_t bblerrmsk:1;
1168 + uint32_t xacterrmsk:1;
1169 + uint32_t nyetmsk:1;
1170 + uint32_t ackmsk:1;
1171 + uint32_t nakmsk:1;
1172 + uint32_t stallmsk:1;
1173 + uint32_t ahberrmsk:1;
1174 + uint32_t chhltdmsk:1;
1175 + uint32_t xfercomplmsk:1;
1176 + } s;
1177 + struct cvmx_usbcx_hcintmskx_s cn30xx;
1178 + struct cvmx_usbcx_hcintmskx_s cn31xx;
1179 + struct cvmx_usbcx_hcintmskx_s cn50xx;
1180 + struct cvmx_usbcx_hcintmskx_s cn52xx;
1181 + struct cvmx_usbcx_hcintmskx_s cn52xxp1;
1182 + struct cvmx_usbcx_hcintmskx_s cn56xx;
1183 + struct cvmx_usbcx_hcintmskx_s cn56xxp1;
1184 +};
1185 +
1186 +union cvmx_usbcx_hcspltx {
1187 + uint32_t u32;
1188 + struct cvmx_usbcx_hcspltx_s {
1189 + uint32_t spltena:1;
1190 + uint32_t reserved_17_30:14;
1191 + uint32_t compsplt:1;
1192 + uint32_t xactpos:2;
1193 + uint32_t hubaddr:7;
1194 + uint32_t prtaddr:7;
1195 + } s;
1196 + struct cvmx_usbcx_hcspltx_s cn30xx;
1197 + struct cvmx_usbcx_hcspltx_s cn31xx;
1198 + struct cvmx_usbcx_hcspltx_s cn50xx;
1199 + struct cvmx_usbcx_hcspltx_s cn52xx;
1200 + struct cvmx_usbcx_hcspltx_s cn52xxp1;
1201 + struct cvmx_usbcx_hcspltx_s cn56xx;
1202 + struct cvmx_usbcx_hcspltx_s cn56xxp1;
1203 +};
1204 +
1205 +union cvmx_usbcx_hctsizx {
1206 + uint32_t u32;
1207 + struct cvmx_usbcx_hctsizx_s {
1208 + uint32_t dopng:1;
1209 + uint32_t pid:2;
1210 + uint32_t pktcnt:10;
1211 + uint32_t xfersize:19;
1212 + } s;
1213 + struct cvmx_usbcx_hctsizx_s cn30xx;
1214 + struct cvmx_usbcx_hctsizx_s cn31xx;
1215 + struct cvmx_usbcx_hctsizx_s cn50xx;
1216 + struct cvmx_usbcx_hctsizx_s cn52xx;
1217 + struct cvmx_usbcx_hctsizx_s cn52xxp1;
1218 + struct cvmx_usbcx_hctsizx_s cn56xx;
1219 + struct cvmx_usbcx_hctsizx_s cn56xxp1;
1220 +};
1221 +
1222 +union cvmx_usbcx_hfir {
1223 + uint32_t u32;
1224 + struct cvmx_usbcx_hfir_s {
1225 + uint32_t reserved_16_31:16;
1226 + uint32_t frint:16;
1227 + } s;
1228 + struct cvmx_usbcx_hfir_s cn30xx;
1229 + struct cvmx_usbcx_hfir_s cn31xx;
1230 + struct cvmx_usbcx_hfir_s cn50xx;
1231 + struct cvmx_usbcx_hfir_s cn52xx;
1232 + struct cvmx_usbcx_hfir_s cn52xxp1;
1233 + struct cvmx_usbcx_hfir_s cn56xx;
1234 + struct cvmx_usbcx_hfir_s cn56xxp1;
1235 +};
1236 +
1237 +union cvmx_usbcx_hfnum {
1238 + uint32_t u32;
1239 + struct cvmx_usbcx_hfnum_s {
1240 + uint32_t frrem:16;
1241 + uint32_t frnum:16;
1242 + } s;
1243 + struct cvmx_usbcx_hfnum_s cn30xx;
1244 + struct cvmx_usbcx_hfnum_s cn31xx;
1245 + struct cvmx_usbcx_hfnum_s cn50xx;
1246 + struct cvmx_usbcx_hfnum_s cn52xx;
1247 + struct cvmx_usbcx_hfnum_s cn52xxp1;
1248 + struct cvmx_usbcx_hfnum_s cn56xx;
1249 + struct cvmx_usbcx_hfnum_s cn56xxp1;
1250 +};
1251 +
1252 +union cvmx_usbcx_hprt {
1253 + uint32_t u32;
1254 + struct cvmx_usbcx_hprt_s {
1255 + uint32_t reserved_19_31:13;
1256 + uint32_t prtspd:2;
1257 + uint32_t prttstctl:4;
1258 + uint32_t prtpwr:1;
1259 + uint32_t prtlnsts:2;
1260 + uint32_t reserved_9_9:1;
1261 + uint32_t prtrst:1;
1262 + uint32_t prtsusp:1;
1263 + uint32_t prtres:1;
1264 + uint32_t prtovrcurrchng:1;
1265 + uint32_t prtovrcurract:1;
1266 + uint32_t prtenchng:1;
1267 + uint32_t prtena:1;
1268 + uint32_t prtconndet:1;
1269 + uint32_t prtconnsts:1;
1270 + } s;
1271 + struct cvmx_usbcx_hprt_s cn30xx;
1272 + struct cvmx_usbcx_hprt_s cn31xx;
1273 + struct cvmx_usbcx_hprt_s cn50xx;
1274 + struct cvmx_usbcx_hprt_s cn52xx;
1275 + struct cvmx_usbcx_hprt_s cn52xxp1;
1276 + struct cvmx_usbcx_hprt_s cn56xx;
1277 + struct cvmx_usbcx_hprt_s cn56xxp1;
1278 +};
1279 +
1280 +union cvmx_usbcx_hptxfsiz {
1281 + uint32_t u32;
1282 + struct cvmx_usbcx_hptxfsiz_s {
1283 + uint32_t ptxfsize:16;
1284 + uint32_t ptxfstaddr:16;
1285 + } s;
1286 + struct cvmx_usbcx_hptxfsiz_s cn30xx;
1287 + struct cvmx_usbcx_hptxfsiz_s cn31xx;
1288 + struct cvmx_usbcx_hptxfsiz_s cn50xx;
1289 + struct cvmx_usbcx_hptxfsiz_s cn52xx;
1290 + struct cvmx_usbcx_hptxfsiz_s cn52xxp1;
1291 + struct cvmx_usbcx_hptxfsiz_s cn56xx;
1292 + struct cvmx_usbcx_hptxfsiz_s cn56xxp1;
1293 +};
1294 +
1295 +union cvmx_usbcx_hptxsts {
1296 + uint32_t u32;
1297 + struct cvmx_usbcx_hptxsts_s {
1298 + uint32_t ptxqtop:8;
1299 + uint32_t ptxqspcavail:8;
1300 + uint32_t ptxfspcavail:16;
1301 + } s;
1302 + struct cvmx_usbcx_hptxsts_s cn30xx;
1303 + struct cvmx_usbcx_hptxsts_s cn31xx;
1304 + struct cvmx_usbcx_hptxsts_s cn50xx;
1305 + struct cvmx_usbcx_hptxsts_s cn52xx;
1306 + struct cvmx_usbcx_hptxsts_s cn52xxp1;
1307 + struct cvmx_usbcx_hptxsts_s cn56xx;
1308 + struct cvmx_usbcx_hptxsts_s cn56xxp1;
1309 +};
1310 +
1311 +union cvmx_usbcx_nptxdfifox {
1312 + uint32_t u32;
1313 + struct cvmx_usbcx_nptxdfifox_s {
1314 + uint32_t data:32;
1315 + } s;
1316 + struct cvmx_usbcx_nptxdfifox_s cn30xx;
1317 + struct cvmx_usbcx_nptxdfifox_s cn31xx;
1318 + struct cvmx_usbcx_nptxdfifox_s cn50xx;
1319 + struct cvmx_usbcx_nptxdfifox_s cn52xx;
1320 + struct cvmx_usbcx_nptxdfifox_s cn52xxp1;
1321 + struct cvmx_usbcx_nptxdfifox_s cn56xx;
1322 + struct cvmx_usbcx_nptxdfifox_s cn56xxp1;
1323 +};
1324 +
1325 +union cvmx_usbcx_pcgcctl {
1326 + uint32_t u32;
1327 + struct cvmx_usbcx_pcgcctl_s {
1328 + uint32_t reserved_5_31:27;
1329 + uint32_t physuspended:1;
1330 + uint32_t rstpdwnmodule:1;
1331 + uint32_t pwrclmp:1;
1332 + uint32_t gatehclk:1;
1333 + uint32_t stoppclk:1;
1334 + } s;
1335 + struct cvmx_usbcx_pcgcctl_s cn30xx;
1336 + struct cvmx_usbcx_pcgcctl_s cn31xx;
1337 + struct cvmx_usbcx_pcgcctl_s cn50xx;
1338 + struct cvmx_usbcx_pcgcctl_s cn52xx;
1339 + struct cvmx_usbcx_pcgcctl_s cn52xxp1;
1340 + struct cvmx_usbcx_pcgcctl_s cn56xx;
1341 + struct cvmx_usbcx_pcgcctl_s cn56xxp1;
1342 +};
1343 +
1344 +#endif
1345 diff --git a/arch/mips/include/asm/octeon/cvmx-usbnx-defs.h b/arch/mips/include/asm/octeon/cvmx-usbnx-defs.h
1346 new file mode 100644
1347 index 0000000..90be974
1348 --- /dev/null
1349 +++ b/arch/mips/include/asm/octeon/cvmx-usbnx-defs.h
1350 @@ -0,0 +1,760 @@
1351 +/***********************license start***************
1352 + * Author: Cavium Networks
1353 + *
1354 + * Contact: support@caviumnetworks.com
1355 + * This file is part of the OCTEON SDK
1356 + *
1357 + * Copyright (c) 2003-2008 Cavium Networks
1358 + *
1359 + * This file is free software; you can redistribute it and/or modify
1360 + * it under the terms of the GNU General Public License, Version 2, as
1361 + * published by the Free Software Foundation.
1362 + *
1363 + * This file is distributed in the hope that it will be useful, but
1364 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
1365 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
1366 + * NONINFRINGEMENT. See the GNU General Public License for more
1367 + * details.
1368 + *
1369 + * You should have received a copy of the GNU General Public License
1370 + * along with this file; if not, write to the Free Software
1371 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1372 + * or visit http://www.gnu.org/licenses/.
1373 + *
1374 + * This file may also be available under a different license from Cavium.
1375 + * Contact Cavium Networks for more information
1376 + ***********************license end**************************************/
1377 +
1378 +#ifndef __CVMX_USBNX_DEFS_H__
1379 +#define __CVMX_USBNX_DEFS_H__
1380 +
1381 +#define CVMX_USBNX_BIST_STATUS(block_id) \
1382 + CVMX_ADD_IO_SEG(0x00011800680007F8ull + (((block_id) & 1) * 0x10000000ull))
1383 +#define CVMX_USBNX_CLK_CTL(block_id) \
1384 + CVMX_ADD_IO_SEG(0x0001180068000010ull + (((block_id) & 1) * 0x10000000ull))
1385 +#define CVMX_USBNX_CTL_STATUS(block_id) \
1386 + CVMX_ADD_IO_SEG(0x00016F0000000800ull + (((block_id) & 1) * 0x100000000000ull))
1387 +#define CVMX_USBNX_DMA0_INB_CHN0(block_id) \
1388 + CVMX_ADD_IO_SEG(0x00016F0000000818ull + (((block_id) & 1) * 0x100000000000ull))
1389 +#define CVMX_USBNX_DMA0_INB_CHN1(block_id) \
1390 + CVMX_ADD_IO_SEG(0x00016F0000000820ull + (((block_id) & 1) * 0x100000000000ull))
1391 +#define CVMX_USBNX_DMA0_INB_CHN2(block_id) \
1392 + CVMX_ADD_IO_SEG(0x00016F0000000828ull + (((block_id) & 1) * 0x100000000000ull))
1393 +#define CVMX_USBNX_DMA0_INB_CHN3(block_id) \
1394 + CVMX_ADD_IO_SEG(0x00016F0000000830ull + (((block_id) & 1) * 0x100000000000ull))
1395 +#define CVMX_USBNX_DMA0_INB_CHN4(block_id) \
1396 + CVMX_ADD_IO_SEG(0x00016F0000000838ull + (((block_id) & 1) * 0x100000000000ull))
1397 +#define CVMX_USBNX_DMA0_INB_CHN5(block_id) \
1398 + CVMX_ADD_IO_SEG(0x00016F0000000840ull + (((block_id) & 1) * 0x100000000000ull))
1399 +#define CVMX_USBNX_DMA0_INB_CHN6(block_id) \
1400 + CVMX_ADD_IO_SEG(0x00016F0000000848ull + (((block_id) & 1) * 0x100000000000ull))
1401 +#define CVMX_USBNX_DMA0_INB_CHN7(block_id) \
1402 + CVMX_ADD_IO_SEG(0x00016F0000000850ull + (((block_id) & 1) * 0x100000000000ull))
1403 +#define CVMX_USBNX_DMA0_OUTB_CHN0(block_id) \
1404 + CVMX_ADD_IO_SEG(0x00016F0000000858ull + (((block_id) & 1) * 0x100000000000ull))
1405 +#define CVMX_USBNX_DMA0_OUTB_CHN1(block_id) \
1406 + CVMX_ADD_IO_SEG(0x00016F0000000860ull + (((block_id) & 1) * 0x100000000000ull))
1407 +#define CVMX_USBNX_DMA0_OUTB_CHN2(block_id) \
1408 + CVMX_ADD_IO_SEG(0x00016F0000000868ull + (((block_id) & 1) * 0x100000000000ull))
1409 +#define CVMX_USBNX_DMA0_OUTB_CHN3(block_id) \
1410 + CVMX_ADD_IO_SEG(0x00016F0000000870ull + (((block_id) & 1) * 0x100000000000ull))
1411 +#define CVMX_USBNX_DMA0_OUTB_CHN4(block_id) \
1412 + CVMX_ADD_IO_SEG(0x00016F0000000878ull + (((block_id) & 1) * 0x100000000000ull))
1413 +#define CVMX_USBNX_DMA0_OUTB_CHN5(block_id) \
1414 + CVMX_ADD_IO_SEG(0x00016F0000000880ull + (((block_id) & 1) * 0x100000000000ull))
1415 +#define CVMX_USBNX_DMA0_OUTB_CHN6(block_id) \
1416 + CVMX_ADD_IO_SEG(0x00016F0000000888ull + (((block_id) & 1) * 0x100000000000ull))
1417 +#define CVMX_USBNX_DMA0_OUTB_CHN7(block_id) \
1418 + CVMX_ADD_IO_SEG(0x00016F0000000890ull + (((block_id) & 1) * 0x100000000000ull))
1419 +#define CVMX_USBNX_DMA_TEST(block_id) \
1420 + CVMX_ADD_IO_SEG(0x00016F0000000808ull + (((block_id) & 1) * 0x100000000000ull))
1421 +#define CVMX_USBNX_INT_ENB(block_id) \
1422 + CVMX_ADD_IO_SEG(0x0001180068000008ull + (((block_id) & 1) * 0x10000000ull))
1423 +#define CVMX_USBNX_INT_SUM(block_id) \
1424 + CVMX_ADD_IO_SEG(0x0001180068000000ull + (((block_id) & 1) * 0x10000000ull))
1425 +#define CVMX_USBNX_USBP_CTL_STATUS(block_id) \
1426 + CVMX_ADD_IO_SEG(0x0001180068000018ull + (((block_id) & 1) * 0x10000000ull))
1427 +
1428 +union cvmx_usbnx_bist_status {
1429 + uint64_t u64;
1430 + struct cvmx_usbnx_bist_status_s {
1431 + uint64_t reserved_7_63:57;
1432 + uint64_t u2nc_bis:1;
1433 + uint64_t u2nf_bis:1;
1434 + uint64_t e2hc_bis:1;
1435 + uint64_t n2uf_bis:1;
1436 + uint64_t usbc_bis:1;
1437 + uint64_t nif_bis:1;
1438 + uint64_t nof_bis:1;
1439 + } s;
1440 + struct cvmx_usbnx_bist_status_cn30xx {
1441 + uint64_t reserved_3_63:61;
1442 + uint64_t usbc_bis:1;
1443 + uint64_t nif_bis:1;
1444 + uint64_t nof_bis:1;
1445 + } cn30xx;
1446 + struct cvmx_usbnx_bist_status_cn30xx cn31xx;
1447 + struct cvmx_usbnx_bist_status_s cn50xx;
1448 + struct cvmx_usbnx_bist_status_s cn52xx;
1449 + struct cvmx_usbnx_bist_status_s cn52xxp1;
1450 + struct cvmx_usbnx_bist_status_s cn56xx;
1451 + struct cvmx_usbnx_bist_status_s cn56xxp1;
1452 +};
1453 +
1454 +union cvmx_usbnx_clk_ctl {
1455 + uint64_t u64;
1456 + struct cvmx_usbnx_clk_ctl_s {
1457 + uint64_t reserved_20_63:44;
1458 + uint64_t divide2:2;
1459 + uint64_t hclk_rst:1;
1460 + uint64_t p_x_on:1;
1461 + uint64_t reserved_14_15:2;
1462 + uint64_t p_com_on:1;
1463 + uint64_t p_c_sel:2;
1464 + uint64_t cdiv_byp:1;
1465 + uint64_t sd_mode:2;
1466 + uint64_t s_bist:1;
1467 + uint64_t por:1;
1468 + uint64_t enable:1;
1469 + uint64_t prst:1;
1470 + uint64_t hrst:1;
1471 + uint64_t divide:3;
1472 + } s;
1473 + struct cvmx_usbnx_clk_ctl_cn30xx {
1474 + uint64_t reserved_18_63:46;
1475 + uint64_t hclk_rst:1;
1476 + uint64_t p_x_on:1;
1477 + uint64_t p_rclk:1;
1478 + uint64_t p_xenbn:1;
1479 + uint64_t p_com_on:1;
1480 + uint64_t p_c_sel:2;
1481 + uint64_t cdiv_byp:1;
1482 + uint64_t sd_mode:2;
1483 + uint64_t s_bist:1;
1484 + uint64_t por:1;
1485 + uint64_t enable:1;
1486 + uint64_t prst:1;
1487 + uint64_t hrst:1;
1488 + uint64_t divide:3;
1489 + } cn30xx;
1490 + struct cvmx_usbnx_clk_ctl_cn30xx cn31xx;
1491 + struct cvmx_usbnx_clk_ctl_cn50xx {
1492 + uint64_t reserved_20_63:44;
1493 + uint64_t divide2:2;
1494 + uint64_t hclk_rst:1;
1495 + uint64_t reserved_16_16:1;
1496 + uint64_t p_rtype:2;
1497 + uint64_t p_com_on:1;
1498 + uint64_t p_c_sel:2;
1499 + uint64_t cdiv_byp:1;
1500 + uint64_t sd_mode:2;
1501 + uint64_t s_bist:1;
1502 + uint64_t por:1;
1503 + uint64_t enable:1;
1504 + uint64_t prst:1;
1505 + uint64_t hrst:1;
1506 + uint64_t divide:3;
1507 + } cn50xx;
1508 + struct cvmx_usbnx_clk_ctl_cn50xx cn52xx;
1509 + struct cvmx_usbnx_clk_ctl_cn50xx cn52xxp1;
1510 + struct cvmx_usbnx_clk_ctl_cn50xx cn56xx;
1511 + struct cvmx_usbnx_clk_ctl_cn50xx cn56xxp1;
1512 +};
1513 +
1514 +union cvmx_usbnx_ctl_status {
1515 + uint64_t u64;
1516 + struct cvmx_usbnx_ctl_status_s {
1517 + uint64_t reserved_6_63:58;
1518 + uint64_t dma_0pag:1;
1519 + uint64_t dma_stt:1;
1520 + uint64_t dma_test:1;
1521 + uint64_t inv_a2:1;
1522 + uint64_t l2c_emod:2;
1523 + } s;
1524 + struct cvmx_usbnx_ctl_status_s cn30xx;
1525 + struct cvmx_usbnx_ctl_status_s cn31xx;
1526 + struct cvmx_usbnx_ctl_status_s cn50xx;
1527 + struct cvmx_usbnx_ctl_status_s cn52xx;
1528 + struct cvmx_usbnx_ctl_status_s cn52xxp1;
1529 + struct cvmx_usbnx_ctl_status_s cn56xx;
1530 + struct cvmx_usbnx_ctl_status_s cn56xxp1;
1531 +};
1532 +
1533 +union cvmx_usbnx_dma0_inb_chn0 {
1534 + uint64_t u64;
1535 + struct cvmx_usbnx_dma0_inb_chn0_s {
1536 + uint64_t reserved_36_63:28;
1537 + uint64_t addr:36;
1538 + } s;
1539 + struct cvmx_usbnx_dma0_inb_chn0_s cn30xx;
1540 + struct cvmx_usbnx_dma0_inb_chn0_s cn31xx;
1541 + struct cvmx_usbnx_dma0_inb_chn0_s cn50xx;
1542 + struct cvmx_usbnx_dma0_inb_chn0_s cn52xx;
1543 + struct cvmx_usbnx_dma0_inb_chn0_s cn52xxp1;
1544 + struct cvmx_usbnx_dma0_inb_chn0_s cn56xx;
1545 + struct cvmx_usbnx_dma0_inb_chn0_s cn56xxp1;
1546 +};
1547 +
1548 +union cvmx_usbnx_dma0_inb_chn1 {
1549 + uint64_t u64;
1550 + struct cvmx_usbnx_dma0_inb_chn1_s {
1551 + uint64_t reserved_36_63:28;
1552 + uint64_t addr:36;
1553 + } s;
1554 + struct cvmx_usbnx_dma0_inb_chn1_s cn30xx;
1555 + struct cvmx_usbnx_dma0_inb_chn1_s cn31xx;
1556 + struct cvmx_usbnx_dma0_inb_chn1_s cn50xx;
1557 + struct cvmx_usbnx_dma0_inb_chn1_s cn52xx;
1558 + struct cvmx_usbnx_dma0_inb_chn1_s cn52xxp1;
1559 + struct cvmx_usbnx_dma0_inb_chn1_s cn56xx;
1560 + struct cvmx_usbnx_dma0_inb_chn1_s cn56xxp1;
1561 +};
1562 +
1563 +union cvmx_usbnx_dma0_inb_chn2 {
1564 + uint64_t u64;
1565 + struct cvmx_usbnx_dma0_inb_chn2_s {
1566 + uint64_t reserved_36_63:28;
1567 + uint64_t addr:36;
1568 + } s;
1569 + struct cvmx_usbnx_dma0_inb_chn2_s cn30xx;
1570 + struct cvmx_usbnx_dma0_inb_chn2_s cn31xx;
1571 + struct cvmx_usbnx_dma0_inb_chn2_s cn50xx;
1572 + struct cvmx_usbnx_dma0_inb_chn2_s cn52xx;
1573 + struct cvmx_usbnx_dma0_inb_chn2_s cn52xxp1;
1574 + struct cvmx_usbnx_dma0_inb_chn2_s cn56xx;
1575 + struct cvmx_usbnx_dma0_inb_chn2_s cn56xxp1;
1576 +};
1577 +
1578 +union cvmx_usbnx_dma0_inb_chn3 {
1579 + uint64_t u64;
1580 + struct cvmx_usbnx_dma0_inb_chn3_s {
1581 + uint64_t reserved_36_63:28;
1582 + uint64_t addr:36;
1583 + } s;
1584 + struct cvmx_usbnx_dma0_inb_chn3_s cn30xx;
1585 + struct cvmx_usbnx_dma0_inb_chn3_s cn31xx;
1586 + struct cvmx_usbnx_dma0_inb_chn3_s cn50xx;
1587 + struct cvmx_usbnx_dma0_inb_chn3_s cn52xx;
1588 + struct cvmx_usbnx_dma0_inb_chn3_s cn52xxp1;
1589 + struct cvmx_usbnx_dma0_inb_chn3_s cn56xx;
1590 + struct cvmx_usbnx_dma0_inb_chn3_s cn56xxp1;
1591 +};
1592 +
1593 +union cvmx_usbnx_dma0_inb_chn4 {
1594 + uint64_t u64;
1595 + struct cvmx_usbnx_dma0_inb_chn4_s {
1596 + uint64_t reserved_36_63:28;
1597 + uint64_t addr:36;
1598 + } s;
1599 + struct cvmx_usbnx_dma0_inb_chn4_s cn30xx;
1600 + struct cvmx_usbnx_dma0_inb_chn4_s cn31xx;
1601 + struct cvmx_usbnx_dma0_inb_chn4_s cn50xx;
1602 + struct cvmx_usbnx_dma0_inb_chn4_s cn52xx;
1603 + struct cvmx_usbnx_dma0_inb_chn4_s cn52xxp1;
1604 + struct cvmx_usbnx_dma0_inb_chn4_s cn56xx;
1605 + struct cvmx_usbnx_dma0_inb_chn4_s cn56xxp1;
1606 +};
1607 +
1608 +union cvmx_usbnx_dma0_inb_chn5 {
1609 + uint64_t u64;
1610 + struct cvmx_usbnx_dma0_inb_chn5_s {
1611 + uint64_t reserved_36_63:28;
1612 + uint64_t addr:36;
1613 + } s;
1614 + struct cvmx_usbnx_dma0_inb_chn5_s cn30xx;
1615 + struct cvmx_usbnx_dma0_inb_chn5_s cn31xx;
1616 + struct cvmx_usbnx_dma0_inb_chn5_s cn50xx;
1617 + struct cvmx_usbnx_dma0_inb_chn5_s cn52xx;
1618 + struct cvmx_usbnx_dma0_inb_chn5_s cn52xxp1;
1619 + struct cvmx_usbnx_dma0_inb_chn5_s cn56xx;
1620 + struct cvmx_usbnx_dma0_inb_chn5_s cn56xxp1;
1621 +};
1622 +
1623 +union cvmx_usbnx_dma0_inb_chn6 {
1624 + uint64_t u64;
1625 + struct cvmx_usbnx_dma0_inb_chn6_s {
1626 + uint64_t reserved_36_63:28;
1627 + uint64_t addr:36;
1628 + } s;
1629 + struct cvmx_usbnx_dma0_inb_chn6_s cn30xx;
1630 + struct cvmx_usbnx_dma0_inb_chn6_s cn31xx;
1631 + struct cvmx_usbnx_dma0_inb_chn6_s cn50xx;
1632 + struct cvmx_usbnx_dma0_inb_chn6_s cn52xx;
1633 + struct cvmx_usbnx_dma0_inb_chn6_s cn52xxp1;
1634 + struct cvmx_usbnx_dma0_inb_chn6_s cn56xx;
1635 + struct cvmx_usbnx_dma0_inb_chn6_s cn56xxp1;
1636 +};
1637 +
1638 +union cvmx_usbnx_dma0_inb_chn7 {
1639 + uint64_t u64;
1640 + struct cvmx_usbnx_dma0_inb_chn7_s {
1641 + uint64_t reserved_36_63:28;
1642 + uint64_t addr:36;
1643 + } s;
1644 + struct cvmx_usbnx_dma0_inb_chn7_s cn30xx;
1645 + struct cvmx_usbnx_dma0_inb_chn7_s cn31xx;
1646 + struct cvmx_usbnx_dma0_inb_chn7_s cn50xx;
1647 + struct cvmx_usbnx_dma0_inb_chn7_s cn52xx;
1648 + struct cvmx_usbnx_dma0_inb_chn7_s cn52xxp1;
1649 + struct cvmx_usbnx_dma0_inb_chn7_s cn56xx;
1650 + struct cvmx_usbnx_dma0_inb_chn7_s cn56xxp1;
1651 +};
1652 +
1653 +union cvmx_usbnx_dma0_outb_chn0 {
1654 + uint64_t u64;
1655 + struct cvmx_usbnx_dma0_outb_chn0_s {
1656 + uint64_t reserved_36_63:28;
1657 + uint64_t addr:36;
1658 + } s;
1659 + struct cvmx_usbnx_dma0_outb_chn0_s cn30xx;
1660 + struct cvmx_usbnx_dma0_outb_chn0_s cn31xx;
1661 + struct cvmx_usbnx_dma0_outb_chn0_s cn50xx;
1662 + struct cvmx_usbnx_dma0_outb_chn0_s cn52xx;
1663 + struct cvmx_usbnx_dma0_outb_chn0_s cn52xxp1;
1664 + struct cvmx_usbnx_dma0_outb_chn0_s cn56xx;
1665 + struct cvmx_usbnx_dma0_outb_chn0_s cn56xxp1;
1666 +};
1667 +
1668 +union cvmx_usbnx_dma0_outb_chn1 {
1669 + uint64_t u64;
1670 + struct cvmx_usbnx_dma0_outb_chn1_s {
1671 + uint64_t reserved_36_63:28;
1672 + uint64_t addr:36;
1673 + } s;
1674 + struct cvmx_usbnx_dma0_outb_chn1_s cn30xx;
1675 + struct cvmx_usbnx_dma0_outb_chn1_s cn31xx;
1676 + struct cvmx_usbnx_dma0_outb_chn1_s cn50xx;
1677 + struct cvmx_usbnx_dma0_outb_chn1_s cn52xx;
1678 + struct cvmx_usbnx_dma0_outb_chn1_s cn52xxp1;
1679 + struct cvmx_usbnx_dma0_outb_chn1_s cn56xx;
1680 + struct cvmx_usbnx_dma0_outb_chn1_s cn56xxp1;
1681 +};
1682 +
1683 +union cvmx_usbnx_dma0_outb_chn2 {
1684 + uint64_t u64;
1685 + struct cvmx_usbnx_dma0_outb_chn2_s {
1686 + uint64_t reserved_36_63:28;
1687 + uint64_t addr:36;
1688 + } s;
1689 + struct cvmx_usbnx_dma0_outb_chn2_s cn30xx;
1690 + struct cvmx_usbnx_dma0_outb_chn2_s cn31xx;
1691 + struct cvmx_usbnx_dma0_outb_chn2_s cn50xx;
1692 + struct cvmx_usbnx_dma0_outb_chn2_s cn52xx;
1693 + struct cvmx_usbnx_dma0_outb_chn2_s cn52xxp1;
1694 + struct cvmx_usbnx_dma0_outb_chn2_s cn56xx;
1695 + struct cvmx_usbnx_dma0_outb_chn2_s cn56xxp1;
1696 +};
1697 +
1698 +union cvmx_usbnx_dma0_outb_chn3 {
1699 + uint64_t u64;
1700 + struct cvmx_usbnx_dma0_outb_chn3_s {
1701 + uint64_t reserved_36_63:28;
1702 + uint64_t addr:36;
1703 + } s;
1704 + struct cvmx_usbnx_dma0_outb_chn3_s cn30xx;
1705 + struct cvmx_usbnx_dma0_outb_chn3_s cn31xx;
1706 + struct cvmx_usbnx_dma0_outb_chn3_s cn50xx;
1707 + struct cvmx_usbnx_dma0_outb_chn3_s cn52xx;
1708 + struct cvmx_usbnx_dma0_outb_chn3_s cn52xxp1;
1709 + struct cvmx_usbnx_dma0_outb_chn3_s cn56xx;
1710 + struct cvmx_usbnx_dma0_outb_chn3_s cn56xxp1;
1711 +};
1712 +
1713 +union cvmx_usbnx_dma0_outb_chn4 {
1714 + uint64_t u64;
1715 + struct cvmx_usbnx_dma0_outb_chn4_s {
1716 + uint64_t reserved_36_63:28;
1717 + uint64_t addr:36;
1718 + } s;
1719 + struct cvmx_usbnx_dma0_outb_chn4_s cn30xx;
1720 + struct cvmx_usbnx_dma0_outb_chn4_s cn31xx;
1721 + struct cvmx_usbnx_dma0_outb_chn4_s cn50xx;
1722 + struct cvmx_usbnx_dma0_outb_chn4_s cn52xx;
1723 + struct cvmx_usbnx_dma0_outb_chn4_s cn52xxp1;
1724 + struct cvmx_usbnx_dma0_outb_chn4_s cn56xx;
1725 + struct cvmx_usbnx_dma0_outb_chn4_s cn56xxp1;
1726 +};
1727 +
1728 +union cvmx_usbnx_dma0_outb_chn5 {
1729 + uint64_t u64;
1730 + struct cvmx_usbnx_dma0_outb_chn5_s {
1731 + uint64_t reserved_36_63:28;
1732 + uint64_t addr:36;
1733 + } s;
1734 + struct cvmx_usbnx_dma0_outb_chn5_s cn30xx;
1735 + struct cvmx_usbnx_dma0_outb_chn5_s cn31xx;
1736 + struct cvmx_usbnx_dma0_outb_chn5_s cn50xx;
1737 + struct cvmx_usbnx_dma0_outb_chn5_s cn52xx;
1738 + struct cvmx_usbnx_dma0_outb_chn5_s cn52xxp1;
1739 + struct cvmx_usbnx_dma0_outb_chn5_s cn56xx;
1740 + struct cvmx_usbnx_dma0_outb_chn5_s cn56xxp1;
1741 +};
1742 +
1743 +union cvmx_usbnx_dma0_outb_chn6 {
1744 + uint64_t u64;
1745 + struct cvmx_usbnx_dma0_outb_chn6_s {
1746 + uint64_t reserved_36_63:28;
1747 + uint64_t addr:36;
1748 + } s;
1749 + struct cvmx_usbnx_dma0_outb_chn6_s cn30xx;
1750 + struct cvmx_usbnx_dma0_outb_chn6_s cn31xx;
1751 + struct cvmx_usbnx_dma0_outb_chn6_s cn50xx;
1752 + struct cvmx_usbnx_dma0_outb_chn6_s cn52xx;
1753 + struct cvmx_usbnx_dma0_outb_chn6_s cn52xxp1;
1754 + struct cvmx_usbnx_dma0_outb_chn6_s cn56xx;
1755 + struct cvmx_usbnx_dma0_outb_chn6_s cn56xxp1;
1756 +};
1757 +
1758 +union cvmx_usbnx_dma0_outb_chn7 {
1759 + uint64_t u64;
1760 + struct cvmx_usbnx_dma0_outb_chn7_s {
1761 + uint64_t reserved_36_63:28;
1762 + uint64_t addr:36;
1763 + } s;
1764 + struct cvmx_usbnx_dma0_outb_chn7_s cn30xx;
1765 + struct cvmx_usbnx_dma0_outb_chn7_s cn31xx;
1766 + struct cvmx_usbnx_dma0_outb_chn7_s cn50xx;
1767 + struct cvmx_usbnx_dma0_outb_chn7_s cn52xx;
1768 + struct cvmx_usbnx_dma0_outb_chn7_s cn52xxp1;
1769 + struct cvmx_usbnx_dma0_outb_chn7_s cn56xx;
1770 + struct cvmx_usbnx_dma0_outb_chn7_s cn56xxp1;
1771 +};
1772 +
1773 +union cvmx_usbnx_dma_test {
1774 + uint64_t u64;
1775 + struct cvmx_usbnx_dma_test_s {
1776 + uint64_t reserved_40_63:24;
1777 + uint64_t done:1;
1778 + uint64_t req:1;
1779 + uint64_t f_addr:18;
1780 + uint64_t count:11;
1781 + uint64_t channel:5;
1782 + uint64_t burst:4;
1783 + } s;
1784 + struct cvmx_usbnx_dma_test_s cn30xx;
1785 + struct cvmx_usbnx_dma_test_s cn31xx;
1786 + struct cvmx_usbnx_dma_test_s cn50xx;
1787 + struct cvmx_usbnx_dma_test_s cn52xx;
1788 + struct cvmx_usbnx_dma_test_s cn52xxp1;
1789 + struct cvmx_usbnx_dma_test_s cn56xx;
1790 + struct cvmx_usbnx_dma_test_s cn56xxp1;
1791 +};
1792 +
1793 +union cvmx_usbnx_int_enb {
1794 + uint64_t u64;
1795 + struct cvmx_usbnx_int_enb_s {
1796 + uint64_t reserved_38_63:26;
1797 + uint64_t nd4o_dpf:1;
1798 + uint64_t nd4o_dpe:1;
1799 + uint64_t nd4o_rpf:1;
1800 + uint64_t nd4o_rpe:1;
1801 + uint64_t ltl_f_pf:1;
1802 + uint64_t ltl_f_pe:1;
1803 + uint64_t u2n_c_pe:1;
1804 + uint64_t u2n_c_pf:1;
1805 + uint64_t u2n_d_pf:1;
1806 + uint64_t u2n_d_pe:1;
1807 + uint64_t n2u_pe:1;
1808 + uint64_t n2u_pf:1;
1809 + uint64_t uod_pf:1;
1810 + uint64_t uod_pe:1;
1811 + uint64_t rq_q3_e:1;
1812 + uint64_t rq_q3_f:1;
1813 + uint64_t rq_q2_e:1;
1814 + uint64_t rq_q2_f:1;
1815 + uint64_t rg_fi_f:1;
1816 + uint64_t rg_fi_e:1;
1817 + uint64_t l2_fi_f:1;
1818 + uint64_t l2_fi_e:1;
1819 + uint64_t l2c_a_f:1;
1820 + uint64_t l2c_s_e:1;
1821 + uint64_t dcred_f:1;
1822 + uint64_t dcred_e:1;
1823 + uint64_t lt_pu_f:1;
1824 + uint64_t lt_po_e:1;
1825 + uint64_t nt_pu_f:1;
1826 + uint64_t nt_po_e:1;
1827 + uint64_t pt_pu_f:1;
1828 + uint64_t pt_po_e:1;
1829 + uint64_t lr_pu_f:1;
1830 + uint64_t lr_po_e:1;
1831 + uint64_t nr_pu_f:1;
1832 + uint64_t nr_po_e:1;
1833 + uint64_t pr_pu_f:1;
1834 + uint64_t pr_po_e:1;
1835 + } s;
1836 + struct cvmx_usbnx_int_enb_s cn30xx;
1837 + struct cvmx_usbnx_int_enb_s cn31xx;
1838 + struct cvmx_usbnx_int_enb_cn50xx {
1839 + uint64_t reserved_38_63:26;
1840 + uint64_t nd4o_dpf:1;
1841 + uint64_t nd4o_dpe:1;
1842 + uint64_t nd4o_rpf:1;
1843 + uint64_t nd4o_rpe:1;
1844 + uint64_t ltl_f_pf:1;
1845 + uint64_t ltl_f_pe:1;
1846 + uint64_t reserved_26_31:6;
1847 + uint64_t uod_pf:1;
1848 + uint64_t uod_pe:1;
1849 + uint64_t rq_q3_e:1;
1850 + uint64_t rq_q3_f:1;
1851 + uint64_t rq_q2_e:1;
1852 + uint64_t rq_q2_f:1;
1853 + uint64_t rg_fi_f:1;
1854 + uint64_t rg_fi_e:1;
1855 + uint64_t l2_fi_f:1;
1856 + uint64_t l2_fi_e:1;
1857 + uint64_t l2c_a_f:1;
1858 + uint64_t l2c_s_e:1;
1859 + uint64_t dcred_f:1;
1860 + uint64_t dcred_e:1;
1861 + uint64_t lt_pu_f:1;
1862 + uint64_t lt_po_e:1;
1863 + uint64_t nt_pu_f:1;
1864 + uint64_t nt_po_e:1;
1865 + uint64_t pt_pu_f:1;
1866 + uint64_t pt_po_e:1;
1867 + uint64_t lr_pu_f:1;
1868 + uint64_t lr_po_e:1;
1869 + uint64_t nr_pu_f:1;
1870 + uint64_t nr_po_e:1;
1871 + uint64_t pr_pu_f:1;
1872 + uint64_t pr_po_e:1;
1873 + } cn50xx;
1874 + struct cvmx_usbnx_int_enb_cn50xx cn52xx;
1875 + struct cvmx_usbnx_int_enb_cn50xx cn52xxp1;
1876 + struct cvmx_usbnx_int_enb_cn50xx cn56xx;
1877 + struct cvmx_usbnx_int_enb_cn50xx cn56xxp1;
1878 +};
1879 +
1880 +union cvmx_usbnx_int_sum {
1881 + uint64_t u64;
1882 + struct cvmx_usbnx_int_sum_s {
1883 + uint64_t reserved_38_63:26;
1884 + uint64_t nd4o_dpf:1;
1885 + uint64_t nd4o_dpe:1;
1886 + uint64_t nd4o_rpf:1;
1887 + uint64_t nd4o_rpe:1;
1888 + uint64_t ltl_f_pf:1;
1889 + uint64_t ltl_f_pe:1;
1890 + uint64_t u2n_c_pe:1;
1891 + uint64_t u2n_c_pf:1;
1892 + uint64_t u2n_d_pf:1;
1893 + uint64_t u2n_d_pe:1;
1894 + uint64_t n2u_pe:1;
1895 + uint64_t n2u_pf:1;
1896 + uint64_t uod_pf:1;
1897 + uint64_t uod_pe:1;
1898 + uint64_t rq_q3_e:1;
1899 + uint64_t rq_q3_f:1;
1900 + uint64_t rq_q2_e:1;
1901 + uint64_t rq_q2_f:1;
1902 + uint64_t rg_fi_f:1;
1903 + uint64_t rg_fi_e:1;
1904 + uint64_t lt_fi_f:1;
1905 + uint64_t lt_fi_e:1;
1906 + uint64_t l2c_a_f:1;
1907 + uint64_t l2c_s_e:1;
1908 + uint64_t dcred_f:1;
1909 + uint64_t dcred_e:1;
1910 + uint64_t lt_pu_f:1;
1911 + uint64_t lt_po_e:1;
1912 + uint64_t nt_pu_f:1;
1913 + uint64_t nt_po_e:1;
1914 + uint64_t pt_pu_f:1;
1915 + uint64_t pt_po_e:1;
1916 + uint64_t lr_pu_f:1;
1917 + uint64_t lr_po_e:1;
1918 + uint64_t nr_pu_f:1;
1919 + uint64_t nr_po_e:1;
1920 + uint64_t pr_pu_f:1;
1921 + uint64_t pr_po_e:1;
1922 + } s;
1923 + struct cvmx_usbnx_int_sum_s cn30xx;
1924 + struct cvmx_usbnx_int_sum_s cn31xx;
1925 + struct cvmx_usbnx_int_sum_cn50xx {
1926 + uint64_t reserved_38_63:26;
1927 + uint64_t nd4o_dpf:1;
1928 + uint64_t nd4o_dpe:1;
1929 + uint64_t nd4o_rpf:1;
1930 + uint64_t nd4o_rpe:1;
1931 + uint64_t ltl_f_pf:1;
1932 + uint64_t ltl_f_pe:1;
1933 + uint64_t reserved_26_31:6;
1934 + uint64_t uod_pf:1;
1935 + uint64_t uod_pe:1;
1936 + uint64_t rq_q3_e:1;
1937 + uint64_t rq_q3_f:1;
1938 + uint64_t rq_q2_e:1;
1939 + uint64_t rq_q2_f:1;
1940 + uint64_t rg_fi_f:1;
1941 + uint64_t rg_fi_e:1;
1942 + uint64_t lt_fi_f:1;
1943 + uint64_t lt_fi_e:1;
1944 + uint64_t l2c_a_f:1;
1945 + uint64_t l2c_s_e:1;
1946 + uint64_t dcred_f:1;
1947 + uint64_t dcred_e:1;
1948 + uint64_t lt_pu_f:1;
1949 + uint64_t lt_po_e:1;
1950 + uint64_t nt_pu_f:1;
1951 + uint64_t nt_po_e:1;
1952 + uint64_t pt_pu_f:1;
1953 + uint64_t pt_po_e:1;
1954 + uint64_t lr_pu_f:1;
1955 + uint64_t lr_po_e:1;
1956 + uint64_t nr_pu_f:1;
1957 + uint64_t nr_po_e:1;
1958 + uint64_t pr_pu_f:1;
1959 + uint64_t pr_po_e:1;
1960 + } cn50xx;
1961 + struct cvmx_usbnx_int_sum_cn50xx cn52xx;
1962 + struct cvmx_usbnx_int_sum_cn50xx cn52xxp1;
1963 + struct cvmx_usbnx_int_sum_cn50xx cn56xx;
1964 + struct cvmx_usbnx_int_sum_cn50xx cn56xxp1;
1965 +};
1966 +
1967 +union cvmx_usbnx_usbp_ctl_status {
1968 + uint64_t u64;
1969 + struct cvmx_usbnx_usbp_ctl_status_s {
1970 + uint64_t txrisetune:1;
1971 + uint64_t txvreftune:4;
1972 + uint64_t txfslstune:4;
1973 + uint64_t txhsxvtune:2;
1974 + uint64_t sqrxtune:3;
1975 + uint64_t compdistune:3;
1976 + uint64_t otgtune:3;
1977 + uint64_t otgdisable:1;
1978 + uint64_t portreset:1;
1979 + uint64_t drvvbus:1;
1980 + uint64_t lsbist:1;
1981 + uint64_t fsbist:1;
1982 + uint64_t hsbist:1;
1983 + uint64_t bist_done:1;
1984 + uint64_t bist_err:1;
1985 + uint64_t tdata_out:4;
1986 + uint64_t siddq:1;
1987 + uint64_t txpreemphasistune:1;
1988 + uint64_t dma_bmode:1;
1989 + uint64_t usbc_end:1;
1990 + uint64_t usbp_bist:1;
1991 + uint64_t tclk:1;
1992 + uint64_t dp_pulld:1;
1993 + uint64_t dm_pulld:1;
1994 + uint64_t hst_mode:1;
1995 + uint64_t tuning:4;
1996 + uint64_t tx_bs_enh:1;
1997 + uint64_t tx_bs_en:1;
1998 + uint64_t loop_enb:1;
1999 + uint64_t vtest_enb:1;
2000 + uint64_t bist_enb:1;
2001 + uint64_t tdata_sel:1;
2002 + uint64_t taddr_in:4;
2003 + uint64_t tdata_in:8;
2004 + uint64_t ate_reset:1;
2005 + } s;
2006 + struct cvmx_usbnx_usbp_ctl_status_cn30xx {
2007 + uint64_t reserved_38_63:26;
2008 + uint64_t bist_done:1;
2009 + uint64_t bist_err:1;
2010 + uint64_t tdata_out:4;
2011 + uint64_t reserved_30_31:2;
2012 + uint64_t dma_bmode:1;
2013 + uint64_t usbc_end:1;
2014 + uint64_t usbp_bist:1;
2015 + uint64_t tclk:1;
2016 + uint64_t dp_pulld:1;
2017 + uint64_t dm_pulld:1;
2018 + uint64_t hst_mode:1;
2019 + uint64_t tuning:4;
2020 + uint64_t tx_bs_enh:1;
2021 + uint64_t tx_bs_en:1;
2022 + uint64_t loop_enb:1;
2023 + uint64_t vtest_enb:1;
2024 + uint64_t bist_enb:1;
2025 + uint64_t tdata_sel:1;
2026 + uint64_t taddr_in:4;
2027 + uint64_t tdata_in:8;
2028 + uint64_t ate_reset:1;
2029 + } cn30xx;
2030 + struct cvmx_usbnx_usbp_ctl_status_cn30xx cn31xx;
2031 + struct cvmx_usbnx_usbp_ctl_status_cn50xx {
2032 + uint64_t txrisetune:1;
2033 + uint64_t txvreftune:4;
2034 + uint64_t txfslstune:4;
2035 + uint64_t txhsxvtune:2;
2036 + uint64_t sqrxtune:3;
2037 + uint64_t compdistune:3;
2038 + uint64_t otgtune:3;
2039 + uint64_t otgdisable:1;
2040 + uint64_t portreset:1;
2041 + uint64_t drvvbus:1;
2042 + uint64_t lsbist:1;
2043 + uint64_t fsbist:1;
2044 + uint64_t hsbist:1;
2045 + uint64_t bist_done:1;
2046 + uint64_t bist_err:1;
2047 + uint64_t tdata_out:4;
2048 + uint64_t reserved_31_31:1;
2049 + uint64_t txpreemphasistune:1;
2050 + uint64_t dma_bmode:1;
2051 + uint64_t usbc_end:1;
2052 + uint64_t usbp_bist:1;
2053 + uint64_t tclk:1;
2054 + uint64_t dp_pulld:1;
2055 + uint64_t dm_pulld:1;
2056 + uint64_t hst_mode:1;
2057 + uint64_t reserved_19_22:4;
2058 + uint64_t tx_bs_enh:1;
2059 + uint64_t tx_bs_en:1;
2060 + uint64_t loop_enb:1;
2061 + uint64_t vtest_enb:1;
2062 + uint64_t bist_enb:1;
2063 + uint64_t tdata_sel:1;
2064 + uint64_t taddr_in:4;
2065 + uint64_t tdata_in:8;
2066 + uint64_t ate_reset:1;
2067 + } cn50xx;
2068 + struct cvmx_usbnx_usbp_ctl_status_cn50xx cn52xx;
2069 + struct cvmx_usbnx_usbp_ctl_status_cn50xx cn52xxp1;
2070 + struct cvmx_usbnx_usbp_ctl_status_cn56xx {
2071 + uint64_t txrisetune:1;
2072 + uint64_t txvreftune:4;
2073 + uint64_t txfslstune:4;
2074 + uint64_t txhsxvtune:2;
2075 + uint64_t sqrxtune:3;
2076 + uint64_t compdistune:3;
2077 + uint64_t otgtune:3;
2078 + uint64_t otgdisable:1;
2079 + uint64_t portreset:1;
2080 + uint64_t drvvbus:1;
2081 + uint64_t lsbist:1;
2082 + uint64_t fsbist:1;
2083 + uint64_t hsbist:1;
2084 + uint64_t bist_done:1;
2085 + uint64_t bist_err:1;
2086 + uint64_t tdata_out:4;
2087 + uint64_t siddq:1;
2088 + uint64_t txpreemphasistune:1;
2089 + uint64_t dma_bmode:1;
2090 + uint64_t usbc_end:1;
2091 + uint64_t usbp_bist:1;
2092 + uint64_t tclk:1;
2093 + uint64_t dp_pulld:1;
2094 + uint64_t dm_pulld:1;
2095 + uint64_t hst_mode:1;
2096 + uint64_t reserved_19_22:4;
2097 + uint64_t tx_bs_enh:1;
2098 + uint64_t tx_bs_en:1;
2099 + uint64_t loop_enb:1;
2100 + uint64_t vtest_enb:1;
2101 + uint64_t bist_enb:1;
2102 + uint64_t tdata_sel:1;
2103 + uint64_t taddr_in:4;
2104 + uint64_t tdata_in:8;
2105 + uint64_t ate_reset:1;
2106 + } cn56xx;
2107 + struct cvmx_usbnx_usbp_ctl_status_cn50xx cn56xxp1;
2108 +};
2109 +
2110 +#endif
2111 --
2112 1.6.0.6
2113
2114 --
2115 To unsubscribe from this list: send the line "unsubscribe linux-usb" in
2116 the body of a message to majordomo@vger.kernel.org
2117 More majordomo info at http://vger.kernel.org/majordomo-info.htmlSigned-off-by: David Daney <ddaney@caviumnetworks.com>
2118 ---
2119 drivers/usb/host/Kconfig | 8 +
2120 drivers/usb/host/Makefile | 1 +
2121 drivers/usb/host/dwc_otg/Kbuild | 16 +
2122 drivers/usb/host/dwc_otg/dwc_otg_attr.c | 854 ++++++++
2123 drivers/usb/host/dwc_otg/dwc_otg_attr.h | 63 +
2124 drivers/usb/host/dwc_otg/dwc_otg_cil.c | 2887 ++++++++++++++++++++++++++
2125 drivers/usb/host/dwc_otg/dwc_otg_cil.h | 866 ++++++++
2126 drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c | 689 ++++++
2127 drivers/usb/host/dwc_otg/dwc_otg_driver.h | 63 +
2128 drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 2878 +++++++++++++++++++++++++
2129 drivers/usb/host/dwc_otg/dwc_otg_hcd.h | 661 ++++++
2130 drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 1890 +++++++++++++++++
2131 drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 695 +++++++
2132 drivers/usb/host/dwc_otg/dwc_otg_octeon.c | 1078 ++++++++++
2133 drivers/usb/host/dwc_otg/dwc_otg_plat.h | 236 +++
2134 drivers/usb/host/dwc_otg/dwc_otg_regs.h | 2355 +++++++++++++++++++++
2135 16 files changed, 15240 insertions(+), 0 deletions(-)
2136 create mode 100644 drivers/usb/host/dwc_otg/Kbuild
2137 create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_attr.c
2138 create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_attr.h
2139 create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_cil.c
2140 create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_cil.h
2141 create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c
2142 create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_driver.h
2143 create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_hcd.c
2144 create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_hcd.h
2145 create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
2146 create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c
2147 create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_octeon.c
2148 create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_plat.h
2149 create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_regs.h
2150
2151 diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
2152 index 9b43b22..342dc54 100644
2153 --- a/drivers/usb/host/Kconfig
2154 +++ b/drivers/usb/host/Kconfig
2155 @@ -381,3 +381,11 @@ config USB_HWA_HCD
2156
2157 To compile this driver a module, choose M here: the module
2158 will be called "hwa-hc".
2159 +
2160 +config USB_DWC_OTG
2161 + tristate "Cavium Octeon USB"
2162 + depends on USB && CPU_CAVIUM_OCTEON
2163 + ---help---
2164 + The Cavium Octeon on-chip USB controller. To compile this
2165 + driver as a module, choose M here: the module will be called
2166 + "dwc_otg".
2167 diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
2168 index f58b249..76faf12 100644
2169 --- a/drivers/usb/host/Makefile
2170 +++ b/drivers/usb/host/Makefile
2171 @@ -15,6 +15,7 @@ endif
2172 xhci-objs := xhci-hcd.o xhci-mem.o xhci-pci.o xhci-ring.o xhci-hub.o xhci-dbg.o
2173
2174 obj-$(CONFIG_USB_WHCI_HCD) += whci/
2175 +obj-$(CONFIG_USB_DWC_OTG) += dwc_otg/
2176
2177 obj-$(CONFIG_PCI) += pci-quirks.o
2178
2179 diff --git a/drivers/usb/host/dwc_otg/Kbuild b/drivers/usb/host/dwc_otg/Kbuild
2180 new file mode 100644
2181 index 0000000..cb32638
2182 --- /dev/null
2183 +++ b/drivers/usb/host/dwc_otg/Kbuild
2184 @@ -0,0 +1,16 @@
2185 +#
2186 +# Makefile for DWC_otg Highspeed USB controller driver
2187 +#
2188 +
2189 +# Use one of the following flags to compile the software in host-only or
2190 +# device-only mode.
2191 +#EXTRA_CFLAGS += -DDWC_HOST_ONLY
2192 +#EXTRA_CFLAGS += -DDWC_DEVICE_ONLY
2193 +
2194 +EXTRA_CFLAGS += -DDWC_HOST_ONLY
2195 +obj-$(CONFIG_USB_DWC_OTG) += dwc_otg.o
2196 +
2197 +dwc_otg-y := dwc_otg_octeon.o dwc_otg_attr.o
2198 +dwc_otg-y += dwc_otg_cil.o dwc_otg_cil_intr.o
2199 +dwc_otg-y += dwc_otg_hcd.o dwc_otg_hcd_intr.o dwc_otg_hcd_queue.o
2200 +
2201 diff --git a/drivers/usb/host/dwc_otg/dwc_otg_attr.c b/drivers/usb/host/dwc_otg/dwc_otg_attr.c
2202 new file mode 100644
2203 index 0000000..d854a79
2204 --- /dev/null
2205 +++ b/drivers/usb/host/dwc_otg/dwc_otg_attr.c
2206 @@ -0,0 +1,854 @@
2207 +/* ==========================================================================
2208 + *
2209 + * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
2210 + * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
2211 + * otherwise expressly agreed to in writing between Synopsys and you.
2212 + *
2213 + * The Software IS NOT an item of Licensed Software or Licensed Product under
2214 + * any End User Software License Agreement or Agreement for Licensed Product
2215 + * with Synopsys or any supplement thereto. You are permitted to use and
2216 + * redistribute this Software in source and binary forms, with or without
2217 + * modification, provided that redistributions of source code must retain this
2218 + * notice. You may not view, use, disclose, copy or distribute this file or
2219 + * any information contained herein except pursuant to this license grant from
2220 + * Synopsys. If you do not agree with this notice, including the disclaimer
2221 + * below, then you are not authorized to use the Software.
2222 + *
2223 + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
2224 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2225 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2226 + * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
2227 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2228 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2229 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
2230 + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2231 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2232 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
2233 + * DAMAGE.
2234 + * ========================================================================== */
2235 +
2236 +/*
2237 + *
2238 + * The diagnostic interface will provide access to the controller for
2239 + * bringing up the hardware and testing. The Linux driver attributes
2240 + * feature will be used to provide the Linux Diagnostic
2241 + * Interface. These attributes are accessed through sysfs.
2242 + */
2243 +
2244 +/** @page "Linux Module Attributes"
2245 + *
2246 + * The Linux module attributes feature is used to provide the Linux
2247 + * Diagnostic Interface. These attributes are accessed through sysfs.
2248 + * The diagnostic interface will provide access to the controller for
2249 + * bringing up the hardware and testing.
2250 +
2251 + The following table shows the attributes.
2252 + <table>
2253 + <tr>
2254 + <td><b> Name</b></td>
2255 + <td><b> Description</b></td>
2256 + <td><b> Access</b></td>
2257 + </tr>
2258 +
2259 + <tr>
2260 + <td> mode </td>
2261 + <td> Returns the current mode: 0 for device mode, 1 for host mode</td>
2262 + <td> Read</td>
2263 + </tr>
2264 +
2265 + <tr>
2266 + <td> hnpcapable </td>
2267 + <td> Gets or sets the "HNP-capable" bit in the Core USB Configuraton Register.
2268 + Read returns the current value.</td>
2269 + <td> Read/Write</td>
2270 + </tr>
2271 +
2272 + <tr>
2273 + <td> srpcapable </td>
2274 + <td> Gets or sets the "SRP-capable" bit in the Core USB Configuraton Register.
2275 + Read returns the current value.</td>
2276 + <td> Read/Write</td>
2277 + </tr>
2278 +
2279 + <tr>
2280 + <td> hnp </td>
2281 + <td> Initiates the Host Negotiation Protocol. Read returns the status.</td>
2282 + <td> Read/Write</td>
2283 + </tr>
2284 +
2285 + <tr>
2286 + <td> srp </td>
2287 + <td> Initiates the Session Request Protocol. Read returns the status.</td>
2288 + <td> Read/Write</td>
2289 + </tr>
2290 +
2291 + <tr>
2292 + <td> buspower </td>
2293 + <td> Gets or sets the Power State of the bus (0 - Off or 1 - On)</td>
2294 + <td> Read/Write</td>
2295 + </tr>
2296 +
2297 + <tr>
2298 + <td> bussuspend </td>
2299 + <td> Suspends the USB bus.</td>
2300 + <td> Read/Write</td>
2301 + </tr>
2302 +
2303 + <tr>
2304 + <td> busconnected </td>
2305 + <td> Gets the connection status of the bus</td>
2306 + <td> Read</td>
2307 + </tr>
2308 +
2309 + <tr>
2310 + <td> gotgctl </td>
2311 + <td> Gets or sets the Core Control Status Register.</td>
2312 + <td> Read/Write</td>
2313 + </tr>
2314 +
2315 + <tr>
2316 + <td> gusbcfg </td>
2317 + <td> Gets or sets the Core USB Configuration Register</td>
2318 + <td> Read/Write</td>
2319 + </tr>
2320 +
2321 + <tr>
2322 + <td> grxfsiz </td>
2323 + <td> Gets or sets the Receive FIFO Size Register</td>
2324 + <td> Read/Write</td>
2325 + </tr>
2326 +
2327 + <tr>
2328 + <td> gnptxfsiz </td>
2329 + <td> Gets or sets the non-periodic Transmit Size Register</td>
2330 + <td> Read/Write</td>
2331 + </tr>
2332 +
2333 + <tr>
2334 + <td> gpvndctl </td>
2335 + <td> Gets or sets the PHY Vendor Control Register</td>
2336 + <td> Read/Write</td>
2337 + </tr>
2338 +
2339 + <tr>
2340 + <td> ggpio </td>
2341 + <td> Gets the value in the lower 16-bits of the General Purpose IO Register
2342 + or sets the upper 16 bits.</td>
2343 + <td> Read/Write</td>
2344 + </tr>
2345 +
2346 + <tr>
2347 + <td> guid </td>
2348 + <td> Gets or sets the value of the User ID Register</td>
2349 + <td> Read/Write</td>
2350 + </tr>
2351 +
2352 + <tr>
2353 + <td> gsnpsid </td>
2354 + <td> Gets the value of the Synopsys ID Regester</td>
2355 + <td> Read</td>
2356 + </tr>
2357 +
2358 + <tr>
2359 + <td> devspeed </td>
2360 + <td> Gets or sets the device speed setting in the DCFG register</td>
2361 + <td> Read/Write</td>
2362 + </tr>
2363 +
2364 + <tr>
2365 + <td> enumspeed </td>
2366 + <td> Gets the device enumeration Speed.</td>
2367 + <td> Read</td>
2368 + </tr>
2369 +
2370 + <tr>
2371 + <td> hptxfsiz </td>
2372 + <td> Gets the value of the Host Periodic Transmit FIFO</td>
2373 + <td> Read</td>
2374 + </tr>
2375 +
2376 + <tr>
2377 + <td> hprt0 </td>
2378 + <td> Gets or sets the value in the Host Port Control and Status Register</td>
2379 + <td> Read/Write</td>
2380 + </tr>
2381 +
2382 + <tr>
2383 + <td> regoffset </td>
2384 + <td> Sets the register offset for the next Register Access</td>
2385 + <td> Read/Write</td>
2386 + </tr>
2387 +
2388 + <tr>
2389 + <td> regvalue </td>
2390 + <td> Gets or sets the value of the register at the offset in the regoffset attribute.</td>
2391 + <td> Read/Write</td>
2392 + </tr>
2393 +
2394 + <tr>
2395 + <td> remote_wakeup </td>
2396 + <td> On read, shows the status of Remote Wakeup. On write, initiates a remote
2397 + wakeup of the host. When bit 0 is 1 and Remote Wakeup is enabled, the Remote
2398 + Wakeup signalling bit in the Device Control Register is set for 1
2399 + milli-second.</td>
2400 + <td> Read/Write</td>
2401 + </tr>
2402 +
2403 + <tr>
2404 + <td> regdump </td>
2405 + <td> Dumps the contents of core registers.</td>
2406 + <td> Read</td>
2407 + </tr>
2408 +
2409 + <tr>
2410 + <td> hcddump </td>
2411 + <td> Dumps the current HCD state.</td>
2412 + <td> Read</td>
2413 + </tr>
2414 +
2415 + <tr>
2416 + <td> hcd_frrem </td>
2417 + <td> Shows the average value of the Frame Remaining
2418 + field in the Host Frame Number/Frame Remaining register when an SOF interrupt
2419 + occurs. This can be used to determine the average interrupt latency. Also
2420 + shows the average Frame Remaining value for start_transfer and the "a" and
2421 + "b" sample points. The "a" and "b" sample points may be used during debugging
2422 + bto determine how long it takes to execute a section of the HCD code.</td>
2423 + <td> Read</td>
2424 + </tr>
2425 +
2426 + <tr>
2427 + <td> rd_reg_test </td>
2428 + <td> Displays the time required to read the GNPTXFSIZ register many times
2429 + (the output shows the number of times the register is read).
2430 + <td> Read</td>
2431 + </tr>
2432 +
2433 + <tr>
2434 + <td> wr_reg_test </td>
2435 + <td> Displays the time required to write the GNPTXFSIZ register many times
2436 + (the output shows the number of times the register is written).
2437 + <td> Read</td>
2438 + </tr>
2439 +
2440 + </table>
2441 +
2442 + Example usage:
2443 + To get the current mode:
2444 + cat /sys/devices/lm0/mode
2445 +
2446 + To power down the USB:
2447 + echo 0 > /sys/devices/lm0/buspower
2448 + */
2449 +
2450 +#include <linux/kernel.h>
2451 +#include <linux/module.h>
2452 +#include <linux/moduleparam.h>
2453 +#include <linux/init.h>
2454 +#include <linux/device.h>
2455 +#include <linux/errno.h>
2456 +#include <linux/types.h>
2457 +#include <linux/stat.h> /* permission constants */
2458 +
2459 +#include <asm/io.h>
2460 +
2461 +#include "dwc_otg_plat.h"
2462 +#include "dwc_otg_attr.h"
2463 +#include "dwc_otg_driver.h"
2464 +#ifndef DWC_HOST_ONLY
2465 +#include "dwc_otg_pcd.h"
2466 +#endif
2467 +#include "dwc_otg_hcd.h"
2468 +
2469 +/*
2470 + * MACROs for defining sysfs attribute
2471 + */
2472 +#define DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_, _addr_, \
2473 + _mask_, _shift_, _string_) \
2474 + static ssize_t _otg_attr_name_##_show (struct device *_dev, \
2475 + struct device_attribute *attr, \
2476 + char *buf) \
2477 + { \
2478 + struct dwc_otg_device *otg_dev = _dev->platform_data; \
2479 + uint32_t val; \
2480 + val = dwc_read_reg32(_addr_); \
2481 + val = (val & (_mask_)) >> _shift_; \
2482 + return sprintf(buf, "%s = 0x%x\n", _string_, val); \
2483 + }
2484 +
2485 +#define DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_, _addr_, \
2486 + _mask_, _shift_, _string_) \
2487 + static ssize_t _otg_attr_name_##_store (struct device *_dev, \
2488 + struct device_attribute *attr, \
2489 + const char *buf, size_t count) \
2490 + { \
2491 + struct dwc_otg_device *otg_dev = _dev->platform_data; \
2492 + uint32_t set = simple_strtoul(buf, NULL, 16); \
2493 + uint32_t clear = set; \
2494 + clear = ((~clear) << _shift_) & _mask_; \
2495 + set = (set << _shift_) & _mask_; \
2496 + dev_dbg(_dev, \
2497 + "Storing Address=%p Set=0x%08x Clear=0x%08x\n", \
2498 + _addr_, set, clear); \
2499 + dwc_modify_reg32(_addr_, clear, set); \
2500 + return count; \
2501 + }
2502 +
2503 +#define DWC_OTG_DEVICE_ATTR_BITFIELD_RW(_otg_attr_name_, _addr_, \
2504 + _mask_, _shift_, _string_) \
2505 + DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_, _addr_, \
2506 + _mask_, _shift_, _string_) \
2507 + DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_, _addr_, \
2508 + _mask_, _shift_, _string_) \
2509 + DEVICE_ATTR(_otg_attr_name_, 0644, _otg_attr_name_##_show, \
2510 + _otg_attr_name_##_store);
2511 +
2512 +#define DWC_OTG_DEVICE_ATTR_BITFIELD_RO(_otg_attr_name_, _addr_, \
2513 + _mask_, _shift_, _string_) \
2514 + DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_, \
2515 + _addr_, _mask_, _shift_, _string_) \
2516 + DEVICE_ATTR(_otg_attr_name_, 0444, _otg_attr_name_##_show, NULL);
2517 +
2518 +/*
2519 + * MACROs for defining sysfs attribute for 32-bit registers
2520 + */
2521 +#define DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_, _addr_, _string_) \
2522 + static ssize_t _otg_attr_name_##_show(struct device *_dev, \
2523 + struct device_attribute *attr, \
2524 + char *buf) \
2525 + { \
2526 + struct dwc_otg_device *otg_dev = _dev->platform_data; \
2527 + uint32_t val; \
2528 + val = dwc_read_reg32(_addr_); \
2529 + return sprintf(buf, "%s = 0x%08x\n", _string_, val); \
2530 + }
2531 +
2532 +#define DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_, _addr_, _string_) \
2533 + static ssize_t _otg_attr_name_##_store(struct device *_dev, \
2534 + struct device_attribute *attr, \
2535 + const char *buf, size_t count) \
2536 + { \
2537 + struct dwc_otg_device *otg_dev = _dev->platform_data; \
2538 + uint32_t val = simple_strtoul(buf, NULL, 16); \
2539 + dev_dbg(_dev, "Storing Address=%p Val=0x%08x\n", _addr_, val); \
2540 + dwc_write_reg32(_addr_, val); \
2541 + return count; \
2542 + }
2543 +
2544 +#define DWC_OTG_DEVICE_ATTR_REG32_RW(_otg_attr_name_, _addr_, _string_) \
2545 + DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_, _addr_, _string_) \
2546 + DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_, _addr_, _string_) \
2547 + DEVICE_ATTR(_otg_attr_name_, 0644, _otg_attr_name_##_show, \
2548 + _otg_attr_name_##_store);
2549 +
2550 +#define DWC_OTG_DEVICE_ATTR_REG32_RO(_otg_attr_name_, _addr_, _string_) \
2551 + DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_, _addr_, _string_) \
2552 + DEVICE_ATTR(_otg_attr_name_, 0444, _otg_attr_name_##_show, NULL);
2553 +
2554 +/**
2555 + * Show the register offset of the Register Access.
2556 + */
2557 +static ssize_t regoffset_show(struct device *_dev,
2558 + struct device_attribute *attr, char *buf)
2559 +{
2560 + struct dwc_otg_device *otg_dev = _dev->platform_data;
2561 + return snprintf(buf, sizeof("0xFFFFFFFF\n") + 1, "0x%08x\n",
2562 + otg_dev->reg_offset);
2563 +}
2564 +
2565 +/**
2566 + * Set the register offset for the next Register Access Read/Write
2567 + */
2568 +static ssize_t regoffset_store(struct device *_dev,
2569 + struct device_attribute *attr, const char *buf,
2570 + size_t count)
2571 +{
2572 + struct dwc_otg_device *otg_dev = _dev->platform_data;
2573 + uint32_t offset = simple_strtoul(buf, NULL, 16);
2574 +
2575 + if (offset < SZ_256K)
2576 + otg_dev->reg_offset = offset;
2577 + else
2578 + dev_err(_dev, "invalid offset\n");
2579 +
2580 + return count;
2581 +}
2582 +
2583 +DEVICE_ATTR(regoffset, S_IRUGO | S_IWUSR, regoffset_show, regoffset_store);
2584 +
2585 +/**
2586 + * Show the value of the register at the offset in the reg_offset
2587 + * attribute.
2588 + */
2589 +static ssize_t regvalue_show(struct device *_dev, struct device_attribute *attr,
2590 + char *buf)
2591 +{
2592 + struct dwc_otg_device *otg_dev = _dev->platform_data;
2593 + uint32_t val;
2594 + uint32_t *addr;
2595 +
2596 + if (otg_dev->reg_offset != 0xFFFFFFFF && 0 != otg_dev->base) {
2597 + /* Calculate the address */
2598 + addr = (uint32_t *) (otg_dev->reg_offset +
2599 + (uint8_t *) otg_dev->base);
2600 +
2601 + val = dwc_read_reg32(addr);
2602 + return snprintf(buf,
2603 + sizeof("Reg@0xFFFFFFFF = 0xFFFFFFFF\n") + 1,
2604 + "Reg@0x%06x = 0x%08x\n", otg_dev->reg_offset,
2605 + val);
2606 + } else {
2607 + dev_err(_dev, "Invalid offset (0x%0x)\n", otg_dev->reg_offset);
2608 + return sprintf(buf, "invalid offset\n");
2609 + }
2610 +}
2611 +
2612 +/**
2613 + * Store the value in the register at the offset in the reg_offset
2614 + * attribute.
2615 + *
2616 + */
2617 +static ssize_t regvalue_store(struct device *_dev,
2618 + struct device_attribute *attr, const char *buf,
2619 + size_t count)
2620 +{
2621 + struct dwc_otg_device *otg_dev = _dev->platform_data;
2622 + uint32_t *addr;
2623 + uint32_t val = simple_strtoul(buf, NULL, 16);
2624 +
2625 + if (otg_dev->reg_offset != 0xFFFFFFFF && 0 != otg_dev->base) {
2626 + /* Calculate the address */
2627 + addr = (uint32_t *) (otg_dev->reg_offset +
2628 + (uint8_t *) otg_dev->base);
2629 +
2630 + dwc_write_reg32(addr, val);
2631 + } else {
2632 + dev_err(_dev, "Invalid Register Offset (0x%08x)\n",
2633 + otg_dev->reg_offset);
2634 + }
2635 + return count;
2636 +}
2637 +
2638 +DEVICE_ATTR(regvalue, S_IRUGO | S_IWUSR, regvalue_show, regvalue_store);
2639 +
2640 +/*
2641 + * Attributes
2642 + */
2643 +DWC_OTG_DEVICE_ATTR_BITFIELD_RO(mode,
2644 + &(otg_dev->core_if->core_global_regs->gotgctl),
2645 + (1 << 20), 20, "Mode");
2646 +DWC_OTG_DEVICE_ATTR_BITFIELD_RW(hnpcapable,
2647 + &(otg_dev->core_if->core_global_regs->gusbcfg),
2648 + (1 << 9), 9, "Mode");
2649 +DWC_OTG_DEVICE_ATTR_BITFIELD_RW(srpcapable,
2650 + &(otg_dev->core_if->core_global_regs->gusbcfg),
2651 + (1 << 8), 8, "Mode");
2652 +#if 0
2653 +DWC_OTG_DEVICE_ATTR_BITFIELD_RW(buspower, &(otg_dev->core_if->core_global_regs->gotgctl), (1<<8), 8, "Mode");
2654 +DWC_OTG_DEVICE_ATTR_BITFIELD_RW(bussuspend, &(otg_dev->core_if->core_global_regs->gotgctl), (1<<8), 8, "Mode");
2655 +#endif
2656 +DWC_OTG_DEVICE_ATTR_BITFIELD_RO(busconnected, otg_dev->core_if->host_if->hprt0,
2657 + 0x01, 0, "Bus Connected");
2658 +
2659 +DWC_OTG_DEVICE_ATTR_REG32_RW(gotgctl,
2660 + &(otg_dev->core_if->core_global_regs->gotgctl),
2661 + "GOTGCTL");
2662 +DWC_OTG_DEVICE_ATTR_REG32_RW(gusbcfg,
2663 + &(otg_dev->core_if->core_global_regs->gusbcfg),
2664 + "GUSBCFG");
2665 +DWC_OTG_DEVICE_ATTR_REG32_RW(grxfsiz,
2666 + &(otg_dev->core_if->core_global_regs->grxfsiz),
2667 + "GRXFSIZ");
2668 +DWC_OTG_DEVICE_ATTR_REG32_RW(gnptxfsiz,
2669 + &(otg_dev->core_if->core_global_regs->gnptxfsiz),
2670 + "GNPTXFSIZ");
2671 +DWC_OTG_DEVICE_ATTR_REG32_RW(gpvndctl,
2672 + &(otg_dev->core_if->core_global_regs->gpvndctl),
2673 + "GPVNDCTL");
2674 +DWC_OTG_DEVICE_ATTR_REG32_RW(ggpio,
2675 + &(otg_dev->core_if->core_global_regs->ggpio),
2676 + "GGPIO");
2677 +DWC_OTG_DEVICE_ATTR_REG32_RW(guid, &(otg_dev->core_if->core_global_regs->guid),
2678 + "GUID");
2679 +DWC_OTG_DEVICE_ATTR_REG32_RO(gsnpsid,
2680 + &(otg_dev->core_if->core_global_regs->gsnpsid),
2681 + "GSNPSID");
2682 +DWC_OTG_DEVICE_ATTR_BITFIELD_RW(devspeed,
2683 + &(otg_dev->core_if->dev_if->dev_global_regs->
2684 + dcfg), 0x3, 0, "Device Speed");
2685 +DWC_OTG_DEVICE_ATTR_BITFIELD_RO(enumspeed,
2686 + &(otg_dev->core_if->dev_if->dev_global_regs->
2687 + dsts), 0x6, 1, "Device Enumeration Speed");
2688 +
2689 +DWC_OTG_DEVICE_ATTR_REG32_RO(hptxfsiz,
2690 + &(otg_dev->core_if->core_global_regs->hptxfsiz),
2691 + "HPTXFSIZ");
2692 +DWC_OTG_DEVICE_ATTR_REG32_RW(hprt0, otg_dev->core_if->host_if->hprt0, "HPRT0");
2693 +
2694 +/**
2695 + * @todo Add code to initiate the HNP.
2696 + */
2697 +/**
2698 + * Show the HNP status bit
2699 + */
2700 +static ssize_t hnp_show(struct device *_dev, struct device_attribute *attr,
2701 + char *buf)
2702 +{
2703 + struct dwc_otg_device *otg_dev = _dev->platform_data;
2704 + union gotgctl_data val;
2705 + val.d32 =
2706 + dwc_read_reg32(&(otg_dev->core_if->core_global_regs->gotgctl));
2707 + return sprintf(buf, "HstNegScs = 0x%x\n", val.b.hstnegscs);
2708 +}
2709 +
2710 +/**
2711 + * Set the HNP Request bit
2712 + */
2713 +static ssize_t hnp_store(struct device *_dev, struct device_attribute *attr,
2714 + const char *buf, size_t count)
2715 +{
2716 + struct dwc_otg_device *otg_dev = _dev->platform_data;
2717 + uint32_t in = simple_strtoul(buf, NULL, 16);
2718 + uint32_t *addr =
2719 + (uint32_t *) &(otg_dev->core_if->core_global_regs->gotgctl);
2720 + union gotgctl_data mem;
2721 + mem.d32 = dwc_read_reg32(addr);
2722 + mem.b.hnpreq = in;
2723 + dev_dbg(_dev, "Storing Address=%p Data=0x%08x\n", addr, mem.d32);
2724 + dwc_write_reg32(addr, mem.d32);
2725 + return count;
2726 +}
2727 +
2728 +DEVICE_ATTR(hnp, 0644, hnp_show, hnp_store);
2729 +
2730 +/**
2731 + * @todo Add code to initiate the SRP.
2732 + */
2733 +/**
2734 + * Show the SRP status bit
2735 + */
2736 +static ssize_t srp_show(struct device *_dev, struct device_attribute *attr,
2737 + char *buf)
2738 +{
2739 +#ifndef DWC_HOST_ONLY
2740 + struct dwc_otg_device *otg_dev = _dev->platform_data;
2741 + union gotgctl_data val;
2742 + val.d32 =
2743 + dwc_read_reg32(&(otg_dev->core_if->core_global_regs->gotgctl));
2744 + return sprintf(buf, "SesReqScs = 0x%x\n", val.b.sesreqscs);
2745 +#else
2746 + return sprintf(buf, "Host Only Mode!\n");
2747 +#endif
2748 +}
2749 +
2750 +/**
2751 + * Set the SRP Request bit
2752 + */
2753 +static ssize_t srp_store(struct device *_dev, struct device_attribute *attr,
2754 + const char *buf, size_t count)
2755 +{
2756 +#ifndef DWC_HOST_ONLY
2757 + struct dwc_otg_device *otg_dev = _dev->platform_data;
2758 + dwc_otg_pcd_initiate_srp(otg_dev->pcd);
2759 +#endif
2760 + return count;
2761 +}
2762 +
2763 +DEVICE_ATTR(srp, 0644, srp_show, srp_store);
2764 +
2765 +/**
2766 + * @todo Need to do more for power on/off?
2767 + */
2768 +/**
2769 + * Show the Bus Power status
2770 + */
2771 +static ssize_t buspower_show(struct device *_dev, struct device_attribute *attr,
2772 + char *buf)
2773 +{
2774 + struct dwc_otg_device *otg_dev = _dev->platform_data;
2775 + union hprt0_data val;
2776 + val.d32 = dwc_read_reg32(otg_dev->core_if->host_if->hprt0);
2777 + return sprintf(buf, "Bus Power = 0x%x\n", val.b.prtpwr);
2778 +}
2779 +
2780 +/**
2781 + * Set the Bus Power status
2782 + */
2783 +static ssize_t buspower_store(struct device *_dev,
2784 + struct device_attribute *attr, const char *buf,
2785 + size_t count)
2786 +{
2787 + struct dwc_otg_device *otg_dev = _dev->platform_data;
2788 + uint32_t on = simple_strtoul(buf, NULL, 16);
2789 + uint32_t *addr = (uint32_t *) otg_dev->core_if->host_if->hprt0;
2790 + union hprt0_data mem;
2791 +
2792 + mem.d32 = dwc_read_reg32(addr);
2793 + mem.b.prtpwr = on;
2794 +
2795 + dwc_write_reg32(addr, mem.d32);
2796 +
2797 + return count;
2798 +}
2799 +
2800 +DEVICE_ATTR(buspower, 0644, buspower_show, buspower_store);
2801 +
2802 +/**
2803 + * @todo Need to do more for suspend?
2804 + */
2805 +/**
2806 + * Show the Bus Suspend status
2807 + */
2808 +static ssize_t bussuspend_show(struct device *_dev,
2809 + struct device_attribute *attr, char *buf)
2810 +{
2811 + struct dwc_otg_device *otg_dev = _dev->platform_data;
2812 + union hprt0_data val;
2813 + val.d32 = dwc_read_reg32(otg_dev->core_if->host_if->hprt0);
2814 + return sprintf(buf, "Bus Suspend = 0x%x\n", val.b.prtsusp);
2815 +}
2816 +
2817 +/**
2818 + * Set the Bus Suspend status
2819 + */
2820 +static ssize_t bussuspend_store(struct device *_dev,
2821 + struct device_attribute *attr, const char *buf,
2822 + size_t count)
2823 +{
2824 + struct dwc_otg_device *otg_dev = _dev->platform_data;
2825 + uint32_t in = simple_strtoul(buf, NULL, 16);
2826 + uint32_t *addr = (uint32_t *) otg_dev->core_if->host_if->hprt0;
2827 + union hprt0_data mem;
2828 + mem.d32 = dwc_read_reg32(addr);
2829 + mem.b.prtsusp = in;
2830 + dev_dbg(_dev, "Storing Address=%p Data=0x%08x\n", addr, mem.d32);
2831 + dwc_write_reg32(addr, mem.d32);
2832 + return count;
2833 +}
2834 +
2835 +DEVICE_ATTR(bussuspend, 0644, bussuspend_show, bussuspend_store);
2836 +
2837 +/**
2838 + * Show the status of Remote Wakeup.
2839 + */
2840 +static ssize_t remote_wakeup_show(struct device *_dev,
2841 + struct device_attribute *attr, char *buf)
2842 +{
2843 +#ifndef DWC_HOST_ONLY
2844 + struct dwc_otg_device *otg_dev = _dev->platform_data;
2845 + union dctl_data val;
2846 + val.d32 =
2847 + dwc_read_reg32(&otg_dev->core_if->dev_if->dev_global_regs->dctl);
2848 + return sprintf(buf, "Remote Wakeup = %d Enabled = %d\n",
2849 + val.b.rmtwkupsig, otg_dev->pcd->remote_wakeup_enable);
2850 +#else
2851 + return sprintf(buf, "Host Only Mode!\n");
2852 +#endif
2853 +}
2854 +
2855 +/**
2856 + * Initiate a remote wakeup of the host. The Device control register
2857 + * Remote Wakeup Signal bit is written if the PCD Remote wakeup enable
2858 + * flag is set.
2859 + *
2860 + */
2861 +static ssize_t remote_wakeup_store(struct device *_dev,
2862 + struct device_attribute *attr,
2863 + const char *buf, size_t count)
2864 +{
2865 +#ifndef DWC_HOST_ONLY
2866 + uint32_t val = simple_strtoul(buf, NULL, 16);
2867 + struct dwc_otg_device *otg_dev = _dev->platform_data;
2868 + if (val & 1)
2869 + dwc_otg_pcd_remote_wakeup(otg_dev->pcd, 1);
2870 + else
2871 + dwc_otg_pcd_remote_wakeup(otg_dev->pcd, 0);
2872 +#endif
2873 + return count;
2874 +}
2875 +
2876 +DEVICE_ATTR(remote_wakeup, S_IRUGO | S_IWUSR, remote_wakeup_show,
2877 + remote_wakeup_store);
2878 +
2879 +/**
2880 + * Dump global registers and either host or device registers (depending on the
2881 + * current mode of the core).
2882 + */
2883 +static ssize_t regdump_show(struct device *_dev, struct device_attribute *attr,
2884 + char *buf)
2885 +{
2886 + struct dwc_otg_device *otg_dev = _dev->platform_data;
2887 +
2888 + dwc_otg_dump_global_registers(otg_dev->core_if);
2889 + if (dwc_otg_is_host_mode(otg_dev->core_if))
2890 + dwc_otg_dump_host_registers(otg_dev->core_if);
2891 + else
2892 + dwc_otg_dump_dev_registers(otg_dev->core_if);
2893 +
2894 + return sprintf(buf, "Register Dump\n");
2895 +}
2896 +
2897 +DEVICE_ATTR(regdump, S_IRUGO | S_IWUSR, regdump_show, 0);
2898 +
2899 +/**
2900 + * Dump the current hcd state.
2901 + */
2902 +static ssize_t hcddump_show(struct device *_dev, struct device_attribute *attr,
2903 + char *buf)
2904 +{
2905 +#ifndef DWC_DEVICE_ONLY
2906 + struct dwc_otg_device *otg_dev = _dev->platform_data;
2907 + dwc_otg_hcd_dump_state(otg_dev->hcd);
2908 +#endif
2909 + return sprintf(buf, "HCD Dump\n");
2910 +}
2911 +
2912 +DEVICE_ATTR(hcddump, S_IRUGO | S_IWUSR, hcddump_show, 0);
2913 +
2914 +/**
2915 + * Dump the average frame remaining at SOF. This can be used to
2916 + * determine average interrupt latency. Frame remaining is also shown for
2917 + * start transfer and two additional sample points.
2918 + */
2919 +static ssize_t hcd_frrem_show(struct device *_dev,
2920 + struct device_attribute *attr, char *buf)
2921 +{
2922 +#ifndef DWC_DEVICE_ONLY
2923 + struct dwc_otg_device *otg_dev = _dev->platform_data;
2924 + dwc_otg_hcd_dump_frrem(otg_dev->hcd);
2925 +#endif
2926 + return sprintf(buf, "HCD Dump Frame Remaining\n");
2927 +}
2928 +
2929 +DEVICE_ATTR(hcd_frrem, S_IRUGO | S_IWUSR, hcd_frrem_show, 0);
2930 +
2931 +/**
2932 + * Displays the time required to read the GNPTXFSIZ register many times (the
2933 + * output shows the number of times the register is read).
2934 + */
2935 +#define RW_REG_COUNT 10000000
2936 +#define MSEC_PER_JIFFIE (1000/HZ)
2937 +static ssize_t rd_reg_test_show(struct device *_dev,
2938 + struct device_attribute *attr, char *buf)
2939 +{
2940 + int i;
2941 + int time;
2942 + int start_jiffies;
2943 + struct dwc_otg_device *otg_dev = _dev->platform_data;
2944 +
2945 + pr_info("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n",
2946 + HZ, MSEC_PER_JIFFIE, loops_per_jiffy);
2947 + start_jiffies = jiffies;
2948 + for (i = 0; i < RW_REG_COUNT; i++)
2949 + dwc_read_reg32(&otg_dev->core_if->core_global_regs->gnptxfsiz);
2950 +
2951 + time = jiffies - start_jiffies;
2952 + return sprintf(buf,
2953 + "Time to read GNPTXFSIZ reg %d times: %d msecs (%d jiffies)\n",
2954 + RW_REG_COUNT, time * MSEC_PER_JIFFIE, time);
2955 +}
2956 +
2957 +DEVICE_ATTR(rd_reg_test, S_IRUGO | S_IWUSR, rd_reg_test_show, 0);
2958 +
2959 +/**
2960 + * Displays the time required to write the GNPTXFSIZ register many times (the
2961 + * output shows the number of times the register is written).
2962 + */
2963 +static ssize_t wr_reg_test_show(struct device *_dev,
2964 + struct device_attribute *attr, char *buf)
2965 +{
2966 + int i;
2967 + int time;
2968 + int start_jiffies;
2969 + struct dwc_otg_device *otg_dev = _dev->platform_data;
2970 + uint32_t reg_val;
2971 +
2972 + pr_info("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n",
2973 + HZ, MSEC_PER_JIFFIE, loops_per_jiffy);
2974 + reg_val =
2975 + dwc_read_reg32(&otg_dev->core_if->core_global_regs->gnptxfsiz);
2976 + start_jiffies = jiffies;
2977 + for (i = 0; i < RW_REG_COUNT; i++)
2978 + dwc_write_reg32(&otg_dev->core_if->core_global_regs->gnptxfsiz,
2979 + reg_val);
2980 +
2981 + time = jiffies - start_jiffies;
2982 + return sprintf(buf,
2983 + "Time to write GNPTXFSIZ reg %d times: %d msecs (%d jiffies)\n",
2984 + RW_REG_COUNT, time * MSEC_PER_JIFFIE, time);
2985 +}
2986 +
2987 +DEVICE_ATTR(wr_reg_test, S_IRUGO | S_IWUSR, wr_reg_test_show, 0);
2988 +
2989 +/*
2990 + * Create the device files
2991 + */
2992 +void dwc_otg_attr_create(struct device *dev)
2993 +{
2994 + int error;
2995 + error = device_create_file(dev, &dev_attr_regoffset);
2996 + error |= device_create_file(dev, &dev_attr_regvalue);
2997 + error |= device_create_file(dev, &dev_attr_mode);
2998 + error |= device_create_file(dev, &dev_attr_hnpcapable);
2999 + error |= device_create_file(dev, &dev_attr_srpcapable);
3000 + error |= device_create_file(dev, &dev_attr_hnp);
3001 + error |= device_create_file(dev, &dev_attr_srp);
3002 + error |= device_create_file(dev, &dev_attr_buspower);
3003 + error |= device_create_file(dev, &dev_attr_bussuspend);
3004 + error |= device_create_file(dev, &dev_attr_busconnected);
3005 + error |= device_create_file(dev, &dev_attr_gotgctl);
3006 + error |= device_create_file(dev, &dev_attr_gusbcfg);
3007 + error |= device_create_file(dev, &dev_attr_grxfsiz);
3008 + error |= device_create_file(dev, &dev_attr_gnptxfsiz);
3009 + error |= device_create_file(dev, &dev_attr_gpvndctl);
3010 + error |= device_create_file(dev, &dev_attr_ggpio);
3011 + error |= device_create_file(dev, &dev_attr_guid);
3012 + error |= device_create_file(dev, &dev_attr_gsnpsid);
3013 + error |= device_create_file(dev, &dev_attr_devspeed);
3014 + error |= device_create_file(dev, &dev_attr_enumspeed);
3015 + error |= device_create_file(dev, &dev_attr_hptxfsiz);
3016 + error |= device_create_file(dev, &dev_attr_hprt0);
3017 + error |= device_create_file(dev, &dev_attr_remote_wakeup);
3018 + error |= device_create_file(dev, &dev_attr_regdump);
3019 + error |= device_create_file(dev, &dev_attr_hcddump);
3020 + error |= device_create_file(dev, &dev_attr_hcd_frrem);
3021 + error |= device_create_file(dev, &dev_attr_rd_reg_test);
3022 + error |= device_create_file(dev, &dev_attr_wr_reg_test);
3023 + if (error)
3024 + pr_err("DWC_OTG: Creating some device files failed\n");
3025 +}
3026 +
3027 +/*
3028 + * Remove the device files
3029 + */
3030 +void dwc_otg_attr_remove(struct device *dev)
3031 +{
3032 + device_remove_file(dev, &dev_attr_regoffset);
3033 + device_remove_file(dev, &dev_attr_regvalue);
3034 + device_remove_file(dev, &dev_attr_mode);
3035 + device_remove_file(dev, &dev_attr_hnpcapable);
3036 + device_remove_file(dev, &dev_attr_srpcapable);
3037 + device_remove_file(dev, &dev_attr_hnp);
3038 + device_remove_file(dev, &dev_attr_srp);
3039 + device_remove_file(dev, &dev_attr_buspower);
3040 + device_remove_file(dev, &dev_attr_bussuspend);
3041 + device_remove_file(dev, &dev_attr_busconnected);
3042 + device_remove_file(dev, &dev_attr_gotgctl);
3043 + device_remove_file(dev, &dev_attr_gusbcfg);
3044 + device_remove_file(dev, &dev_attr_grxfsiz);
3045 + device_remove_file(dev, &dev_attr_gnptxfsiz);
3046 + device_remove_file(dev, &dev_attr_gpvndctl);
3047 + device_remove_file(dev, &dev_attr_ggpio);
3048 + device_remove_file(dev, &dev_attr_guid);
3049 + device_remove_file(dev, &dev_attr_gsnpsid);
3050 + device_remove_file(dev, &dev_attr_devspeed);
3051 + device_remove_file(dev, &dev_attr_enumspeed);
3052 + device_remove_file(dev, &dev_attr_hptxfsiz);
3053 + device_remove_file(dev, &dev_attr_hprt0);
3054 + device_remove_file(dev, &dev_attr_remote_wakeup);
3055 + device_remove_file(dev, &dev_attr_regdump);
3056 + device_remove_file(dev, &dev_attr_hcddump);
3057 + device_remove_file(dev, &dev_attr_hcd_frrem);
3058 + device_remove_file(dev, &dev_attr_rd_reg_test);
3059 + device_remove_file(dev, &dev_attr_wr_reg_test);
3060 +}
3061 diff --git a/drivers/usb/host/dwc_otg/dwc_otg_attr.h b/drivers/usb/host/dwc_otg/dwc_otg_attr.h
3062 new file mode 100644
3063 index 0000000..925524f
3064 --- /dev/null
3065 +++ b/drivers/usb/host/dwc_otg/dwc_otg_attr.h
3066 @@ -0,0 +1,63 @@
3067 +/* ==========================================================================
3068 + *
3069 + * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
3070 + * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
3071 + * otherwise expressly agreed to in writing between Synopsys and you.
3072 + *
3073 + * The Software IS NOT an item of Licensed Software or Licensed Product under
3074 + * any End User Software License Agreement or Agreement for Licensed Product
3075 + * with Synopsys or any supplement thereto. You are permitted to use and
3076 + * redistribute this Software in source and binary forms, with or without
3077 + * modification, provided that redistributions of source code must retain this
3078 + * notice. You may not view, use, disclose, copy or distribute this file or
3079 + * any information contained herein except pursuant to this license grant from
3080 + * Synopsys. If you do not agree with this notice, including the disclaimer
3081 + * below, then you are not authorized to use the Software.
3082 + *
3083 + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
3084 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
3085 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
3086 + * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
3087 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
3088 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
3089 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
3090 + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3091 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3092 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
3093 + * DAMAGE.
3094 + * ========================================================================== */
3095 +
3096 +#if !defined(__DWC_OTG_ATTR_H__)
3097 +#define __DWC_OTG_ATTR_H__
3098 +
3099 +/*
3100 + * This file contains the interface to the Linux device attributes.
3101 + */
3102 +extern struct device_attribute dev_attr_regoffset;
3103 +extern struct device_attribute dev_attr_regvalue;
3104 +
3105 +extern struct device_attribute dev_attr_mode;
3106 +extern struct device_attribute dev_attr_hnpcapable;
3107 +extern struct device_attribute dev_attr_srpcapable;
3108 +extern struct device_attribute dev_attr_hnp;
3109 +extern struct device_attribute dev_attr_srp;
3110 +extern struct device_attribute dev_attr_buspower;
3111 +extern struct device_attribute dev_attr_bussuspend;
3112 +extern struct device_attribute dev_attr_busconnected;
3113 +extern struct device_attribute dev_attr_gotgctl;
3114 +extern struct device_attribute dev_attr_gusbcfg;
3115 +extern struct device_attribute dev_attr_grxfsiz;
3116 +extern struct device_attribute dev_attr_gnptxfsiz;
3117 +extern struct device_attribute dev_attr_gpvndctl;
3118 +extern struct device_attribute dev_attr_ggpio;
3119 +extern struct device_attribute dev_attr_guid;
3120 +extern struct device_attribute dev_attr_gsnpsid;
3121 +extern struct device_attribute dev_attr_devspeed;
3122 +extern struct device_attribute dev_attr_enumspeed;
3123 +extern struct device_attribute dev_attr_hptxfsiz;
3124 +extern struct device_attribute dev_attr_hprt0;
3125 +
3126 +void dwc_otg_attr_create(struct device *dev);
3127 +void dwc_otg_attr_remove(struct device *dev);
3128 +
3129 +#endif
3130 diff --git a/drivers/usb/host/dwc_otg/dwc_otg_cil.c b/drivers/usb/host/dwc_otg/dwc_otg_cil.c
3131 new file mode 100644
3132 index 0000000..86153ba
3133 --- /dev/null
3134 +++ b/drivers/usb/host/dwc_otg/dwc_otg_cil.c
3135 @@ -0,0 +1,2887 @@
3136 +/* ==========================================================================
3137 + *
3138 + * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
3139 + * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
3140 + * otherwise expressly agreed to in writing between Synopsys and you.
3141 + *
3142 + * The Software IS NOT an item of Licensed Software or Licensed Product under
3143 + * any End User Software License Agreement or Agreement for Licensed Product
3144 + * with Synopsys or any supplement thereto. You are permitted to use and
3145 + * redistribute this Software in source and binary forms, with or without
3146 + * modification, provided that redistributions of source code must retain this
3147 + * notice. You may not view, use, disclose, copy or distribute this file or
3148 + * any information contained herein except pursuant to this license grant from
3149 + * Synopsys. If you do not agree with this notice, including the disclaimer
3150 + * below, then you are not authorized to use the Software.
3151 + *
3152 + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
3153 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
3154 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
3155 + * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
3156 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
3157 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
3158 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
3159 + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3160 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3161 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
3162 + * DAMAGE.
3163 + * ========================================================================== */
3164 +
3165 +/*
3166 + *
3167 + * The Core Interface Layer provides basic services for accessing and
3168 + * managing the DWC_otg hardware. These services are used by both the
3169 + * Host Controller Driver and the Peripheral Controller Driver.
3170 + *
3171 + * The CIL manages the memory map for the core so that the HCD and PCD
3172 + * don't have to do this separately. It also handles basic tasks like
3173 + * reading/writing the registers and data FIFOs in the controller.
3174 + * Some of the data access functions provide encapsulation of several
3175 + * operations required to perform a task, such as writing multiple
3176 + * registers to start a transfer. Finally, the CIL performs basic
3177 + * services that are not specific to either the host or device modes
3178 + * of operation. These services include management of the OTG Host
3179 + * Negotiation Protocol (HNP) and Session Request Protocol (SRP). A
3180 + * Diagnostic API is also provided to allow testing of the controller
3181 + * hardware.
3182 + *
3183 + * The Core Interface Layer has the following requirements:
3184 + * - Provides basic controller operations.
3185 + * - Minimal use of OS services.
3186 + * - The OS services used will be abstracted by using inline functions
3187 + * or macros.
3188 + *
3189 + */
3190 +#include <asm/unaligned.h>
3191 +#ifdef DEBUG
3192 +#include <linux/jiffies.h>
3193 +#endif
3194 +
3195 +#include "dwc_otg_plat.h"
3196 +#include "dwc_otg_regs.h"
3197 +#include "dwc_otg_cil.h"
3198 +
3199 +/**
3200 + * This function is called to initialize the DWC_otg CSR data
3201 + * structures. The register addresses in the device and host
3202 + * structures are initialized from the base address supplied by the
3203 + * caller. The calling function must make the OS calls to get the
3204 + * base address of the DWC_otg controller registers. The core_params
3205 + * argument holds the parameters that specify how the core should be
3206 + * configured.
3207 + *
3208 + * @reg_base_addr: Base address of DWC_otg core registers
3209 + * @core_params: Pointer to the core configuration parameters
3210 + *
3211 + */
3212 +struct dwc_otg_core_if *dwc_otg_cil_init(const uint32_t *reg_base_addr,
3213 + struct dwc_otg_core_params *core_params)
3214 +{
3215 + struct dwc_otg_core_if *core_if = 0;
3216 + struct dwc_otg_dev_if *dev_if = 0;
3217 + struct dwc_otg_host_if *host_if = 0;
3218 + uint8_t *reg_base = (uint8_t *) reg_base_addr;
3219 + int i = 0;
3220 +
3221 + DWC_DEBUGPL(DBG_CILV, "%s(%p,%p)\n", __func__, reg_base_addr,
3222 + core_params);
3223 +
3224 + core_if = kmalloc(sizeof(struct dwc_otg_core_if), GFP_KERNEL);
3225 + if (core_if == 0) {
3226 + DWC_DEBUGPL(DBG_CIL,
3227 + "Allocation of struct dwc_otg_core_if failed\n");
3228 + return 0;
3229 + }
3230 + memset(core_if, 0, sizeof(struct dwc_otg_core_if));
3231 +
3232 + core_if->core_params = core_params;
3233 + core_if->core_global_regs =
3234 + (struct dwc_otg_core_global_regs *)reg_base;
3235 + /*
3236 + * Allocate the Device Mode structures.
3237 + */
3238 + dev_if = kmalloc(sizeof(struct dwc_otg_dev_if), GFP_KERNEL);
3239 + if (dev_if == 0) {
3240 + DWC_DEBUGPL(DBG_CIL, "Allocation of struct dwc_otg_dev_if "
3241 + "failed\n");
3242 + kfree(core_if);
3243 + return 0;
3244 + }
3245 +
3246 + dev_if->dev_global_regs =
3247 + (struct dwc_otg_dev_global_regs *) (reg_base +
3248 + DWC_DEV_GLOBAL_REG_OFFSET);
3249 +
3250 + for (i = 0; i < MAX_EPS_CHANNELS; i++) {
3251 + dev_if->in_ep_regs[i] = (struct dwc_otg_dev_in_ep_regs *)
3252 + (reg_base + DWC_DEV_IN_EP_REG_OFFSET +
3253 + (i * DWC_EP_REG_OFFSET));
3254 +
3255 + dev_if->out_ep_regs[i] = (struct dwc_otg_dev_out_ep_regs *)
3256 + (reg_base + DWC_DEV_OUT_EP_REG_OFFSET +
3257 + (i * DWC_EP_REG_OFFSET));
3258 + DWC_DEBUGPL(DBG_CILV, "in_ep_regs[%d]->diepctl=%p\n",
3259 + i, &dev_if->in_ep_regs[i]->diepctl);
3260 + DWC_DEBUGPL(DBG_CILV, "out_ep_regs[%d]->doepctl=%p\n",
3261 + i, &dev_if->out_ep_regs[i]->doepctl);
3262 + }
3263 + dev_if->speed = 0; /* unknown */
3264 + dev_if->num_eps = MAX_EPS_CHANNELS;
3265 + dev_if->num_perio_eps = 0;
3266 +
3267 + core_if->dev_if = dev_if;
3268 + /*
3269 + * Allocate the Host Mode structures.
3270 + */
3271 + host_if = kmalloc(sizeof(struct dwc_otg_host_if), GFP_KERNEL);
3272 + if (host_if == 0) {
3273 + DWC_DEBUGPL(DBG_CIL,
3274 + "Allocation of struct dwc_otg_host_if failed\n");
3275 + kfree(dev_if);
3276 + kfree(core_if);
3277 + return 0;
3278 + }
3279 +
3280 + host_if->host_global_regs = (struct dwc_otg_host_global_regs *)
3281 + (reg_base + DWC_OTG_HOST_GLOBAL_REG_OFFSET);
3282 + host_if->hprt0 =
3283 + (uint32_t *) (reg_base + DWC_OTG_HOST_PORT_REGS_OFFSET);
3284 + for (i = 0; i < MAX_EPS_CHANNELS; i++) {
3285 + host_if->hc_regs[i] = (struct dwc_otg_hc_regs *)
3286 + (reg_base + DWC_OTG_HOST_CHAN_REGS_OFFSET +
3287 + (i * DWC_OTG_CHAN_REGS_OFFSET));
3288 + DWC_DEBUGPL(DBG_CILV, "hc_reg[%d]->hcchar=%p\n",
3289 + i, &host_if->hc_regs[i]->hcchar);
3290 + }
3291 + host_if->num_host_channels = MAX_EPS_CHANNELS;
3292 + core_if->host_if = host_if;
3293 +
3294 + for (i = 0; i < MAX_EPS_CHANNELS; i++) {
3295 + core_if->data_fifo[i] =
3296 + (uint32_t *) (reg_base + DWC_OTG_DATA_FIFO_OFFSET +
3297 + (i * DWC_OTG_DATA_FIFO_SIZE));
3298 + DWC_DEBUGPL(DBG_CILV, "data_fifo[%d]=%p\n",
3299 + i, core_if->data_fifo[i]);
3300 + }
3301 +
3302 + core_if->pcgcctl = (uint32_t *) (reg_base + DWC_OTG_PCGCCTL_OFFSET);
3303 +
3304 + /*
3305 + * Store the contents of the hardware configuration registers here for
3306 + * easy access later.
3307 + */
3308 + core_if->hwcfg1.d32 =
3309 + dwc_read_reg32(&core_if->core_global_regs->ghwcfg1);
3310 + core_if->hwcfg2.d32 =
3311 + dwc_read_reg32(&core_if->core_global_regs->ghwcfg2);
3312 + core_if->hwcfg3.d32 =
3313 + dwc_read_reg32(&core_if->core_global_regs->ghwcfg3);
3314 + core_if->hwcfg4.d32 =
3315 + dwc_read_reg32(&core_if->core_global_regs->ghwcfg4);
3316 +
3317 + DWC_DEBUGPL(DBG_CILV, "hwcfg1=%08x\n", core_if->hwcfg1.d32);
3318 + DWC_DEBUGPL(DBG_CILV, "hwcfg2=%08x\n", core_if->hwcfg2.d32);
3319 + DWC_DEBUGPL(DBG_CILV, "hwcfg3=%08x\n", core_if->hwcfg3.d32);
3320 + DWC_DEBUGPL(DBG_CILV, "hwcfg4=%08x\n", core_if->hwcfg4.d32);
3321 +
3322 + DWC_DEBUGPL(DBG_CILV, "op_mode=%0x\n", core_if->hwcfg2.b.op_mode);
3323 + DWC_DEBUGPL(DBG_CILV, "arch=%0x\n", core_if->hwcfg2.b.architecture);
3324 + DWC_DEBUGPL(DBG_CILV, "num_dev_ep=%d\n", core_if->hwcfg2.b.num_dev_ep);
3325 + DWC_DEBUGPL(DBG_CILV, "num_host_chan=%d\n",
3326 + core_if->hwcfg2.b.num_host_chan);
3327 + DWC_DEBUGPL(DBG_CILV, "nonperio_tx_q_depth=0x%0x\n",
3328 + core_if->hwcfg2.b.nonperio_tx_q_depth);
3329 + DWC_DEBUGPL(DBG_CILV, "host_perio_tx_q_depth=0x%0x\n",
3330 + core_if->hwcfg2.b.host_perio_tx_q_depth);
3331 + DWC_DEBUGPL(DBG_CILV, "dev_token_q_depth=0x%0x\n",
3332 + core_if->hwcfg2.b.dev_token_q_depth);
3333 +
3334 + DWC_DEBUGPL(DBG_CILV, "Total FIFO SZ=%d\n",
3335 + core_if->hwcfg3.b.dfifo_depth);
3336 + DWC_DEBUGPL(DBG_CILV, "xfer_size_cntr_width=%0x\n",
3337 + core_if->hwcfg3.b.xfer_size_cntr_width);
3338 +
3339 + /*
3340 + * Set the SRP sucess bit for FS-I2c
3341 + */
3342 + core_if->srp_success = 0;
3343 + core_if->srp_timer_started = 0;
3344 +
3345 + return core_if;
3346 +}
3347 +
3348 +/**
3349 + * This function frees the structures allocated by dwc_otg_cil_init().
3350 + *
3351 + * @core_if: The core interface pointer returned from
3352 + * dwc_otg_cil_init().
3353 + *
3354 + */
3355 +void dwc_otg_cil_remove(struct dwc_otg_core_if *core_if)
3356 +{
3357 + /* Disable all interrupts */
3358 + dwc_modify_reg32(&core_if->core_global_regs->gahbcfg, 1, 0);
3359 + dwc_write_reg32(&core_if->core_global_regs->gintmsk, 0);
3360 +
3361 + kfree(core_if->dev_if);
3362 + kfree(core_if->host_if);
3363 +
3364 + kfree(core_if);
3365 +}
3366 +
3367 +/**
3368 + * This function enables the controller's Global Interrupt in the AHB Config
3369 + * register.
3370 + *
3371 + * @core_if: Programming view of DWC_otg controller.
3372 + */
3373 +extern void dwc_otg_enable_global_interrupts(struct dwc_otg_core_if *core_if)
3374 +{
3375 + union gahbcfg_data ahbcfg = {.d32 = 0 };
3376 + ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */
3377 + dwc_modify_reg32(&core_if->core_global_regs->gahbcfg, 0, ahbcfg.d32);
3378 +}
3379 +
3380 +/**
3381 + * This function disables the controller's Global Interrupt in the AHB Config
3382 + * register.
3383 + *
3384 + * @core_if: Programming view of DWC_otg controller.
3385 + */
3386 +extern void dwc_otg_disable_global_interrupts(struct dwc_otg_core_if *core_if)
3387 +{
3388 + union gahbcfg_data ahbcfg = {.d32 = 0 };
3389 + ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */
3390 + dwc_modify_reg32(&core_if->core_global_regs->gahbcfg, ahbcfg.d32, 0);
3391 +}
3392 +
3393 +/**
3394 + * This function initializes the commmon interrupts, used in both
3395 + * device and host modes.
3396 + *
3397 + * @core_if: Programming view of the DWC_otg controller
3398 + *
3399 + */
3400 +static void dwc_otg_enable_common_interrupts(struct dwc_otg_core_if *core_if)
3401 +{
3402 + struct dwc_otg_core_global_regs *global_regs =
3403 + core_if->core_global_regs;
3404 + union gintmsk_data intr_mask = {.d32 = 0 };
3405 + /* Clear any pending OTG Interrupts */
3406 + dwc_write_reg32(&global_regs->gotgint, 0xFFFFFFFF);
3407 + /* Clear any pending interrupts */
3408 + dwc_write_reg32(&global_regs->gintsts, 0xFFFFFFFF);
3409 + /*
3410 + * Enable the interrupts in the GINTMSK.
3411 + */
3412 + intr_mask.b.modemismatch = 1;
3413 + intr_mask.b.otgintr = 1;
3414 + if (!core_if->dma_enable)
3415 + intr_mask.b.rxstsqlvl = 1;
3416 +
3417 + intr_mask.b.conidstschng = 1;
3418 + intr_mask.b.wkupintr = 1;
3419 + intr_mask.b.disconnect = 1;
3420 + intr_mask.b.usbsuspend = 1;
3421 + intr_mask.b.sessreqintr = 1;
3422 + dwc_write_reg32(&global_regs->gintmsk, intr_mask.d32);
3423 +}
3424 +
3425 +/**
3426 + * Initializes the FSLSPClkSel field of the HCFG register depending on the PHY
3427 + * type.
3428 + */
3429 +static void init_fslspclksel(struct dwc_otg_core_if *core_if)
3430 +{
3431 + uint32_t val;
3432 + union hcfg_data hcfg;
3433 +
3434 + if (((core_if->hwcfg2.b.hs_phy_type == 2) &&
3435 + (core_if->hwcfg2.b.fs_phy_type == 1) &&
3436 + (core_if->core_params->ulpi_fs_ls)) ||
3437 + (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
3438 + /* Full speed PHY */
3439 + val = DWC_HCFG_48_MHZ;
3440 + } else {
3441 + /* High speed PHY running at full speed or high speed */
3442 + val = DWC_HCFG_30_60_MHZ;
3443 + }
3444 +
3445 + DWC_DEBUGPL(DBG_CIL, "Initializing HCFG.FSLSPClkSel to 0x%1x\n", val);
3446 + hcfg.d32 = dwc_read_reg32(&core_if->host_if->host_global_regs->hcfg);
3447 + hcfg.b.fslspclksel = val;
3448 + dwc_write_reg32(&core_if->host_if->host_global_regs->hcfg, hcfg.d32);
3449 +}
3450 +
3451 +/**
3452 + * Initializes the DevSpd field of the DCFG register depending on the PHY type
3453 + * and the enumeration speed of the device.
3454 + */
3455 +static void init_devspd(struct dwc_otg_core_if *core_if)
3456 +{
3457 + uint32_t val;
3458 + union dcfg_data dcfg;
3459 +
3460 + if (((core_if->hwcfg2.b.hs_phy_type == 2) &&
3461 + (core_if->hwcfg2.b.fs_phy_type == 1) &&
3462 + (core_if->core_params->ulpi_fs_ls)) ||
3463 + (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
3464 + /* Full speed PHY */
3465 + val = 0x3;
3466 + } else if (core_if->core_params->speed == DWC_SPEED_PARAM_FULL) {
3467 + /* High speed PHY running at full speed */
3468 + val = 0x1;
3469 + } else {
3470 + /* High speed PHY running at high speed */
3471 + val = 0x0;
3472 + }
3473 +
3474 + DWC_DEBUGPL(DBG_CIL, "Initializing DCFG.DevSpd to 0x%1x\n", val);
3475 + dcfg.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dcfg);
3476 + dcfg.b.devspd = val;
3477 + dwc_write_reg32(&core_if->dev_if->dev_global_regs->dcfg, dcfg.d32);
3478 +}
3479 +
3480 +/**
3481 + * This function initializes the DWC_otg controller registers and
3482 + * prepares the core for device mode or host mode operation.
3483 + *
3484 + * @core_if: Programming view of the DWC_otg controller
3485 + *
3486 + */
3487 +void dwc_otg_core_init(struct dwc_otg_core_if *core_if)
3488 +{
3489 + struct dwc_otg_core_global_regs *global_regs = core_if->core_global_regs;
3490 + struct dwc_otg_dev_if *dev_if = core_if->dev_if;
3491 + int i = 0;
3492 + union gahbcfg_data ahbcfg = {.d32 = 0 };
3493 + union gusbcfg_data usbcfg = {.d32 = 0 };
3494 + union gi2cctl_data i2cctl = {.d32 = 0 };
3495 +
3496 + DWC_DEBUGPL(DBG_CILV, "dwc_otg_core_init(%p)\n", core_if);
3497 +
3498 + /* Common Initialization */
3499 +
3500 + usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
3501 +
3502 + /* Program the ULPI External VBUS bit if needed */
3503 + usbcfg.b.ulpi_ext_vbus_drv =
3504 + (core_if->core_params->phy_ulpi_ext_vbus ==
3505 + DWC_PHY_ULPI_EXTERNAL_VBUS) ? 1 : 0;
3506 +
3507 + /* Set external TS Dline pulsing */
3508 + usbcfg.b.term_sel_dl_pulse =
3509 + (core_if->core_params->ts_dline == 1) ? 1 : 0;
3510 + dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
3511 +
3512 + /* Reset the Controller */
3513 + dwc_otg_core_reset(core_if);
3514 +
3515 + /* Initialize parameters from Hardware configuration registers. */
3516 + dev_if->num_eps = core_if->hwcfg2.b.num_dev_ep;
3517 + dev_if->num_perio_eps = core_if->hwcfg4.b.num_dev_perio_in_ep;
3518 +
3519 + DWC_DEBUGPL(DBG_CIL, "num_dev_perio_in_ep=%d\n",
3520 + core_if->hwcfg4.b.num_dev_perio_in_ep);
3521 + for (i = 0; i < core_if->hwcfg4.b.num_dev_perio_in_ep; i++) {
3522 + dev_if->perio_tx_fifo_size[i] =
3523 + dwc_read_reg32(&global_regs->dptxfsiz[i]) >> 16;
3524 + DWC_DEBUGPL(DBG_CIL, "Periodic Tx FIFO SZ #%d=0x%0x\n",
3525 + i, dev_if->perio_tx_fifo_size[i]);
3526 + }
3527 +
3528 + core_if->total_fifo_size = core_if->hwcfg3.b.dfifo_depth;
3529 + core_if->rx_fifo_size = dwc_read_reg32(&global_regs->grxfsiz);
3530 + core_if->nperio_tx_fifo_size =
3531 + dwc_read_reg32(&global_regs->gnptxfsiz) >> 16;
3532 +
3533 + DWC_DEBUGPL(DBG_CIL, "Total FIFO SZ=%d\n", core_if->total_fifo_size);
3534 + DWC_DEBUGPL(DBG_CIL, "Rx FIFO SZ=%d\n", core_if->rx_fifo_size);
3535 + DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO SZ=%d\n",
3536 + core_if->nperio_tx_fifo_size);
3537 +
3538 + /* This programming sequence needs to happen in FS mode before any other
3539 + * programming occurs */
3540 + if ((core_if->core_params->speed == DWC_SPEED_PARAM_FULL) &&
3541 + (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
3542 + /* If FS mode with FS PHY */
3543 +
3544 + /* core_init() is now called on every switch so only call the
3545 + * following for the first time through. */
3546 + if (!core_if->phy_init_done) {
3547 + core_if->phy_init_done = 1;
3548 + DWC_DEBUGPL(DBG_CIL, "FS_PHY detected\n");
3549 + usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
3550 + usbcfg.b.physel = 1;
3551 + dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
3552 +
3553 + /* Reset after a PHY select */
3554 + dwc_otg_core_reset(core_if);
3555 + }
3556 +
3557 + /* Program DCFG.DevSpd or HCFG.FSLSPclkSel to 48Mhz in FS. Also
3558 + * do this on HNP Dev/Host mode switches (done in dev_init and
3559 + * host_init). */
3560 + if (dwc_otg_is_host_mode(core_if))
3561 + init_fslspclksel(core_if);
3562 + else
3563 + init_devspd(core_if);
3564 +
3565 + if (core_if->core_params->i2c_enable) {
3566 + DWC_DEBUGPL(DBG_CIL, "FS_PHY Enabling I2c\n");
3567 + /* Program GUSBCFG.OtgUtmifsSel to I2C */
3568 + usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
3569 + usbcfg.b.otgutmifssel = 1;
3570 + dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
3571 +
3572 + /* Program GI2CCTL.I2CEn */
3573 + i2cctl.d32 = dwc_read_reg32(&global_regs->gi2cctl);
3574 + i2cctl.b.i2cdevaddr = 1;
3575 + i2cctl.b.i2cen = 0;
3576 + dwc_write_reg32(&global_regs->gi2cctl, i2cctl.d32);
3577 + i2cctl.b.i2cen = 1;
3578 + dwc_write_reg32(&global_regs->gi2cctl, i2cctl.d32);
3579 + }
3580 +
3581 + }
3582 + /* endif speed == DWC_SPEED_PARAM_FULL */
3583 + else {
3584 + /* High speed PHY. */
3585 + if (!core_if->phy_init_done) {
3586 + core_if->phy_init_done = 1;
3587 + /* HS PHY parameters. These parameters are preserved
3588 + * during soft reset so only program the first time. Do
3589 + * a soft reset immediately after setting phyif. */
3590 + usbcfg.b.ulpi_utmi_sel =
3591 + (core_if->core_params->phy_type ==
3592 + DWC_PHY_TYPE_PARAM_ULPI);
3593 + if (usbcfg.b.ulpi_utmi_sel == 1) {
3594 + /* ULPI interface */
3595 + usbcfg.b.phyif = 0;
3596 + usbcfg.b.ddrsel =
3597 + core_if->core_params->phy_ulpi_ddr;
3598 + } else {
3599 + /* UTMI+ interface */
3600 + if (core_if->core_params->phy_utmi_width == 16)
3601 + usbcfg.b.phyif = 1;
3602 + else
3603 + usbcfg.b.phyif = 0;
3604 + }
3605 + dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
3606 +
3607 + /* Reset after setting the PHY parameters */
3608 + dwc_otg_core_reset(core_if);
3609 + }
3610 + }
3611 +
3612 + if ((core_if->hwcfg2.b.hs_phy_type == 2) &&
3613 + (core_if->hwcfg2.b.fs_phy_type == 1) &&
3614 + (core_if->core_params->ulpi_fs_ls)) {
3615 + DWC_DEBUGPL(DBG_CIL, "Setting ULPI FSLS\n");
3616 + usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
3617 + usbcfg.b.ulpi_fsls = 1;
3618 + usbcfg.b.ulpi_clk_sus_m = 1;
3619 + dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
3620 + } else {
3621 + usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
3622 + usbcfg.b.ulpi_fsls = 0;
3623 + usbcfg.b.ulpi_clk_sus_m = 0;
3624 + dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
3625 + }
3626 +
3627 + /* Program the GAHBCFG Register. */
3628 + switch (core_if->hwcfg2.b.architecture) {
3629 +
3630 + case DWC_SLAVE_ONLY_ARCH:
3631 + DWC_DEBUGPL(DBG_CIL, "Slave Only Mode\n");
3632 + ahbcfg.b.nptxfemplvl = DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
3633 + ahbcfg.b.ptxfemplvl = DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
3634 + core_if->dma_enable = 0;
3635 + break;
3636 +
3637 + case DWC_EXT_DMA_ARCH:
3638 + DWC_DEBUGPL(DBG_CIL, "External DMA Mode\n");
3639 + ahbcfg.b.hburstlen = core_if->core_params->dma_burst_size;
3640 + core_if->dma_enable = (core_if->core_params->dma_enable != 0);
3641 + break;
3642 +
3643 + case DWC_INT_DMA_ARCH:
3644 + DWC_DEBUGPL(DBG_CIL, "Internal DMA Mode\n");
3645 + ahbcfg.b.hburstlen = DWC_GAHBCFG_INT_DMA_BURST_INCR;
3646 + core_if->dma_enable = (core_if->core_params->dma_enable != 0);
3647 + break;
3648 +
3649 + }
3650 + ahbcfg.b.dmaenable = core_if->dma_enable;
3651 + dwc_write_reg32(&global_regs->gahbcfg, ahbcfg.d32);
3652 +
3653 + /*
3654 + * Program the GUSBCFG register.
3655 + */
3656 + usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
3657 +
3658 + switch (core_if->hwcfg2.b.op_mode) {
3659 + case DWC_MODE_HNP_SRP_CAPABLE:
3660 + usbcfg.b.hnpcap = (core_if->core_params->otg_cap ==
3661 + DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE);
3662 + usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
3663 + DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
3664 + break;
3665 +
3666 + case DWC_MODE_SRP_ONLY_CAPABLE:
3667 + usbcfg.b.hnpcap = 0;
3668 + usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
3669 + DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
3670 + break;
3671 +
3672 + case DWC_MODE_NO_HNP_SRP_CAPABLE:
3673 + usbcfg.b.hnpcap = 0;
3674 + usbcfg.b.srpcap = 0;
3675 + break;
3676 +
3677 + case DWC_MODE_SRP_CAPABLE_DEVICE:
3678 + usbcfg.b.hnpcap = 0;
3679 + usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
3680 + DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
3681 + break;
3682 +
3683 + case DWC_MODE_NO_SRP_CAPABLE_DEVICE:
3684 + usbcfg.b.hnpcap = 0;
3685 + usbcfg.b.srpcap = 0;
3686 + break;
3687 +
3688 + case DWC_MODE_SRP_CAPABLE_HOST:
3689 + usbcfg.b.hnpcap = 0;
3690 + usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
3691 + DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
3692 + break;
3693 +
3694 + case DWC_MODE_NO_SRP_CAPABLE_HOST:
3695 + usbcfg.b.hnpcap = 0;
3696 + usbcfg.b.srpcap = 0;
3697 + break;
3698 + }
3699 +
3700 + dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
3701 +
3702 + /* Enable common interrupts */
3703 + dwc_otg_enable_common_interrupts(core_if);
3704 +
3705 + /* Do device or host intialization based on mode during PCD
3706 + * and HCD initialization */
3707 + if (dwc_otg_is_host_mode(core_if)) {
3708 + DWC_DEBUGPL(DBG_ANY, "Host Mode\n");
3709 + core_if->op_state = A_HOST;
3710 + } else {
3711 + DWC_DEBUGPL(DBG_ANY, "Device Mode\n");
3712 + core_if->op_state = B_PERIPHERAL;
3713 +#ifdef DWC_DEVICE_ONLY
3714 + dwc_otg_core_dev_init(core_if);
3715 +#endif
3716 + }
3717 +}
3718 +
3719 +/**
3720 + * This function enables the Device mode interrupts.
3721 + *
3722 + * @core_if: Programming view of DWC_otg controller
3723 + */
3724 +void dwc_otg_enable_device_interrupts(struct dwc_otg_core_if *core_if)
3725 +{
3726 + union gintmsk_data intr_mask = {.d32 = 0 };
3727 + struct dwc_otg_core_global_regs *global_regs = core_if->core_global_regs;
3728 +
3729 + DWC_DEBUGPL(DBG_CIL, "%s()\n", __func__);
3730 +
3731 + /* Disable all interrupts. */
3732 + dwc_write_reg32(&global_regs->gintmsk, 0);
3733 +
3734 + /* Clear any pending interrupts */
3735 + dwc_write_reg32(&global_regs->gintsts, 0xFFFFFFFF);
3736 +
3737 + /* Enable the common interrupts */
3738 + dwc_otg_enable_common_interrupts(core_if);
3739 +
3740 + /* Enable interrupts */
3741 + intr_mask.b.usbreset = 1;
3742 + intr_mask.b.enumdone = 1;
3743 + intr_mask.b.epmismatch = 1;
3744 + intr_mask.b.inepintr = 1;
3745 + intr_mask.b.outepintr = 1;
3746 + intr_mask.b.erlysuspend = 1;
3747 +
3748 +#ifdef USE_PERIODIC_EP
3749 + /** @todo NGS: Should this be a module parameter? */
3750 + intr_mask.b.isooutdrop = 1;
3751 + intr_mask.b.eopframe = 1;
3752 + intr_mask.b.incomplisoin = 1;
3753 + intr_mask.b.incomplisoout = 1;
3754 +#endif
3755 + dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
3756 +
3757 + DWC_DEBUGPL(DBG_CIL, "%s() gintmsk=%0x\n", __func__,
3758 + dwc_read_reg32(&global_regs->gintmsk));
3759 +}
3760 +
3761 +/**
3762 + * This function initializes the DWC_otg controller registers for
3763 + * device mode.
3764 + *
3765 + * @core_if: Programming view of DWC_otg controller
3766 + *
3767 + */
3768 +void dwc_otg_core_dev_init(struct dwc_otg_core_if *core_if)
3769 +{
3770 + struct dwc_otg_core_global_regs *global_regs = core_if->core_global_regs;
3771 + struct dwc_otg_dev_if *dev_if = core_if->dev_if;
3772 + struct dwc_otg_core_params *params = core_if->core_params;
3773 + union dcfg_data dcfg = {.d32 = 0 };
3774 + union grstctl_data resetctl = {.d32 = 0 };
3775 + int i;
3776 + uint32_t rx_fifo_size;
3777 + union fifosize_data nptxfifosize;
3778 +#ifdef USE_PERIODIC_EP
3779 + union fifosize_data ptxfifosize;
3780 +#endif
3781 +
3782 + /* Restart the Phy Clock */
3783 + dwc_write_reg32(core_if->pcgcctl, 0);
3784 +
3785 + /* Device configuration register */
3786 + init_devspd(core_if);
3787 + dcfg.d32 = dwc_read_reg32(&dev_if->dev_global_regs->dcfg);
3788 + dcfg.b.perfrint = DWC_DCFG_FRAME_INTERVAL_80;
3789 + dwc_write_reg32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
3790 +
3791 + /* Configure data FIFO sizes */
3792 + if (core_if->hwcfg2.b.dynamic_fifo && params->enable_dynamic_fifo) {
3793 +
3794 + DWC_DEBUGPL(DBG_CIL, "Total FIFO Size=%d\n",
3795 + core_if->total_fifo_size);
3796 + DWC_DEBUGPL(DBG_CIL, "Rx FIFO Size=%d\n",
3797 + params->dev_rx_fifo_size);
3798 + DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO Size=%d\n",
3799 + params->dev_nperio_tx_fifo_size);
3800 +
3801 + /* Rx FIFO */
3802 + DWC_DEBUGPL(DBG_CIL, "initial grxfsiz=%08x\n",
3803 + dwc_read_reg32(&global_regs->grxfsiz));
3804 + rx_fifo_size = params->dev_rx_fifo_size;
3805 + dwc_write_reg32(&global_regs->grxfsiz, rx_fifo_size);
3806 + DWC_DEBUGPL(DBG_CIL, "new grxfsiz=%08x\n",
3807 + dwc_read_reg32(&global_regs->grxfsiz));
3808 +
3809 + /* Non-periodic Tx FIFO */
3810 + DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n",
3811 + dwc_read_reg32(&global_regs->gnptxfsiz));
3812 + nptxfifosize.b.depth = params->dev_nperio_tx_fifo_size;
3813 + nptxfifosize.b.startaddr = params->dev_rx_fifo_size;
3814 + dwc_write_reg32(&global_regs->gnptxfsiz, nptxfifosize.d32);
3815 + DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",
3816 + dwc_read_reg32(&global_regs->gnptxfsiz));
3817 +
3818 +#ifdef USE_PERIODIC_EP
3819 + /**@todo NGS: Fix Periodic FIFO Sizing! */
3820 + /*
3821 + * Periodic Tx FIFOs These FIFOs are numbered from 1 to 15.
3822 + * Indexes of the FIFO size module parameters in the
3823 + * dev_perio_tx_fifo_size array and the FIFO size registers in
3824 + * the dptxfsiz array run from 0 to 14.
3825 + */
3826 + /** @todo Finish debug of this */
3827 + ptxfifosize.b.startaddr =
3828 + nptxfifosize.b.startaddr + nptxfifosize.b.depth;
3829 + for (i = 0; i < dev_if->num_perio_eps; i++) {
3830 + ptxfifosize.b.depth = params->dev_perio_tx_fifo_size[i];
3831 + DWC_DEBUGPL(DBG_CIL, "initial dptxfsiz[%d]=%08x\n", i,
3832 + dwc_read_reg32(&global_regs->dptxfsiz[i]));
3833 + dwc_write_reg32(&global_regs->dptxfsiz[i],
3834 + ptxfifosize.d32);
3835 + DWC_DEBUGPL(DBG_CIL, "new dptxfsiz[%d]=%08x\n", i,
3836 + dwc_read_reg32(&global_regs->dptxfsiz[i]));
3837 + ptxfifosize.b.startaddr += ptxfifosize.b.depth;
3838 + }
3839 +#endif
3840 + }
3841 + /* Flush the FIFOs */
3842 + dwc_otg_flush_tx_fifo(core_if, 0x10); /* all Tx FIFOs */
3843 + dwc_otg_flush_rx_fifo(core_if);
3844 +
3845 + /* Flush the Learning Queue. */
3846 + resetctl.b.intknqflsh = 1;
3847 + dwc_write_reg32(&core_if->core_global_regs->grstctl, resetctl.d32);
3848 +
3849 + /* Clear all pending Device Interrupts */
3850 + dwc_write_reg32(&dev_if->dev_global_regs->diepmsk, 0);
3851 + dwc_write_reg32(&dev_if->dev_global_regs->doepmsk, 0);
3852 + dwc_write_reg32(&dev_if->dev_global_regs->daint, 0xFFFFFFFF);
3853 + dwc_write_reg32(&dev_if->dev_global_regs->daintmsk, 0);
3854 +
3855 + for (i = 0; i < dev_if->num_eps; i++) {
3856 + union depctl_data depctl;
3857 + depctl.d32 = dwc_read_reg32(&dev_if->in_ep_regs[i]->diepctl);
3858 + if (depctl.b.epena) {
3859 + depctl.d32 = 0;
3860 + depctl.b.epdis = 1;
3861 + depctl.b.snak = 1;
3862 + } else {
3863 + depctl.d32 = 0;
3864 + }
3865 + dwc_write_reg32(&dev_if->in_ep_regs[i]->diepctl, depctl.d32);
3866 +
3867 + depctl.d32 = dwc_read_reg32(&dev_if->out_ep_regs[i]->doepctl);
3868 + if (depctl.b.epena) {
3869 + depctl.d32 = 0;
3870 + depctl.b.epdis = 1;
3871 + depctl.b.snak = 1;
3872 + } else {
3873 + depctl.d32 = 0;
3874 + }
3875 + dwc_write_reg32(&dev_if->out_ep_regs[i]->doepctl, depctl.d32);
3876 +
3877 + dwc_write_reg32(&dev_if->in_ep_regs[i]->dieptsiz, 0);
3878 + dwc_write_reg32(&dev_if->out_ep_regs[i]->doeptsiz, 0);
3879 + dwc_write_reg32(&dev_if->in_ep_regs[i]->diepdma, 0);
3880 + dwc_write_reg32(&dev_if->out_ep_regs[i]->doepdma, 0);
3881 + dwc_write_reg32(&dev_if->in_ep_regs[i]->diepint, 0xFF);
3882 + dwc_write_reg32(&dev_if->out_ep_regs[i]->doepint, 0xFF);
3883 + }
3884 +
3885 + dwc_otg_enable_device_interrupts(core_if);
3886 +}
3887 +
3888 +/**
3889 + * This function enables the Host mode interrupts.
3890 + *
3891 + * @core_if: Programming view of DWC_otg controller
3892 + */
3893 +void dwc_otg_enable_host_interrupts(struct dwc_otg_core_if *core_if)
3894 +{
3895 + struct dwc_otg_core_global_regs *global_regs = core_if->core_global_regs;
3896 + union gintmsk_data intr_mask = {.d32 = 0 };
3897 +
3898 + DWC_DEBUGPL(DBG_CIL, "%s()\n", __func__);
3899 +
3900 + /* Disable all interrupts. */
3901 + dwc_write_reg32(&global_regs->gintmsk, 0);
3902 +
3903 + /* Clear any pending interrupts. */
3904 + dwc_write_reg32(&global_regs->gintsts, 0xFFFFFFFF);
3905 +
3906 + /* Enable the common interrupts */
3907 + dwc_otg_enable_common_interrupts(core_if);
3908 +
3909 + /*
3910 + * Enable host mode interrupts without disturbing common
3911 + * interrupts.
3912 + */
3913 + intr_mask.b.sofintr = 1;
3914 + intr_mask.b.portintr = 1;
3915 + intr_mask.b.hcintr = 1;
3916 +
3917 + dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
3918 +}
3919 +
3920 +/**
3921 + * This function disables the Host Mode interrupts.
3922 + *
3923 + * @core_if: Programming view of DWC_otg controller
3924 + */
3925 +void dwc_otg_disable_host_interrupts(struct dwc_otg_core_if *core_if)
3926 +{
3927 + struct dwc_otg_core_global_regs *global_regs = core_if->core_global_regs;
3928 + union gintmsk_data intr_mask = {.d32 = 0 };
3929 +
3930 + DWC_DEBUGPL(DBG_CILV, "%s()\n", __func__);
3931 +
3932 + /*
3933 + * Disable host mode interrupts without disturbing common
3934 + * interrupts.
3935 + */
3936 + intr_mask.b.sofintr = 1;
3937 + intr_mask.b.portintr = 1;
3938 + intr_mask.b.hcintr = 1;
3939 + intr_mask.b.ptxfempty = 1;
3940 + intr_mask.b.nptxfempty = 1;
3941 +
3942 + dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, 0);
3943 +}
3944 +
3945 +/**
3946 + * The FIFOs are established based on a default percentage of the
3947 + * total FIFO depth. This function converts the percentage into the
3948 + * proper setting.
3949 + *
3950 + */
3951 +static inline uint32_t fifo_percentage(uint16_t total_fifo_size,
3952 + int32_t percentage)
3953 +{
3954 + /* 16-byte aligned */
3955 + return ((total_fifo_size * percentage) / 100) & (-1 << 3);
3956 +}
3957 +
3958 +/**
3959 + * This function initializes the DWC_otg controller registers for
3960 + * host mode.
3961 + *
3962 + * This function flushes the Tx and Rx FIFOs and it flushes any entries in the
3963 + * request queues. Host channels are reset to ensure that they are ready for
3964 + * performing transfers.
3965 + *
3966 + * @core_if: Programming view of DWC_otg controller
3967 + *
3968 + */
3969 +void dwc_otg_core_host_init(struct dwc_otg_core_if *core_if)
3970 +{
3971 + struct dwc_otg_core_global_regs *global_regs = core_if->core_global_regs;
3972 + struct dwc_otg_host_if *host_if = core_if->host_if;
3973 + struct dwc_otg_core_params *params = core_if->core_params;
3974 + union hprt0_data hprt0 = {.d32 = 0 };
3975 + union fifosize_data nptxfifosize;
3976 + union fifosize_data ptxfifosize;
3977 + int i;
3978 + union hcchar_data hcchar;
3979 + union hcfg_data hcfg;
3980 + struct dwc_otg_hc_regs *hc_regs;
3981 + int num_channels;
3982 + union gotgctl_data gotgctl = {.d32 = 0 };
3983 +
3984 + DWC_DEBUGPL(DBG_CILV, "%s(%p)\n", __func__, core_if);
3985 +
3986 + /* Restart the Phy Clock */
3987 + dwc_write_reg32(core_if->pcgcctl, 0);
3988 +
3989 + /* Initialize Host Configuration Register */
3990 + init_fslspclksel(core_if);
3991 + if (core_if->core_params->speed == DWC_SPEED_PARAM_FULL) {
3992 + hcfg.d32 = dwc_read_reg32(&host_if->host_global_regs->hcfg);
3993 + hcfg.b.fslssupp = 1;
3994 + dwc_write_reg32(&host_if->host_global_regs->hcfg, hcfg.d32);
3995 + }
3996 +
3997 + /* Configure data FIFO sizes */
3998 + if (core_if->hwcfg2.b.dynamic_fifo && params->enable_dynamic_fifo) {
3999 + DWC_DEBUGPL(DBG_CIL, "Total FIFO Size=%d\n",
4000 + core_if->total_fifo_size);
4001 + DWC_DEBUGPL(DBG_CIL, "Rx FIFO Size=%d\n",
4002 + params->host_rx_fifo_size);
4003 + DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO Size=%d\n",
4004 + params->host_nperio_tx_fifo_size);
4005 + DWC_DEBUGPL(DBG_CIL, "P Tx FIFO Size=%d\n",
4006 + params->host_perio_tx_fifo_size);
4007 +
4008 + /* Rx FIFO */
4009 + DWC_DEBUGPL(DBG_CIL, "initial grxfsiz=%08x\n",
4010 + dwc_read_reg32(&global_regs->grxfsiz));
4011 + dwc_write_reg32(&global_regs->grxfsiz,
4012 + fifo_percentage(core_if->total_fifo_size,
4013 + dwc_param_host_rx_fifo_size_percentage));
4014 + DWC_DEBUGPL(DBG_CIL, "new grxfsiz=%08x\n",
4015 + dwc_read_reg32(&global_regs->grxfsiz));
4016 +
4017 + /* Non-periodic Tx FIFO */
4018 + DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n",
4019 + dwc_read_reg32(&global_regs->gnptxfsiz));
4020 + nptxfifosize.b.depth =
4021 + fifo_percentage(core_if->total_fifo_size,
4022 + dwc_param_host_nperio_tx_fifo_size_percentage);
4023 + nptxfifosize.b.startaddr =
4024 + dwc_read_reg32(&global_regs->grxfsiz);
4025 + dwc_write_reg32(&global_regs->gnptxfsiz, nptxfifosize.d32);
4026 + DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",
4027 + dwc_read_reg32(&global_regs->gnptxfsiz));
4028 +
4029 + /* Periodic Tx FIFO */
4030 + DWC_DEBUGPL(DBG_CIL, "initial hptxfsiz=%08x\n",
4031 + dwc_read_reg32(&global_regs->hptxfsiz));
4032 + ptxfifosize.b.depth =
4033 + core_if->total_fifo_size -
4034 + dwc_read_reg32(&global_regs->grxfsiz) -
4035 + nptxfifosize.b.depth;
4036 + ptxfifosize.b.startaddr =
4037 + nptxfifosize.b.startaddr + nptxfifosize.b.depth;
4038 + dwc_write_reg32(&global_regs->hptxfsiz, ptxfifosize.d32);
4039 + DWC_DEBUGPL(DBG_CIL, "new hptxfsiz=%08x\n",
4040 + dwc_read_reg32(&global_regs->hptxfsiz));
4041 + }
4042 +
4043 + /* Clear Host Set HNP Enable in the OTG Control Register */
4044 + gotgctl.b.hstsethnpen = 1;
4045 + dwc_modify_reg32(&global_regs->gotgctl, gotgctl.d32, 0);
4046 +
4047 + /* Make sure the FIFOs are flushed. */
4048 + dwc_otg_flush_tx_fifo(core_if, 0x10); /* all Tx FIFOs */
4049 + dwc_otg_flush_rx_fifo(core_if);
4050 +
4051 + /* Flush out any leftover queued requests. */
4052 + num_channels = core_if->core_params->host_channels;
4053 + for (i = 0; i < num_channels; i++) {
4054 + hc_regs = core_if->host_if->hc_regs[i];
4055 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
4056 + hcchar.b.chen = 0;
4057 + hcchar.b.chdis = 1;
4058 + hcchar.b.epdir = 0;
4059 + dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
4060 + }
4061 +
4062 + /* Halt all channels to put them into a known state. */
4063 + for (i = 0; i < num_channels; i++) {
4064 + int count = 0;
4065 + hc_regs = core_if->host_if->hc_regs[i];
4066 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
4067 + hcchar.b.chen = 1;
4068 + hcchar.b.chdis = 1;
4069 + hcchar.b.epdir = 0;
4070 + dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
4071 + DWC_DEBUGPL(DBG_HCDV, "%s: Halt channel %d\n", __func__, i);
4072 + do {
4073 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
4074 + if (++count > 1000) {
4075 + DWC_ERROR
4076 + ("%s: Unable to clear halt on channel %d\n",
4077 + __func__, i);
4078 + break;
4079 + }
4080 + } while (hcchar.b.chen);
4081 + }
4082 +
4083 + /* Turn on the vbus power. */
4084 + DWC_PRINT("Init: Port Power? op_state=%d\n", core_if->op_state);
4085 + if (core_if->op_state == A_HOST) {
4086 + hprt0.d32 = dwc_otg_read_hprt0(core_if);
4087 + DWC_PRINT("Init: Power Port (%d)\n", hprt0.b.prtpwr);
4088 + if (hprt0.b.prtpwr == 0) {
4089 + hprt0.b.prtpwr = 1;
4090 + dwc_write_reg32(host_if->hprt0, hprt0.d32);
4091 + }
4092 + }
4093 +
4094 + dwc_otg_enable_host_interrupts(core_if);
4095 +}
4096 +
4097 +/**
4098 + * Prepares a host channel for transferring packets to/from a specific
4099 + * endpoint. The HCCHARn register is set up with the characteristics specified
4100 + * in hc. Host channel interrupts that may need to be serviced while this
4101 + * transfer is in progress are enabled.
4102 + *
4103 + * @core_if: Programming view of DWC_otg controller
4104 + * @hc: Information needed to initialize the host channel
4105 + */
4106 +void dwc_otg_hc_init(struct dwc_otg_core_if *core_if, struct dwc_hc *hc)
4107 +{
4108 + uint32_t intr_enable;
4109 + union hcintmsk_data hc_intr_mask;
4110 + union gintmsk_data gintmsk = {.d32 = 0 };
4111 + union hcchar_data hcchar;
4112 + union hcsplt_data hcsplt;
4113 +
4114 + uint8_t hc_num = hc->hc_num;
4115 + struct dwc_otg_host_if *host_if = core_if->host_if;
4116 + struct dwc_otg_hc_regs *hc_regs = host_if->hc_regs[hc_num];
4117 +
4118 + /* Clear old interrupt conditions for this host channel. */
4119 + hc_intr_mask.d32 = 0xFFFFFFFF;
4120 + hc_intr_mask.b.reserved = 0;
4121 + dwc_write_reg32(&hc_regs->hcint, hc_intr_mask.d32);
4122 +
4123 + /* Enable channel interrupts required for this transfer. */
4124 + hc_intr_mask.d32 = 0;
4125 + hc_intr_mask.b.chhltd = 1;
4126 + if (core_if->dma_enable) {
4127 + hc_intr_mask.b.ahberr = 1;
4128 + if (hc->error_state && !hc->do_split &&
4129 + hc->ep_type != DWC_OTG_EP_TYPE_ISOC) {
4130 + hc_intr_mask.b.ack = 1;
4131 + if (hc->ep_is_in) {
4132 + hc_intr_mask.b.datatglerr = 1;
4133 + if (hc->ep_type != DWC_OTG_EP_TYPE_INTR)
4134 + hc_intr_mask.b.nak = 1;
4135 + }
4136 + }
4137 + } else {
4138 + switch (hc->ep_type) {
4139 + case DWC_OTG_EP_TYPE_CONTROL:
4140 + case DWC_OTG_EP_TYPE_BULK:
4141 + hc_intr_mask.b.xfercompl = 1;
4142 + hc_intr_mask.b.stall = 1;
4143 + hc_intr_mask.b.xacterr = 1;
4144 + hc_intr_mask.b.datatglerr = 1;
4145 + if (hc->ep_is_in) {
4146 + hc_intr_mask.b.bblerr = 1;
4147 + } else {
4148 + hc_intr_mask.b.nak = 1;
4149 + hc_intr_mask.b.nyet = 1;
4150 + if (hc->do_ping)
4151 + hc_intr_mask.b.ack = 1;
4152 + }
4153 +
4154 + if (hc->do_split) {
4155 + hc_intr_mask.b.nak = 1;
4156 + if (hc->complete_split)
4157 + hc_intr_mask.b.nyet = 1;
4158 + else
4159 + hc_intr_mask.b.ack = 1;
4160 + }
4161 +
4162 + if (hc->error_state)
4163 + hc_intr_mask.b.ack = 1;
4164 + break;
4165 + case DWC_OTG_EP_TYPE_INTR:
4166 + hc_intr_mask.b.xfercompl = 1;
4167 + hc_intr_mask.b.nak = 1;
4168 + hc_intr_mask.b.stall = 1;
4169 + hc_intr_mask.b.xacterr = 1;
4170 + hc_intr_mask.b.datatglerr = 1;
4171 + hc_intr_mask.b.frmovrun = 1;
4172 +
4173 + if (hc->ep_is_in)
4174 + hc_intr_mask.b.bblerr = 1;
4175 + if (hc->error_state)
4176 + hc_intr_mask.b.ack = 1;
4177 + if (hc->do_split) {
4178 + if (hc->complete_split)
4179 + hc_intr_mask.b.nyet = 1;
4180 + else
4181 + hc_intr_mask.b.ack = 1;
4182 + }
4183 + break;
4184 + case DWC_OTG_EP_TYPE_ISOC:
4185 + hc_intr_mask.b.xfercompl = 1;
4186 + hc_intr_mask.b.frmovrun = 1;
4187 + hc_intr_mask.b.ack = 1;
4188 +
4189 + if (hc->ep_is_in) {
4190 + hc_intr_mask.b.xacterr = 1;
4191 + hc_intr_mask.b.bblerr = 1;
4192 + }
4193 + break;
4194 + }
4195 + }
4196 + dwc_write_reg32(&hc_regs->hcintmsk, hc_intr_mask.d32);
4197 +
4198 + /* Enable the top level host channel interrupt. */
4199 + intr_enable = (1 << hc_num);
4200 + dwc_modify_reg32(&host_if->host_global_regs->haintmsk, 0, intr_enable);
4201 +
4202 + /* Make sure host channel interrupts are enabled. */
4203 + gintmsk.b.hcintr = 1;
4204 + dwc_modify_reg32(&core_if->core_global_regs->gintmsk, 0, gintmsk.d32);
4205 +
4206 + /*
4207 + * Program the HCCHARn register with the endpoint characteristics for
4208 + * the current transfer.
4209 + */
4210 + hcchar.d32 = 0;
4211 + hcchar.b.devaddr = hc->dev_addr;
4212 + hcchar.b.epnum = hc->ep_num;
4213 + hcchar.b.epdir = hc->ep_is_in;
4214 + hcchar.b.lspddev = (hc->speed == DWC_OTG_EP_SPEED_LOW);
4215 + hcchar.b.eptype = hc->ep_type;
4216 + hcchar.b.mps = hc->max_packet;
4217 +
4218 + dwc_write_reg32(&host_if->hc_regs[hc_num]->hcchar, hcchar.d32);
4219 +
4220 + DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
4221 + DWC_DEBUGPL(DBG_HCDV, " Dev Addr: %d\n", hcchar.b.devaddr);
4222 + DWC_DEBUGPL(DBG_HCDV, " Ep Num: %d\n", hcchar.b.epnum);
4223 + DWC_DEBUGPL(DBG_HCDV, " Is In: %d\n", hcchar.b.epdir);
4224 + DWC_DEBUGPL(DBG_HCDV, " Is Low Speed: %d\n", hcchar.b.lspddev);
4225 + DWC_DEBUGPL(DBG_HCDV, " Ep Type: %d\n", hcchar.b.eptype);
4226 + DWC_DEBUGPL(DBG_HCDV, " Max Pkt: %d\n", hcchar.b.mps);
4227 + DWC_DEBUGPL(DBG_HCDV, " Multi Cnt: %d\n", hcchar.b.multicnt);
4228 +
4229 + /*
4230 + * Program the HCSPLIT register for SPLITs
4231 + */
4232 + hcsplt.d32 = 0;
4233 + if (hc->do_split) {
4234 + DWC_DEBUGPL(DBG_HCDV, "Programming HC %d with split --> %s\n",
4235 + hc->hc_num,
4236 + hc->complete_split ? "CSPLIT" : "SSPLIT");
4237 + hcsplt.b.compsplt = hc->complete_split;
4238 + hcsplt.b.xactpos = hc->xact_pos;
4239 + hcsplt.b.hubaddr = hc->hub_addr;
4240 + hcsplt.b.prtaddr = hc->port_addr;
4241 + DWC_DEBUGPL(DBG_HCDV, " comp split %d\n",
4242 + hc->complete_split);
4243 + DWC_DEBUGPL(DBG_HCDV, " xact pos %d\n", hc->xact_pos);
4244 + DWC_DEBUGPL(DBG_HCDV, " hub addr %d\n", hc->hub_addr);
4245 + DWC_DEBUGPL(DBG_HCDV, " port addr %d\n", hc->port_addr);
4246 + DWC_DEBUGPL(DBG_HCDV, " is_in %d\n", hc->ep_is_in);
4247 + DWC_DEBUGPL(DBG_HCDV, " Max Pkt: %d\n", hcchar.b.mps);
4248 + DWC_DEBUGPL(DBG_HCDV, " xferlen: %d\n", hc->xfer_len);
4249 + }
4250 + dwc_write_reg32(&host_if->hc_regs[hc_num]->hcsplt, hcsplt.d32);
4251 +
4252 +}
4253 +
4254 +/**
4255 + * Attempts to halt a host channel. This function should only be called in
4256 + * Slave mode or to abort a transfer in either Slave mode or DMA mode. Under
4257 + * normal circumstances in DMA mode, the controller halts the channel when the
4258 + * transfer is complete or a condition occurs that requires application
4259 + * intervention.
4260 + *
4261 + * In slave mode, checks for a free request queue entry, then sets the Channel
4262 + * Enable and Channel Disable bits of the Host Channel Characteristics
4263 + * register of the specified channel to intiate the halt. If there is no free
4264 + * request queue entry, sets only the Channel Disable bit of the HCCHARn
4265 + * register to flush requests for this channel. In the latter case, sets a
4266 + * flag to indicate that the host channel needs to be halted when a request
4267 + * queue slot is open.
4268 + *
4269 + * In DMA mode, always sets the Channel Enable and Channel Disable bits of the
4270 + * HCCHARn register. The controller ensures there is space in the request
4271 + * queue before submitting the halt request.
4272 + *
4273 + * Some time may elapse before the core flushes any posted requests for this
4274 + * host channel and halts. The Channel Halted interrupt handler completes the
4275 + * deactivation of the host channel.
4276 + *
4277 + * @core_if: Controller register interface.
4278 + * @hc: Host channel to halt.
4279 + * @halt_status: Reason for halting the channel.
4280 + */
4281 +void dwc_otg_hc_halt(struct dwc_otg_core_if *core_if,
4282 + struct dwc_hc *hc, enum dwc_otg_halt_status halt_status)
4283 +{
4284 + union gnptxsts_data nptxsts;
4285 + union hptxsts_data hptxsts;
4286 + union hcchar_data hcchar;
4287 + struct dwc_otg_hc_regs *hc_regs;
4288 + struct dwc_otg_core_global_regs *global_regs;
4289 + struct dwc_otg_host_global_regs *host_global_regs;
4290 +
4291 + hc_regs = core_if->host_if->hc_regs[hc->hc_num];
4292 + global_regs = core_if->core_global_regs;
4293 + host_global_regs = core_if->host_if->host_global_regs;
4294 +
4295 + WARN_ON(halt_status == DWC_OTG_HC_XFER_NO_HALT_STATUS);
4296 +
4297 + if (halt_status == DWC_OTG_HC_XFER_URB_DEQUEUE ||
4298 + halt_status == DWC_OTG_HC_XFER_AHB_ERR) {
4299 + /*
4300 + * Disable all channel interrupts except Ch Halted. The QTD
4301 + * and QH state associated with this transfer has been cleared
4302 + * (in the case of URB_DEQUEUE), so the channel needs to be
4303 + * shut down carefully to prevent crashes.
4304 + */
4305 + union hcintmsk_data hcintmsk;
4306 + hcintmsk.d32 = 0;
4307 + hcintmsk.b.chhltd = 1;
4308 + dwc_write_reg32(&hc_regs->hcintmsk, hcintmsk.d32);
4309 +
4310 + /*
4311 + * Make sure no other interrupts besides halt are currently
4312 + * pending. Handling another interrupt could cause a crash due
4313 + * to the QTD and QH state.
4314 + */
4315 + dwc_write_reg32(&hc_regs->hcint, ~hcintmsk.d32);
4316 +
4317 + /*
4318 + * Make sure the halt status is set to URB_DEQUEUE or AHB_ERR
4319 + * even if the channel was already halted for some other
4320 + * reason.
4321 + */
4322 + hc->halt_status = halt_status;
4323 +
4324 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
4325 + if (hcchar.b.chen == 0) {
4326 + /*
4327 + * The channel is either already halted or it hasn't
4328 + * started yet. In DMA mode, the transfer may halt if
4329 + * it finishes normally or a condition occurs that
4330 + * requires driver intervention. Don't want to halt
4331 + * the channel again. In either Slave or DMA mode,
4332 + * it's possible that the transfer has been assigned
4333 + * to a channel, but not started yet when an URB is
4334 + * dequeued. Don't want to halt a channel that hasn't
4335 + * started yet.
4336 + */
4337 + return;
4338 + }
4339 + }
4340 +
4341 + if (hc->halt_pending) {
4342 + /*
4343 + * A halt has already been issued for this channel. This might
4344 + * happen when a transfer is aborted by a higher level in
4345 + * the stack.
4346 + */
4347 +#ifdef DEBUG
4348 + DWC_PRINT
4349 + ("*** %s: Channel %d, hc->halt_pending already set ***\n",
4350 + __func__, hc->hc_num);
4351 +
4352 +/* dwc_otg_dump_global_registers(core_if); */
4353 +/* dwc_otg_dump_host_registers(core_if); */
4354 +#endif
4355 + return;
4356 + }
4357 +
4358 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
4359 + hcchar.b.chen = 1;
4360 + hcchar.b.chdis = 1;
4361 +
4362 + if (!core_if->dma_enable) {
4363 + /* Check for space in the request queue to issue the halt. */
4364 + if (hc->ep_type == DWC_OTG_EP_TYPE_CONTROL ||
4365 + hc->ep_type == DWC_OTG_EP_TYPE_BULK) {
4366 + nptxsts.d32 = dwc_read_reg32(&global_regs->gnptxsts);
4367 + if (nptxsts.b.nptxqspcavail == 0)
4368 + hcchar.b.chen = 0;
4369 + } else {
4370 + hptxsts.d32 =
4371 + dwc_read_reg32(&host_global_regs->hptxsts);
4372 + if ((hptxsts.b.ptxqspcavail == 0)
4373 + || (core_if->queuing_high_bandwidth)) {
4374 + hcchar.b.chen = 0;
4375 + }
4376 + }
4377 + }
4378 +
4379 + dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
4380 +
4381 + hc->halt_status = halt_status;
4382 +
4383 + if (hcchar.b.chen) {
4384 + hc->halt_pending = 1;
4385 + hc->halt_on_queue = 0;
4386 + } else {
4387 + hc->halt_on_queue = 1;
4388 + }
4389 +
4390 + DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
4391 + DWC_DEBUGPL(DBG_HCDV, " hcchar: 0x%08x\n", hcchar.d32);
4392 + DWC_DEBUGPL(DBG_HCDV, " halt_pending: %d\n", hc->halt_pending);
4393 + DWC_DEBUGPL(DBG_HCDV, " halt_on_queue: %d\n", hc->halt_on_queue);
4394 + DWC_DEBUGPL(DBG_HCDV, " halt_status: %d\n", hc->halt_status);
4395 +
4396 + return;
4397 +}
4398 +
4399 +/**
4400 + * Clears the transfer state for a host channel. This function is normally
4401 + * called after a transfer is done and the host channel is being released.
4402 + *
4403 + * @core_if: Programming view of DWC_otg controller.
4404 + * @hc: Identifies the host channel to clean up.
4405 + */
4406 +void dwc_otg_hc_cleanup(struct dwc_otg_core_if *core_if, struct dwc_hc *hc)
4407 +{
4408 + struct dwc_otg_hc_regs *hc_regs;
4409 +
4410 + hc->xfer_started = 0;
4411 +
4412 + /*
4413 + * Clear channel interrupt enables and any unhandled channel interrupt
4414 + * conditions.
4415 + */
4416 + hc_regs = core_if->host_if->hc_regs[hc->hc_num];
4417 + dwc_write_reg32(&hc_regs->hcintmsk, 0);
4418 + dwc_write_reg32(&hc_regs->hcint, 0xFFFFFFFF);
4419 +
4420 +#ifdef DEBUG
4421 + del_timer(&core_if->hc_xfer_timer[hc->hc_num]);
4422 + {
4423 + union hcchar_data hcchar;
4424 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
4425 + if (hcchar.b.chdis) {
4426 + DWC_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n",
4427 + __func__, hc->hc_num, hcchar.d32);
4428 + }
4429 + }
4430 +#endif
4431 +}
4432 +
4433 +/**
4434 + * Sets the channel property that indicates in which frame a periodic transfer
4435 + * should occur. This is always set to the _next_ frame. This function has no
4436 + * effect on non-periodic transfers.
4437 + *
4438 + * @core_if: Programming view of DWC_otg controller.
4439 + * @hc: Identifies the host channel to set up and its properties.
4440 + * @hcchar: Current value of the HCCHAR register for the specified host
4441 + * channel.
4442 + */
4443 +static inline void hc_set_even_odd_frame(struct dwc_otg_core_if *core_if,
4444 + struct dwc_hc *hc,
4445 + union hcchar_data *hcchar)
4446 +{
4447 + if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
4448 + hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
4449 + union hfnum_data hfnum;
4450 + hfnum.d32 =
4451 + dwc_read_reg32(&core_if->host_if->host_global_regs->hfnum);
4452 + /* 1 if _next_ frame is odd, 0 if it's even */
4453 + hcchar->b.oddfrm = (hfnum.b.frnum & 0x1) ? 0 : 1;
4454 +#ifdef DEBUG
4455 + if (hc->ep_type == DWC_OTG_EP_TYPE_INTR && hc->do_split
4456 + && !hc->complete_split) {
4457 + switch (hfnum.b.frnum & 0x7) {
4458 + case 7:
4459 + core_if->hfnum_7_samples++;
4460 + core_if->hfnum_7_frrem_accum += hfnum.b.frrem;
4461 + break;
4462 + case 0:
4463 + core_if->hfnum_0_samples++;
4464 + core_if->hfnum_0_frrem_accum += hfnum.b.frrem;
4465 + break;
4466 + default:
4467 + core_if->hfnum_other_samples++;
4468 + core_if->hfnum_other_frrem_accum +=
4469 + hfnum.b.frrem;
4470 + break;
4471 + }
4472 + }
4473 +#endif
4474 + }
4475 +}
4476 +
4477 +#ifdef DEBUG
4478 +static void hc_xfer_timeout(unsigned long _ptr)
4479 +{
4480 + struct hc_xfer_info *xfer_info = (struct hc_xfer_info *) _ptr;
4481 + int hc_num = xfer_info->hc->hc_num;
4482 + DWC_WARN("%s: timeout on channel %d\n", __func__, hc_num);
4483 + DWC_WARN(" start_hcchar_val 0x%08x\n",
4484 + xfer_info->core_if->start_hcchar_val[hc_num]);
4485 +}
4486 +#endif
4487 +
4488 +/**
4489 + * This function does the setup for a data transfer for a host channel and
4490 + * starts the transfer. May be called in either Slave mode or DMA mode. In
4491 + * Slave mode, the caller must ensure that there is sufficient space in the
4492 + * request queue and Tx Data FIFO.
4493 + *
4494 + * For an OUT transfer in Slave mode, it loads a data packet into the
4495 + * appropriate FIFO. If necessary, additional data packets will be loaded in
4496 + * the Host ISR.
4497 + *
4498 + * For an IN transfer in Slave mode, a data packet is requested. The data
4499 + * packets are unloaded from the Rx FIFO in the Host ISR. If necessary,
4500 + * additional data packets are requested in the Host ISR.
4501 + *
4502 + * For a PING transfer in Slave mode, the Do Ping bit is set in the HCTSIZ
4503 + * register along with a packet count of 1 and the channel is enabled. This
4504 + * causes a single PING transaction to occur. Other fields in HCTSIZ are
4505 + * simply set to 0 since no data transfer occurs in this case.
4506 + *
4507 + * For a PING transfer in DMA mode, the HCTSIZ register is initialized with
4508 + * all the information required to perform the subsequent data transfer. In
4509 + * addition, the Do Ping bit is set in the HCTSIZ register. In this case, the
4510 + * controller performs the entire PING protocol, then starts the data
4511 + * transfer.
4512 + *
4513 + * @core_if: Programming view of DWC_otg controller.
4514 + * @hc: Information needed to initialize the host channel. The xfer_len
4515 + * value may be reduced to accommodate the max widths of the XferSize and
4516 + * PktCnt fields in the HCTSIZn register. The multi_count value may be changed
4517 + * to reflect the final xfer_len value.
4518 + */
4519 +void dwc_otg_hc_start_transfer(struct dwc_otg_core_if *core_if,
4520 + struct dwc_hc *hc)
4521 +{
4522 + union hcchar_data hcchar;
4523 + union hctsiz_data hctsiz;
4524 + uint16_t num_packets;
4525 + uint32_t max_hc_xfer_size = core_if->core_params->max_transfer_size;
4526 + uint16_t max_hc_pkt_count = core_if->core_params->max_packet_count;
4527 + struct dwc_otg_hc_regs *hc_regs = core_if->host_if->hc_regs[hc->hc_num];
4528 +
4529 + hctsiz.d32 = 0;
4530 +
4531 + if (hc->do_ping) {
4532 + if (!core_if->dma_enable) {
4533 + dwc_otg_hc_do_ping(core_if, hc);
4534 + hc->xfer_started = 1;
4535 + return;
4536 + } else {
4537 + hctsiz.b.dopng = 1;
4538 + }
4539 + }
4540 +
4541 + if (hc->do_split) {
4542 + num_packets = 1;
4543 +
4544 + if (hc->complete_split && !hc->ep_is_in) {
4545 + /* For CSPLIT OUT Transfer, set the size to 0 so the
4546 + * core doesn't expect any data written to the FIFO */
4547 + hc->xfer_len = 0;
4548 + } else if (hc->ep_is_in || (hc->xfer_len > hc->max_packet)) {
4549 + hc->xfer_len = hc->max_packet;
4550 + } else if (!hc->ep_is_in && (hc->xfer_len > 188)) {
4551 + hc->xfer_len = 188;
4552 + }
4553 +
4554 + hctsiz.b.xfersize = hc->xfer_len;
4555 + } else {
4556 + /*
4557 + * Ensure that the transfer length and packet count will fit
4558 + * in the widths allocated for them in the HCTSIZn register.
4559 + */
4560 + if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
4561 + hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
4562 + /*
4563 + * Make sure the transfer size is no larger than one
4564 + * (micro)frame's worth of data. (A check was done
4565 + * when the periodic transfer was accepted to ensure
4566 + * that a (micro)frame's worth of data can be
4567 + * programmed into a channel.)
4568 + */
4569 + uint32_t max_periodic_len =
4570 + hc->multi_count * hc->max_packet;
4571 + if (hc->xfer_len > max_periodic_len)
4572 + hc->xfer_len = max_periodic_len;
4573 + } else if (hc->xfer_len > max_hc_xfer_size) {
4574 + /*
4575 + * Make sure that xfer_len is a multiple of
4576 + * max packet size.
4577 + */
4578 + hc->xfer_len = max_hc_xfer_size - hc->max_packet + 1;
4579 + }
4580 +
4581 + if (hc->xfer_len > 0) {
4582 + num_packets =
4583 + (hc->xfer_len + hc->max_packet -
4584 + 1) / hc->max_packet;
4585 + if (num_packets > max_hc_pkt_count) {
4586 + num_packets = max_hc_pkt_count;
4587 + hc->xfer_len = num_packets * hc->max_packet;
4588 + }
4589 + } else {
4590 + /* Need 1 packet for transfer length of 0. */
4591 + num_packets = 1;
4592 + }
4593 +
4594 + if (hc->ep_is_in) {
4595 + /*
4596 + * Always program an integral # of max packets
4597 + * for IN transfers.
4598 + */
4599 + hc->xfer_len = num_packets * hc->max_packet;
4600 + }
4601 +
4602 + if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
4603 + hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
4604 + /*
4605 + * Make sure that the multi_count field matches the
4606 + * actual transfer length.
4607 + */
4608 + hc->multi_count = num_packets;
4609 +
4610 + }
4611 +
4612 + if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
4613 + /* Set up the initial PID for the transfer. */
4614 + if (hc->speed == DWC_OTG_EP_SPEED_HIGH) {
4615 + if (hc->ep_is_in) {
4616 + if (hc->multi_count == 1) {
4617 + hc->data_pid_start =
4618 + DWC_OTG_HC_PID_DATA0;
4619 + } else if (hc->multi_count == 2) {
4620 + hc->data_pid_start =
4621 + DWC_OTG_HC_PID_DATA1;
4622 + } else {
4623 + hc->data_pid_start =
4624 + DWC_OTG_HC_PID_DATA2;
4625 + }
4626 + } else {
4627 + if (hc->multi_count == 1) {
4628 + hc->data_pid_start =
4629 + DWC_OTG_HC_PID_DATA0;
4630 + } else {
4631 + hc->data_pid_start =
4632 + DWC_OTG_HC_PID_MDATA;
4633 + }
4634 + }
4635 + } else {
4636 + hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
4637 + }
4638 + }
4639 +
4640 + hctsiz.b.xfersize = hc->xfer_len;
4641 + }
4642 +
4643 + hc->start_pkt_count = num_packets;
4644 + hctsiz.b.pktcnt = num_packets;
4645 + hctsiz.b.pid = hc->data_pid_start;
4646 + dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
4647 +
4648 + DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
4649 + DWC_DEBUGPL(DBG_HCDV, " Xfer Size: %d\n", hctsiz.b.xfersize);
4650 + DWC_DEBUGPL(DBG_HCDV, " Num Pkts: %d\n", hctsiz.b.pktcnt);
4651 + DWC_DEBUGPL(DBG_HCDV, " Start PID: %d\n", hctsiz.b.pid);
4652 +
4653 + if (core_if->dma_enable) {
4654 +#ifdef CONFIG_CPU_CAVIUM_OCTEON
4655 + /* Octeon uses external DMA */
4656 + const uint64_t USBN_DMA0_OUTB_CHN0 =
4657 + CVMX_USBNX_DMA0_OUTB_CHN0(core_if->usb_num);
4658 + wmb();
4659 + cvmx_write_csr(USBN_DMA0_OUTB_CHN0 + hc->hc_num * 8,
4660 + (unsigned long)hc->xfer_buff);
4661 + cvmx_read_csr(USBN_DMA0_OUTB_CHN0 + hc->hc_num * 8);
4662 + DWC_DEBUGPL(DBG_HCDV,
4663 + "OUT: hc->hc_num = %d, hc->xfer_buff = %p\n",
4664 + hc->hc_num, hc->xfer_buff);
4665 +#else
4666 + dwc_write_reg32(&hc_regs->hcdma,
4667 + (uint32_t) (long)hc->xfer_buff);
4668 +#endif /* CONFIG_CPU_CAVIUM_OCTEON */
4669 + }
4670 +
4671 + /* Start the split */
4672 + if (hc->do_split) {
4673 + union hcsplt_data hcsplt;
4674 + hcsplt.d32 = dwc_read_reg32(&hc_regs->hcsplt);
4675 + hcsplt.b.spltena = 1;
4676 + dwc_write_reg32(&hc_regs->hcsplt, hcsplt.d32);
4677 + }
4678 +
4679 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
4680 + hcchar.b.multicnt = hc->multi_count;
4681 + hc_set_even_odd_frame(core_if, hc, &hcchar);
4682 +#ifdef DEBUG
4683 + core_if->start_hcchar_val[hc->hc_num] = hcchar.d32;
4684 + if (hcchar.b.chdis) {
4685 + DWC_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n",
4686 + __func__, hc->hc_num, hcchar.d32);
4687 + }
4688 +#endif
4689 +
4690 + /* Set host channel enable after all other setup is complete. */
4691 + hcchar.b.chen = 1;
4692 + hcchar.b.chdis = 0;
4693 + dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
4694 +
4695 + hc->xfer_started = 1;
4696 + hc->requests++;
4697 +
4698 + if (!core_if->dma_enable && !hc->ep_is_in && hc->xfer_len > 0) {
4699 + /* Load OUT packet into the appropriate Tx FIFO. */
4700 + dwc_otg_hc_write_packet(core_if, hc);
4701 + }
4702 +#ifdef DEBUG
4703 + /* Start a timer for this transfer. */
4704 + core_if->hc_xfer_timer[hc->hc_num].function = hc_xfer_timeout;
4705 + core_if->hc_xfer_info[hc->hc_num].core_if = core_if;
4706 + core_if->hc_xfer_info[hc->hc_num].hc = hc;
4707 + core_if->hc_xfer_timer[hc->hc_num].data =
4708 + (unsigned long)(&core_if->hc_xfer_info[hc->hc_num]);
4709 + core_if->hc_xfer_timer[hc->hc_num].expires = jiffies + (HZ * 10);
4710 + add_timer(&core_if->hc_xfer_timer[hc->hc_num]);
4711 +#endif
4712 +}
4713 +
4714 +/**
4715 + * This function continues a data transfer that was started by previous call
4716 + * to <code>dwc_otg_hc_start_transfer</code>. The caller must ensure there is
4717 + * sufficient space in the request queue and Tx Data FIFO. This function
4718 + * should only be called in Slave mode. In DMA mode, the controller acts
4719 + * autonomously to complete transfers programmed to a host channel.
4720 + *
4721 + * For an OUT transfer, a new data packet is loaded into the appropriate FIFO
4722 + * if there is any data remaining to be queued. For an IN transfer, another
4723 + * data packet is always requested. For the SETUP phase of a control transfer,
4724 + * this function does nothing.
4725 + *
4726 + * Returns 1 if a new request is queued, 0 if no more requests are required
4727 + * for this transfer.
4728 + */
4729 +int dwc_otg_hc_continue_transfer(struct dwc_otg_core_if *core_if,
4730 + struct dwc_hc *hc)
4731 +{
4732 + DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
4733 +
4734 + if (hc->do_split) {
4735 + /* SPLITs always queue just once per channel */
4736 + return 0;
4737 + } else if (hc->data_pid_start == DWC_OTG_HC_PID_SETUP) {
4738 + /* SETUPs are queued only once since they can't be NAKed. */
4739 + return 0;
4740 + } else if (hc->ep_is_in) {
4741 + /*
4742 + * Always queue another request for other IN transfers. If
4743 + * back-to-back INs are issued and NAKs are received for both,
4744 + * the driver may still be processing the first NAK when the
4745 + * second NAK is received. When the interrupt handler clears
4746 + * the NAK interrupt for the first NAK, the second NAK will
4747 + * not be seen. So we can't depend on the NAK interrupt
4748 + * handler to requeue a NAKed request. Instead, IN requests
4749 + * are issued each time this function is called. When the
4750 + * transfer completes, the extra requests for the channel will
4751 + * be flushed.
4752 + */
4753 + union hcchar_data hcchar;
4754 + struct dwc_otg_hc_regs *hc_regs =
4755 + core_if->host_if->hc_regs[hc->hc_num];
4756 +
4757 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
4758 + hc_set_even_odd_frame(core_if, hc, &hcchar);
4759 + hcchar.b.chen = 1;
4760 + hcchar.b.chdis = 0;
4761 + DWC_DEBUGPL(DBG_HCDV, " IN xfer: hcchar = 0x%08x\n",
4762 + hcchar.d32);
4763 + dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
4764 + hc->requests++;
4765 + return 1;
4766 + } else {
4767 + /* OUT transfers. */
4768 + if (hc->xfer_count < hc->xfer_len) {
4769 + if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
4770 + hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
4771 + union hcchar_data hcchar;
4772 + struct dwc_otg_hc_regs *hc_regs;
4773 + hc_regs =
4774 + core_if->host_if->hc_regs[hc->hc_num];
4775 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
4776 + hc_set_even_odd_frame(core_if, hc, &hcchar);
4777 + }
4778 +
4779 + /* Load OUT packet into the appropriate Tx FIFO. */
4780 + dwc_otg_hc_write_packet(core_if, hc);
4781 + hc->requests++;
4782 + return 1;
4783 + } else {
4784 + return 0;
4785 + }
4786 + }
4787 +}
4788 +
4789 +/**
4790 + * Starts a PING transfer. This function should only be called in Slave mode.
4791 + * The Do Ping bit is set in the HCTSIZ register, then the channel is enabled.
4792 + */
4793 +void dwc_otg_hc_do_ping(struct dwc_otg_core_if *core_if, struct dwc_hc *hc)
4794 +{
4795 + union hcchar_data hcchar;
4796 + union hctsiz_data hctsiz;
4797 + struct dwc_otg_hc_regs *hc_regs = core_if->host_if->hc_regs[hc->hc_num];
4798 +
4799 + DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
4800 +
4801 + hctsiz.d32 = 0;
4802 + hctsiz.b.dopng = 1;
4803 + hctsiz.b.pktcnt = 1;
4804 + dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
4805 +
4806 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
4807 + hcchar.b.chen = 1;
4808 + hcchar.b.chdis = 0;
4809 + dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
4810 +}
4811 +
4812 +/*
4813 + * This function writes a packet into the Tx FIFO associated with the Host
4814 + * Channel. For a channel associated with a non-periodic EP, the non-periodic
4815 + * Tx FIFO is written. For a channel associated with a periodic EP, the
4816 + * periodic Tx FIFO is written. This function should only be called in Slave
4817 + * mode.
4818 + *
4819 + * Upon return the xfer_buff and xfer_count fields in hc are incremented by
4820 + * then number of bytes written to the Tx FIFO.
4821 + */
4822 +void dwc_otg_hc_write_packet(struct dwc_otg_core_if *core_if, struct dwc_hc *hc)
4823 +{
4824 + uint32_t i;
4825 + uint32_t remaining_count;
4826 + uint32_t byte_count;
4827 + uint32_t dword_count;
4828 +
4829 + uint32_t *data_buff = (uint32_t *) (hc->xfer_buff);
4830 + uint32_t *data_fifo = core_if->data_fifo[hc->hc_num];
4831 +
4832 + remaining_count = hc->xfer_len - hc->xfer_count;
4833 + if (remaining_count > hc->max_packet)
4834 + byte_count = hc->max_packet;
4835 + else
4836 + byte_count = remaining_count;
4837 +
4838 + dword_count = (byte_count + 3) / 4;
4839 +
4840 + if ((((unsigned long)data_buff) & 0x3) == 0) {
4841 + /* xfer_buff is DWORD aligned. */
4842 + for (i = 0; i < dword_count; i++, data_buff++)
4843 + dwc_write_reg32(data_fifo, *data_buff);
4844 + } else {
4845 + /* xfer_buff is not DWORD aligned. */
4846 + for (i = 0; i < dword_count; i++, data_buff++)
4847 + dwc_write_reg32(data_fifo, get_unaligned(data_buff));
4848 + }
4849 +
4850 + hc->xfer_count += byte_count;
4851 + hc->xfer_buff += byte_count;
4852 +}
4853 +
4854 +/**
4855 + * Gets the current USB frame number. This is the frame number from the last
4856 + * SOF packet.
4857 + */
4858 +uint32_t dwc_otg_get_frame_number(struct dwc_otg_core_if *core_if)
4859 +{
4860 + union dsts_data dsts;
4861 + dsts.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts);
4862 +
4863 + /* read current frame/microfreme number from DSTS register */
4864 + return dsts.b.soffn;
4865 +}
4866 +
4867 +/**
4868 + * This function reads a setup packet from the Rx FIFO into the destination
4869 + * buffer. This function is called from the Rx Status Queue Level (RxStsQLvl)
4870 + * Interrupt routine when a SETUP packet has been received in Slave mode.
4871 + *
4872 + * @core_if: Programming view of DWC_otg controller.
4873 + * @dest: Destination buffer for packet data.
4874 + */
4875 +void dwc_otg_read_setup_packet(struct dwc_otg_core_if *core_if, uint32_t *dest)
4876 +{
4877 + /* Get the 8 bytes of a setup transaction data */
4878 +
4879 + /* Pop 2 DWORDS off the receive data FIFO into memory */
4880 + dest[0] = dwc_read_reg32(core_if->data_fifo[0]);
4881 + dest[1] = dwc_read_reg32(core_if->data_fifo[0]);
4882 +}
4883 +
4884 +/**
4885 + * This function enables EP0 OUT to receive SETUP packets and configures EP0
4886 + * IN for transmitting packets. It is normally called when the
4887 + * "Enumeration Done" interrupt occurs.
4888 + *
4889 + * @core_if: Programming view of DWC_otg controller.
4890 + * @ep: The EP0 data.
4891 + */
4892 +void dwc_otg_ep0_activate(struct dwc_otg_core_if *core_if, struct dwc_ep *ep)
4893 +{
4894 + struct dwc_otg_dev_if *dev_if = core_if->dev_if;
4895 + union dsts_data dsts;
4896 + union depctl_data diepctl;
4897 + union depctl_data doepctl;
4898 + union dctl_data dctl = {.d32 = 0 };
4899 +
4900 + /* Read the Device Status and Endpoint 0 Control registers */
4901 + dsts.d32 = dwc_read_reg32(&dev_if->dev_global_regs->dsts);
4902 + diepctl.d32 = dwc_read_reg32(&dev_if->in_ep_regs[0]->diepctl);
4903 + doepctl.d32 = dwc_read_reg32(&dev_if->out_ep_regs[0]->doepctl);
4904 +
4905 + /* Set the MPS of the IN EP based on the enumeration speed */
4906 + switch (dsts.b.enumspd) {
4907 + case DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
4908 + case DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
4909 + case DWC_DSTS_ENUMSPD_FS_PHY_48MHZ:
4910 + diepctl.b.mps = DWC_DEP0CTL_MPS_64;
4911 + break;
4912 + case DWC_DSTS_ENUMSPD_LS_PHY_6MHZ:
4913 + diepctl.b.mps = DWC_DEP0CTL_MPS_8;
4914 + break;
4915 + }
4916 +
4917 + dwc_write_reg32(&dev_if->in_ep_regs[0]->diepctl, diepctl.d32);
4918 +
4919 + /* Enable OUT EP for receive */
4920 + doepctl.b.epena = 1;
4921 + dwc_write_reg32(&dev_if->out_ep_regs[0]->doepctl, doepctl.d32);
4922 +
4923 +#ifdef VERBOSE
4924 + DWC_DEBUGPL(DBG_PCDV, "doepctl0=%0x\n",
4925 + dwc_read_reg32(&dev_if->out_ep_regs[0]->doepctl));
4926 + DWC_DEBUGPL(DBG_PCDV, "diepctl0=%0x\n",
4927 + dwc_read_reg32(&dev_if->in_ep_regs[0]->diepctl));
4928 +#endif
4929 + dctl.b.cgnpinnak = 1;
4930 + dwc_modify_reg32(&dev_if->dev_global_regs->dctl, dctl.d32, dctl.d32);
4931 + DWC_DEBUGPL(DBG_PCDV, "dctl=%0x\n",
4932 + dwc_read_reg32(&dev_if->dev_global_regs->dctl));
4933 +}
4934 +
4935 +/**
4936 + * This function activates an EP. The Device EP control register for
4937 + * the EP is configured as defined in the ep structure. Note: This
4938 + * function is not used for EP0.
4939 + *
4940 + * @core_if: Programming view of DWC_otg controller.
4941 + * @ep: The EP to activate.
4942 + */
4943 +void dwc_otg_ep_activate(struct dwc_otg_core_if *core_if, struct dwc_ep *ep)
4944 +{
4945 + struct dwc_otg_dev_if *dev_if = core_if->dev_if;
4946 + union depctl_data depctl;
4947 + uint32_t *addr;
4948 + union daint_data daintmsk = {.d32 = 0 };
4949 +
4950 + DWC_DEBUGPL(DBG_PCDV, "%s() EP%d-%s\n", __func__, ep->num,
4951 + (ep->is_in ? "IN" : "OUT"));
4952 +
4953 + /* Read DEPCTLn register */
4954 + if (ep->is_in == 1) {
4955 + addr = &dev_if->in_ep_regs[ep->num]->diepctl;
4956 + daintmsk.ep.in = 1 << ep->num;
4957 + } else {
4958 + addr = &dev_if->out_ep_regs[ep->num]->doepctl;
4959 + daintmsk.ep.out = 1 << ep->num;
4960 + }
4961 +
4962 + /* If the EP is already active don't change the EP Control
4963 + * register. */
4964 + depctl.d32 = dwc_read_reg32(addr);
4965 + if (!depctl.b.usbactep) {
4966 + depctl.b.mps = ep->maxpacket;
4967 + depctl.b.eptype = ep->type;
4968 + depctl.b.txfnum = ep->tx_fifo_num;
4969 +
4970 + if (ep->type != DWC_OTG_EP_TYPE_ISOC)
4971 + depctl.b.setd0pid = 1;
4972 +
4973 + depctl.b.usbactep = 1;
4974 +
4975 + dwc_write_reg32(addr, depctl.d32);
4976 + DWC_DEBUGPL(DBG_PCDV, "DEPCTL=%08x\n", dwc_read_reg32(addr));
4977 + }
4978 +
4979 + /* Enable the Interrupt for this EP */
4980 + dwc_modify_reg32(&dev_if->dev_global_regs->daintmsk, 0, daintmsk.d32);
4981 + DWC_DEBUGPL(DBG_PCDV, "DAINTMSK=%0x\n",
4982 + dwc_read_reg32(&dev_if->dev_global_regs->daintmsk));
4983 + return;
4984 +}
4985 +
4986 +/**
4987 + * This function deactivates an EP. This is done by clearing the USB Active
4988 + * EP bit in the Device EP control register. Note: This function is not used
4989 + * for EP0. EP0 cannot be deactivated.
4990 + *
4991 + * @core_if: Programming view of DWC_otg controller.
4992 + * @ep: The EP to deactivate.
4993 + */
4994 +void dwc_otg_ep_deactivate(struct dwc_otg_core_if *core_if, struct dwc_ep *ep)
4995 +{
4996 + union depctl_data depctl = {.d32 = 0 };
4997 + uint32_t *addr;
4998 + union daint_data daintmsk = {.d32 = 0 };
4999 +
5000 + /* Read DEPCTLn register */
5001 + if (ep->is_in == 1) {
5002 + addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl;
5003 + daintmsk.ep.in = 1 << ep->num;
5004 + } else {
5005 + addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl;
5006 + daintmsk.ep.out = 1 << ep->num;
5007 + }
5008 +
5009 + depctl.b.usbactep = 0;
5010 + dwc_write_reg32(addr, depctl.d32);
5011 +
5012 + /* Disable the Interrupt for this EP */
5013 + dwc_modify_reg32(&core_if->dev_if->dev_global_regs->daintmsk,
5014 + daintmsk.d32, 0);
5015 +
5016 + return;
5017 +}
5018 +
5019 +/**
5020 + * This function does the setup for a data transfer for an EP and
5021 + * starts the transfer. For an IN transfer, the packets will be
5022 + * loaded into the appropriate Tx FIFO in the ISR. For OUT transfers,
5023 + * the packets are unloaded from the Rx FIFO in the ISR. the ISR.
5024 + *
5025 + * @core_if: Programming view of DWC_otg controller.
5026 + * @ep: The EP to start the transfer on.
5027 + */
5028 +void dwc_otg_ep_start_transfer(struct dwc_otg_core_if *core_if,
5029 + struct dwc_ep *ep)
5030 +{
5031 + /*
5032 + * @todo Refactor this funciton to check the transfer size
5033 + * count value does not execed the number bits in the Transfer
5034 + * count register.
5035 + */
5036 + union depctl_data depctl;
5037 + union deptsiz_data deptsiz;
5038 + union gintmsk_data intr_mask = {.d32 = 0 };
5039 +
5040 +#ifdef CHECK_PACKET_COUNTER_WIDTH
5041 + const uint32_t MAX_XFER_SIZE = core_if->core_params->max_transfer_size;
5042 + const uint32_t MAX_PKT_COUNT = core_if->core_params->max_packet_count;
5043 + uint32_t num_packets;
5044 + uint32_t transfer_len;
5045 + struct dwc_otg_dev_out_ep_regs *out_regs =
5046 + core_if->dev_if->out_ep_regs[ep->num];
5047 + struct dwc_otg_dev_in_ep_regs *in_regs =
5048 + core_if->dev_if->in_ep_regs[ep->num];
5049 + union gnptxsts_data txstatus;
5050 +
5051 + int lvl = SET_DEBUG_LEVEL(DBG_PCD);
5052 +
5053 + DWC_DEBUGPL(DBG_PCD, "ep%d-%s xfer_len=%d xfer_cnt=%d "
5054 + "xfer_buff=%p start_xfer_buff=%p\n",
5055 + ep->num, (ep->is_in ? "IN" : "OUT"), ep->xfer_len,
5056 + ep->xfer_count, ep->xfer_buff, ep->start_xfer_buff);
5057 +
5058 + transfer_len = ep->xfer_len - ep->xfer_count;
5059 + if (transfer_len > MAX_XFER_SIZE)
5060 + transfer_len = MAX_XFER_SIZE;
5061 +
5062 + if (transfer_len == 0) {
5063 + num_packets = 1;
5064 + /* OUT EP to recieve Zero-length packet set transfer
5065 + * size to maxpacket size. */
5066 + if (!ep->is_in)
5067 + transfer_len = ep->maxpacket;
5068 + } else {
5069 + num_packets =
5070 + (transfer_len + ep->maxpacket - 1) / ep->maxpacket;
5071 + if (num_packets > MAX_PKT_COUNT)
5072 + num_packets = MAX_PKT_COUNT;
5073 + }
5074 + DWC_DEBUGPL(DBG_PCD, "transfer_len=%d #pckt=%d\n", transfer_len,
5075 + num_packets);
5076 +
5077 + deptsiz.b.xfersize = transfer_len;
5078 + deptsiz.b.pktcnt = num_packets;
5079 +
5080 + /* IN endpoint */
5081 + if (ep->is_in == 1) {
5082 + depctl.d32 = dwc_read_reg32(&in_regs->diepctl);
5083 + } else { /* OUT endpoint */
5084 + depctl.d32 = dwc_read_reg32(&out_regs->doepctl);
5085 + }
5086 +
5087 + /* EP enable, IN data in FIFO */
5088 + depctl.b.cnak = 1;
5089 + depctl.b.epena = 1;
5090 + /* IN endpoint */
5091 + if (ep->is_in == 1) {
5092 + txstatus.d32 =
5093 + dwc_read_reg32(&core_if->core_global_regs->gnptxsts);
5094 + if (txstatus.b.nptxqspcavail == 0) {
5095 + DWC_DEBUGPL(DBG_ANY, "TX Queue Full (0x%0x)\n",
5096 + txstatus.d32);
5097 + return;
5098 + }
5099 + dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
5100 + dwc_write_reg32(&in_regs->diepctl, depctl.d32);
5101 + /*
5102 + * Enable the Non-Periodic Tx FIFO empty interrupt, the
5103 + * data will be written into the fifo by the ISR.
5104 + */
5105 + if (core_if->dma_enable) {
5106 + dwc_write_reg32(&in_regs->diepdma,
5107 + (uint32_t) ep->xfer_buff);
5108 + } else {
5109 + intr_mask.b.nptxfempty = 1;
5110 + dwc_modify_reg32(&core_if->core_global_regs->gintsts,
5111 + intr_mask.d32, 0);
5112 + dwc_modify_reg32(&core_if->core_global_regs->gintmsk,
5113 + intr_mask.d32, intr_mask.d32);
5114 + }
5115 + } else { /* OUT endpoint */
5116 + dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32);
5117 + dwc_write_reg32(&out_regs->doepctl, depctl.d32);
5118 + if (core_if->dma_enable) {
5119 + dwc_write_reg32(&out_regs->doepdma,
5120 + (uint32_t) ep->xfer_buff);
5121 + }
5122 + }
5123 + DWC_DEBUGPL(DBG_PCD, "DOEPCTL=%08x DOEPTSIZ=%08x\n",
5124 + dwc_read_reg32(&out_regs->doepctl),
5125 + dwc_read_reg32(&out_regs->doeptsiz));
5126 + DWC_DEBUGPL(DBG_PCD, "DAINTMSK=%08x GINTMSK=%08x\n",
5127 + dwc_read_reg32(&core_if->dev_if->dev_global_regs->
5128 + daintmsk),
5129 + dwc_read_reg32(&core_if->core_global_regs->gintmsk));
5130 +
5131 + SET_DEBUG_LEVEL(lvl);
5132 +#endif
5133 + DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s()\n", __func__);
5134 +
5135 + DWC_DEBUGPL(DBG_PCD, "ep%d-%s xfer_len=%d xfer_cnt=%d "
5136 + "xfer_buff=%p start_xfer_buff=%p\n",
5137 + ep->num, (ep->is_in ? "IN" : "OUT"), ep->xfer_len,
5138 + ep->xfer_count, ep->xfer_buff, ep->start_xfer_buff);
5139 +
5140 + /* IN endpoint */
5141 + if (ep->is_in == 1) {
5142 + struct dwc_otg_dev_in_ep_regs *in_regs =
5143 + core_if->dev_if->in_ep_regs[ep->num];
5144 + union gnptxsts_data txstatus;
5145 +
5146 + txstatus.d32 =
5147 + dwc_read_reg32(&core_if->core_global_regs->gnptxsts);
5148 + if (txstatus.b.nptxqspcavail == 0) {
5149 +#ifdef DEBUG
5150 + DWC_PRINT("TX Queue Full (0x%0x)\n", txstatus.d32);
5151 +#endif
5152 + return;
5153 + }
5154 +
5155 + depctl.d32 = dwc_read_reg32(&(in_regs->diepctl));
5156 + deptsiz.d32 = dwc_read_reg32(&(in_regs->dieptsiz));
5157 +
5158 + /* Zero Length Packet? */
5159 + if (ep->xfer_len == 0) {
5160 + deptsiz.b.xfersize = 0;
5161 + deptsiz.b.pktcnt = 1;
5162 + } else {
5163 +
5164 + /* Program the transfer size and packet count
5165 + * as follows: xfersize = N * maxpacket +
5166 + * short_packet pktcnt = N + (short_packet
5167 + * exist ? 1 : 0)
5168 + */
5169 + deptsiz.b.xfersize = ep->xfer_len;
5170 + deptsiz.b.pktcnt =
5171 + (ep->xfer_len - 1 + ep->maxpacket) /
5172 + ep->maxpacket;
5173 + }
5174 +
5175 + dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
5176 +
5177 + /* Write the DMA register */
5178 + if (core_if->dma_enable) {
5179 + dwc_write_reg32(&(in_regs->diepdma),
5180 + (uint32_t) ep->dma_addr);
5181 + } else {
5182 + /*
5183 + * Enable the Non-Periodic Tx FIFO empty interrupt,
5184 + * the data will be written into the fifo by the ISR.
5185 + */
5186 + intr_mask.b.nptxfempty = 1;
5187 + dwc_modify_reg32(&core_if->core_global_regs->gintsts,
5188 + intr_mask.d32, 0);
5189 + dwc_modify_reg32(&core_if->core_global_regs->gintmsk,
5190 + intr_mask.d32, intr_mask.d32);
5191 + }
5192 +
5193 + /* EP enable, IN data in FIFO */
5194 + depctl.b.cnak = 1;
5195 + depctl.b.epena = 1;
5196 + dwc_write_reg32(&in_regs->diepctl, depctl.d32);
5197 +
5198 + depctl.d32 =
5199 + dwc_read_reg32(&core_if->dev_if->in_ep_regs[0]->diepctl);
5200 + depctl.b.nextep = ep->num;
5201 + dwc_write_reg32(&core_if->dev_if->in_ep_regs[0]->diepctl,
5202 + depctl.d32);
5203 +
5204 + } else {
5205 + /* OUT endpoint */
5206 + struct dwc_otg_dev_out_ep_regs *out_regs =
5207 + core_if->dev_if->out_ep_regs[ep->num];
5208 +
5209 + depctl.d32 = dwc_read_reg32(&(out_regs->doepctl));
5210 + deptsiz.d32 = dwc_read_reg32(&(out_regs->doeptsiz));
5211 +
5212 + /* Program the transfer size and packet count as follows:
5213 + *
5214 + * pktcnt = N
5215 + * xfersize = N * maxpacket
5216 + */
5217 + if (ep->xfer_len == 0) {
5218 + /* Zero Length Packet */
5219 + deptsiz.b.xfersize = ep->maxpacket;
5220 + deptsiz.b.pktcnt = 1;
5221 + } else {
5222 + deptsiz.b.pktcnt =
5223 + (ep->xfer_len + (ep->maxpacket - 1)) /
5224 + ep->maxpacket;
5225 + deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket;
5226 + }
5227 + dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32);
5228 +
5229 + DWC_DEBUGPL(DBG_PCDV, "ep%d xfersize=%d pktcnt=%d\n",
5230 + ep->num, deptsiz.b.xfersize, deptsiz.b.pktcnt);
5231 +
5232 + if (core_if->dma_enable) {
5233 + dwc_write_reg32(&(out_regs->doepdma),
5234 + (uint32_t) ep->dma_addr);
5235 + }
5236 +
5237 + if (ep->type == DWC_OTG_EP_TYPE_ISOC) {
5238 + /*
5239 + * @todo NGS: dpid is read-only. Use setd0pid
5240 + * or setd1pid.
5241 + */
5242 + depctl.b.dpid = ep->even_odd_frame;
5243 + }
5244 +
5245 + /* EP enable */
5246 + depctl.b.cnak = 1;
5247 + depctl.b.epena = 1;
5248 +
5249 + dwc_write_reg32(&out_regs->doepctl, depctl.d32);
5250 +
5251 + DWC_DEBUGPL(DBG_PCD, "DOEPCTL=%08x DOEPTSIZ=%08x\n",
5252 + dwc_read_reg32(&out_regs->doepctl),
5253 + dwc_read_reg32(&out_regs->doeptsiz));
5254 + DWC_DEBUGPL(DBG_PCD, "DAINTMSK=%08x GINTMSK=%08x\n",
5255 + dwc_read_reg32(&core_if->dev_if->dev_global_regs->
5256 + daintmsk),
5257 + dwc_read_reg32(&core_if->core_global_regs->
5258 + gintmsk));
5259 + }
5260 +}
5261 +
5262 +/**
5263 + * This function does the setup for a data transfer for EP0 and starts
5264 + * the transfer. For an IN transfer, the packets will be loaded into
5265 + * the appropriate Tx FIFO in the ISR. For OUT transfers, the packets are
5266 + * unloaded from the Rx FIFO in the ISR.
5267 + *
5268 + * @core_if: Programming view of DWC_otg controller.
5269 + * @ep: The EP0 data.
5270 + */
5271 +void dwc_otg_ep0_start_transfer(struct dwc_otg_core_if *core_if,
5272 + struct dwc_ep *ep)
5273 +{
5274 + union depctl_data depctl;
5275 + union deptsiz0_data deptsiz;
5276 + union gintmsk_data intr_mask = {.d32 = 0 };
5277 +
5278 + DWC_DEBUGPL(DBG_PCD, "ep%d-%s xfer_len=%d xfer_cnt=%d "
5279 + "xfer_buff=%p start_xfer_buff=%p total_len=%d\n",
5280 + ep->num, (ep->is_in ? "IN" : "OUT"), ep->xfer_len,
5281 + ep->xfer_count, ep->xfer_buff, ep->start_xfer_buff,
5282 + ep->total_len);
5283 + ep->total_len = ep->xfer_len;
5284 +
5285 + /* IN endpoint */
5286 + if (ep->is_in == 1) {
5287 + struct dwc_otg_dev_in_ep_regs *in_regs =
5288 + core_if->dev_if->in_ep_regs[0];
5289 + union gnptxsts_data tx_status = {.d32 = 0 };
5290 +
5291 + tx_status.d32 =
5292 + dwc_read_reg32(&core_if->core_global_regs->gnptxsts);
5293 + if (tx_status.b.nptxqspcavail == 0) {
5294 +#ifdef DEBUG
5295 + deptsiz.d32 = dwc_read_reg32(&in_regs->dieptsiz);
5296 + DWC_DEBUGPL(DBG_PCD, "DIEPCTL0=%0x\n",
5297 + dwc_read_reg32(&in_regs->diepctl));
5298 + DWC_DEBUGPL(DBG_PCD, "DIEPTSIZ0=%0x (sz=%d, pcnt=%d)\n",
5299 + deptsiz.d32,
5300 + deptsiz.b.xfersize, deptsiz.b.pktcnt);
5301 + DWC_PRINT("TX Queue or FIFO Full (0x%0x)\n",
5302 + tx_status.d32);
5303 +#endif
5304 +
5305 + return;
5306 + }
5307 +
5308 + depctl.d32 = dwc_read_reg32(&in_regs->diepctl);
5309 + deptsiz.d32 = dwc_read_reg32(&in_regs->dieptsiz);
5310 +
5311 + /* Zero Length Packet? */
5312 + if (ep->xfer_len == 0) {
5313 + deptsiz.b.xfersize = 0;
5314 + deptsiz.b.pktcnt = 1;
5315 + } else {
5316 + /* Program the transfer size and packet count
5317 + * as follows: xfersize = N * maxpacket +
5318 + * short_packet pktcnt = N + (short_packet
5319 + * exist ? 1 : 0)
5320 + */
5321 + if (ep->xfer_len > ep->maxpacket) {
5322 + ep->xfer_len = ep->maxpacket;
5323 + deptsiz.b.xfersize = ep->maxpacket;
5324 + } else {
5325 + deptsiz.b.xfersize = ep->xfer_len;
5326 + }
5327 + deptsiz.b.pktcnt = 1;
5328 +
5329 + }
5330 + dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
5331 + DWC_DEBUGPL(DBG_PCDV,
5332 + "IN len=%d xfersize=%d pktcnt=%d [%08x]\n",
5333 + ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt,
5334 + deptsiz.d32);
5335 +
5336 + /* Write the DMA register */
5337 + if (core_if->dma_enable) {
5338 + dwc_write_reg32(&(in_regs->diepdma),
5339 + (uint32_t) ep->dma_addr);
5340 + }
5341 +
5342 + /* EP enable, IN data in FIFO */
5343 + depctl.b.cnak = 1;
5344 + depctl.b.epena = 1;
5345 + dwc_write_reg32(&in_regs->diepctl, depctl.d32);
5346 +
5347 + /*
5348 + * Enable the Non-Periodic Tx FIFO empty interrupt, the
5349 + * data will be written into the fifo by the ISR.
5350 + */
5351 + if (!core_if->dma_enable) {
5352 + /* First clear it from GINTSTS */
5353 + intr_mask.b.nptxfempty = 1;
5354 + dwc_modify_reg32(&core_if->core_global_regs->gintsts,
5355 + intr_mask.d32, 0);
5356 +
5357 + dwc_modify_reg32(&core_if->core_global_regs->gintmsk,
5358 + intr_mask.d32, intr_mask.d32);
5359 + }
5360 +
5361 + } else { /* OUT endpoint */
5362 + struct dwc_otg_dev_out_ep_regs *out_regs =
5363 + core_if->dev_if->out_ep_regs[ep->num];
5364 +
5365 + depctl.d32 = dwc_read_reg32(&out_regs->doepctl);
5366 + deptsiz.d32 = dwc_read_reg32(&out_regs->doeptsiz);
5367 +
5368 + /* Program the transfer size and packet count as follows:
5369 + * xfersize = N * (maxpacket + 4 - (maxpacket % 4))
5370 + * pktcnt = N */
5371 + if (ep->xfer_len == 0) {
5372 + /* Zero Length Packet */
5373 + deptsiz.b.xfersize = ep->maxpacket;
5374 + deptsiz.b.pktcnt = 1;
5375 + } else {
5376 + deptsiz.b.pktcnt =
5377 + (ep->xfer_len + (ep->maxpacket - 1)) /
5378 + ep->maxpacket;
5379 + deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket;
5380 + }
5381 +
5382 + dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32);
5383 + DWC_DEBUGPL(DBG_PCDV, "len=%d xfersize=%d pktcnt=%d\n",
5384 + ep->xfer_len,
5385 + deptsiz.b.xfersize, deptsiz.b.pktcnt);
5386 +
5387 + if (core_if->dma_enable) {
5388 + dwc_write_reg32(&(out_regs->doepdma),
5389 + (uint32_t) ep->dma_addr);
5390 + }
5391 +
5392 + /* EP enable */
5393 + depctl.b.cnak = 1;
5394 + depctl.b.epena = 1;
5395 + dwc_write_reg32(&(out_regs->doepctl), depctl.d32);
5396 + }
5397 +}
5398 +
5399 +/**
5400 + * This function continues control IN transfers started by
5401 + * dwc_otg_ep0_start_transfer, when the transfer does not fit in a
5402 + * single packet. NOTE: The DIEPCTL0/DOEPCTL0 registers only have one
5403 + * bit for the packet count.
5404 + *
5405 + * @core_if: Programming view of DWC_otg controller.
5406 + * @ep: The EP0 data.
5407 + */
5408 +void dwc_otg_ep0_continue_transfer(struct dwc_otg_core_if *core_if,
5409 + struct dwc_ep *ep)
5410 +{
5411 + union depctl_data depctl;
5412 + union deptsiz0_data deptsiz;
5413 + union gintmsk_data intr_mask = {.d32 = 0 };
5414 +
5415 + if (ep->is_in == 1) {
5416 + struct dwc_otg_dev_in_ep_regs *in_regs =
5417 + core_if->dev_if->in_ep_regs[0];
5418 + union gnptxsts_data tx_status = {.d32 = 0 };
5419 +
5420 + tx_status.d32 =
5421 + dwc_read_reg32(&core_if->core_global_regs->gnptxsts);
5422 + /*
5423 + * @todo Should there be check for room in the Tx
5424 + * Status Queue. If not remove the code above this comment.
5425 + */
5426 +
5427 + depctl.d32 = dwc_read_reg32(&in_regs->diepctl);
5428 + deptsiz.d32 = dwc_read_reg32(&in_regs->dieptsiz);
5429 +
5430 + /*
5431 + * Program the transfer size and packet count
5432 + * as follows: xfersize = N * maxpacket +
5433 + * short_packet pktcnt = N + (short_packet
5434 + * exist ? 1 : 0)
5435 + */
5436 + deptsiz.b.xfersize =
5437 + (ep->total_len - ep->xfer_count) >
5438 + ep->maxpacket ? ep->maxpacket : (ep->total_len -
5439 + ep->xfer_count);
5440 + deptsiz.b.pktcnt = 1;
5441 + ep->xfer_len += deptsiz.b.xfersize;
5442 +
5443 + dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
5444 + DWC_DEBUGPL(DBG_PCDV,
5445 + "IN len=%d xfersize=%d pktcnt=%d [%08x]\n",
5446 + ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt,
5447 + deptsiz.d32);
5448 +
5449 + /* Write the DMA register */
5450 + if (core_if->hwcfg2.b.architecture == DWC_INT_DMA_ARCH) {
5451 + dwc_write_reg32(&(in_regs->diepdma),
5452 + (uint32_t) ep->dma_addr);
5453 + }
5454 +
5455 + /* EP enable, IN data in FIFO */
5456 + depctl.b.cnak = 1;
5457 + depctl.b.epena = 1;
5458 + dwc_write_reg32(&in_regs->diepctl, depctl.d32);
5459 +
5460 + /*
5461 + * Enable the Non-Periodic Tx FIFO empty interrupt, the
5462 + * data will be written into the fifo by the ISR.
5463 + */
5464 + if (!core_if->dma_enable) {
5465 + /* First clear it from GINTSTS */
5466 + intr_mask.b.nptxfempty = 1;
5467 + dwc_write_reg32(&core_if->core_global_regs->gintsts,
5468 + intr_mask.d32);
5469 +
5470 + dwc_modify_reg32(&core_if->core_global_regs->gintmsk,
5471 + intr_mask.d32, intr_mask.d32);
5472 + }
5473 +
5474 + }
5475 +
5476 +}
5477 +
5478 +#ifdef DEBUG
5479 +void dump_msg(const u8 *buf, unsigned int length)
5480 +{
5481 + unsigned int start, num, i;
5482 + char line[52], *p;
5483 +
5484 + if (length >= 512)
5485 + return;
5486 + start = 0;
5487 + while (length > 0) {
5488 + num = min(length, 16u);
5489 + p = line;
5490 + for (i = 0; i < num; ++i) {
5491 + if (i == 8)
5492 + *p++ = ' ';
5493 + sprintf(p, " %02x", buf[i]);
5494 + p += 3;
5495 + }
5496 + *p = 0;
5497 + DWC_PRINT("%6x: %s\n", start, line);
5498 + buf += num;
5499 + start += num;
5500 + length -= num;
5501 + }
5502 +}
5503 +#else
5504 +static inline void dump_msg(const u8 *buf, unsigned int length)
5505 +{
5506 +}
5507 +#endif
5508 +
5509 +/**
5510 + * This function writes a packet into the Tx FIFO associated with the
5511 + * EP. For non-periodic EPs the non-periodic Tx FIFO is written. For
5512 + * periodic EPs the periodic Tx FIFO associated with the EP is written
5513 + * with all packets for the next micro-frame.
5514 + *
5515 + * @core_if: Programming view of DWC_otg controller.
5516 + * @ep: The EP to write packet for.
5517 + * @_dma: Indicates if DMA is being used.
5518 + */
5519 +void dwc_otg_ep_write_packet(struct dwc_otg_core_if *core_if,
5520 + struct dwc_ep *ep,
5521 + int _dma)
5522 +{
5523 + /**
5524 + * The buffer is padded to DWORD on a per packet basis in
5525 + * slave/dma mode if the MPS is not DWORD aligned. The last
5526 + * packet, if short, is also padded to a multiple of DWORD.
5527 + *
5528 + * ep->xfer_buff always starts DWORD aligned in memory and is a
5529 + * multiple of DWORD in length
5530 + *
5531 + * ep->xfer_len can be any number of bytes
5532 + *
5533 + * ep->xfer_count is a multiple of ep->maxpacket until the last
5534 + * packet
5535 + *
5536 + * FIFO access is DWORD */
5537 +
5538 + uint32_t i;
5539 + uint32_t byte_count;
5540 + uint32_t dword_count;
5541 + uint32_t *fifo;
5542 + uint32_t *data_buff = (uint32_t *) ep->xfer_buff;
5543 +
5544 + if (ep->xfer_count >= ep->xfer_len) {
5545 + DWC_WARN("%s() No data for EP%d!!!\n", __func__, ep->num);
5546 + return;
5547 + }
5548 +
5549 + /* Find the byte length of the packet either short packet or MPS */
5550 + if ((ep->xfer_len - ep->xfer_count) < ep->maxpacket)
5551 + byte_count = ep->xfer_len - ep->xfer_count;
5552 + else
5553 + byte_count = ep->maxpacket;
5554 +
5555 + /* Find the DWORD length, padded by extra bytes as neccessary if MPS
5556 + * is not a multiple of DWORD */
5557 + dword_count = (byte_count + 3) / 4;
5558 +
5559 +#ifdef VERBOSE
5560 + dump_msg(ep->xfer_buff, byte_count);
5561 +#endif
5562 + if (ep->type == DWC_OTG_EP_TYPE_ISOC)
5563 + /*
5564 + *@todo NGS Where are the Periodic Tx FIFO addresses
5565 + * intialized? What should this be?
5566 + */
5567 + fifo = core_if->data_fifo[ep->tx_fifo_num];
5568 + else
5569 + fifo = core_if->data_fifo[ep->num];
5570 +
5571 + DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "fifo=%p buff=%p *p=%08x bc=%d\n",
5572 + fifo, data_buff, *data_buff, byte_count);
5573 +
5574 + if (!_dma) {
5575 + for (i = 0; i < dword_count; i++, data_buff++)
5576 + dwc_write_reg32(fifo, *data_buff);
5577 + }
5578 +
5579 + ep->xfer_count += byte_count;
5580 + ep->xfer_buff += byte_count;
5581 +}
5582 +
5583 +/**
5584 + * Set the EP STALL.
5585 + *
5586 + * @core_if: Programming view of DWC_otg controller.
5587 + * @ep: The EP to set the stall on.
5588 + */
5589 +void dwc_otg_ep_set_stall(struct dwc_otg_core_if *core_if, struct dwc_ep *ep)
5590 +{
5591 + union depctl_data depctl;
5592 + uint32_t *depctl_addr;
5593 +
5594 + DWC_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, ep->num,
5595 + (ep->is_in ? "IN" : "OUT"));
5596 +
5597 + if (ep->is_in == 1) {
5598 + depctl_addr =
5599 + &(core_if->dev_if->in_ep_regs[ep->num]->diepctl);
5600 + depctl.d32 = dwc_read_reg32(depctl_addr);
5601 +
5602 + /* set the disable and stall bits */
5603 + if (depctl.b.epena)
5604 + depctl.b.epdis = 1;
5605 + depctl.b.stall = 1;
5606 + dwc_write_reg32(depctl_addr, depctl.d32);
5607 +
5608 + } else {
5609 + depctl_addr =
5610 + &(core_if->dev_if->out_ep_regs[ep->num]->doepctl);
5611 + depctl.d32 = dwc_read_reg32(depctl_addr);
5612 +
5613 + /* set the stall bit */
5614 + depctl.b.stall = 1;
5615 + dwc_write_reg32(depctl_addr, depctl.d32);
5616 + }
5617 + DWC_DEBUGPL(DBG_PCD, "DEPCTL=%0x\n", dwc_read_reg32(depctl_addr));
5618 + return;
5619 +}
5620 +
5621 +/**
5622 + * Clear the EP STALL.
5623 + *
5624 + * @core_if: Programming view of DWC_otg controller.
5625 + * @ep: The EP to clear stall from.
5626 + */
5627 +void dwc_otg_ep_clear_stall(struct dwc_otg_core_if *core_if, struct dwc_ep *ep)
5628 +{
5629 + union depctl_data depctl;
5630 + uint32_t *depctl_addr;
5631 +
5632 + DWC_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, ep->num,
5633 + (ep->is_in ? "IN" : "OUT"));
5634 +
5635 + if (ep->is_in == 1) {
5636 + depctl_addr =
5637 + &(core_if->dev_if->in_ep_regs[ep->num]->diepctl);
5638 + } else {
5639 + depctl_addr =
5640 + &(core_if->dev_if->out_ep_regs[ep->num]->doepctl);
5641 + }
5642 +
5643 + depctl.d32 = dwc_read_reg32(depctl_addr);
5644 +
5645 + /* clear the stall bits */
5646 + depctl.b.stall = 0;
5647 +
5648 + /*
5649 + * USB Spec 9.4.5: For endpoints using data toggle, regardless
5650 + * of whether an endpoint has the Halt feature set, a
5651 + * ClearFeature(ENDPOINT_HALT) request always results in the
5652 + * data toggle being reinitialized to DATA0.
5653 + */
5654 + if (ep->type == DWC_OTG_EP_TYPE_INTR ||
5655 + ep->type == DWC_OTG_EP_TYPE_BULK) {
5656 + depctl.b.setd0pid = 1; /* DATA0 */
5657 + }
5658 +
5659 + dwc_write_reg32(depctl_addr, depctl.d32);
5660 + DWC_DEBUGPL(DBG_PCD, "DEPCTL=%0x\n", dwc_read_reg32(depctl_addr));
5661 + return;
5662 +}
5663 +
5664 +/**
5665 + * This function reads a packet from the Rx FIFO into the destination
5666 + * buffer. To read SETUP data use dwc_otg_read_setup_packet.
5667 + *
5668 + * @core_if: Programming view of DWC_otg controller.
5669 + * @dest: Destination buffer for the packet.
5670 + * @bytes: Number of bytes to copy to the destination.
5671 + */
5672 +void dwc_otg_read_packet(struct dwc_otg_core_if *core_if,
5673 + uint8_t *dest, uint16_t bytes)
5674 +{
5675 + int i;
5676 + int word_count = (bytes + 3) / 4;
5677 +
5678 + uint32_t *fifo = core_if->data_fifo[0];
5679 + uint32_t *data_buff = (uint32_t *) dest;
5680 +
5681 + /**
5682 + * @todo Account for the case where dest is not dword aligned. This
5683 + * requires reading data from the FIFO into a uint32_t temp buffer,
5684 + * then moving it into the data buffer.
5685 + */
5686 +
5687 + DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s(%p,%p,%d)\n", __func__,
5688 + core_if, dest, bytes);
5689 +
5690 + for (i = 0; i < word_count; i++, data_buff++)
5691 + *data_buff = dwc_read_reg32(fifo);
5692 + return;
5693 +}
5694 +
5695 +/**
5696 + * This functions reads the device registers and prints them
5697 + *
5698 + * @core_if: Programming view of DWC_otg controller.
5699 + */
5700 +void dwc_otg_dump_dev_registers(struct dwc_otg_core_if *core_if)
5701 +{
5702 + int i;
5703 + uint32_t *addr;
5704 +
5705 + DWC_PRINT("Device Global Registers\n");
5706 + addr = &core_if->dev_if->dev_global_regs->dcfg;
5707 + DWC_PRINT("DCFG @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5708 + addr = &core_if->dev_if->dev_global_regs->dctl;
5709 + DWC_PRINT("DCTL @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5710 + addr = &core_if->dev_if->dev_global_regs->dsts;
5711 + DWC_PRINT("DSTS @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5712 + addr = &core_if->dev_if->dev_global_regs->diepmsk;
5713 + DWC_PRINT("DIEPMSK @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5714 + addr = &core_if->dev_if->dev_global_regs->doepmsk;
5715 + DWC_PRINT("DOEPMSK @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5716 + addr = &core_if->dev_if->dev_global_regs->daint;
5717 + DWC_PRINT("DAINT @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5718 + addr = &core_if->dev_if->dev_global_regs->dtknqr1;
5719 + DWC_PRINT("DTKNQR1 @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5720 + if (core_if->hwcfg2.b.dev_token_q_depth > 6) {
5721 + addr = &core_if->dev_if->dev_global_regs->dtknqr2;
5722 + DWC_PRINT("DTKNQR2 @%p : 0x%08X\n",
5723 + addr, dwc_read_reg32(addr));
5724 + }
5725 +
5726 + addr = &core_if->dev_if->dev_global_regs->dvbusdis;
5727 + DWC_PRINT("DVBUSID @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5728 +
5729 + addr = &core_if->dev_if->dev_global_regs->dvbuspulse;
5730 + DWC_PRINT("DVBUSPULSE @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5731 +
5732 + if (core_if->hwcfg2.b.dev_token_q_depth > 14) {
5733 + addr = &core_if->dev_if->dev_global_regs->dtknqr3;
5734 + DWC_PRINT("DTKNQR3 @%p : 0x%08X\n",
5735 + addr, dwc_read_reg32(addr));
5736 + }
5737 +
5738 + if (core_if->hwcfg2.b.dev_token_q_depth > 22) {
5739 + addr = &core_if->dev_if->dev_global_regs->dtknqr4;
5740 + DWC_PRINT("DTKNQR4 @%p : 0x%08X\n",
5741 + addr, dwc_read_reg32(addr));
5742 + }
5743 +
5744 + for (i = 0; i < core_if->dev_if->num_eps; i++) {
5745 + DWC_PRINT("Device IN EP %d Registers\n", i);
5746 + addr = &core_if->dev_if->in_ep_regs[i]->diepctl;
5747 + DWC_PRINT("DIEPCTL @%p : 0x%08X\n", addr,
5748 + dwc_read_reg32(addr));
5749 + addr = &core_if->dev_if->in_ep_regs[i]->diepint;
5750 + DWC_PRINT("DIEPINT @%p : 0x%08X\n", addr,
5751 + dwc_read_reg32(addr));
5752 + addr = &core_if->dev_if->in_ep_regs[i]->dieptsiz;
5753 + DWC_PRINT("DIETSIZ @%p : 0x%08X\n", addr,
5754 + dwc_read_reg32(addr));
5755 + addr = &core_if->dev_if->in_ep_regs[i]->diepdma;
5756 + DWC_PRINT("DIEPDMA @%p : 0x%08X\n", addr,
5757 + dwc_read_reg32(addr));
5758 +
5759 + DWC_PRINT("Device OUT EP %d Registers\n", i);
5760 + addr = &core_if->dev_if->out_ep_regs[i]->doepctl;
5761 + DWC_PRINT("DOEPCTL @%p : 0x%08X\n", addr,
5762 + dwc_read_reg32(addr));
5763 + addr = &core_if->dev_if->out_ep_regs[i]->doepfn;
5764 + DWC_PRINT("DOEPFN @%p : 0x%08X\n", addr,
5765 + dwc_read_reg32(addr));
5766 + addr = &core_if->dev_if->out_ep_regs[i]->doepint;
5767 + DWC_PRINT("DOEPINT @%p : 0x%08X\n", addr,
5768 + dwc_read_reg32(addr));
5769 + addr = &core_if->dev_if->out_ep_regs[i]->doeptsiz;
5770 + DWC_PRINT("DOETSIZ @%p : 0x%08X\n", addr,
5771 + dwc_read_reg32(addr));
5772 + addr = &core_if->dev_if->out_ep_regs[i]->doepdma;
5773 + DWC_PRINT("DOEPDMA @%p : 0x%08X\n", addr,
5774 + dwc_read_reg32(addr));
5775 + }
5776 + return;
5777 +}
5778 +
5779 +/**
5780 + * This function reads the host registers and prints them
5781 + *
5782 + * @core_if: Programming view of DWC_otg controller.
5783 + */
5784 +void dwc_otg_dump_host_registers(struct dwc_otg_core_if *core_if)
5785 +{
5786 + int i;
5787 + uint32_t *addr;
5788 +
5789 + DWC_PRINT("Host Global Registers\n");
5790 + addr = &core_if->host_if->host_global_regs->hcfg;
5791 + DWC_PRINT("HCFG @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5792 + addr = &core_if->host_if->host_global_regs->hfir;
5793 + DWC_PRINT("HFIR @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5794 + addr = &core_if->host_if->host_global_regs->hfnum;
5795 + DWC_PRINT("HFNUM @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5796 + addr = &core_if->host_if->host_global_regs->hptxsts;
5797 + DWC_PRINT("HPTXSTS @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5798 + addr = &core_if->host_if->host_global_regs->haint;
5799 + DWC_PRINT("HAINT @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5800 + addr = &core_if->host_if->host_global_regs->haintmsk;
5801 + DWC_PRINT("HAINTMSK @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5802 + addr = core_if->host_if->hprt0;
5803 + DWC_PRINT("HPRT0 @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5804 +
5805 + for (i = 0; i < core_if->core_params->host_channels; i++) {
5806 + DWC_PRINT("Host Channel %d Specific Registers\n", i);
5807 + addr = &core_if->host_if->hc_regs[i]->hcchar;
5808 + DWC_PRINT("HCCHAR @%p : 0x%08X\n", addr,
5809 + dwc_read_reg32(addr));
5810 + addr = &core_if->host_if->hc_regs[i]->hcsplt;
5811 + DWC_PRINT("HCSPLT @%p : 0x%08X\n", addr,
5812 + dwc_read_reg32(addr));
5813 + addr = &core_if->host_if->hc_regs[i]->hcint;
5814 + DWC_PRINT("HCINT @%p : 0x%08X\n", addr,
5815 + dwc_read_reg32(addr));
5816 + addr = &core_if->host_if->hc_regs[i]->hcintmsk;
5817 + DWC_PRINT("HCINTMSK @%p : 0x%08X\n", addr,
5818 + dwc_read_reg32(addr));
5819 + addr = &core_if->host_if->hc_regs[i]->hctsiz;
5820 + DWC_PRINT("HCTSIZ @%p : 0x%08X\n", addr,
5821 + dwc_read_reg32(addr));
5822 + addr = &core_if->host_if->hc_regs[i]->hcdma;
5823 + DWC_PRINT("HCDMA @%p : 0x%08X\n", addr,
5824 + dwc_read_reg32(addr));
5825 +
5826 + }
5827 + return;
5828 +}
5829 +
5830 +/**
5831 + * This function reads the core global registers and prints them
5832 + *
5833 + * @core_if: Programming view of DWC_otg controller.
5834 + */
5835 +void dwc_otg_dump_global_registers(struct dwc_otg_core_if *core_if)
5836 +{
5837 + int i;
5838 + uint32_t *addr;
5839 +
5840 + DWC_PRINT("Core Global Registers\n");
5841 + addr = &core_if->core_global_regs->gotgctl;
5842 + DWC_PRINT("GOTGCTL @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5843 + addr = &core_if->core_global_regs->gotgint;
5844 + DWC_PRINT("GOTGINT @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5845 + addr = &core_if->core_global_regs->gahbcfg;
5846 + DWC_PRINT("GAHBCFG @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5847 + addr = &core_if->core_global_regs->gusbcfg;
5848 + DWC_PRINT("GUSBCFG @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5849 + addr = &core_if->core_global_regs->grstctl;
5850 + DWC_PRINT("GRSTCTL @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5851 + addr = &core_if->core_global_regs->gintsts;
5852 + DWC_PRINT("GINTSTS @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5853 + addr = &core_if->core_global_regs->gintmsk;
5854 + DWC_PRINT("GINTMSK @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5855 + addr = &core_if->core_global_regs->grxstsr;
5856 + DWC_PRINT("GRXSTSR @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5857 + addr = &core_if->core_global_regs->grxfsiz;
5858 + DWC_PRINT("GRXFSIZ @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5859 + addr = &core_if->core_global_regs->gnptxfsiz;
5860 + DWC_PRINT("GNPTXFSIZ @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5861 + addr = &core_if->core_global_regs->gnptxsts;
5862 + DWC_PRINT("GNPTXSTS @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5863 + addr = &core_if->core_global_regs->gi2cctl;
5864 + DWC_PRINT("GI2CCTL @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5865 + addr = &core_if->core_global_regs->gpvndctl;
5866 + DWC_PRINT("GPVNDCTL @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5867 + addr = &core_if->core_global_regs->ggpio;
5868 + DWC_PRINT("GGPIO @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5869 + addr = &core_if->core_global_regs->guid;
5870 + DWC_PRINT("GUID @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5871 + addr = &core_if->core_global_regs->gsnpsid;
5872 + DWC_PRINT("GSNPSID @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5873 + addr = &core_if->core_global_regs->ghwcfg1;
5874 + DWC_PRINT("GHWCFG1 @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5875 + addr = &core_if->core_global_regs->ghwcfg2;
5876 + DWC_PRINT("GHWCFG2 @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5877 + addr = &core_if->core_global_regs->ghwcfg3;
5878 + DWC_PRINT("GHWCFG3 @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5879 + addr = &core_if->core_global_regs->ghwcfg4;
5880 + DWC_PRINT("GHWCFG4 @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5881 + addr = &core_if->core_global_regs->hptxfsiz;
5882 + DWC_PRINT("HPTXFSIZ @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5883 +
5884 + for (i = 0; i < core_if->hwcfg4.b.num_dev_perio_in_ep; i++) {
5885 + addr = &core_if->core_global_regs->dptxfsiz[i];
5886 + DWC_PRINT("DPTXFSIZ[%d] @%p : 0x%08X\n", i, addr,
5887 + dwc_read_reg32(addr));
5888 + }
5889 +
5890 +}
5891 +
5892 +/**
5893 + * Flush a Tx FIFO.
5894 + *
5895 + * @core_if: Programming view of DWC_otg controller.
5896 + * @_num: Tx FIFO to flush.
5897 + */
5898 +extern void dwc_otg_flush_tx_fifo(struct dwc_otg_core_if *core_if, const int _num)
5899 +{
5900 + struct dwc_otg_core_global_regs *global_regs = core_if->core_global_regs;
5901 + union grstctl_data greset = {.d32 = 0 };
5902 + int count = 0;
5903 +
5904 + DWC_DEBUGPL((DBG_CIL | DBG_PCDV), "Flush Tx FIFO %d\n", _num);
5905 +
5906 + greset.b.txfflsh = 1;
5907 + greset.b.txfnum = _num;
5908 + dwc_write_reg32(&global_regs->grstctl, greset.d32);
5909 +
5910 + do {
5911 + greset.d32 = dwc_read_reg32(&global_regs->grstctl);
5912 + if (++count > 10000) {
5913 + DWC_WARN("%s() HANG! GRSTCTL=%0x GNPTXSTS=0x%08x\n",
5914 + __func__, greset.d32,
5915 + dwc_read_reg32(&global_regs->gnptxsts));
5916 + break;
5917 + }
5918 +
5919 + } while (greset.b.txfflsh == 1);
5920 + /* Wait for 3 PHY Clocks */
5921 + udelay(1);
5922 +}
5923 +
5924 +/**
5925 + * Flush Rx FIFO.
5926 + *
5927 + * @core_if: Programming view of DWC_otg controller.
5928 + */
5929 +extern void dwc_otg_flush_rx_fifo(struct dwc_otg_core_if *core_if)
5930 +{
5931 + struct dwc_otg_core_global_regs *global_regs = core_if->core_global_regs;
5932 + union grstctl_data greset = {.d32 = 0 };
5933 + int count = 0;
5934 +
5935 + DWC_DEBUGPL((DBG_CIL | DBG_PCDV), "%s\n", __func__);
5936 + /*
5937 + *
5938 + */
5939 + greset.b.rxfflsh = 1;
5940 + dwc_write_reg32(&global_regs->grstctl, greset.d32);
5941 +
5942 + do {
5943 + greset.d32 = dwc_read_reg32(&global_regs->grstctl);
5944 + if (++count > 10000) {
5945 + DWC_WARN("%s() HANG! GRSTCTL=%0x\n", __func__,
5946 + greset.d32);
5947 + break;
5948 + }
5949 + } while (greset.b.rxfflsh == 1);
5950 + /* Wait for 3 PHY Clocks */
5951 + udelay(1);
5952 +}
5953 +
5954 +/**
5955 + * Do core a soft reset of the core. Be careful with this because it
5956 + * resets all the internal state machines of the core.
5957 + */
5958 +void dwc_otg_core_reset(struct dwc_otg_core_if *core_if)
5959 +{
5960 + struct dwc_otg_core_global_regs *global_regs = core_if->core_global_regs;
5961 + union grstctl_data greset = {.d32 = 0 };
5962 + int count = 0;
5963 +
5964 + DWC_DEBUGPL(DBG_CILV, "%s\n", __func__);
5965 + /* Wait for AHB master IDLE state. */
5966 + do {
5967 + udelay(10);
5968 + greset.d32 = dwc_read_reg32(&global_regs->grstctl);
5969 + if (++count > 100000) {
5970 + DWC_WARN("%s() HANG! AHB Idle GRSTCTL=%0x\n", __func__,
5971 + greset.d32);
5972 + return;
5973 + }
5974 + } while (greset.b.ahbidle == 0);
5975 +
5976 + /* Core Soft Reset */
5977 + count = 0;
5978 + greset.b.csftrst = 1;
5979 + dwc_write_reg32(&global_regs->grstctl, greset.d32);
5980 + do {
5981 + greset.d32 = dwc_read_reg32(&global_regs->grstctl);
5982 + if (++count > 10000) {
5983 + DWC_WARN("%s() HANG! Soft Reset GRSTCTL=%0x\n",
5984 + __func__, greset.d32);
5985 + break;
5986 + }
5987 + } while (greset.b.csftrst == 1);
5988 + /* Wait for 3 PHY Clocks */
5989 + mdelay(100);
5990 +}
5991 +
5992 +/**
5993 + * Register HCD callbacks. The callbacks are used to start and stop
5994 + * the HCD for interrupt processing.
5995 + *
5996 + * @core_if: Programming view of DWC_otg controller.
5997 + * @_cb: the HCD callback structure.
5998 + * @_p: pointer to be passed to callback function (usb_hcd*).
5999 + */
6000 +extern void dwc_otg_cil_register_hcd_callbacks(struct dwc_otg_core_if *core_if,
6001 + struct dwc_otg_cil_callbacks *_cb,
6002 + void *_p)
6003 +{
6004 + core_if->hcd_cb = _cb;
6005 + _cb->p = _p;
6006 +}
6007 +
6008 +/**
6009 + * Register PCD callbacks. The callbacks are used to start and stop
6010 + * the PCD for interrupt processing.
6011 + *
6012 + * @core_if: Programming view of DWC_otg controller.
6013 + * @_cb: the PCD callback structure.
6014 + * @_p: pointer to be passed to callback function (pcd*).
6015 + */
6016 +extern void dwc_otg_cil_register_pcd_callbacks(struct dwc_otg_core_if *core_if,
6017 + struct dwc_otg_cil_callbacks *_cb,
6018 + void *_p)
6019 +{
6020 + core_if->pcd_cb = _cb;
6021 + _cb->p = _p;
6022 +}
6023 diff --git a/drivers/usb/host/dwc_otg/dwc_otg_cil.h b/drivers/usb/host/dwc_otg/dwc_otg_cil.h
6024 new file mode 100644
6025 index 0000000..36ef561
6026 --- /dev/null
6027 +++ b/drivers/usb/host/dwc_otg/dwc_otg_cil.h
6028 @@ -0,0 +1,866 @@
6029 +/* ==========================================================================
6030 + *
6031 + * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
6032 + * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
6033 + * otherwise expressly agreed to in writing between Synopsys and you.
6034 + *
6035 + * The Software IS NOT an item of Licensed Software or Licensed Product under
6036 + * any End User Software License Agreement or Agreement for Licensed Product
6037 + * with Synopsys or any supplement thereto. You are permitted to use and
6038 + * redistribute this Software in source and binary forms, with or without
6039 + * modification, provided that redistributions of source code must retain this
6040 + * notice. You may not view, use, disclose, copy or distribute this file or
6041 + * any information contained herein except pursuant to this license grant from
6042 + * Synopsys. If you do not agree with this notice, including the disclaimer
6043 + * below, then you are not authorized to use the Software.
6044 + *
6045 + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
6046 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
6047 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
6048 + * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
6049 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
6050 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
6051 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
6052 + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
6053 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
6054 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
6055 + * DAMAGE.
6056 + * ========================================================================== */
6057 +
6058 +#if !defined(__DWC_CIL_H__)
6059 +#define __DWC_CIL_H__
6060 +
6061 +#include "dwc_otg_plat.h"
6062 +#include "dwc_otg_regs.h"
6063 +#ifdef DEBUG
6064 +#include "linux/timer.h"
6065 +#endif
6066 +
6067 +/*
6068 + * This file contains the interface to the Core Interface Layer.
6069 + */
6070 +
6071 +/**
6072 + * The <code>dwc_ep</code> structure represents the state of a single
6073 + * endpoint when acting in device mode. It contains the data items
6074 + * needed for an endpoint to be activated and transfer packets.
6075 + */
6076 +struct dwc_ep {
6077 + /** EP number used for register address lookup */
6078 + uint8_t num;
6079 + /** EP direction 0 = OUT */
6080 + unsigned is_in:1;
6081 + /** EP active. */
6082 + unsigned active:1;
6083 +
6084 + /*
6085 + * Periodic Tx FIFO # for IN EPs For INTR EP set to 0 to use
6086 + * non-periodic Tx FIFO
6087 + */
6088 + unsigned tx_fifo_num:4;
6089 + /** EP type: 0 - Control, 1 - ISOC, 2 - BULK, 3 - INTR */
6090 + unsigned type:2;
6091 +#define DWC_OTG_EP_TYPE_CONTROL 0
6092 +#define DWC_OTG_EP_TYPE_ISOC 1
6093 +#define DWC_OTG_EP_TYPE_BULK 2
6094 +#define DWC_OTG_EP_TYPE_INTR 3
6095 +
6096 + /** DATA start PID for INTR and BULK EP */
6097 + unsigned data_pid_start:1;
6098 + /** Frame (even/odd) for ISOC EP */
6099 + unsigned even_odd_frame:1;
6100 + /** Max Packet bytes */
6101 + unsigned maxpacket:11;
6102 +
6103 + /** @name Transfer state */
6104 + /** @{ */
6105 +
6106 + /**
6107 + * Pointer to the beginning of the transfer buffer -- do not modify
6108 + * during transfer.
6109 + */
6110 +
6111 + uint32_t dma_addr;
6112 +
6113 + uint8_t *start_xfer_buff;
6114 + /** pointer to the transfer buffer */
6115 + uint8_t *xfer_buff;
6116 + /** Number of bytes to transfer */
6117 + unsigned xfer_len:19;
6118 + /** Number of bytes transferred. */
6119 + unsigned xfer_count:19;
6120 + /** Sent ZLP */
6121 + unsigned sent_zlp:1;
6122 + /** Total len for control transfer */
6123 + unsigned total_len:19;
6124 +
6125 + /** @} */
6126 +};
6127 +
6128 +/*
6129 + * Reasons for halting a host channel.
6130 + */
6131 +enum dwc_otg_halt_status {
6132 + DWC_OTG_HC_XFER_NO_HALT_STATUS,
6133 + DWC_OTG_HC_XFER_COMPLETE,
6134 + DWC_OTG_HC_XFER_URB_COMPLETE,
6135 + DWC_OTG_HC_XFER_ACK,
6136 + DWC_OTG_HC_XFER_NAK,
6137 + DWC_OTG_HC_XFER_NYET,
6138 + DWC_OTG_HC_XFER_STALL,
6139 + DWC_OTG_HC_XFER_XACT_ERR,
6140 + DWC_OTG_HC_XFER_FRAME_OVERRUN,
6141 + DWC_OTG_HC_XFER_BABBLE_ERR,
6142 + DWC_OTG_HC_XFER_DATA_TOGGLE_ERR,
6143 + DWC_OTG_HC_XFER_AHB_ERR,
6144 + DWC_OTG_HC_XFER_PERIODIC_INCOMPLETE,
6145 + DWC_OTG_HC_XFER_URB_DEQUEUE
6146 +};
6147 +
6148 +/**
6149 + * Host channel descriptor. This structure represents the state of a single
6150 + * host channel when acting in host mode. It contains the data items needed to
6151 + * transfer packets to an endpoint via a host channel.
6152 + */
6153 +struct dwc_hc {
6154 + /** Host channel number used for register address lookup */
6155 + uint8_t hc_num;
6156 +
6157 + /** Device to access */
6158 + unsigned dev_addr:7;
6159 +
6160 + /** EP to access */
6161 + unsigned ep_num:4;
6162 +
6163 + /** EP direction. 0: OUT, 1: IN */
6164 + unsigned ep_is_in:1;
6165 +
6166 + /**
6167 + * EP speed.
6168 + * One of the following values:
6169 + * - DWC_OTG_EP_SPEED_LOW
6170 + * - DWC_OTG_EP_SPEED_FULL
6171 + * - DWC_OTG_EP_SPEED_HIGH
6172 + */
6173 + unsigned speed:2;
6174 +#define DWC_OTG_EP_SPEED_LOW 0
6175 +#define DWC_OTG_EP_SPEED_FULL 1
6176 +#define DWC_OTG_EP_SPEED_HIGH 2
6177 +
6178 + /**
6179 + * Endpoint type.
6180 + * One of the following values:
6181 + * - DWC_OTG_EP_TYPE_CONTROL: 0
6182 + * - DWC_OTG_EP_TYPE_ISOC: 1
6183 + * - DWC_OTG_EP_TYPE_BULK: 2
6184 + * - DWC_OTG_EP_TYPE_INTR: 3
6185 + */
6186 + unsigned ep_type:2;
6187 +
6188 + /** Max packet size in bytes */
6189 + unsigned max_packet:11;
6190 +
6191 + /**
6192 + * PID for initial transaction.
6193 + * 0: DATA0,<br>
6194 + * 1: DATA2,<br>
6195 + * 2: DATA1,<br>
6196 + * 3: MDATA (non-Control EP),
6197 + * SETUP (Control EP)
6198 + */
6199 + unsigned data_pid_start:2;
6200 +#define DWC_OTG_HC_PID_DATA0 0
6201 +#define DWC_OTG_HC_PID_DATA2 1
6202 +#define DWC_OTG_HC_PID_DATA1 2
6203 +#define DWC_OTG_HC_PID_MDATA 3
6204 +#define DWC_OTG_HC_PID_SETUP 3
6205 +
6206 + /** Number of periodic transactions per (micro)frame */
6207 + unsigned multi_count:2;
6208 +
6209 + /** @name Transfer State */
6210 + /** @{ */
6211 +
6212 + /** Pointer to the current transfer buffer position. */
6213 + uint8_t *xfer_buff;
6214 + /** Total number of bytes to transfer. */
6215 + uint32_t xfer_len;
6216 + /** Number of bytes transferred so far. */
6217 + uint32_t xfer_count;
6218 + /** Packet count at start of transfer.*/
6219 + uint16_t start_pkt_count;
6220 +
6221 + /**
6222 + * Flag to indicate whether the transfer has been started. Set to 1 if
6223 + * it has been started, 0 otherwise.
6224 + */
6225 + uint8_t xfer_started;
6226 +
6227 + /**
6228 + * Set to 1 to indicate that a PING request should be issued on this
6229 + * channel. If 0, process normally.
6230 + */
6231 + uint8_t do_ping;
6232 +
6233 + /**
6234 + * Set to 1 to indicate that the error count for this transaction is
6235 + * non-zero. Set to 0 if the error count is 0.
6236 + */
6237 + uint8_t error_state;
6238 +
6239 + /**
6240 + * Set to 1 to indicate that this channel should be halted the next
6241 + * time a request is queued for the channel. This is necessary in
6242 + * slave mode if no request queue space is available when an attempt
6243 + * is made to halt the channel.
6244 + */
6245 + uint8_t halt_on_queue;
6246 +
6247 + /**
6248 + * Set to 1 if the host channel has been halted, but the core is not
6249 + * finished flushing queued requests. Otherwise 0.
6250 + */
6251 + uint8_t halt_pending;
6252 +
6253 + /**
6254 + * Reason for halting the host channel.
6255 + */
6256 + enum dwc_otg_halt_status halt_status;
6257 +
6258 + /*
6259 + * Split settings for the host channel
6260 + */
6261 + uint8_t do_split; /**< Enable split for the channel */
6262 + uint8_t complete_split; /**< Enable complete split */
6263 + uint8_t hub_addr; /**< Address of high speed hub */
6264 +
6265 + uint8_t port_addr; /**< Port of the low/full speed device */
6266 + /** Split transaction position
6267 + * One of the following values:
6268 + * - DWC_HCSPLIT_XACTPOS_MID
6269 + * - DWC_HCSPLIT_XACTPOS_BEGIN
6270 + * - DWC_HCSPLIT_XACTPOS_END
6271 + * - DWC_HCSPLIT_XACTPOS_ALL */
6272 + uint8_t xact_pos;
6273 +
6274 + /** Set when the host channel does a short read. */
6275 + uint8_t short_read;
6276 +
6277 + /**
6278 + * Number of requests issued for this channel since it was assigned to
6279 + * the current transfer (not counting PINGs).
6280 + */
6281 + uint8_t requests;
6282 +
6283 + /**
6284 + * Queue Head for the transfer being processed by this channel.
6285 + */
6286 + struct dwc_otg_qh *qh;
6287 +
6288 + /** @} */
6289 +
6290 + /** Entry in list of host channels. */
6291 + struct list_head hc_list_entry;
6292 +};
6293 +
6294 +/**
6295 + * The following parameters may be specified when starting the module. These
6296 + * parameters define how the DWC_otg controller should be configured.
6297 + * Parameter values are passed to the CIL initialization function
6298 + * dwc_otg_cil_init.
6299 + */
6300 +struct dwc_otg_core_params {
6301 + int32_t opt;
6302 +#define dwc_param_opt_default 1
6303 +
6304 + /*
6305 + * Specifies the OTG capabilities. The driver will automatically
6306 + * detect the value for this parameter if none is specified.
6307 + * 0 - HNP and SRP capable (default)
6308 + * 1 - SRP Only capable
6309 + * 2 - No HNP/SRP capable
6310 + */
6311 + int32_t otg_cap;
6312 +#define DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE 0
6313 +#define DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE 1
6314 +#define DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE 2
6315 +#define dwc_param_otg_cap_default DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE
6316 +
6317 + /*
6318 + * Specifies whether to use slave or DMA mode for accessing the data
6319 + * FIFOs. The driver will automatically detect the value for this
6320 + * parameter if none is specified.
6321 + * 0 - Slave
6322 + * 1 - DMA (default, if available)
6323 + */
6324 + int32_t dma_enable;
6325 +#define dwc_param_dma_enable_default 1
6326 +
6327 + /*
6328 + * The DMA Burst size (applicable only for External DMA
6329 + * Mode). 1, 4, 8 16, 32, 64, 128, 256 (default 32)
6330 + */
6331 + int32_t dma_burst_size; /* Translate this to GAHBCFG values */
6332 +#define dwc_param_dma_burst_size_default 32
6333 +
6334 + /*
6335 + * Specifies the maximum speed of operation in host and device mode.
6336 + * The actual speed depends on the speed of the attached device and
6337 + * the value of phy_type. The actual speed depends on the speed of the
6338 + * attached device.
6339 + * 0 - High Speed (default)
6340 + * 1 - Full Speed
6341 + */
6342 + int32_t speed;
6343 +#define dwc_param_speed_default 0
6344 +#define DWC_SPEED_PARAM_HIGH 0
6345 +#define DWC_SPEED_PARAM_FULL 1
6346 +
6347 + /** Specifies whether low power mode is supported when attached
6348 + * to a Full Speed or Low Speed device in host mode.
6349 + * 0 - Don't support low power mode (default)
6350 + * 1 - Support low power mode
6351 + */
6352 + int32_t host_support_fs_ls_low_power;
6353 +#define dwc_param_host_support_fs_ls_low_power_default 0
6354 +
6355 + /** Specifies the PHY clock rate in low power mode when connected to a
6356 + * Low Speed device in host mode. This parameter is applicable only if
6357 + * HOST_SUPPORT_FS_LS_LOW_POWER is enabled. If PHY_TYPE is set to FS
6358 + * then defaults to 6 MHZ otherwise 48 MHZ.
6359 + *
6360 + * 0 - 48 MHz
6361 + * 1 - 6 MHz
6362 + */
6363 + int32_t host_ls_low_power_phy_clk;
6364 +#define dwc_param_host_ls_low_power_phy_clk_default 0
6365 +#define DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ 0
6366 +#define DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ 1
6367 +
6368 + /**
6369 + * 0 - Use cC FIFO size parameters
6370 + * 1 - Allow dynamic FIFO sizing (default)
6371 + */
6372 + int32_t enable_dynamic_fifo;
6373 +#define dwc_param_enable_dynamic_fifo_default 1
6374 +
6375 + /** Total number of 4-byte words in the data FIFO memory. This
6376 + * memory includes the Rx FIFO, non-periodic Tx FIFO, and periodic
6377 + * Tx FIFOs.
6378 + * 32 to 32768 (default 8192)
6379 + * Note: The total FIFO memory depth in the FPGA configuration is 8192.
6380 + */
6381 + int32_t data_fifo_size;
6382 +#define dwc_param_data_fifo_size_default 8192
6383 +
6384 + /** Number of 4-byte words in the Rx FIFO in device mode when dynamic
6385 + * FIFO sizing is enabled.
6386 + * 16 to 32768 (default 1064)
6387 + */
6388 + int32_t dev_rx_fifo_size;
6389 +#define dwc_param_dev_rx_fifo_size_default 1064
6390 +
6391 + /** Number of 4-byte words in the non-periodic Tx FIFO in device mode
6392 + * when dynamic FIFO sizing is enabled.
6393 + * 16 to 32768 (default 1024)
6394 + */
6395 + int32_t dev_nperio_tx_fifo_size;
6396 +#define dwc_param_dev_nperio_tx_fifo_size_default 1024
6397 +
6398 + /** Number of 4-byte words in each of the periodic Tx FIFOs in device
6399 + * mode when dynamic FIFO sizing is enabled.
6400 + * 4 to 768 (default 256)
6401 + */
6402 + uint32_t dev_perio_tx_fifo_size[MAX_PERIO_FIFOS];
6403 +#define dwc_param_dev_perio_tx_fifo_size_default 256
6404 +
6405 + /** Number of 4-byte words in the Rx FIFO in host mode when dynamic
6406 + * FIFO sizing is enabled.
6407 + * 16 to 32768 (default 1024)
6408 + */
6409 + int32_t host_rx_fifo_size;
6410 +#define dwc_param_host_rx_fifo_size_default 1024
6411 +#define dwc_param_host_rx_fifo_size_percentage 30
6412 +
6413 + /** Number of 4-byte words in the non-periodic Tx FIFO in host mode
6414 + * when Dynamic FIFO sizing is enabled in the core.
6415 + * 16 to 32768 (default 1024)
6416 + */
6417 + int32_t host_nperio_tx_fifo_size;
6418 +#define dwc_param_host_nperio_tx_fifo_size_default 1024
6419 +#define dwc_param_host_nperio_tx_fifo_size_percentage 40
6420 +
6421 + /*
6422 + * Number of 4-byte words in the host periodic Tx FIFO when dynamic
6423 + * FIFO sizing is enabled.
6424 + * 16 to 32768 (default 1024)
6425 + */
6426 + int32_t host_perio_tx_fifo_size;
6427 +#define dwc_param_host_perio_tx_fifo_size_default 1024
6428 +#define dwc_param_host_perio_tx_fifo_size_percentage 30
6429 +
6430 + /*
6431 + * The maximum transfer size supported in bytes.
6432 + * 2047 to 65,535 (default 65,535)
6433 + */
6434 + int32_t max_transfer_size;
6435 +#define dwc_param_max_transfer_size_default 65535
6436 +
6437 + /*
6438 + * The maximum number of packets in a transfer.
6439 + * 15 to 511 (default 511)
6440 + */
6441 + int32_t max_packet_count;
6442 +#define dwc_param_max_packet_count_default 511
6443 +
6444 + /*
6445 + * The number of host channel registers to use.
6446 + * 1 to 16 (default 12)
6447 + * Note: The FPGA configuration supports a maximum of 12 host channels.
6448 + */
6449 + int32_t host_channels;
6450 +#define dwc_param_host_channels_default 12
6451 +
6452 + /*
6453 + * The number of endpoints in addition to EP0 available for device
6454 + * mode operations.
6455 + * 1 to 15 (default 6 IN and OUT)
6456 + * Note: The FPGA configuration supports a maximum of 6 IN and OUT
6457 + * endpoints in addition to EP0.
6458 + */
6459 + int32_t dev_endpoints;
6460 +#define dwc_param_dev_endpoints_default 6
6461 +
6462 + /*
6463 + * Specifies the type of PHY interface to use. By default, the driver
6464 + * will automatically detect the phy_type.
6465 + *
6466 + * 0 - Full Speed PHY
6467 + * 1 - UTMI+ (default)
6468 + * 2 - ULPI
6469 + */
6470 + int32_t phy_type;
6471 +#define DWC_PHY_TYPE_PARAM_FS 0
6472 +#define DWC_PHY_TYPE_PARAM_UTMI 1
6473 +#define DWC_PHY_TYPE_PARAM_ULPI 2
6474 +#define dwc_param_phy_type_default DWC_PHY_TYPE_PARAM_UTMI
6475 +
6476 + /*
6477 + * Specifies the UTMI+ Data Width. This parameter is
6478 + * applicable for a PHY_TYPE of UTMI+ or ULPI. (For a ULPI
6479 + * PHY_TYPE, this parameter indicates the data width between
6480 + * the MAC and the ULPI Wrapper.) Also, this parameter is
6481 + * applicable only if the OTG_HSPHY_WIDTH cC parameter was set
6482 + * to "8 and 16 bits", meaning that the core has been
6483 + * configured to work at either data path width.
6484 + *
6485 + * 8 or 16 bits (default 16)
6486 + */
6487 + int32_t phy_utmi_width;
6488 +#define dwc_param_phy_utmi_width_default 16
6489 +
6490 + /*
6491 + * Specifies whether the ULPI operates at double or single
6492 + * data rate. This parameter is only applicable if PHY_TYPE is
6493 + * ULPI.
6494 + *
6495 + * 0 - single data rate ULPI interface with 8 bit wide data
6496 + * bus (default)
6497 + * 1 - double data rate ULPI interface with 4 bit wide data
6498 + * bus
6499 + */
6500 + int32_t phy_ulpi_ddr;
6501 +#define dwc_param_phy_ulpi_ddr_default 0
6502 +
6503 + /*
6504 + * Specifies whether to use the internal or external supply to
6505 + * drive the vbus with a ULPI phy.
6506 + */
6507 + int32_t phy_ulpi_ext_vbus;
6508 +#define DWC_PHY_ULPI_INTERNAL_VBUS 0
6509 +#define DWC_PHY_ULPI_EXTERNAL_VBUS 1
6510 +#define dwc_param_phy_ulpi_ext_vbus_default DWC_PHY_ULPI_INTERNAL_VBUS
6511 +
6512 + /*
6513 + * Specifies whether to use the I2Cinterface for full speed PHY. This
6514 + * parameter is only applicable if PHY_TYPE is FS.
6515 + * 0 - No (default)
6516 + * 1 - Yes
6517 + */
6518 + int32_t i2c_enable;
6519 +#define dwc_param_i2c_enable_default 0
6520 +
6521 + int32_t ulpi_fs_ls;
6522 +#define dwc_param_ulpi_fs_ls_default 0
6523 +
6524 + int32_t ts_dline;
6525 +#define dwc_param_ts_dline_default 0
6526 +
6527 +};
6528 +
6529 +/**
6530 + * The FIFOs are established based on a default percentage of the total
6531 + * FIFO depth. This check insures that the defaults are reasonable.
6532 + */
6533 +#if (((dwc_param_host_rx_fifo_size_percentage) \
6534 + +(dwc_param_host_nperio_tx_fifo_size_percentage) \
6535 + +(dwc_param_host_perio_tx_fifo_size_percentage)) > 100)
6536 +#error Invalid FIFO allocation
6537 +#endif
6538 +
6539 +#ifdef DEBUG
6540 +struct dwc_otg_core_if;
6541 +struct hc_xfer_info {
6542 + struct dwc_otg_core_if *core_if;
6543 + struct dwc_hc *hc;
6544 +};
6545 +#endif
6546 +
6547 +/*
6548 + * The <code>dwc_otg_core_if</code> structure contains information
6549 + * needed to manage the DWC_otg controller acting in either host or
6550 + * device mode. It represents the programming view of the controller
6551 + * as a whole.
6552 + */
6553 +struct dwc_otg_core_if {
6554 + /** USB block index number for Octeon's that support multiple */
6555 + int usb_num;
6556 +
6557 + /** Parameters that define how the core should be configured.*/
6558 + struct dwc_otg_core_params *core_params;
6559 +
6560 + /** Core Global registers starting at offset 000h. */
6561 + struct dwc_otg_core_global_regs *core_global_regs;
6562 +
6563 + /** Device-specific information */
6564 + struct dwc_otg_dev_if *dev_if;
6565 + /** Host-specific information */
6566 + struct dwc_otg_host_if *host_if;
6567 +
6568 + /*
6569 + * Set to 1 if the core PHY interface bits in USBCFG have been
6570 + * initialized.
6571 + */
6572 + uint8_t phy_init_done;
6573 +
6574 + /*
6575 + * SRP Success flag, set by srp success interrupt in FS I2C mode
6576 + */
6577 + uint8_t srp_success;
6578 + uint8_t srp_timer_started;
6579 +
6580 + /* Common configuration information */
6581 + /** Power and Clock Gating Control Register */
6582 + uint32_t *pcgcctl;
6583 +#define DWC_OTG_PCGCCTL_OFFSET 0xE00
6584 +
6585 + /** Push/pop addresses for endpoints or host channels.*/
6586 + uint32_t *data_fifo[MAX_EPS_CHANNELS];
6587 +#define DWC_OTG_DATA_FIFO_OFFSET 0x1000
6588 +#define DWC_OTG_DATA_FIFO_SIZE 0x1000
6589 +
6590 + /** Total RAM for FIFOs (Bytes) */
6591 + uint16_t total_fifo_size;
6592 + /** Size of Rx FIFO (Bytes) */
6593 + uint16_t rx_fifo_size;
6594 + /** Size of Non-periodic Tx FIFO (Bytes) */
6595 + uint16_t nperio_tx_fifo_size;
6596 +
6597 + /** 1 if DMA is enabled, 0 otherwise. */
6598 + uint8_t dma_enable;
6599 +
6600 + /** Set to 1 if multiple packets of a high-bandwidth transfer is in
6601 + * process of being queued */
6602 + uint8_t queuing_high_bandwidth;
6603 +
6604 + /** Hardware Configuration -- stored here for convenience.*/
6605 + union hwcfg1_data hwcfg1;
6606 + union hwcfg2_data hwcfg2;
6607 + union hwcfg3_data hwcfg3;
6608 + union hwcfg4_data hwcfg4;
6609 +
6610 + /*
6611 + * The operational State, during transations
6612 + * (a_host>>a_peripherial and b_device=>b_host) this may not
6613 + * match the core but allows the software to determine
6614 + * transitions.
6615 + */
6616 + uint8_t op_state;
6617 +
6618 + /*
6619 + * Set to 1 if the HCD needs to be restarted on a session request
6620 + * interrupt. This is required if no connector ID status change has
6621 + * occurred since the HCD was last disconnected.
6622 + */
6623 + uint8_t restart_hcd_on_session_req;
6624 +
6625 + /** HCD callbacks */
6626 + /** A-Device is a_host */
6627 +#define A_HOST (1)
6628 + /** A-Device is a_suspend */
6629 +#define A_SUSPEND (2)
6630 + /** A-Device is a_peripherial */
6631 +#define A_PERIPHERAL (3)
6632 + /** B-Device is operating as a Peripheral. */
6633 +#define B_PERIPHERAL (4)
6634 + /** B-Device is operating as a Host. */
6635 +#define B_HOST (5)
6636 +
6637 + /** HCD callbacks */
6638 + struct dwc_otg_cil_callbacks *hcd_cb;
6639 + /** PCD callbacks */
6640 + struct dwc_otg_cil_callbacks *pcd_cb;
6641 +
6642 +#ifdef DEBUG
6643 + uint32_t start_hcchar_val[MAX_EPS_CHANNELS];
6644 +
6645 + struct hc_xfer_info hc_xfer_info[MAX_EPS_CHANNELS];
6646 + struct timer_list hc_xfer_timer[MAX_EPS_CHANNELS];
6647 +
6648 + uint32_t hfnum_7_samples;
6649 + uint64_t hfnum_7_frrem_accum;
6650 + uint32_t hfnum_0_samples;
6651 + uint64_t hfnum_0_frrem_accum;
6652 + uint32_t hfnum_other_samples;
6653 + uint64_t hfnum_other_frrem_accum;
6654 +#endif
6655 +
6656 +};
6657 +
6658 +/*
6659 + * The following functions support initialization of the CIL driver component
6660 + * and the DWC_otg controller.
6661 + */
6662 +extern struct dwc_otg_core_if *dwc_otg_cil_init(const uint32_t *reg_base_addr,
6663 + struct dwc_otg_core_params *
6664 + _core_params);
6665 +extern void dwc_otg_cil_remove(struct dwc_otg_core_if *core_if);
6666 +extern void dwc_otg_core_init(struct dwc_otg_core_if *core_if);
6667 +extern void dwc_otg_core_host_init(struct dwc_otg_core_if *core_if);
6668 +extern void dwc_otg_core_dev_init(struct dwc_otg_core_if *core_if);
6669 +extern void dwc_otg_enable_global_interrupts(struct dwc_otg_core_if *core_if);
6670 +extern void dwc_otg_disable_global_interrupts(struct dwc_otg_core_if *core_if);
6671 +
6672 +/* Device CIL Functions
6673 + * The following functions support managing the DWC_otg controller in device
6674 + * mode.
6675 + */
6676 +
6677 +extern void dwc_otg_wakeup(struct dwc_otg_core_if *core_if);
6678 +extern void dwc_otg_read_setup_packet(struct dwc_otg_core_if *core_if,
6679 + uint32_t *dest);
6680 +extern uint32_t dwc_otg_get_frame_number(struct dwc_otg_core_if *core_if);
6681 +extern void dwc_otg_ep0_activate(struct dwc_otg_core_if *core_if,
6682 + struct dwc_ep *ep);
6683 +extern void dwc_otg_ep_activate(struct dwc_otg_core_if *core_if,
6684 + struct dwc_ep *ep);
6685 +extern void dwc_otg_ep_deactivate(struct dwc_otg_core_if *core_if,
6686 + struct dwc_ep *ep);
6687 +extern void dwc_otg_ep_start_transfer(struct dwc_otg_core_if *core_if,
6688 + struct dwc_ep *ep);
6689 +extern void dwc_otg_ep0_start_transfer(struct dwc_otg_core_if *core_if,
6690 + struct dwc_ep *ep);
6691 +extern void dwc_otg_ep0_continue_transfer(struct dwc_otg_core_if *core_if,
6692 + struct dwc_ep *ep);
6693 +extern void dwc_otg_ep_write_packet(struct dwc_otg_core_if *core_if,
6694 + struct dwc_ep *ep, int _dma);
6695 +extern void dwc_otg_ep_set_stall(struct dwc_otg_core_if *core_if,
6696 + struct dwc_ep *ep);
6697 +extern void dwc_otg_ep_clear_stall(struct dwc_otg_core_if *core_if,
6698 + struct dwc_ep *ep);
6699 +extern void dwc_otg_enable_device_interrupts(struct dwc_otg_core_if *core_if);
6700 +extern void dwc_otg_dump_dev_registers(struct dwc_otg_core_if *core_if);
6701 +
6702 +/* Host CIL Functions
6703 + * The following functions support managing the DWC_otg controller in host
6704 + * mode.
6705 + */
6706 +
6707 +extern void dwc_otg_hc_init(struct dwc_otg_core_if *core_if, struct dwc_hc *hc);
6708 +extern void dwc_otg_hc_halt(struct dwc_otg_core_if *core_if,
6709 + struct dwc_hc *hc,
6710 + enum dwc_otg_halt_status halt_status);
6711 +extern void dwc_otg_hc_cleanup(struct dwc_otg_core_if *core_if,
6712 + struct dwc_hc *hc);
6713 +extern void dwc_otg_hc_start_transfer(struct dwc_otg_core_if *core_if,
6714 + struct dwc_hc *hc);
6715 +extern int dwc_otg_hc_continue_transfer(struct dwc_otg_core_if *core_if,
6716 + struct dwc_hc *hc);
6717 +extern void dwc_otg_hc_do_ping(struct dwc_otg_core_if *core_if,
6718 + struct dwc_hc *hc);
6719 +extern void dwc_otg_hc_write_packet(struct dwc_otg_core_if *core_if,
6720 + struct dwc_hc *hc);
6721 +extern void dwc_otg_enable_host_interrupts(struct dwc_otg_core_if *core_if);
6722 +extern void dwc_otg_disable_host_interrupts(struct dwc_otg_core_if *core_if);
6723 +
6724 +/**
6725 + * This function Reads HPRT0 in preparation to modify. It keeps the
6726 + * WC bits 0 so that if they are read as 1, they won't clear when you
6727 + * write it back
6728 + */
6729 +static inline uint32_t dwc_otg_read_hprt0(struct dwc_otg_core_if *core_if)
6730 +{
6731 + union hprt0_data hprt0;
6732 + hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
6733 + hprt0.b.prtena = 0;
6734 + hprt0.b.prtconndet = 0;
6735 + hprt0.b.prtenchng = 0;
6736 + hprt0.b.prtovrcurrchng = 0;
6737 + return hprt0.d32;
6738 +}
6739 +
6740 +extern void dwc_otg_dump_host_registers(struct dwc_otg_core_if *core_if);
6741 +
6742 +/* Common CIL Functions
6743 + * The following functions support managing the DWC_otg controller in either
6744 + * device or host mode.
6745 + */
6746 +
6747 +
6748 +extern void dwc_otg_read_packet(struct dwc_otg_core_if *core_if,
6749 + uint8_t *dest, uint16_t bytes);
6750 +
6751 +extern void dwc_otg_dump_global_registers(struct dwc_otg_core_if *core_if);
6752 +
6753 +extern void dwc_otg_flush_tx_fifo(struct dwc_otg_core_if *core_if,
6754 + const int _num);
6755 +extern void dwc_otg_flush_rx_fifo(struct dwc_otg_core_if *core_if);
6756 +extern void dwc_otg_core_reset(struct dwc_otg_core_if *core_if);
6757 +
6758 +/**
6759 + * This function returns the Core Interrupt register.
6760 + */
6761 +static inline uint32_t dwc_otg_read_core_intr(struct dwc_otg_core_if *core_if)
6762 +{
6763 + return dwc_read_reg32(&core_if->core_global_regs->gintsts) &
6764 + dwc_read_reg32(&core_if->core_global_regs->gintmsk);
6765 +}
6766 +
6767 +/**
6768 + * This function returns the OTG Interrupt register.
6769 + */
6770 +static inline uint32_t dwc_otg_read_otg_intr(struct dwc_otg_core_if *core_if)
6771 +{
6772 + return dwc_read_reg32(&core_if->core_global_regs->gotgint);
6773 +}
6774 +
6775 +/**
6776 + * This function reads the Device All Endpoints Interrupt register and
6777 + * returns the IN endpoint interrupt bits.
6778 + */
6779 +static inline uint32_t dwc_otg_read_dev_all_in_ep_intr(struct dwc_otg_core_if *
6780 + core_if)
6781 +{
6782 + uint32_t v;
6783 + v = dwc_read_reg32(&core_if->dev_if->dev_global_regs->daint) &
6784 + dwc_read_reg32(&core_if->dev_if->dev_global_regs->daintmsk);
6785 + return v & 0xffff;
6786 +
6787 +}
6788 +
6789 +/**
6790 + * This function reads the Device All Endpoints Interrupt register and
6791 + * returns the OUT endpoint interrupt bits.
6792 + */
6793 +static inline uint32_t
6794 +dwc_otg_read_dev_all_out_ep_intr(struct dwc_otg_core_if *core_if)
6795 +{
6796 + uint32_t v;
6797 + v = dwc_read_reg32(&core_if->dev_if->dev_global_regs->daint) &
6798 + dwc_read_reg32(&core_if->dev_if->dev_global_regs->daintmsk);
6799 + return (v & 0xffff0000) >> 16;
6800 +}
6801 +
6802 +/**
6803 + * This function returns the Device IN EP Interrupt register
6804 + */
6805 +static inline uint32_t
6806 +dwc_otg_read_dev_in_ep_intr(struct dwc_otg_core_if *core_if, struct dwc_ep *ep)
6807 +{
6808 + struct dwc_otg_dev_if *dev_if = core_if->dev_if;
6809 + uint32_t v;
6810 + v = dwc_read_reg32(&dev_if->in_ep_regs[ep->num]->diepint) &
6811 + dwc_read_reg32(&dev_if->dev_global_regs->diepmsk);
6812 + return v;
6813 +}
6814 +
6815 +/**
6816 + * This function returns the Device OUT EP Interrupt register
6817 + */
6818 +static inline uint32_t dwc_otg_read_dev_out_ep_intr(struct dwc_otg_core_if *
6819 + core_if, struct dwc_ep *ep)
6820 +{
6821 + struct dwc_otg_dev_if *dev_if = core_if->dev_if;
6822 + uint32_t v;
6823 + v = dwc_read_reg32(&dev_if->out_ep_regs[ep->num]->doepint) &
6824 + dwc_read_reg32(&dev_if->dev_global_regs->diepmsk);
6825 + return v;
6826 +}
6827 +
6828 +/**
6829 + * This function returns the Host All Channel Interrupt register
6830 + */
6831 +static inline uint32_t
6832 +dwc_otg_read_host_all_channels_intr(struct dwc_otg_core_if *core_if)
6833 +{
6834 + return dwc_read_reg32(&core_if->host_if->host_global_regs->haint);
6835 +}
6836 +
6837 +static inline uint32_t
6838 +dwc_otg_read_host_channel_intr(struct dwc_otg_core_if *core_if,
6839 + struct dwc_hc *hc)
6840 +{
6841 + return dwc_read_reg32(&core_if->host_if->hc_regs[hc->hc_num]->hcint);
6842 +}
6843 +
6844 +/**
6845 + * This function returns the mode of the operation, host or device.
6846 + *
6847 + * Returns 0 - Device Mode, 1 - Host Mode
6848 + */
6849 +static inline uint32_t dwc_otg_mode(struct dwc_otg_core_if *core_if)
6850 +{
6851 + return dwc_read_reg32(&core_if->core_global_regs->gintsts) & 0x1;
6852 +}
6853 +
6854 +static inline uint8_t dwc_otg_is_device_mode(struct dwc_otg_core_if *core_if)
6855 +{
6856 + return dwc_otg_mode(core_if) != DWC_HOST_MODE;
6857 +}
6858 +
6859 +static inline uint8_t dwc_otg_is_host_mode(struct dwc_otg_core_if *core_if)
6860 +{
6861 + return dwc_otg_mode(core_if) == DWC_HOST_MODE;
6862 +}
6863 +
6864 +extern int32_t dwc_otg_handle_common_intr(struct dwc_otg_core_if *core_if);
6865 +
6866 +/*
6867 + * DWC_otg CIL callback structure. This structure allows the HCD and
6868 + * PCD to register functions used for starting and stopping the PCD
6869 + * and HCD for role change on for a DRD.
6870 + */
6871 +struct dwc_otg_cil_callbacks {
6872 + /* Start function for role change */
6873 + int (*start) (void *p);
6874 + /* Stop Function for role change */
6875 + int (*stop) (void *p);
6876 + /* Disconnect Function for role change */
6877 + int (*disconnect) (void *p);
6878 + /* Resume/Remote wakeup Function */
6879 + int (*resume_wakeup) (void *p);
6880 + /* Suspend function */
6881 + int (*suspend) (void *p);
6882 + /* Session Start (SRP) */
6883 + int (*session_start) (void *p);
6884 + /* Pointer passed to start() and stop() */
6885 + void *p;
6886 +};
6887 +
6888 +extern void dwc_otg_cil_register_pcd_callbacks(struct dwc_otg_core_if *core_if,
6889 + struct dwc_otg_cil_callbacks *cb,
6890 + void *p);
6891 +extern void dwc_otg_cil_register_hcd_callbacks(struct dwc_otg_core_if *core_if,
6892 + struct dwc_otg_cil_callbacks *cb,
6893 + void *p);
6894 +#endif
6895 diff --git a/drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c b/drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c
6896 new file mode 100644
6897 index 0000000..38c46df
6898 --- /dev/null
6899 +++ b/drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c
6900 @@ -0,0 +1,689 @@
6901 +/* ==========================================================================
6902 + * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
6903 + * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
6904 + * otherwise expressly agreed to in writing between Synopsys and you.
6905 + *
6906 + * The Software IS NOT an item of Licensed Software or Licensed Product under
6907 + * any End User Software License Agreement or Agreement for Licensed Product
6908 + * with Synopsys or any supplement thereto. You are permitted to use and
6909 + * redistribute this Software in source and binary forms, with or without
6910 + * modification, provided that redistributions of source code must retain this
6911 + * notice. You may not view, use, disclose, copy or distribute this file or
6912 + * any information contained herein except pursuant to this license grant from
6913 + * Synopsys. If you do not agree with this notice, including the disclaimer
6914 + * below, then you are not authorized to use the Software.
6915 + *
6916 + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
6917 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
6918 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
6919 + * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
6920 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
6921 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
6922 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
6923 + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
6924 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
6925 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
6926 + * DAMAGE.
6927 + * ========================================================================== */
6928 +
6929 +/**
6930 + *
6931 + * The Core Interface Layer provides basic services for accessing and
6932 + * managing the DWC_otg hardware. These services are used by both the
6933 + * Host Controller Driver and the Peripheral Controller Driver.
6934 + *
6935 + * This file contains the Common Interrupt handlers.
6936 + */
6937 +#include "dwc_otg_plat.h"
6938 +#include "dwc_otg_regs.h"
6939 +#include "dwc_otg_cil.h"
6940 +
6941 +#ifdef DEBUG
6942 +inline const char *op_state_str(struct dwc_otg_core_if *core_if)
6943 +{
6944 + return (core_if->op_state == A_HOST ? "a_host" :
6945 + (core_if->op_state == A_SUSPEND ? "a_suspend" :
6946 + (core_if->op_state == A_PERIPHERAL ? "a_peripheral" :
6947 + (core_if->op_state == B_PERIPHERAL ? "b_peripheral" :
6948 + (core_if->op_state == B_HOST ? "b_host" : "unknown")))));
6949 +}
6950 +#endif
6951 +
6952 +/** This function will log a debug message
6953 + *
6954 + * @core_if: Programming view of DWC_otg controller.
6955 + */
6956 +int32_t dwc_otg_handle_mode_mismatch_intr(struct dwc_otg_core_if *core_if)
6957 +{
6958 + union gintsts_data gintsts;
6959 + DWC_WARN("Mode Mismatch Interrupt: currently in %s mode\n",
6960 + dwc_otg_mode(core_if) ? "Host" : "Device");
6961 +
6962 + /* Clear interrupt */
6963 + gintsts.d32 = 0;
6964 + gintsts.b.modemismatch = 1;
6965 + dwc_write_reg32(&core_if->core_global_regs->gintsts, gintsts.d32);
6966 + return 1;
6967 +}
6968 +
6969 +/** Start the HCD. Helper function for using the HCD callbacks.
6970 + *
6971 + * @core_if: Programming view of DWC_otg controller.
6972 + */
6973 +static inline void hcd_start(struct dwc_otg_core_if *core_if)
6974 +{
6975 + if (core_if->hcd_cb && core_if->hcd_cb->start)
6976 + core_if->hcd_cb->start(core_if->hcd_cb->p);
6977 +}
6978 +
6979 +/** Stop the HCD. Helper function for using the HCD callbacks.
6980 + *
6981 + * @core_if: Programming view of DWC_otg controller.
6982 + */
6983 +static inline void hcd_stop(struct dwc_otg_core_if *core_if)
6984 +{
6985 + if (core_if->hcd_cb && core_if->hcd_cb->stop)
6986 + core_if->hcd_cb->stop(core_if->hcd_cb->p);
6987 +}
6988 +
6989 +/** Disconnect the HCD. Helper function for using the HCD callbacks.
6990 + *
6991 + * @core_if: Programming view of DWC_otg controller.
6992 + */
6993 +static inline void hcd_disconnect(struct dwc_otg_core_if *core_if)
6994 +{
6995 + if (core_if->hcd_cb && core_if->hcd_cb->disconnect)
6996 + core_if->hcd_cb->disconnect(core_if->hcd_cb->p);
6997 +}
6998 +
6999 +/** Inform the HCD the a New Session has begun. Helper function for
7000 + * using the HCD callbacks.
7001 + *
7002 + * @core_if: Programming view of DWC_otg controller.
7003 + */
7004 +static inline void hcd_session_start(struct dwc_otg_core_if *core_if)
7005 +{
7006 + if (core_if->hcd_cb && core_if->hcd_cb->session_start)
7007 + core_if->hcd_cb->session_start(core_if->hcd_cb->p);
7008 +}
7009 +
7010 +/** Start the PCD. Helper function for using the PCD callbacks.
7011 + *
7012 + * @core_if: Programming view of DWC_otg controller.
7013 + */
7014 +static inline void pcd_start(struct dwc_otg_core_if *core_if)
7015 +{
7016 + if (core_if->pcd_cb && core_if->pcd_cb->start)
7017 + core_if->pcd_cb->start(core_if->pcd_cb->p);
7018 +}
7019 +
7020 +/** Stop the PCD. Helper function for using the PCD callbacks.
7021 + *
7022 + * @core_if: Programming view of DWC_otg controller.
7023 + */
7024 +static inline void pcd_stop(struct dwc_otg_core_if *core_if)
7025 +{
7026 + if (core_if->pcd_cb && core_if->pcd_cb->stop)
7027 + core_if->pcd_cb->stop(core_if->pcd_cb->p);
7028 +}
7029 +
7030 +/** Suspend the PCD. Helper function for using the PCD callbacks.
7031 + *
7032 + * @core_if: Programming view of DWC_otg controller.
7033 + */
7034 +static inline void pcd_suspend(struct dwc_otg_core_if *core_if)
7035 +{
7036 + if (core_if->pcd_cb && core_if->pcd_cb->suspend)
7037 + core_if->pcd_cb->suspend(core_if->pcd_cb->p);
7038 +}
7039 +
7040 +/** Resume the PCD. Helper function for using the PCD callbacks.
7041 + *
7042 + * @core_if: Programming view of DWC_otg controller.
7043 + */
7044 +static inline void pcd_resume(struct dwc_otg_core_if *core_if)
7045 +{
7046 + if (core_if->pcd_cb && core_if->pcd_cb->resume_wakeup)
7047 + core_if->pcd_cb->resume_wakeup(core_if->pcd_cb->p);
7048 +}
7049 +
7050 +/**
7051 + * This function handles the OTG Interrupts. It reads the OTG
7052 + * Interrupt Register (GOTGINT) to determine what interrupt has
7053 + * occurred.
7054 + *
7055 + * @core_if: Programming view of DWC_otg controller.
7056 + */
7057 +int32_t dwc_otg_handle_otg_intr(struct dwc_otg_core_if *core_if)
7058 +{
7059 + struct dwc_otg_core_global_regs *global_regs = core_if->core_global_regs;
7060 + union gotgint_data gotgint;
7061 + union gotgctl_data gotgctl;
7062 + union gintmsk_data gintmsk;
7063 +
7064 + gotgint.d32 = dwc_read_reg32(&global_regs->gotgint);
7065 + gotgctl.d32 = dwc_read_reg32(&global_regs->gotgctl);
7066 + DWC_DEBUGPL(DBG_CIL, "++OTG Interrupt gotgint=%0x [%s]\n", gotgint.d32,
7067 + op_state_str(core_if));
7068 +
7069 + if (gotgint.b.sesenddet) {
7070 + DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: "
7071 + "Session End Detected++ (%s)\n",
7072 + op_state_str(core_if));
7073 + gotgctl.d32 = dwc_read_reg32(&global_regs->gotgctl);
7074 +
7075 + if (core_if->op_state == B_HOST) {
7076 + pcd_start(core_if);
7077 + core_if->op_state = B_PERIPHERAL;
7078 + } else {
7079 + /* If not B_HOST and Device HNP still set. HNP
7080 + * Did not succeed!*/
7081 + if (gotgctl.b.devhnpen) {
7082 + DWC_DEBUGPL(DBG_ANY, "Session End Detected\n");
7083 + DWC_ERROR("Device Not Connected/Responding!\n");
7084 + }
7085 +
7086 + /* If Session End Detected the B-Cable has
7087 + * been disconnected. */
7088 + /* Reset PCD and Gadget driver to a
7089 + * clean state. */
7090 + pcd_stop(core_if);
7091 + }
7092 + gotgctl.d32 = 0;
7093 + gotgctl.b.devhnpen = 1;
7094 + dwc_modify_reg32(&global_regs->gotgctl, gotgctl.d32, 0);
7095 + }
7096 + if (gotgint.b.sesreqsucstschng) {
7097 + DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: "
7098 + "Session Reqeust Success Status Change++\n");
7099 + gotgctl.d32 = dwc_read_reg32(&global_regs->gotgctl);
7100 + if (gotgctl.b.sesreqscs) {
7101 + if ((core_if->core_params->phy_type ==
7102 + DWC_PHY_TYPE_PARAM_FS)
7103 + && (core_if->core_params->i2c_enable)) {
7104 + core_if->srp_success = 1;
7105 + } else {
7106 + pcd_resume(core_if);
7107 + /* Clear Session Request */
7108 + gotgctl.d32 = 0;
7109 + gotgctl.b.sesreq = 1;
7110 + dwc_modify_reg32(&global_regs->gotgctl,
7111 + gotgctl.d32, 0);
7112 + }
7113 + }
7114 + }
7115 + if (gotgint.b.hstnegsucstschng) {
7116 + /* Print statements during the HNP interrupt handling
7117 + * can cause it to fail.*/
7118 + gotgctl.d32 = dwc_read_reg32(&global_regs->gotgctl);
7119 + if (gotgctl.b.hstnegscs) {
7120 + if (dwc_otg_is_host_mode(core_if)) {
7121 + core_if->op_state = B_HOST;
7122 + /*
7123 + * Need to disable SOF interrupt immediately.
7124 + * When switching from device to host, the PCD
7125 + * interrupt handler won't handle the
7126 + * interrupt if host mode is already set. The
7127 + * HCD interrupt handler won't get called if
7128 + * the HCD state is HALT. This means that the
7129 + * interrupt does not get handled and Linux
7130 + * complains loudly.
7131 + */
7132 + gintmsk.d32 = 0;
7133 + gintmsk.b.sofintr = 1;
7134 + dwc_modify_reg32(&global_regs->gintmsk,
7135 + gintmsk.d32, 0);
7136 + pcd_stop(core_if);
7137 + /*
7138 + * Initialize the Core for Host mode.
7139 + */
7140 + hcd_start(core_if);
7141 + core_if->op_state = B_HOST;
7142 + }
7143 + } else {
7144 + gotgctl.d32 = 0;
7145 + gotgctl.b.hnpreq = 1;
7146 + gotgctl.b.devhnpen = 1;
7147 + dwc_modify_reg32(&global_regs->gotgctl, gotgctl.d32, 0);
7148 + DWC_DEBUGPL(DBG_ANY, "HNP Failed\n");
7149 + DWC_ERROR("Device Not Connected/Responding\n");
7150 + }
7151 + }
7152 + if (gotgint.b.hstnegdet) {
7153 + /* The disconnect interrupt is set at the same time as
7154 + * Host Negotiation Detected. During the mode
7155 + * switch all interrupts are cleared so the disconnect
7156 + * interrupt handler will not get executed.
7157 + */
7158 + DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: "
7159 + "Host Negotiation Detected++ (%s)\n",
7160 + (dwc_otg_is_host_mode(core_if) ? "Host" :
7161 + "Device"));
7162 + if (dwc_otg_is_device_mode(core_if)) {
7163 + DWC_DEBUGPL(DBG_ANY, "a_suspend->a_peripheral (%d)\n",
7164 + core_if->op_state);
7165 + hcd_disconnect(core_if);
7166 + pcd_start(core_if);
7167 + core_if->op_state = A_PERIPHERAL;
7168 + } else {
7169 + /*
7170 + * Need to disable SOF interrupt immediately. When
7171 + * switching from device to host, the PCD interrupt
7172 + * handler won't handle the interrupt if host mode is
7173 + * already set. The HCD interrupt handler won't get
7174 + * called if the HCD state is HALT. This means that
7175 + * the interrupt does not get handled and Linux
7176 + * complains loudly.
7177 + */
7178 + gintmsk.d32 = 0;
7179 + gintmsk.b.sofintr = 1;
7180 + dwc_modify_reg32(&global_regs->gintmsk, gintmsk.d32, 0);
7181 + pcd_stop(core_if);
7182 + hcd_start(core_if);
7183 + core_if->op_state = A_HOST;
7184 + }
7185 + }
7186 + if (gotgint.b.adevtoutchng)
7187 + DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: "
7188 + "A-Device Timeout Change++\n");
7189 + if (gotgint.b.debdone)
7190 + DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: " "Debounce Done++\n");
7191 +
7192 + /* Clear GOTGINT */
7193 + dwc_write_reg32(&core_if->core_global_regs->gotgint, gotgint.d32);
7194 +
7195 + return 1;
7196 +}
7197 +
7198 +/**
7199 + * This function handles the Connector ID Status Change Interrupt. It
7200 + * reads the OTG Interrupt Register (GOTCTL) to determine whether this
7201 + * is a Device to Host Mode transition or a Host Mode to Device
7202 + * Transition.
7203 + *
7204 + * This only occurs when the cable is connected/removed from the PHY
7205 + * connector.
7206 + *
7207 + * @core_if: Programming view of DWC_otg controller.
7208 + */
7209 +int32_t dwc_otg_handle_conn_id_status_change_intr(struct dwc_otg_core_if *core_if)
7210 +{
7211 + uint32_t count = 0;
7212 +
7213 + union gintsts_data gintsts = {.d32 = 0 };
7214 + union gintmsk_data gintmsk = {.d32 = 0 };
7215 + union gotgctl_data gotgctl = {.d32 = 0 };
7216 +
7217 + /*
7218 + * Need to disable SOF interrupt immediately. If switching from device
7219 + * to host, the PCD interrupt handler won't handle the interrupt if
7220 + * host mode is already set. The HCD interrupt handler won't get
7221 + * called if the HCD state is HALT. This means that the interrupt does
7222 + * not get handled and Linux complains loudly.
7223 + */
7224 + gintmsk.b.sofintr = 1;
7225 + dwc_modify_reg32(&core_if->core_global_regs->gintmsk, gintmsk.d32, 0);
7226 +
7227 + DWC_DEBUGPL(DBG_CIL,
7228 + " ++Connector ID Status Change Interrupt++ (%s)\n",
7229 + (dwc_otg_is_host_mode(core_if) ? "Host" : "Device"));
7230 + gotgctl.d32 = dwc_read_reg32(&core_if->core_global_regs->gotgctl);
7231 + DWC_DEBUGPL(DBG_CIL, "gotgctl=%0x\n", gotgctl.d32);
7232 + DWC_DEBUGPL(DBG_CIL, "gotgctl.b.conidsts=%d\n", gotgctl.b.conidsts);
7233 +
7234 + /* B-Device connector (Device Mode) */
7235 + if (gotgctl.b.conidsts) {
7236 + /* Wait for switch to device mode. */
7237 + while (!dwc_otg_is_device_mode(core_if)) {
7238 + DWC_PRINT("Waiting for Peripheral Mode, Mode=%s\n",
7239 + (dwc_otg_is_host_mode(core_if) ? "Host" :
7240 + "Peripheral"));
7241 + mdelay(100);
7242 + if (++count > 10000)
7243 + *(uint32_t *) NULL = 0;
7244 + }
7245 + core_if->op_state = B_PERIPHERAL;
7246 + dwc_otg_core_init(core_if);
7247 + dwc_otg_enable_global_interrupts(core_if);
7248 + pcd_start(core_if);
7249 + } else {
7250 + /* A-Device connector (Host Mode) */
7251 + while (!dwc_otg_is_host_mode(core_if)) {
7252 + DWC_PRINT("Waiting for Host Mode, Mode=%s\n",
7253 + (dwc_otg_is_host_mode(core_if) ? "Host" :
7254 + "Peripheral"));
7255 + mdelay(100);
7256 + if (++count > 10000)
7257 + *(uint32_t *) NULL = 0;
7258 + }
7259 + core_if->op_state = A_HOST;
7260 + /*
7261 + * Initialize the Core for Host mode.
7262 + */
7263 + dwc_otg_core_init(core_if);
7264 + dwc_otg_enable_global_interrupts(core_if);
7265 + hcd_start(core_if);
7266 + }
7267 +
7268 + /* Set flag and clear interrupt */
7269 + gintsts.b.conidstschng = 1;
7270 + dwc_write_reg32(&core_if->core_global_regs->gintsts, gintsts.d32);
7271 +
7272 + return 1;
7273 +}
7274 +
7275 +/**
7276 + * This interrupt indicates that a device is initiating the Session
7277 + * Request Protocol to request the host to turn on bus power so a new
7278 + * session can begin. The handler responds by turning on bus power. If
7279 + * the DWC_otg controller is in low power mode, the handler brings the
7280 + * controller out of low power mode before turning on bus power.
7281 + *
7282 + * @core_if: Programming view of DWC_otg controller.
7283 + */
7284 +int32_t dwc_otg_handle_session_req_intr(struct dwc_otg_core_if *core_if)
7285 +{
7286 + union gintsts_data gintsts;
7287 +#ifndef DWC_HOST_ONLY
7288 + union hprt0_data hprt0;
7289 +
7290 + DWC_DEBUGPL(DBG_ANY, "++Session Request Interrupt++\n");
7291 +
7292 + if (dwc_otg_is_device_mode(core_if)) {
7293 + DWC_PRINT("SRP: Device mode\n");
7294 + } else {
7295 + DWC_PRINT("SRP: Host mode\n");
7296 +
7297 + /* Turn on the port power bit. */
7298 + hprt0.d32 = dwc_otg_read_hprt0(core_if);
7299 + hprt0.b.prtpwr = 1;
7300 + dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
7301 +
7302 + /* Start the Connection timer. So a message can be displayed
7303 + * if connect does not occur within 10 seconds. */
7304 + hcd_session_start(core_if);
7305 + }
7306 +#endif
7307 +
7308 + /* Clear interrupt */
7309 + gintsts.d32 = 0;
7310 + gintsts.b.sessreqintr = 1;
7311 + dwc_write_reg32(&core_if->core_global_regs->gintsts, gintsts.d32);
7312 +
7313 + return 1;
7314 +}
7315 +
7316 +/**
7317 + * This interrupt indicates that the DWC_otg controller has detected a
7318 + * resume or remote wakeup sequence. If the DWC_otg controller is in
7319 + * low power mode, the handler must brings the controller out of low
7320 + * power mode. The controller automatically begins resume
7321 + * signaling. The handler schedules a time to stop resume signaling.
7322 + */
7323 +int32_t dwc_otg_handle_wakeup_detected_intr(struct dwc_otg_core_if *core_if)
7324 +{
7325 + union gintsts_data gintsts;
7326 +
7327 + DWC_DEBUGPL(DBG_ANY,
7328 + "++Resume and Remote Wakeup Detected Interrupt++\n");
7329 +
7330 + if (dwc_otg_is_device_mode(core_if)) {
7331 + union dctl_data dctl = {.d32 = 0 };
7332 + DWC_DEBUGPL(DBG_PCD, "DSTS=0x%0x\n",
7333 + dwc_read_reg32(&core_if->dev_if->dev_global_regs->
7334 + dsts));
7335 +#ifdef PARTIAL_POWER_DOWN
7336 + if (core_if->hwcfg4.b.power_optimiz) {
7337 + union pcgcctl_data power = {.d32 = 0 };
7338 +
7339 + power.d32 = dwc_read_reg32(core_if->pcgcctl);
7340 + DWC_DEBUGPL(DBG_CIL, "PCGCCTL=%0x\n", power.d32);
7341 +
7342 + power.b.stoppclk = 0;
7343 + dwc_write_reg32(core_if->pcgcctl, power.d32);
7344 +
7345 + power.b.pwrclmp = 0;
7346 + dwc_write_reg32(core_if->pcgcctl, power.d32);
7347 +
7348 + power.b.rstpdwnmodule = 0;
7349 + dwc_write_reg32(core_if->pcgcctl, power.d32);
7350 + }
7351 +#endif
7352 + /* Clear the Remote Wakeup Signalling */
7353 + dctl.b.rmtwkupsig = 1;
7354 + dwc_modify_reg32(&core_if->dev_if->dev_global_regs->dctl,
7355 + dctl.d32, 0);
7356 +
7357 + if (core_if->pcd_cb && core_if->pcd_cb->resume_wakeup)
7358 + core_if->pcd_cb->resume_wakeup(core_if->pcd_cb->p);
7359 + } else {
7360 + /*
7361 + * Clear the Resume after 70ms. (Need 20 ms minimum. Use 70 ms
7362 + * so that OPT tests pass with all PHYs).
7363 + */
7364 + union hprt0_data hprt0 = {.d32 = 0 };
7365 + union pcgcctl_data pcgcctl = {.d32 = 0 };
7366 + /* Restart the Phy Clock */
7367 + pcgcctl.b.stoppclk = 1;
7368 + dwc_modify_reg32(core_if->pcgcctl, pcgcctl.d32, 0);
7369 + udelay(10);
7370 +
7371 + /* Now wait for 70 ms. */
7372 + hprt0.d32 = dwc_otg_read_hprt0(core_if);
7373 + DWC_DEBUGPL(DBG_ANY, "Resume: HPRT0=%0x\n", hprt0.d32);
7374 + mdelay(70);
7375 + hprt0.b.prtres = 0; /* Resume */
7376 + dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
7377 + DWC_DEBUGPL(DBG_ANY, "Clear Resume: HPRT0=%0x\n",
7378 + dwc_read_reg32(core_if->host_if->hprt0));
7379 + }
7380 +
7381 + /* Clear interrupt */
7382 + gintsts.d32 = 0;
7383 + gintsts.b.wkupintr = 1;
7384 + dwc_write_reg32(&core_if->core_global_regs->gintsts, gintsts.d32);
7385 +
7386 + return 1;
7387 +}
7388 +
7389 +/**
7390 + * This interrupt indicates that a device has been disconnected from
7391 + * the root port.
7392 + */
7393 +int32_t dwc_otg_handle_disconnect_intr(struct dwc_otg_core_if *core_if)
7394 +{
7395 + union gintsts_data gintsts;
7396 +
7397 + DWC_DEBUGPL(DBG_ANY, "++Disconnect Detected Interrupt++ (%s) %s\n",
7398 + (dwc_otg_is_host_mode(core_if) ? "Host" : "Device"),
7399 + op_state_str(core_if));
7400 +
7401 +/** @todo Consolidate this if statement. */
7402 +#ifndef DWC_HOST_ONLY
7403 + if (core_if->op_state == B_HOST) {
7404 + /* If in device mode Disconnect and stop the HCD, then
7405 + * start the PCD. */
7406 + hcd_disconnect(core_if);
7407 + pcd_start(core_if);
7408 + core_if->op_state = B_PERIPHERAL;
7409 + } else if (dwc_otg_is_device_mode(core_if)) {
7410 + union gotgctl_data gotgctl = {.d32 = 0 };
7411 + gotgctl.d32 =
7412 + dwc_read_reg32(&core_if->core_global_regs->gotgctl);
7413 + if (gotgctl.b.hstsethnpen == 1) {
7414 + /* Do nothing, if HNP in process the OTG
7415 + * interrupt "Host Negotiation Detected"
7416 + * interrupt will do the mode switch.
7417 + */
7418 + } else if (gotgctl.b.devhnpen == 0) {
7419 + /* If in device mode Disconnect and stop the HCD, then
7420 + * start the PCD. */
7421 + hcd_disconnect(core_if);
7422 + pcd_start(core_if);
7423 + core_if->op_state = B_PERIPHERAL;
7424 + } else {
7425 + DWC_DEBUGPL(DBG_ANY, "!a_peripheral && !devhnpen\n");
7426 + }
7427 + } else {
7428 + if (core_if->op_state == A_HOST) {
7429 + /* A-Cable still connected but device disconnected. */
7430 + hcd_disconnect(core_if);
7431 + }
7432 + }
7433 +#endif
7434 +
7435 + gintsts.d32 = 0;
7436 + gintsts.b.disconnect = 1;
7437 + dwc_write_reg32(&core_if->core_global_regs->gintsts, gintsts.d32);
7438 + return 1;
7439 +}
7440 +
7441 +/**
7442 + * This interrupt indicates that SUSPEND state has been detected on
7443 + * the USB.
7444 + *
7445 + * For HNP the USB Suspend interrupt signals the change from
7446 + * "a_peripheral" to "a_host".
7447 + *
7448 + * When power management is enabled the core will be put in low power
7449 + * mode.
7450 + */
7451 +int32_t dwc_otg_handle_usb_suspend_intr(struct dwc_otg_core_if *core_if)
7452 +{
7453 + union dsts_data dsts;
7454 + union gintsts_data gintsts;
7455 +
7456 + DWC_DEBUGPL(DBG_ANY, "USB SUSPEND\n");
7457 +
7458 + if (dwc_otg_is_device_mode(core_if)) {
7459 + /* Check the Device status register to determine if the Suspend
7460 + * state is active. */
7461 + dsts.d32 =
7462 + dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts);
7463 + DWC_DEBUGPL(DBG_PCD, "DSTS=0x%0x\n", dsts.d32);
7464 + DWC_DEBUGPL(DBG_PCD, "DSTS.Suspend Status=%d "
7465 + "HWCFG4.power Optimize=%d\n",
7466 + dsts.b.suspsts, core_if->hwcfg4.b.power_optimiz);
7467 +
7468 +#ifdef PARTIAL_POWER_DOWN
7469 +/** @todo Add a module parameter for power management. */
7470 +
7471 + if (dsts.b.suspsts && core_if->hwcfg4.b.power_optimiz) {
7472 + union pcgcctl_data_t power = {.d32 = 0 };
7473 + DWC_DEBUGPL(DBG_CIL, "suspend\n");
7474 +
7475 + power.b.pwrclmp = 1;
7476 + dwc_write_reg32(core_if->pcgcctl, power.d32);
7477 +
7478 + power.b.rstpdwnmodule = 1;
7479 + dwc_modify_reg32(core_if->pcgcctl, 0, power.d32);
7480 +
7481 + power.b.stoppclk = 1;
7482 + dwc_modify_reg32(core_if->pcgcctl, 0, power.d32);
7483 +
7484 + } else {
7485 + DWC_DEBUGPL(DBG_ANY, "disconnect?\n");
7486 + }
7487 +#endif
7488 + /* PCD callback for suspend. */
7489 + pcd_suspend(core_if);
7490 + } else {
7491 + if (core_if->op_state == A_PERIPHERAL) {
7492 + DWC_DEBUGPL(DBG_ANY, "a_peripheral->a_host\n");
7493 + /* Clear the a_peripheral flag, back to a_host. */
7494 + pcd_stop(core_if);
7495 + hcd_start(core_if);
7496 + core_if->op_state = A_HOST;
7497 + }
7498 + }
7499 +
7500 + /* Clear interrupt */
7501 + gintsts.d32 = 0;
7502 + gintsts.b.usbsuspend = 1;
7503 + dwc_write_reg32(&core_if->core_global_regs->gintsts, gintsts.d32);
7504 +
7505 + return 1;
7506 +}
7507 +
7508 +/**
7509 + * This function returns the Core Interrupt register.
7510 + */
7511 +static inline uint32_t dwc_otg_read_common_intr(struct dwc_otg_core_if *core_if)
7512 +{
7513 + union gintsts_data gintsts;
7514 + union gintmsk_data gintmsk;
7515 + union gintmsk_data gintmsk_common = {.d32 = 0 };
7516 + gintmsk_common.b.wkupintr = 1;
7517 + gintmsk_common.b.sessreqintr = 1;
7518 + gintmsk_common.b.conidstschng = 1;
7519 + gintmsk_common.b.otgintr = 1;
7520 + gintmsk_common.b.modemismatch = 1;
7521 + gintmsk_common.b.disconnect = 1;
7522 + gintmsk_common.b.usbsuspend = 1;
7523 + /*
7524 + * @todo: The port interrupt occurs while in device
7525 + * mode. Added code to CIL to clear the interrupt for now!
7526 + */
7527 + gintmsk_common.b.portintr = 1;
7528 +
7529 + gintsts.d32 = dwc_read_reg32(&core_if->core_global_regs->gintsts);
7530 + gintmsk.d32 = dwc_read_reg32(&core_if->core_global_regs->gintmsk);
7531 +#ifdef DEBUG
7532 + /* if any common interrupts set */
7533 + if (gintsts.d32 & gintmsk_common.d32) {
7534 + DWC_DEBUGPL(DBG_ANY, "gintsts=%08x gintmsk=%08x\n",
7535 + gintsts.d32, gintmsk.d32);
7536 + }
7537 +#endif
7538 +
7539 + return (gintsts.d32 & gintmsk.d32) & gintmsk_common.d32;
7540 +
7541 +}
7542 +
7543 +/**
7544 + * Common interrupt handler.
7545 + *
7546 + * The common interrupts are those that occur in both Host and Device mode.
7547 + * This handler handles the following interrupts:
7548 + * - Mode Mismatch Interrupt
7549 + * - Disconnect Interrupt
7550 + * - OTG Interrupt
7551 + * - Connector ID Status Change Interrupt
7552 + * - Session Request Interrupt.
7553 + * - Resume / Remote Wakeup Detected Interrupt.
7554 + *
7555 + */
7556 +extern int32_t dwc_otg_handle_common_intr(struct dwc_otg_core_if *core_if)
7557 +{
7558 + int retval = 0;
7559 + union gintsts_data gintsts;
7560 +
7561 + gintsts.d32 = dwc_otg_read_common_intr(core_if);
7562 +
7563 + if (gintsts.b.modemismatch)
7564 + retval |= dwc_otg_handle_mode_mismatch_intr(core_if);
7565 + if (gintsts.b.otgintr)
7566 + retval |= dwc_otg_handle_otg_intr(core_if);
7567 + if (gintsts.b.conidstschng)
7568 + retval |= dwc_otg_handle_conn_id_status_change_intr(core_if);
7569 + if (gintsts.b.disconnect)
7570 + retval |= dwc_otg_handle_disconnect_intr(core_if);
7571 + if (gintsts.b.sessreqintr)
7572 + retval |= dwc_otg_handle_session_req_intr(core_if);
7573 + if (gintsts.b.wkupintr)
7574 + retval |= dwc_otg_handle_wakeup_detected_intr(core_if);
7575 + if (gintsts.b.usbsuspend)
7576 + retval |= dwc_otg_handle_usb_suspend_intr(core_if);
7577 + if (gintsts.b.portintr && dwc_otg_is_device_mode(core_if)) {
7578 + /* The port interrupt occurs while in device mode with HPRT0
7579 + * Port Enable/Disable.
7580 + */
7581 + gintsts.d32 = 0;
7582 + gintsts.b.portintr = 1;
7583 + dwc_write_reg32(&core_if->core_global_regs->gintsts,
7584 + gintsts.d32);
7585 + retval |= 1;
7586 +
7587 + }
7588 + return retval;
7589 +}
7590 diff --git a/drivers/usb/host/dwc_otg/dwc_otg_driver.h b/drivers/usb/host/dwc_otg/dwc_otg_driver.h
7591 new file mode 100644
7592 index 0000000..1cc116d
7593 --- /dev/null
7594 +++ b/drivers/usb/host/dwc_otg/dwc_otg_driver.h
7595 @@ -0,0 +1,63 @@
7596 +/* ==========================================================================
7597 + * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
7598 + * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
7599 + * otherwise expressly agreed to in writing between Synopsys and you.
7600 + *
7601 + * The Software IS NOT an item of Licensed Software or Licensed Product under
7602 + * any End User Software License Agreement or Agreement for Licensed Product
7603 + * with Synopsys or any supplement thereto. You are permitted to use and
7604 + * redistribute this Software in source and binary forms, with or without
7605 + * modification, provided that redistributions of source code must retain this
7606 + * notice. You may not view, use, disclose, copy or distribute this file or
7607 + * any information contained herein except pursuant to this license grant from
7608 + * Synopsys. If you do not agree with this notice, including the disclaimer
7609 + * below, then you are not authorized to use the Software.
7610 + *
7611 + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
7612 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
7613 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
7614 + * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
7615 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
7616 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
7617 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
7618 + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
7619 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
7620 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
7621 + * DAMAGE.
7622 + * ========================================================================== */
7623 +
7624 +#ifndef __DWC_OTG_DRIVER_H__
7625 +#define __DWC_OTG_DRIVER_H__
7626 +
7627 +#include "dwc_otg_cil.h"
7628 +
7629 +/* Type declarations */
7630 +struct dwc_otg_pcd;
7631 +struct dwc_otg_hcd;
7632 +
7633 +/**
7634 + * This structure is a wrapper that encapsulates the driver components used to
7635 + * manage a single DWC_otg controller.
7636 + */
7637 +struct dwc_otg_device {
7638 + /** Base address returned from ioremap() */
7639 + void *base;
7640 +
7641 + /** Pointer to the core interface structure. */
7642 + struct dwc_otg_core_if *core_if;
7643 +
7644 + /** Register offset for Diagnostic API.*/
7645 + uint32_t reg_offset;
7646 +
7647 + /** Pointer to the PCD structure. */
7648 + struct dwc_otg_pcd *pcd;
7649 +
7650 + /** Pointer to the HCD structure. */
7651 + struct dwc_otg_hcd *hcd;
7652 +
7653 + /** Flag to indicate whether the common IRQ handler is installed. */
7654 + uint8_t common_irq_installed;
7655 +
7656 +};
7657 +
7658 +#endif
7659 diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
7660 new file mode 100644
7661 index 0000000..a4392f5
7662 --- /dev/null
7663 +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
7664 @@ -0,0 +1,2878 @@
7665 +/* ==========================================================================
7666 + * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
7667 + * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
7668 + * otherwise expressly agreed to in writing between Synopsys and you.
7669 + *
7670 + * The Software IS NOT an item of Licensed Software or Licensed Product under
7671 + * any End User Software License Agreement or Agreement for Licensed Product
7672 + * with Synopsys or any supplement thereto. You are permitted to use and
7673 + * redistribute this Software in source and binary forms, with or without
7674 + * modification, provided that redistributions of source code must retain this
7675 + * notice. You may not view, use, disclose, copy or distribute this file or
7676 + * any information contained herein except pursuant to this license grant from
7677 + * Synopsys. If you do not agree with this notice, including the disclaimer
7678 + * below, then you are not authorized to use the Software.
7679 + *
7680 + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
7681 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
7682 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
7683 + * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
7684 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
7685 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
7686 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
7687 + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
7688 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
7689 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
7690 + * DAMAGE.
7691 + * ========================================================================== */
7692 +#ifndef DWC_DEVICE_ONLY
7693 +
7694 +/**
7695 + *
7696 + * This file contains the implementation of the HCD. In Linux, the HCD
7697 + * implements the hc_driver API.
7698 + */
7699 +#include <linux/kernel.h>
7700 +#include <linux/module.h>
7701 +#include <linux/moduleparam.h>
7702 +#include <linux/init.h>
7703 +#include <linux/device.h>
7704 +#include <linux/errno.h>
7705 +#include <linux/list.h>
7706 +#include <linux/interrupt.h>
7707 +#include <linux/string.h>
7708 +#include <linux/dma-mapping.h>
7709 +#include <linux/workqueue.h>
7710 +#include <linux/platform_device.h>
7711 +
7712 +#include "dwc_otg_driver.h"
7713 +#include "dwc_otg_hcd.h"
7714 +#include "dwc_otg_regs.h"
7715 +
7716 +static const char dwc_otg_hcd_name[] = "dwc_otg_hcd";
7717 +
7718 +static const struct hc_driver dwc_otg_hc_driver = {
7719 +
7720 + .description = dwc_otg_hcd_name,
7721 + .product_desc = "DWC OTG Controller",
7722 + .hcd_priv_size = sizeof(struct dwc_otg_hcd),
7723 +
7724 + .irq = dwc_otg_hcd_irq,
7725 +
7726 + .flags = HCD_MEMORY | HCD_USB2,
7727 +
7728 + .start = dwc_otg_hcd_start,
7729 + .stop = dwc_otg_hcd_stop,
7730 +
7731 + .urb_enqueue = dwc_otg_hcd_urb_enqueue,
7732 + .urb_dequeue = dwc_otg_hcd_urb_dequeue,
7733 + .endpoint_disable = dwc_otg_hcd_endpoint_disable,
7734 +
7735 + .get_frame_number = dwc_otg_hcd_get_frame_number,
7736 +
7737 + .hub_status_data = dwc_otg_hcd_hub_status_data,
7738 + .hub_control = dwc_otg_hcd_hub_control,
7739 +};
7740 +
7741 +/**
7742 + * Work queue function for starting the HCD when A-Cable is connected.
7743 + * The dwc_otg_hcd_start() must be called in a process context.
7744 + */
7745 +static void hcd_start_func(struct work_struct *work)
7746 +{
7747 + void *_vp =
7748 + (void *)(atomic_long_read(&work->data) & WORK_STRUCT_WQ_DATA_MASK);
7749 + struct usb_hcd *usb_hcd = (struct usb_hcd *)_vp;
7750 + DWC_DEBUGPL(DBG_HCDV, "%s() %p\n", __func__, usb_hcd);
7751 + if (usb_hcd)
7752 + dwc_otg_hcd_start(usb_hcd);
7753 +}
7754 +
7755 +/**
7756 + * HCD Callback function for starting the HCD when A-Cable is
7757 + * connected.
7758 + *
7759 + * @_p: void pointer to the <code>struct usb_hcd</code>
7760 + */
7761 +static int32_t dwc_otg_hcd_start_cb(void *_p)
7762 +{
7763 + struct dwc_otg_hcd *dwc_otg_hcd = hcd_to_dwc_otg_hcd(_p);
7764 + struct dwc_otg_core_if *core_if = dwc_otg_hcd->core_if;
7765 + union hprt0_data hprt0;
7766 +
7767 + if (core_if->op_state == B_HOST) {
7768 + /*
7769 + * Reset the port. During a HNP mode switch the reset
7770 + * needs to occur within 1ms and have a duration of at
7771 + * least 50ms.
7772 + */
7773 + hprt0.d32 = dwc_otg_read_hprt0(core_if);
7774 + hprt0.b.prtrst = 1;
7775 + dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
7776 + ((struct usb_hcd *)_p)->self.is_b_host = 1;
7777 + } else {
7778 + ((struct usb_hcd *)_p)->self.is_b_host = 0;
7779 + }
7780 +
7781 + /* Need to start the HCD in a non-interrupt context. */
7782 + INIT_WORK(&dwc_otg_hcd->start_work, hcd_start_func);
7783 + atomic_long_set(&dwc_otg_hcd->start_work.data, (long)_p);
7784 + schedule_work(&dwc_otg_hcd->start_work);
7785 +
7786 + return 1;
7787 +}
7788 +
7789 +/**
7790 + * HCD Callback function for stopping the HCD.
7791 + *
7792 + * @_p: void pointer to the <code>struct usb_hcd</code>
7793 + */
7794 +static int32_t dwc_otg_hcd_stop_cb(void *_p)
7795 +{
7796 + struct usb_hcd *usb_hcd = (struct usb_hcd *)_p;
7797 + DWC_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, _p);
7798 + dwc_otg_hcd_stop(usb_hcd);
7799 + return 1;
7800 +}
7801 +
7802 +static void del_xfer_timers(struct dwc_otg_hcd *hcd)
7803 +{
7804 +#ifdef DEBUG
7805 + int i;
7806 + int num_channels = hcd->core_if->core_params->host_channels;
7807 + for (i = 0; i < num_channels; i++)
7808 + del_timer(&hcd->core_if->hc_xfer_timer[i]);
7809 +#endif
7810 +}
7811 +
7812 +static void del_timers(struct dwc_otg_hcd *hcd)
7813 +{
7814 + del_xfer_timers(hcd);
7815 + del_timer(&hcd->conn_timer);
7816 +}
7817 +
7818 +/**
7819 + * Processes all the URBs in a single list of QHs. Completes them with
7820 + * -ETIMEDOUT and frees the QTD.
7821 + */
7822 +static void kill_urbs_in_qh_list(struct dwc_otg_hcd *hcd,
7823 + struct list_head *_qh_list)
7824 +{
7825 + struct dwc_otg_qh *qh;
7826 + struct dwc_otg_qtd *qtd;
7827 + struct dwc_otg_qtd *qtd_next;
7828 +
7829 + list_for_each_entry(qh, _qh_list, qh_list_entry) {
7830 + list_for_each_entry_safe(qtd, qtd_next, &qh->qtd_list,
7831 + qtd_list_entry) {
7832 + if (qtd->urb != NULL) {
7833 + dwc_otg_hcd_complete_urb(hcd, qtd->urb,
7834 + -ETIMEDOUT);
7835 + qtd->urb = NULL;
7836 + }
7837 + dwc_otg_hcd_qtd_remove_and_free(qtd);
7838 + }
7839 + }
7840 +}
7841 +
7842 +/**
7843 + * Responds with an error status of ETIMEDOUT to all URBs in the non-periodic
7844 + * and periodic schedules. The QTD associated with each URB is removed from
7845 + * the schedule and freed. This function may be called when a disconnect is
7846 + * detected or when the HCD is being stopped.
7847 + */
7848 +static void kill_all_urbs(struct dwc_otg_hcd *hcd)
7849 +{
7850 + kill_urbs_in_qh_list(hcd, &hcd->non_periodic_sched_inactive);
7851 + kill_urbs_in_qh_list(hcd, &hcd->non_periodic_sched_active);
7852 + kill_urbs_in_qh_list(hcd, &hcd->periodic_sched_inactive);
7853 + kill_urbs_in_qh_list(hcd, &hcd->periodic_sched_ready);
7854 + kill_urbs_in_qh_list(hcd, &hcd->periodic_sched_assigned);
7855 + kill_urbs_in_qh_list(hcd, &hcd->periodic_sched_queued);
7856 +}
7857 +
7858 +/**
7859 + * HCD Callback function for disconnect of the HCD.
7860 + *
7861 + * @_p: void pointer to the <code>struct usb_hcd</code>
7862 + */
7863 +static int32_t dwc_otg_hcd_disconnect_cb(void *_p)
7864 +{
7865 + union gintsts_data intr;
7866 + struct dwc_otg_hcd *dwc_otg_hcd = hcd_to_dwc_otg_hcd(_p);
7867 +
7868 + /*
7869 + * Set status flags for the hub driver.
7870 + */
7871 + dwc_otg_hcd->flags.b.port_connect_status_change = 1;
7872 + dwc_otg_hcd->flags.b.port_connect_status = 0;
7873 +
7874 + /*
7875 + * Shutdown any transfers in process by clearing the Tx FIFO Empty
7876 + * interrupt mask and status bits and disabling subsequent host
7877 + * channel interrupts.
7878 + */
7879 + intr.d32 = 0;
7880 + intr.b.nptxfempty = 1;
7881 + intr.b.ptxfempty = 1;
7882 + intr.b.hcintr = 1;
7883 + dwc_modify_reg32(&dwc_otg_hcd->core_if->core_global_regs->gintmsk,
7884 + intr.d32, 0);
7885 + dwc_modify_reg32(&dwc_otg_hcd->core_if->core_global_regs->gintsts,
7886 + intr.d32, 0);
7887 +
7888 + del_timers(dwc_otg_hcd);
7889 +
7890 + /*
7891 + * Turn off the vbus power only if the core has transitioned to device
7892 + * mode. If still in host mode, need to keep power on to detect a
7893 + * reconnection.
7894 + */
7895 + if (dwc_otg_is_device_mode(dwc_otg_hcd->core_if)) {
7896 + if (dwc_otg_hcd->core_if->op_state != A_SUSPEND) {
7897 + union hprt0_data hprt0 = {.d32 = 0 };
7898 + DWC_PRINT("Disconnect: PortPower off\n");
7899 + hprt0.b.prtpwr = 0;
7900 + dwc_write_reg32(dwc_otg_hcd->core_if->host_if->hprt0,
7901 + hprt0.d32);
7902 + }
7903 +
7904 + dwc_otg_disable_host_interrupts(dwc_otg_hcd->core_if);
7905 + }
7906 +
7907 + /* Respond with an error status to all URBs in the schedule. */
7908 + kill_all_urbs(dwc_otg_hcd);
7909 +
7910 + if (dwc_otg_is_host_mode(dwc_otg_hcd->core_if)) {
7911 + /* Clean up any host channels that were in use. */
7912 + int num_channels;
7913 + int i;
7914 + struct dwc_hc *channel;
7915 + struct dwc_otg_hc_regs *hc_regs;
7916 + union hcchar_data hcchar;
7917 +
7918 + num_channels = dwc_otg_hcd->core_if->core_params->host_channels;
7919 +
7920 + if (!dwc_otg_hcd->core_if->dma_enable) {
7921 + /* Flush out any channel requests in slave mode. */
7922 + for (i = 0; i < num_channels; i++) {
7923 + channel = dwc_otg_hcd->hc_ptr_array[i];
7924 + if (list_empty(&channel->hc_list_entry)) {
7925 + hc_regs =
7926 + dwc_otg_hcd->core_if->host_if->
7927 + hc_regs[i];
7928 + hcchar.d32 =
7929 + dwc_read_reg32(&hc_regs->hcchar);
7930 + if (hcchar.b.chen) {
7931 + hcchar.b.chen = 0;
7932 + hcchar.b.chdis = 1;
7933 + hcchar.b.epdir = 0;
7934 + dwc_write_reg32(&hc_regs->
7935 + hcchar,
7936 + hcchar.d32);
7937 + }
7938 + }
7939 + }
7940 + }
7941 +
7942 + for (i = 0; i < num_channels; i++) {
7943 + channel = dwc_otg_hcd->hc_ptr_array[i];
7944 + if (list_empty(&channel->hc_list_entry)) {
7945 + hc_regs =
7946 + dwc_otg_hcd->core_if->host_if->hc_regs[i];
7947 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
7948 + if (hcchar.b.chen) {
7949 + /* Halt the channel. */
7950 + hcchar.b.chdis = 1;
7951 + dwc_write_reg32(&hc_regs->hcchar,
7952 + hcchar.d32);
7953 + }
7954 +
7955 + dwc_otg_hc_cleanup(dwc_otg_hcd->core_if,
7956 + channel);
7957 + list_add_tail(&channel->hc_list_entry,
7958 + &dwc_otg_hcd->free_hc_list);
7959 + }
7960 + }
7961 + }
7962 +
7963 + /* A disconnect will end the session so the B-Device is no
7964 + * longer a B-host. */
7965 + ((struct usb_hcd *)_p)->self.is_b_host = 0;
7966 + return 1;
7967 +}
7968 +
7969 +/**
7970 + * Connection timeout function. An OTG host is required to display a
7971 + * message if the device does not connect within 10 seconds.
7972 + */
7973 +void dwc_otg_hcd_connect_timeout(unsigned long _ptr)
7974 +{
7975 + DWC_DEBUGPL(DBG_HCDV, "%s(%x)\n", __func__, (int)_ptr);
7976 + DWC_PRINT("Connect Timeout\n");
7977 + DWC_ERROR("Device Not Connected/Responding\n");
7978 +}
7979 +
7980 +/**
7981 + * Start the connection timer. An OTG host is required to display a
7982 + * message if the device does not connect within 10 seconds. The
7983 + * timer is deleted if a port connect interrupt occurs before the
7984 + * timer expires.
7985 + */
7986 +static void dwc_otg_hcd_start_connect_timer(struct dwc_otg_hcd *hcd)
7987 +{
7988 + init_timer(&hcd->conn_timer);
7989 + hcd->conn_timer.function = dwc_otg_hcd_connect_timeout;
7990 + hcd->conn_timer.data = (unsigned long)0;
7991 + hcd->conn_timer.expires = jiffies + (HZ * 10);
7992 + add_timer(&hcd->conn_timer);
7993 +}
7994 +
7995 +/**
7996 + * HCD Callback function for disconnect of the HCD.
7997 + *
7998 + * @_p: void pointer to the <code>struct usb_hcd</code>
7999 + */
8000 +static int32_t dwc_otg_hcd_session_start_cb(void *_p)
8001 +{
8002 + struct dwc_otg_hcd *dwc_otg_hcd = hcd_to_dwc_otg_hcd(_p);
8003 + DWC_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, _p);
8004 + dwc_otg_hcd_start_connect_timer(dwc_otg_hcd);
8005 + return 1;
8006 +}
8007 +
8008 +/**
8009 + * HCD Callback structure for handling mode switching.
8010 + */
8011 +static struct dwc_otg_cil_callbacks hcd_cil_callbacks = {
8012 + .start = dwc_otg_hcd_start_cb,
8013 + .stop = dwc_otg_hcd_stop_cb,
8014 + .disconnect = dwc_otg_hcd_disconnect_cb,
8015 + .session_start = dwc_otg_hcd_session_start_cb,
8016 + .p = 0,
8017 +};
8018 +
8019 +/**
8020 + * Reset tasklet function
8021 + */
8022 +static void reset_tasklet_func(unsigned long data)
8023 +{
8024 + struct dwc_otg_hcd *dwc_otg_hcd = (struct dwc_otg_hcd *)data;
8025 + struct dwc_otg_core_if *core_if = dwc_otg_hcd->core_if;
8026 + union hprt0_data hprt0;
8027 +
8028 + DWC_DEBUGPL(DBG_HCDV, "USB RESET tasklet called\n");
8029 +
8030 + hprt0.d32 = dwc_otg_read_hprt0(core_if);
8031 + hprt0.b.prtrst = 1;
8032 + dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
8033 + mdelay(60);
8034 +
8035 + hprt0.b.prtrst = 0;
8036 + dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
8037 + dwc_otg_hcd->flags.b.port_reset_change = 1;
8038 +
8039 + return;
8040 +}
8041 +
8042 +static struct tasklet_struct reset_tasklet = {
8043 + .next = NULL,
8044 + .state = 0,
8045 + .count = ATOMIC_INIT(0),
8046 + .func = reset_tasklet_func,
8047 + .data = 0,
8048 +};
8049 +
8050 +static enum hrtimer_restart delayed_enable(struct hrtimer *t)
8051 +{
8052 + struct dwc_otg_hcd *hcd = container_of(t, struct dwc_otg_hcd,
8053 + poll_rate_limit);
8054 + struct dwc_otg_core_global_regs *global_regs =
8055 + hcd->core_if->core_global_regs;
8056 + union gintmsk_data intr_mask = {.d32 = 0 };
8057 + intr_mask.b.nptxfempty = 1;
8058 + dwc_modify_reg32(&global_regs->gintmsk, 0, intr_mask.d32);
8059 +
8060 + return HRTIMER_NORESTART;
8061 +}
8062 +
8063 +/**
8064 + * Initializes the HCD. This function allocates memory for and initializes the
8065 + * static parts of the usb_hcd and dwc_otg_hcd structures. It also registers the
8066 + * USB bus with the core and calls the hc_driver->start() function. It returns
8067 + * a negative error on failure.
8068 + */
8069 +int __devinit dwc_otg_hcd_init(struct device *dev)
8070 +{
8071 + struct usb_hcd *hcd = NULL;
8072 + struct dwc_otg_hcd *dwc_otg_hcd = NULL;
8073 + struct dwc_otg_device *otg_dev = dev->platform_data;
8074 +
8075 + int num_channels;
8076 + int i;
8077 + struct dwc_hc *channel;
8078 +
8079 + int retval = 0;
8080 +
8081 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT\n");
8082 +
8083 + /* Set device flags indicating whether the HCD supports DMA. */
8084 + if (otg_dev->core_if->dma_enable) {
8085 + DWC_PRINT("Using DMA mode\n");
8086 + dev->coherent_dma_mask = ~0;
8087 + dev->dma_mask = &dev->coherent_dma_mask;
8088 + } else {
8089 + DWC_PRINT("Using Slave mode\n");
8090 + dev->coherent_dma_mask = 0;
8091 + dev->dma_mask = NULL;
8092 + }
8093 +
8094 + /*
8095 + * Allocate memory for the base HCD plus the DWC OTG HCD.
8096 + * Initialize the base HCD.
8097 + */
8098 + hcd = usb_create_hcd(&dwc_otg_hc_driver, dev, dev_name(dev));
8099 + if (hcd == NULL) {
8100 + retval = -ENOMEM;
8101 + goto error1;
8102 + }
8103 + hcd->regs = otg_dev->base;
8104 + hcd->self.otg_port = 1;
8105 +
8106 + /* Integrate TT in root hub, by default this is disbled. */
8107 + hcd->has_tt = 1;
8108 +
8109 + /* Initialize the DWC OTG HCD. */
8110 + dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
8111 +
8112 + spin_lock_init(&dwc_otg_hcd->global_lock);
8113 +
8114 + dwc_otg_hcd->core_if = otg_dev->core_if;
8115 + otg_dev->hcd = dwc_otg_hcd;
8116 +
8117 + /* Register the HCD CIL Callbacks */
8118 + dwc_otg_cil_register_hcd_callbacks(otg_dev->core_if,
8119 + &hcd_cil_callbacks, hcd);
8120 +
8121 + /* Initialize the non-periodic schedule. */
8122 + INIT_LIST_HEAD(&dwc_otg_hcd->non_periodic_sched_inactive);
8123 + INIT_LIST_HEAD(&dwc_otg_hcd->non_periodic_sched_active);
8124 +
8125 + /* Initialize the periodic schedule. */
8126 + INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_inactive);
8127 + INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_ready);
8128 + INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_assigned);
8129 + INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_queued);
8130 +
8131 + /*
8132 + * Create a host channel descriptor for each host channel implemented
8133 + * in the controller. Initialize the channel descriptor array.
8134 + */
8135 + INIT_LIST_HEAD(&dwc_otg_hcd->free_hc_list);
8136 + num_channels = dwc_otg_hcd->core_if->core_params->host_channels;
8137 + for (i = 0; i < num_channels; i++) {
8138 + channel = kmalloc(sizeof(struct dwc_hc), GFP_KERNEL);
8139 + if (channel == NULL) {
8140 + retval = -ENOMEM;
8141 + DWC_ERROR("%s: host channel allocation failed\n",
8142 + __func__);
8143 + goto error2;
8144 + }
8145 + memset(channel, 0, sizeof(struct dwc_hc));
8146 + channel->hc_num = i;
8147 + dwc_otg_hcd->hc_ptr_array[i] = channel;
8148 +#ifdef DEBUG
8149 + init_timer(&dwc_otg_hcd->core_if->hc_xfer_timer[i]);
8150 +#endif
8151 +
8152 + DWC_DEBUGPL(DBG_HCDV, "HCD Added channel #%d, hc=%p\n", i,
8153 + channel);
8154 + }
8155 +
8156 + /* Initialize the Connection timeout timer. */
8157 + init_timer(&dwc_otg_hcd->conn_timer);
8158 +
8159 + /* Initialize reset tasklet. */
8160 + reset_tasklet.data = (unsigned long)dwc_otg_hcd;
8161 + dwc_otg_hcd->reset_tasklet = &reset_tasklet;
8162 +
8163 + hrtimer_init(&dwc_otg_hcd->poll_rate_limit, CLOCK_MONOTONIC,
8164 + HRTIMER_MODE_REL);
8165 + dwc_otg_hcd->poll_rate_limit.function = delayed_enable;
8166 +
8167 + /*
8168 + * Finish generic HCD initialization and start the HCD. This function
8169 + * allocates the DMA buffer pool, registers the USB bus, requests the
8170 + * IRQ line, and calls dwc_otg_hcd_start method.
8171 + */
8172 + retval =
8173 + usb_add_hcd(hcd, platform_get_irq(to_platform_device(dev), 0),
8174 + IRQF_SHARED);
8175 + if (retval < 0)
8176 + goto error2;
8177 +
8178 + /*
8179 + * Allocate space for storing data on status transactions. Normally no
8180 + * data is sent, but this space acts as a bit bucket. This must be
8181 + * done after usb_add_hcd since that function allocates the DMA buffer
8182 + * pool.
8183 + */
8184 + if (otg_dev->core_if->dma_enable) {
8185 + dwc_otg_hcd->status_buf =
8186 + dma_alloc_coherent(dev,
8187 + DWC_OTG_HCD_STATUS_BUF_SIZE,
8188 + &dwc_otg_hcd->status_buf_dma,
8189 + GFP_KERNEL | GFP_DMA);
8190 + } else {
8191 + dwc_otg_hcd->status_buf = kmalloc(DWC_OTG_HCD_STATUS_BUF_SIZE,
8192 + GFP_KERNEL);
8193 + }
8194 + if (dwc_otg_hcd->status_buf == NULL) {
8195 + retval = -ENOMEM;
8196 + DWC_ERROR("%s: status_buf allocation failed\n", __func__);
8197 + goto error3;
8198 + }
8199 +
8200 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Initialized HCD, usbbus=%d\n",
8201 + hcd->self.busnum);
8202 +
8203 + return 0;
8204 +
8205 + /* Error conditions */
8206 +error3:
8207 + usb_remove_hcd(hcd);
8208 +error2:
8209 + dwc_otg_hcd_free(hcd);
8210 + usb_put_hcd(hcd);
8211 +error1:
8212 + return retval;
8213 +}
8214 +
8215 +/**
8216 + * Removes the HCD.
8217 + * Frees memory and resources associated with the HCD and deregisters the bus.
8218 + */
8219 +void dwc_otg_hcd_remove(struct device *dev)
8220 +{
8221 + struct dwc_otg_device *otg_dev = dev->platform_data;
8222 + struct dwc_otg_hcd *dwc_otg_hcd = otg_dev->hcd;
8223 + struct usb_hcd *hcd = dwc_otg_hcd_to_hcd(dwc_otg_hcd);
8224 +
8225 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD REMOVE\n");
8226 +
8227 + /* Turn off all interrupts */
8228 + dwc_write_reg32(&dwc_otg_hcd->core_if->core_global_regs->gintmsk, 0);
8229 + dwc_modify_reg32(&dwc_otg_hcd->core_if->core_global_regs->gahbcfg, 1,
8230 + 0);
8231 +
8232 + usb_remove_hcd(hcd);
8233 + dwc_otg_hcd_free(hcd);
8234 + usb_put_hcd(hcd);
8235 +
8236 + return;
8237 +}
8238 +
8239 +/* =========================================================================
8240 + * Linux HC Driver Functions
8241 + * ========================================================================= */
8242 +
8243 +/**
8244 + * Initializes dynamic portions of the DWC_otg HCD state.
8245 + */
8246 +static void hcd_reinit(struct dwc_otg_hcd *hcd)
8247 +{
8248 + struct list_head *item;
8249 + int num_channels;
8250 + int i;
8251 + struct dwc_hc *channel;
8252 +
8253 + hcd->flags.d32 = 0;
8254 +
8255 + hcd->non_periodic_qh_ptr = &hcd->non_periodic_sched_active;
8256 + hcd->non_periodic_channels = 0;
8257 + hcd->periodic_channels = 0;
8258 +
8259 + /*
8260 + * Put all channels in the free channel list and clean up channel
8261 + * states.
8262 + */
8263 + item = hcd->free_hc_list.next;
8264 + while (item != &hcd->free_hc_list) {
8265 + list_del(item);
8266 + item = hcd->free_hc_list.next;
8267 + }
8268 + num_channels = hcd->core_if->core_params->host_channels;
8269 + for (i = 0; i < num_channels; i++) {
8270 + channel = hcd->hc_ptr_array[i];
8271 + list_add_tail(&channel->hc_list_entry, &hcd->free_hc_list);
8272 + dwc_otg_hc_cleanup(hcd->core_if, channel);
8273 + }
8274 +
8275 + /* Initialize the DWC core for host mode operation. */
8276 + dwc_otg_core_host_init(hcd->core_if);
8277 +}
8278 +
8279 +/** Initializes the DWC_otg controller and its root hub and prepares it for host
8280 + * mode operation. Activates the root port. Returns 0 on success and a negative
8281 + * error code on failure. */
8282 +int dwc_otg_hcd_start(struct usb_hcd *hcd)
8283 +{
8284 + struct dwc_otg_hcd *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
8285 + struct dwc_otg_core_if *core_if = dwc_otg_hcd->core_if;
8286 + unsigned long flags;
8287 +
8288 + struct usb_bus *bus;
8289 +
8290 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD START\n");
8291 +
8292 + spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags);
8293 +
8294 + bus = hcd_to_bus(hcd);
8295 +
8296 + /* Initialize the bus state. If the core is in Device Mode
8297 + * HALT the USB bus and return. */
8298 + if (dwc_otg_is_device_mode(core_if)) {
8299 + hcd->state = HC_STATE_HALT;
8300 + goto out;
8301 + }
8302 + hcd->state = HC_STATE_RUNNING;
8303 +
8304 + hcd_reinit(dwc_otg_hcd);
8305 +out:
8306 + spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags);
8307 +
8308 + return 0;
8309 +}
8310 +
8311 +static void qh_list_free(struct dwc_otg_hcd *hcd, struct list_head *_qh_list)
8312 +{
8313 + struct list_head *item;
8314 + struct dwc_otg_qh *qh;
8315 +
8316 + if (_qh_list->next == NULL) {
8317 + /* The list hasn't been initialized yet. */
8318 + return;
8319 + }
8320 +
8321 + /* Ensure there are no QTDs or URBs left. */
8322 + kill_urbs_in_qh_list(hcd, _qh_list);
8323 +
8324 + for (item = _qh_list->next; item != _qh_list; item = _qh_list->next) {
8325 + qh = list_entry(item, struct dwc_otg_qh, qh_list_entry);
8326 + dwc_otg_hcd_qh_remove_and_free(hcd, qh);
8327 + }
8328 +}
8329 +
8330 +/**
8331 + * Halts the DWC_otg host mode operations in a clean manner. USB transfers are
8332 + * stopped.
8333 + */
8334 +void dwc_otg_hcd_stop(struct usb_hcd *hcd)
8335 +{
8336 + struct dwc_otg_hcd *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
8337 + union hprt0_data hprt0 = {.d32 = 0 };
8338 +
8339 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD STOP\n");
8340 +
8341 + /* Turn off all host-specific interrupts. */
8342 + dwc_otg_disable_host_interrupts(dwc_otg_hcd->core_if);
8343 +
8344 + /*
8345 + * The root hub should be disconnected before this function is called.
8346 + * The disconnect will clear the QTD lists (via ..._hcd_urb_dequeue)
8347 + * and the QH lists (via ..._hcd_endpoint_disable).
8348 + */
8349 +
8350 + /* Turn off the vbus power */
8351 + DWC_PRINT("PortPower off\n");
8352 + hprt0.b.prtpwr = 0;
8353 + dwc_write_reg32(dwc_otg_hcd->core_if->host_if->hprt0, hprt0.d32);
8354 +
8355 + return;
8356 +}
8357 +
8358 +/** Returns the current frame number. */
8359 +int dwc_otg_hcd_get_frame_number(struct usb_hcd *hcd)
8360 +{
8361 + struct dwc_otg_hcd *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
8362 + union hfnum_data hfnum;
8363 +
8364 + hfnum.d32 =
8365 + dwc_read_reg32(&dwc_otg_hcd->core_if->host_if->host_global_regs->
8366 + hfnum);
8367 +
8368 +#ifdef DEBUG_SOF
8369 + DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD GET FRAME NUMBER %d\n",
8370 + hfnum.b.frnum);
8371 +#endif
8372 + return hfnum.b.frnum;
8373 +}
8374 +
8375 +/**
8376 + * Frees secondary storage associated with the dwc_otg_hcd structure contained
8377 + * in the struct usb_hcd field.
8378 + */
8379 +void dwc_otg_hcd_free(struct usb_hcd *hcd)
8380 +{
8381 + struct dwc_otg_hcd *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
8382 + int i;
8383 +
8384 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD FREE\n");
8385 +
8386 + del_timers(dwc_otg_hcd);
8387 +
8388 + /* Free memory for QH/QTD lists */
8389 + qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->non_periodic_sched_inactive);
8390 + qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->non_periodic_sched_active);
8391 + qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_inactive);
8392 + qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_ready);
8393 + qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_assigned);
8394 + qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_queued);
8395 +
8396 + /* Free memory for the host channels. */
8397 + for (i = 0; i < MAX_EPS_CHANNELS; i++) {
8398 + struct dwc_hc *hc = dwc_otg_hcd->hc_ptr_array[i];
8399 + if (hc != NULL) {
8400 + DWC_DEBUGPL(DBG_HCDV, "HCD Free channel #%i, hc=%p\n",
8401 + i, hc);
8402 + kfree(hc);
8403 + }
8404 + }
8405 +
8406 + if (dwc_otg_hcd->core_if->dma_enable) {
8407 + if (dwc_otg_hcd->status_buf_dma) {
8408 + dma_free_coherent(hcd->self.controller,
8409 + DWC_OTG_HCD_STATUS_BUF_SIZE,
8410 + dwc_otg_hcd->status_buf,
8411 + dwc_otg_hcd->status_buf_dma);
8412 + }
8413 + } else if (dwc_otg_hcd->status_buf != NULL) {
8414 + kfree(dwc_otg_hcd->status_buf);
8415 + }
8416 +
8417 + return;
8418 +}
8419 +
8420 +#ifdef DEBUG
8421 +static void dump_urb_info(struct urb *urb, char *_fn_name)
8422 +{
8423 + DWC_PRINT("%s, urb %p\n", _fn_name, urb);
8424 + DWC_PRINT(" Device address: %d\n", usb_pipedevice(urb->pipe));
8425 + DWC_PRINT(" Endpoint: %d, %s\n", usb_pipeendpoint(urb->pipe),
8426 + (usb_pipein(urb->pipe) ? "IN" : "OUT"));
8427 + DWC_PRINT(" Endpoint type: %s\n",
8428 + ({
8429 + char *pipetype;
8430 + switch (usb_pipetype(urb->pipe)) {
8431 + case PIPE_CONTROL:
8432 + pipetype = "CONTROL";
8433 + break;
8434 + case PIPE_BULK:
8435 + pipetype = "BULK";
8436 + break;
8437 + case PIPE_INTERRUPT:
8438 + pipetype = "INTERRUPT";
8439 + break;
8440 + case PIPE_ISOCHRONOUS:
8441 + pipetype = "ISOCHRONOUS";
8442 + break;
8443 + default:
8444 + pipetype = "UNKNOWN";
8445 + break;
8446 + }
8447 + pipetype;
8448 + })) ;
8449 + DWC_PRINT(" Speed: %s\n",
8450 + ({
8451 + char *speed;
8452 + switch (urb->dev->speed) {
8453 + case USB_SPEED_HIGH:
8454 + speed = "HIGH";
8455 + break;
8456 + case USB_SPEED_FULL:
8457 + speed = "FULL";
8458 + break;
8459 + case USB_SPEED_LOW:
8460 + speed = "LOW";
8461 + break;
8462 + default:
8463 + speed = "UNKNOWN";
8464 + break;
8465 + }
8466 + speed;
8467 + }));
8468 + DWC_PRINT(" Max packet size: %d\n",
8469 + usb_maxpacket(urb->dev, urb->pipe,
8470 + usb_pipeout(urb->pipe)));
8471 + DWC_PRINT(" Data buffer length: %d\n", urb->transfer_buffer_length);
8472 + DWC_PRINT(" Transfer buffer: %p, Transfer DMA: %p\n",
8473 + urb->transfer_buffer, (void *)urb->transfer_dma);
8474 + DWC_PRINT(" Setup buffer: %p, Setup DMA: %p\n",
8475 + urb->setup_packet, (void *)urb->setup_dma);
8476 + DWC_PRINT(" Interval: %d\n", urb->interval);
8477 + if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
8478 + int i;
8479 + for (i = 0; i < urb->number_of_packets; i++) {
8480 + DWC_PRINT(" ISO Desc %d:\n", i);
8481 + DWC_PRINT(" offset: %d, length %d\n",
8482 + urb->iso_frame_desc[i].offset,
8483 + urb->iso_frame_desc[i].length);
8484 + }
8485 + }
8486 +}
8487 +
8488 +static void dump_channel_info(struct dwc_otg_hcd *hcd, struct dwc_otg_qh * qh)
8489 +{
8490 + if (qh->channel != NULL) {
8491 + struct dwc_hc *hc = qh->channel;
8492 + struct list_head *item;
8493 + struct dwc_otg_qh *qh_item;
8494 + int num_channels = hcd->core_if->core_params->host_channels;
8495 + int i;
8496 +
8497 + struct dwc_otg_hc_regs *hc_regs;
8498 + union hcchar_data hcchar;
8499 + union hcsplt_data hcsplt;
8500 + union hctsiz_data hctsiz;
8501 + uint32_t hcdma;
8502 +
8503 + hc_regs = hcd->core_if->host_if->hc_regs[hc->hc_num];
8504 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8505 + hcsplt.d32 = dwc_read_reg32(&hc_regs->hcsplt);
8506 + hctsiz.d32 = dwc_read_reg32(&hc_regs->hctsiz);
8507 + hcdma = dwc_read_reg32(&hc_regs->hcdma);
8508 +
8509 + DWC_PRINT(" Assigned to channel %p:\n", hc);
8510 + DWC_PRINT(" hcchar 0x%08x, hcsplt 0x%08x\n", hcchar.d32,
8511 + hcsplt.d32);
8512 + DWC_PRINT(" hctsiz 0x%08x, hcdma 0x%08x\n", hctsiz.d32,
8513 + hcdma);
8514 + DWC_PRINT(" dev_addr: %d, ep_num: %d, ep_is_in: %d\n",
8515 + hc->dev_addr, hc->ep_num, hc->ep_is_in);
8516 + DWC_PRINT(" ep_type: %d\n", hc->ep_type);
8517 + DWC_PRINT(" max_packet: %d\n", hc->max_packet);
8518 + DWC_PRINT(" data_pid_start: %d\n", hc->data_pid_start);
8519 + DWC_PRINT(" xfer_started: %d\n", hc->xfer_started);
8520 + DWC_PRINT(" halt_status: %d\n", hc->halt_status);
8521 + DWC_PRINT(" xfer_buff: %p\n", hc->xfer_buff);
8522 + DWC_PRINT(" xfer_len: %d\n", hc->xfer_len);
8523 + DWC_PRINT(" qh: %p\n", hc->qh);
8524 + DWC_PRINT(" NP inactive sched:\n");
8525 + list_for_each(item, &hcd->non_periodic_sched_inactive) {
8526 + qh_item = list_entry(item, struct dwc_otg_qh,
8527 + qh_list_entry);
8528 + DWC_PRINT(" %p\n", qh_item);
8529 + }
8530 + DWC_PRINT(" NP active sched:\n");
8531 + list_for_each(item, &hcd->non_periodic_sched_active) {
8532 + qh_item = list_entry(item, struct dwc_otg_qh,
8533 + qh_list_entry);
8534 + DWC_PRINT(" %p\n", qh_item);
8535 + }
8536 + DWC_PRINT(" Channels: \n");
8537 + for (i = 0; i < num_channels; i++) {
8538 + struct dwc_hc *hc = hcd->hc_ptr_array[i];
8539 + DWC_PRINT(" %2d: %p\n", i, hc);
8540 + }
8541 + }
8542 +}
8543 +#endif
8544 +
8545 +/* Starts processing a USB transfer request specified by a USB Request Block
8546 + * (URB). mem_flags indicates the type of memory allocation to use while
8547 + * processing this URB. */
8548 +int dwc_otg_hcd_urb_enqueue(struct usb_hcd *hcd,
8549 + struct urb *urb, unsigned _mem_flags)
8550 +{
8551 + unsigned long flags;
8552 + int retval = 0;
8553 + struct dwc_otg_hcd *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
8554 + struct dwc_otg_qtd *qtd;
8555 +
8556 + spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags);
8557 +
8558 + /*
8559 + * Make sure the start of frame interrupt is enabled now that
8560 + * we know we should have queued data. The SOF interrupt
8561 + * handler automatically disables itself when idle to reduce
8562 + * the number of interrupts. See dwc_otg_hcd_handle_sof_intr()
8563 + * for the disable
8564 + */
8565 + dwc_modify_reg32(&dwc_otg_hcd->core_if->core_global_regs->gintmsk, 0,
8566 + DWC_SOF_INTR_MASK);
8567 +
8568 +#ifdef DEBUG
8569 + if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB))
8570 + dump_urb_info(urb, "dwc_otg_hcd_urb_enqueue");
8571 +#endif
8572 + if (!dwc_otg_hcd->flags.b.port_connect_status) {
8573 + /* No longer connected. */
8574 + retval = -ENODEV;
8575 + goto out;
8576 + }
8577 +
8578 + qtd = dwc_otg_hcd_qtd_create(urb);
8579 + if (qtd == NULL) {
8580 + DWC_ERROR("DWC OTG HCD URB Enqueue failed creating QTD\n");
8581 + retval = -ENOMEM;
8582 + goto out;
8583 + }
8584 +
8585 + retval = dwc_otg_hcd_qtd_add(qtd, dwc_otg_hcd);
8586 + if (retval < 0) {
8587 + DWC_ERROR("DWC OTG HCD URB Enqueue failed adding QTD. "
8588 + "Error status %d\n", retval);
8589 + dwc_otg_hcd_qtd_free(qtd);
8590 + }
8591 +out:
8592 + spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags);
8593 +
8594 + return retval;
8595 +}
8596 +
8597 +/** Aborts/cancels a USB transfer request. Always returns 0 to indicate
8598 + * success. */
8599 +int dwc_otg_hcd_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
8600 +{
8601 + unsigned long flags;
8602 + struct dwc_otg_hcd *dwc_otg_hcd;
8603 + struct dwc_otg_qtd *urb_qtd;
8604 +
8605 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD URB Dequeue\n");
8606 +
8607 + dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
8608 +
8609 + spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags);
8610 +
8611 + urb_qtd = urb->hcpriv;
8612 +
8613 +#ifdef DEBUG
8614 + if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
8615 + dump_urb_info(urb, "dwc_otg_hcd_urb_dequeue");
8616 + if (urb_qtd == urb_qtd->qh->qtd_in_process)
8617 + dump_channel_info(dwc_otg_hcd, urb_qtd->qh);
8618 + }
8619 +#endif
8620 +
8621 + if (urb_qtd == urb_qtd->qh->qtd_in_process) {
8622 + /* The QTD is in process (it has been assigned to a channel). */
8623 +
8624 + if (dwc_otg_hcd->flags.b.port_connect_status) {
8625 + /*
8626 + * If still connected (i.e. in host mode), halt the
8627 + * channel so it can be used for other transfers. If
8628 + * no longer connected, the host registers can't be
8629 + * written to halt the channel since the core is in
8630 + * device mode.
8631 + */
8632 + dwc_otg_hc_halt(dwc_otg_hcd->core_if,
8633 + urb_qtd->qh->channel,
8634 + DWC_OTG_HC_XFER_URB_DEQUEUE);
8635 + }
8636 + }
8637 +
8638 + /*
8639 + * Free the QTD and clean up the associated QH. Leave the QH in the
8640 + * schedule if it has any remaining QTDs.
8641 + */
8642 + dwc_otg_hcd_qtd_remove_and_free(urb_qtd);
8643 + if (urb_qtd == urb_qtd->qh->qtd_in_process) {
8644 + dwc_otg_hcd_qh_deactivate(dwc_otg_hcd, urb_qtd->qh, 0);
8645 + urb_qtd->qh->channel = NULL;
8646 + urb_qtd->qh->qtd_in_process = NULL;
8647 + } else if (list_empty(&urb_qtd->qh->qtd_list)) {
8648 + dwc_otg_hcd_qh_remove(dwc_otg_hcd, urb_qtd->qh);
8649 + }
8650 +
8651 + spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags);
8652 +
8653 + urb->hcpriv = NULL;
8654 +
8655 + /* Higher layer software sets URB status. */
8656 + usb_hcd_giveback_urb(hcd, urb, status);
8657 + if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
8658 + DWC_PRINT("Called usb_hcd_giveback_urb()\n");
8659 + DWC_PRINT(" urb->status = %d\n", urb->status);
8660 + }
8661 +
8662 + return 0;
8663 +}
8664 +
8665 +/* Frees resources in the DWC_otg controller related to a given endpoint. Also
8666 + * clears state in the HCD related to the endpoint. Any URBs for the endpoint
8667 + * must already be dequeued. */
8668 +void dwc_otg_hcd_endpoint_disable(struct usb_hcd *hcd,
8669 + struct usb_host_endpoint *_ep)
8670 +{
8671 + unsigned long flags;
8672 + struct dwc_otg_qh *qh;
8673 + struct dwc_otg_hcd *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
8674 +
8675 + spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags);
8676 +
8677 + DWC_DEBUGPL(DBG_HCD,
8678 + "DWC OTG HCD EP DISABLE: _bEndpointAddress=0x%02x, "
8679 + "endpoint=%d\n", _ep->desc.bEndpointAddress,
8680 + dwc_ep_addr_to_endpoint(_ep->desc.bEndpointAddress));
8681 +
8682 + qh = _ep->hcpriv;
8683 + if (qh != NULL) {
8684 +#if 1
8685 + /*
8686 + * FIXME: Kludge to not crash on Octeon in SMP
8687 + * mode. Normally dwc_otg_hcd_qh_remove_and_free() is
8688 + * called even if the list isn't empty. This causes a
8689 + * crash on SMP, so we don't call it now. It works
8690 + * better, but probably does evil things I don't know
8691 + * about.
8692 + */
8693 + /* Check that the QTD list is really empty */
8694 + if (!list_empty(&qh->qtd_list)) {
8695 + pr_err("DWC OTG HCD EP DISABLE:"
8696 + " QTD List for this endpoint is not empty\n");
8697 + } else
8698 +#endif
8699 + {
8700 + dwc_otg_hcd_qh_remove_and_free(dwc_otg_hcd, qh);
8701 + _ep->hcpriv = NULL;
8702 + }
8703 + }
8704 +
8705 + spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags);
8706 +
8707 + return;
8708 +}
8709 +
8710 +/* Handles host mode interrupts for the DWC_otg controller. Returns IRQ_NONE if
8711 + * there was no interrupt to handle. Returns IRQ_HANDLED if there was a valid
8712 + * interrupt.
8713 + *
8714 + * This function is called by the USB core when an interrupt occurs */
8715 +irqreturn_t dwc_otg_hcd_irq(struct usb_hcd *hcd)
8716 +{
8717 + irqreturn_t result;
8718 + unsigned long flags;
8719 + struct dwc_otg_hcd *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
8720 +
8721 + spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags);
8722 +
8723 + result = IRQ_RETVAL(dwc_otg_hcd_handle_intr(dwc_otg_hcd));
8724 +
8725 + spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags);
8726 +
8727 + return result;
8728 +}
8729 +
8730 +/** Creates Status Change bitmap for the root hub and root port. The bitmap is
8731 + * returned in buf. Bit 0 is the status change indicator for the root hub. Bit 1
8732 + * is the status change indicator for the single root port. Returns 1 if either
8733 + * change indicator is 1, otherwise returns 0. */
8734 +int dwc_otg_hcd_hub_status_data(struct usb_hcd *hcd, char *_buf)
8735 +{
8736 + struct dwc_otg_hcd *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
8737 +
8738 + _buf[0] = 0;
8739 + _buf[0] |= (dwc_otg_hcd->flags.b.port_connect_status_change ||
8740 + dwc_otg_hcd->flags.b.port_reset_change ||
8741 + dwc_otg_hcd->flags.b.port_enable_change ||
8742 + dwc_otg_hcd->flags.b.port_suspend_change ||
8743 + dwc_otg_hcd->flags.b.port_over_current_change) << 1;
8744 +
8745 +#ifdef DEBUG
8746 + if (_buf[0]) {
8747 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB STATUS DATA:"
8748 + " Root port status changed\n");
8749 + DWC_DEBUGPL(DBG_HCDV, " port_connect_status_change: %d\n",
8750 + dwc_otg_hcd->flags.b.port_connect_status_change);
8751 + DWC_DEBUGPL(DBG_HCDV, " port_reset_change: %d\n",
8752 + dwc_otg_hcd->flags.b.port_reset_change);
8753 + DWC_DEBUGPL(DBG_HCDV, " port_enable_change: %d\n",
8754 + dwc_otg_hcd->flags.b.port_enable_change);
8755 + DWC_DEBUGPL(DBG_HCDV, " port_suspend_change: %d\n",
8756 + dwc_otg_hcd->flags.b.port_suspend_change);
8757 + DWC_DEBUGPL(DBG_HCDV, " port_over_current_change: %d\n",
8758 + dwc_otg_hcd->flags.b.port_over_current_change);
8759 + }
8760 +#endif
8761 + return (_buf[0] != 0);
8762 +}
8763 +
8764 +#ifdef DWC_HS_ELECT_TST
8765 +/*
8766 + * Quick and dirty hack to implement the HS Electrical Test
8767 + * SINGLE_STEP_GET_DEVICE_DESCRIPTOR feature.
8768 + *
8769 + * This code was copied from our userspace app "hset". It sends a
8770 + * Get Device Descriptor control sequence in two parts, first the
8771 + * Setup packet by itself, followed some time later by the In and
8772 + * Ack packets. Rather than trying to figure out how to add this
8773 + * functionality to the normal driver code, we just hijack the
8774 + * hardware, using these two function to drive the hardware
8775 + * directly.
8776 + */
8777 +
8778 +struct dwc_otg_core_global_regs *global_regs;
8779 +struct dwc_otg_host_global_regs *hc_global_regs;
8780 +struct dwc_otg_hc_regs *hc_regs;
8781 +uint32_t *data_fifo;
8782 +
8783 +static void do_setup(void)
8784 +{
8785 + union gintsts_data gintsts;
8786 + union hctsiz_data hctsiz;
8787 + union hcchar_data hcchar;
8788 + union haint_data haint;
8789 + union hcint_data hcint;
8790 +
8791 + /* Enable HAINTs */
8792 + dwc_write_reg32(&hc_global_regs->haintmsk, 0x0001);
8793 +
8794 + /* Enable HCINTs */
8795 + dwc_write_reg32(&hc_regs->hcintmsk, 0x04a3);
8796 +
8797 + /* Read GINTSTS */
8798 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8799 +
8800 + /* Read HAINT */
8801 + haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
8802 +
8803 + /* Read HCINT */
8804 + hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
8805 +
8806 + /* Read HCCHAR */
8807 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8808 +
8809 + /* Clear HCINT */
8810 + dwc_write_reg32(&hc_regs->hcint, hcint.d32);
8811 +
8812 + /* Clear HAINT */
8813 + dwc_write_reg32(&hc_global_regs->haint, haint.d32);
8814 +
8815 + /* Clear GINTSTS */
8816 + dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
8817 +
8818 + /* Read GINTSTS */
8819 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8820 +
8821 + /*
8822 + * Send Setup packet (Get Device Descriptor)
8823 + */
8824 +
8825 + /* Make sure channel is disabled */
8826 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8827 + if (hcchar.b.chen) {
8828 + hcchar.b.chdis = 1;
8829 + dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
8830 +
8831 + mdelay(1000);
8832 +
8833 + /* Read GINTSTS */
8834 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8835 +
8836 + /* Read HAINT */
8837 + haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
8838 +
8839 + /* Read HCINT */
8840 + hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
8841 +
8842 + /* Read HCCHAR */
8843 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8844 +
8845 + /* Clear HCINT */
8846 + dwc_write_reg32(&hc_regs->hcint, hcint.d32);
8847 +
8848 + /* Clear HAINT */
8849 + dwc_write_reg32(&hc_global_regs->haint, haint.d32);
8850 +
8851 + /* Clear GINTSTS */
8852 + dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
8853 +
8854 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8855 + }
8856 +
8857 + /* Set HCTSIZ */
8858 + hctsiz.d32 = 0;
8859 + hctsiz.b.xfersize = 8;
8860 + hctsiz.b.pktcnt = 1;
8861 + hctsiz.b.pid = DWC_OTG_HC_PID_SETUP;
8862 + dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
8863 +
8864 + /* Set HCCHAR */
8865 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8866 + hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;
8867 + hcchar.b.epdir = 0;
8868 + hcchar.b.epnum = 0;
8869 + hcchar.b.mps = 8;
8870 + hcchar.b.chen = 1;
8871 + dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
8872 +
8873 + /* Fill FIFO with Setup data for Get Device Descriptor */
8874 + data_fifo = (uint32_t *) ((char *)global_regs + 0x1000);
8875 + dwc_write_reg32(data_fifo++, 0x01000680);
8876 + dwc_write_reg32(data_fifo++, 0x00080000);
8877 +
8878 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8879 +
8880 + /* Wait for host channel interrupt */
8881 + do {
8882 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8883 + } while (gintsts.b.hcintr == 0);
8884 +
8885 +
8886 + /* Disable HCINTs */
8887 + dwc_write_reg32(&hc_regs->hcintmsk, 0x0000);
8888 +
8889 + /* Disable HAINTs */
8890 + dwc_write_reg32(&hc_global_regs->haintmsk, 0x0000);
8891 +
8892 + /* Read HAINT */
8893 + haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
8894 +
8895 + /* Read HCINT */
8896 + hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
8897 +
8898 + /* Read HCCHAR */
8899 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8900 +
8901 + /* Clear HCINT */
8902 + dwc_write_reg32(&hc_regs->hcint, hcint.d32);
8903 +
8904 + /* Clear HAINT */
8905 + dwc_write_reg32(&hc_global_regs->haint, haint.d32);
8906 +
8907 + /* Clear GINTSTS */
8908 + dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
8909 +
8910 + /* Read GINTSTS */
8911 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8912 +}
8913 +
8914 +static void do_in_ack(void)
8915 +{
8916 + union gintsts_data gintsts;
8917 + union hctsiz_data hctsiz;
8918 + union hcchar_data hcchar;
8919 + union haint_data haint;
8920 + union hcint_data hcint;
8921 + union host_grxsts_data grxsts;
8922 +
8923 + /* Enable HAINTs */
8924 + dwc_write_reg32(&hc_global_regs->haintmsk, 0x0001);
8925 +
8926 + /* Enable HCINTs */
8927 + dwc_write_reg32(&hc_regs->hcintmsk, 0x04a3);
8928 +
8929 + /* Read GINTSTS */
8930 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8931 +
8932 + /* Read HAINT */
8933 + haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
8934 +
8935 + /* Read HCINT */
8936 + hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
8937 +
8938 + /* Read HCCHAR */
8939 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8940 +
8941 + /* Clear HCINT */
8942 + dwc_write_reg32(&hc_regs->hcint, hcint.d32);
8943 +
8944 + /* Clear HAINT */
8945 + dwc_write_reg32(&hc_global_regs->haint, haint.d32);
8946 +
8947 + /* Clear GINTSTS */
8948 + dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
8949 +
8950 + /* Read GINTSTS */
8951 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8952 +
8953 + /*
8954 + * Receive Control In packet
8955 + */
8956 +
8957 + /* Make sure channel is disabled */
8958 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8959 + if (hcchar.b.chen) {
8960 + hcchar.b.chdis = 1;
8961 + hcchar.b.chen = 1;
8962 + dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
8963 +
8964 + mdelay(1000);
8965 +
8966 + /* Read GINTSTS */
8967 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8968 +
8969 + /* Read HAINT */
8970 + haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
8971 +
8972 + /* Read HCINT */
8973 + hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
8974 +
8975 + /* Read HCCHAR */
8976 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8977 +
8978 + /* Clear HCINT */
8979 + dwc_write_reg32(&hc_regs->hcint, hcint.d32);
8980 +
8981 + /* Clear HAINT */
8982 + dwc_write_reg32(&hc_global_regs->haint, haint.d32);
8983 +
8984 + /* Clear GINTSTS */
8985 + dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
8986 +
8987 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8988 + }
8989 +
8990 + /* Set HCTSIZ */
8991 + hctsiz.d32 = 0;
8992 + hctsiz.b.xfersize = 8;
8993 + hctsiz.b.pktcnt = 1;
8994 + hctsiz.b.pid = DWC_OTG_HC_PID_DATA1;
8995 + dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
8996 +
8997 + /* Set HCCHAR */
8998 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8999 + hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;
9000 + hcchar.b.epdir = 1;
9001 + hcchar.b.epnum = 0;
9002 + hcchar.b.mps = 8;
9003 + hcchar.b.chen = 1;
9004 + dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
9005 +
9006 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9007 +
9008 + /* Wait for receive status queue interrupt */
9009 + do {
9010 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9011 + } while (gintsts.b.rxstsqlvl == 0);
9012 +
9013 + /* Read RXSTS */
9014 + grxsts.d32 = dwc_read_reg32(&global_regs->grxstsp);
9015 +
9016 + /* Clear RXSTSQLVL in GINTSTS */
9017 + gintsts.d32 = 0;
9018 + gintsts.b.rxstsqlvl = 1;
9019 + dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
9020 +
9021 + switch (grxsts.b.pktsts) {
9022 + case DWC_GRXSTS_PKTSTS_IN:
9023 + /* Read the data into the host buffer */
9024 + if (grxsts.b.bcnt > 0) {
9025 + int i;
9026 + int word_count = (grxsts.b.bcnt + 3) / 4;
9027 +
9028 + data_fifo = (uint32_t *) ((char *)global_regs + 0x1000);
9029 +
9030 + for (i = 0; i < word_count; i++)
9031 + (void)dwc_read_reg32(data_fifo++);
9032 + }
9033 + break;
9034 +
9035 + default:
9036 + break;
9037 + }
9038 +
9039 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9040 +
9041 + /* Wait for receive status queue interrupt */
9042 + do {
9043 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9044 + } while (gintsts.b.rxstsqlvl == 0);
9045 +
9046 +
9047 + /* Read RXSTS */
9048 + grxsts.d32 = dwc_read_reg32(&global_regs->grxstsp);
9049 +
9050 + /* Clear RXSTSQLVL in GINTSTS */
9051 + gintsts.d32 = 0;
9052 + gintsts.b.rxstsqlvl = 1;
9053 + dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
9054 +
9055 + switch (grxsts.b.pktsts) {
9056 + case DWC_GRXSTS_PKTSTS_IN_XFER_COMP:
9057 + break;
9058 +
9059 + default:
9060 + break;
9061 + }
9062 +
9063 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9064 +
9065 + /* Wait for host channel interrupt */
9066 + do {
9067 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9068 + } while (gintsts.b.hcintr == 0);
9069 +
9070 +
9071 + /* Read HAINT */
9072 + haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
9073 +
9074 + /* Read HCINT */
9075 + hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
9076 +
9077 + /* Read HCCHAR */
9078 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
9079 +
9080 + /* Clear HCINT */
9081 + dwc_write_reg32(&hc_regs->hcint, hcint.d32);
9082 +
9083 + /* Clear HAINT */
9084 + dwc_write_reg32(&hc_global_regs->haint, haint.d32);
9085 +
9086 + /* Clear GINTSTS */
9087 + dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
9088 +
9089 + /* Read GINTSTS */
9090 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9091 +
9092 + mdelay(1);
9093 +
9094 + /*
9095 + * Send handshake packet
9096 + */
9097 +
9098 + /* Read HAINT */
9099 + haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
9100 +
9101 + /* Read HCINT */
9102 + hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
9103 +
9104 + /* Read HCCHAR */
9105 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
9106 +
9107 + /* Clear HCINT */
9108 + dwc_write_reg32(&hc_regs->hcint, hcint.d32);
9109 +
9110 + /* Clear HAINT */
9111 + dwc_write_reg32(&hc_global_regs->haint, haint.d32);
9112 +
9113 + /* Clear GINTSTS */
9114 + dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
9115 +
9116 + /* Read GINTSTS */
9117 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9118 +
9119 + /* Make sure channel is disabled */
9120 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
9121 + if (hcchar.b.chen) {
9122 + hcchar.b.chdis = 1;
9123 + hcchar.b.chen = 1;
9124 + dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
9125 +
9126 + mdelay(1000);
9127 +
9128 + /* Read GINTSTS */
9129 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9130 +
9131 + /* Read HAINT */
9132 + haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
9133 +
9134 + /* Read HCINT */
9135 + hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
9136 +
9137 + /* Read HCCHAR */
9138 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
9139 +
9140 + /* Clear HCINT */
9141 + dwc_write_reg32(&hc_regs->hcint, hcint.d32);
9142 +
9143 + /* Clear HAINT */
9144 + dwc_write_reg32(&hc_global_regs->haint, haint.d32);
9145 +
9146 + /* Clear GINTSTS */
9147 + dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
9148 +
9149 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
9150 + }
9151 +
9152 + /* Set HCTSIZ */
9153 + hctsiz.d32 = 0;
9154 + hctsiz.b.xfersize = 0;
9155 + hctsiz.b.pktcnt = 1;
9156 + hctsiz.b.pid = DWC_OTG_HC_PID_DATA1;
9157 + dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
9158 +
9159 + /* Set HCCHAR */
9160 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
9161 + hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;
9162 + hcchar.b.epdir = 0;
9163 + hcchar.b.epnum = 0;
9164 + hcchar.b.mps = 8;
9165 + hcchar.b.chen = 1;
9166 + dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
9167 +
9168 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9169 +
9170 + /* Wait for host channel interrupt */
9171 + do {
9172 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9173 + } while (gintsts.b.hcintr == 0);
9174 +
9175 +
9176 + /* Disable HCINTs */
9177 + dwc_write_reg32(&hc_regs->hcintmsk, 0x0000);
9178 +
9179 + /* Disable HAINTs */
9180 + dwc_write_reg32(&hc_global_regs->haintmsk, 0x0000);
9181 +
9182 + /* Read HAINT */
9183 + haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
9184 +
9185 + /* Read HCINT */
9186 + hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
9187 +
9188 + /* Read HCCHAR */
9189 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
9190 +
9191 + /* Clear HCINT */
9192 + dwc_write_reg32(&hc_regs->hcint, hcint.d32);
9193 +
9194 + /* Clear HAINT */
9195 + dwc_write_reg32(&hc_global_regs->haint, haint.d32);
9196 +
9197 + /* Clear GINTSTS */
9198 + dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
9199 +
9200 + /* Read GINTSTS */
9201 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9202 +}
9203 +#endif /* DWC_HS_ELECT_TST */
9204 +
9205 +/* Handles hub class-specific requests.*/
9206 +int dwc_otg_hcd_hub_control(struct usb_hcd *hcd,
9207 + u16 _typeReq,
9208 + u16 _wValue, u16 _wIndex, char *_buf, u16 _wLength)
9209 +{
9210 + int retval = 0;
9211 + unsigned long flags;
9212 +
9213 + struct dwc_otg_hcd *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
9214 + struct dwc_otg_core_if *core_if = hcd_to_dwc_otg_hcd(hcd)->core_if;
9215 + struct usb_hub_descriptor *desc;
9216 + union hprt0_data hprt0 = {.d32 = 0 };
9217 +
9218 + uint32_t port_status;
9219 +#ifdef DWC_HS_ELECT_TST
9220 + uint32_t t;
9221 + union gintmsk_data gintmsk;
9222 +#endif
9223 + spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags);
9224 +
9225 + switch (_typeReq) {
9226 + case ClearHubFeature:
9227 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9228 + "ClearHubFeature 0x%x\n", _wValue);
9229 + switch (_wValue) {
9230 + case C_HUB_LOCAL_POWER:
9231 + case C_HUB_OVER_CURRENT:
9232 + /* Nothing required here */
9233 + break;
9234 + default:
9235 + retval = -EINVAL;
9236 + DWC_ERROR("DWC OTG HCD - "
9237 + "ClearHubFeature request %xh unknown\n",
9238 + _wValue);
9239 + }
9240 + break;
9241 + case ClearPortFeature:
9242 + if (!_wIndex || _wIndex > 1)
9243 + goto error;
9244 +
9245 + switch (_wValue) {
9246 + case USB_PORT_FEAT_ENABLE:
9247 + DWC_DEBUGPL(DBG_ANY, "DWC OTG HCD HUB CONTROL - "
9248 + "ClearPortFeature USB_PORT_FEAT_ENABLE\n");
9249 + hprt0.d32 = dwc_otg_read_hprt0(core_if);
9250 + hprt0.b.prtena = 1;
9251 + dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
9252 + break;
9253 + case USB_PORT_FEAT_SUSPEND:
9254 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9255 + "ClearPortFeature USB_PORT_FEAT_SUSPEND\n");
9256 + hprt0.d32 = dwc_otg_read_hprt0(core_if);
9257 + hprt0.b.prtres = 1;
9258 + dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
9259 + /* Clear Resume bit */
9260 + mdelay(100);
9261 + hprt0.b.prtres = 0;
9262 + dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
9263 + break;
9264 + case USB_PORT_FEAT_POWER:
9265 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9266 + "ClearPortFeature USB_PORT_FEAT_POWER\n");
9267 + hprt0.d32 = dwc_otg_read_hprt0(core_if);
9268 + hprt0.b.prtpwr = 0;
9269 + dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
9270 + break;
9271 + case USB_PORT_FEAT_INDICATOR:
9272 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9273 + "ClearPortFeature USB_PORT_FEAT_INDICATOR\n");
9274 + /* Port inidicator not supported */
9275 + break;
9276 + case USB_PORT_FEAT_C_CONNECTION:
9277 + /* Clears drivers internal connect status change
9278 + * flag */
9279 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9280 + "ClearPortFeature USB_PORT_FEAT_C_CONNECTION\n");
9281 + dwc_otg_hcd->flags.b.port_connect_status_change = 0;
9282 + break;
9283 + case USB_PORT_FEAT_C_RESET:
9284 + /* Clears the driver's internal Port Reset Change
9285 + * flag */
9286 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9287 + "ClearPortFeature USB_PORT_FEAT_C_RESET\n");
9288 + dwc_otg_hcd->flags.b.port_reset_change = 0;
9289 + break;
9290 + case USB_PORT_FEAT_C_ENABLE:
9291 + /* Clears the driver's internal Port
9292 + * Enable/Disable Change flag */
9293 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9294 + "ClearPortFeature USB_PORT_FEAT_C_ENABLE\n");
9295 + dwc_otg_hcd->flags.b.port_enable_change = 0;
9296 + break;
9297 + case USB_PORT_FEAT_C_SUSPEND:
9298 + /* Clears the driver's internal Port Suspend
9299 + * Change flag, which is set when resume signaling on
9300 + * the host port is complete */
9301 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9302 + "ClearPortFeature USB_PORT_FEAT_C_SUSPEND\n");
9303 + dwc_otg_hcd->flags.b.port_suspend_change = 0;
9304 + break;
9305 + case USB_PORT_FEAT_C_OVER_CURRENT:
9306 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9307 + "ClearPortFeature USB_PORT_FEAT_C_OVER_CURRENT\n");
9308 + dwc_otg_hcd->flags.b.port_over_current_change = 0;
9309 + break;
9310 + default:
9311 + retval = -EINVAL;
9312 + DWC_ERROR("DWC OTG HCD - "
9313 + "ClearPortFeature request %xh "
9314 + "unknown or unsupported\n", _wValue);
9315 + }
9316 + break;
9317 + case GetHubDescriptor:
9318 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9319 + "GetHubDescriptor\n");
9320 + desc = (struct usb_hub_descriptor *)_buf;
9321 + desc->bDescLength = 9;
9322 + desc->bDescriptorType = 0x29;
9323 + desc->bNbrPorts = 1;
9324 + desc->wHubCharacteristics = 0x08;
9325 + desc->bPwrOn2PwrGood = 1;
9326 + desc->bHubContrCurrent = 0;
9327 + desc->bitmap[0] = 0;
9328 + desc->bitmap[1] = 0xff;
9329 + break;
9330 + case GetHubStatus:
9331 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9332 + "GetHubStatus\n");
9333 + memset(_buf, 0, 4);
9334 + break;
9335 + case GetPortStatus:
9336 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9337 + "GetPortStatus\n");
9338 +
9339 + if (!_wIndex || _wIndex > 1)
9340 + goto error;
9341 +
9342 + port_status = 0;
9343 +
9344 + if (dwc_otg_hcd->flags.b.port_connect_status_change)
9345 + port_status |= (1 << USB_PORT_FEAT_C_CONNECTION);
9346 +
9347 + if (dwc_otg_hcd->flags.b.port_enable_change)
9348 + port_status |= (1 << USB_PORT_FEAT_C_ENABLE);
9349 +
9350 + if (dwc_otg_hcd->flags.b.port_suspend_change)
9351 + port_status |= (1 << USB_PORT_FEAT_C_SUSPEND);
9352 +
9353 + if (dwc_otg_hcd->flags.b.port_reset_change)
9354 + port_status |= (1 << USB_PORT_FEAT_C_RESET);
9355 +
9356 + if (dwc_otg_hcd->flags.b.port_over_current_change) {
9357 + DWC_ERROR("Device Not Supported\n");
9358 + port_status |= (1 << USB_PORT_FEAT_C_OVER_CURRENT);
9359 + }
9360 +
9361 + if (!dwc_otg_hcd->flags.b.port_connect_status) {
9362 + /*
9363 + * The port is disconnected, which means the core is
9364 + * either in device mode or it soon will be. Just
9365 + * return 0's for the remainder of the port status
9366 + * since the port register can't be read if the core
9367 + * is in device mode.
9368 + */
9369 + *((__le32 *) _buf) = cpu_to_le32(port_status);
9370 + break;
9371 + }
9372 +
9373 + hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
9374 + DWC_DEBUGPL(DBG_HCDV, " HPRT0: 0x%08x\n", hprt0.d32);
9375 +
9376 + if (hprt0.b.prtconnsts)
9377 + port_status |= (1 << USB_PORT_FEAT_CONNECTION);
9378 +
9379 + if (hprt0.b.prtena)
9380 + port_status |= (1 << USB_PORT_FEAT_ENABLE);
9381 +
9382 + if (hprt0.b.prtsusp)
9383 + port_status |= (1 << USB_PORT_FEAT_SUSPEND);
9384 +
9385 + if (hprt0.b.prtovrcurract)
9386 + port_status |= (1 << USB_PORT_FEAT_OVER_CURRENT);
9387 +
9388 + if (hprt0.b.prtrst)
9389 + port_status |= (1 << USB_PORT_FEAT_RESET);
9390 +
9391 + if (hprt0.b.prtpwr)
9392 + port_status |= (1 << USB_PORT_FEAT_POWER);
9393 +
9394 + if (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_HIGH_SPEED)
9395 + port_status |= (1 << USB_PORT_FEAT_HIGHSPEED);
9396 + else if (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_LOW_SPEED)
9397 + port_status |= (1 << USB_PORT_FEAT_LOWSPEED);
9398 +
9399 + if (hprt0.b.prttstctl)
9400 + port_status |= (1 << USB_PORT_FEAT_TEST);
9401 +
9402 + /* USB_PORT_FEAT_INDICATOR unsupported always 0 */
9403 +
9404 + *((__le32 *) _buf) = cpu_to_le32(port_status);
9405 +
9406 + break;
9407 + case SetHubFeature:
9408 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9409 + "SetHubFeature\n");
9410 + /* No HUB features supported */
9411 + break;
9412 + case SetPortFeature:
9413 + if (_wValue != USB_PORT_FEAT_TEST && (!_wIndex || _wIndex > 1))
9414 + goto error;
9415 +
9416 + if (!dwc_otg_hcd->flags.b.port_connect_status) {
9417 + /*
9418 + * The port is disconnected, which means the core is
9419 + * either in device mode or it soon will be. Just
9420 + * return without doing anything since the port
9421 + * register can't be written if the core is in device
9422 + * mode.
9423 + */
9424 + break;
9425 + }
9426 +
9427 + switch (_wValue) {
9428 + case USB_PORT_FEAT_SUSPEND:
9429 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9430 + "SetPortFeature - USB_PORT_FEAT_SUSPEND\n");
9431 + if (hcd->self.otg_port == _wIndex &&
9432 + hcd->self.b_hnp_enable) {
9433 + union gotgctl_data gotgctl = {.d32 = 0 };
9434 + gotgctl.b.hstsethnpen = 1;
9435 + dwc_modify_reg32(&core_if->core_global_regs->
9436 + gotgctl, 0, gotgctl.d32);
9437 + core_if->op_state = A_SUSPEND;
9438 + }
9439 + hprt0.d32 = dwc_otg_read_hprt0(core_if);
9440 + hprt0.b.prtsusp = 1;
9441 + dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
9442 + /* Suspend the Phy Clock */
9443 + {
9444 + union pcgcctl_data pcgcctl = {.d32 = 0 };
9445 + pcgcctl.b.stoppclk = 1;
9446 + dwc_write_reg32(core_if->pcgcctl, pcgcctl.d32);
9447 + }
9448 +
9449 + /*
9450 + * For HNP the bus must be suspended for at
9451 + * least 200ms.
9452 + */
9453 + if (hcd->self.b_hnp_enable)
9454 + mdelay(200);
9455 + break;
9456 + case USB_PORT_FEAT_POWER:
9457 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9458 + "SetPortFeature - USB_PORT_FEAT_POWER\n");
9459 + hprt0.d32 = dwc_otg_read_hprt0(core_if);
9460 + hprt0.b.prtpwr = 1;
9461 + dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
9462 + break;
9463 + case USB_PORT_FEAT_RESET:
9464 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9465 + "SetPortFeature - USB_PORT_FEAT_RESET\n");
9466 + hprt0.d32 = dwc_otg_read_hprt0(core_if);
9467 + /* When B-Host the Port reset bit is set in
9468 + * the Start HCD Callback function, so that
9469 + * the reset is started within 1ms of the HNP
9470 + * success interrupt. */
9471 + if (!hcd->self.is_b_host) {
9472 + hprt0.b.prtrst = 1;
9473 + dwc_write_reg32(core_if->host_if->hprt0,
9474 + hprt0.d32);
9475 + }
9476 + /* Clear reset bit in 10ms (FS/LS) or 50ms (HS) */
9477 + mdelay(60);
9478 + hprt0.b.prtrst = 0;
9479 + dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
9480 + break;
9481 +
9482 +#ifdef DWC_HS_ELECT_TST
9483 + case USB_PORT_FEAT_TEST:
9484 + t = (_wIndex >> 8); /* MSB wIndex USB */
9485 + DWC_DEBUGPL(DBG_HCD,
9486 + "DWC OTG HCD HUB CONTROL - "
9487 + "SetPortFeature - USB_PORT_FEAT_TEST %d\n", t);
9488 + warn("USB_PORT_FEAT_TEST %d\n", t);
9489 + if (t < 6) {
9490 + hprt0.d32 = dwc_otg_read_hprt0(core_if);
9491 + hprt0.b.prttstctl = t;
9492 + dwc_write_reg32(core_if->host_if->hprt0,
9493 + hprt0.d32);
9494 + } else {
9495 + /* Setup global vars with reg
9496 + * addresses (quick and dirty hack,
9497 + * should be cleaned up)
9498 + */
9499 + global_regs = core_if->core_global_regs;
9500 + hc_global_regs =
9501 + core_if->host_if->host_global_regs;
9502 + hc_regs =
9503 + (struct dwc_otg_hc_regs *) ((char *)
9504 + global_regs +
9505 + 0x500);
9506 + data_fifo =
9507 + (uint32_t *) ((char *)global_regs +
9508 + 0x1000);
9509 +
9510 + if (t == 6) { /* HS_HOST_PORT_SUSPEND_RESUME */
9511 + /* Save current interrupt mask */
9512 + gintmsk.d32 =
9513 + dwc_read_reg32(&global_regs->gintmsk);
9514 +
9515 + /* Disable all interrupts
9516 + * while we muck with the
9517 + * hardware directly
9518 + */
9519 + dwc_write_reg32(&global_regs->gintmsk,
9520 + 0);
9521 +
9522 + /* 15 second delay per the test spec */
9523 + mdelay(15000);
9524 +
9525 + /* Drive suspend on the root port */
9526 + hprt0.d32 =
9527 + dwc_otg_read_hprt0(core_if);
9528 + hprt0.b.prtsusp = 1;
9529 + hprt0.b.prtres = 0;
9530 + dwc_write_reg32(core_if->host_if->hprt0,
9531 + hprt0.d32);
9532 +
9533 + /* 15 second delay per the test spec */
9534 + mdelay(15000);
9535 +
9536 + /* Drive resume on the root port */
9537 + hprt0.d32 = dwc_otg_read_hprt0(core_if);
9538 + hprt0.b.prtsusp = 0;
9539 + hprt0.b.prtres = 1;
9540 + dwc_write_reg32(core_if->host_if->hprt0,
9541 + hprt0.d32);
9542 + mdelay(100);
9543 +
9544 + /* Clear the resume bit */
9545 + hprt0.b.prtres = 0;
9546 + dwc_write_reg32(core_if->host_if->hprt0,
9547 + hprt0.d32);
9548 +
9549 + /* Restore interrupts */
9550 + dwc_write_reg32(&global_regs->gintmsk,
9551 + gintmsk.d32);
9552 + } else if (t == 7) {
9553 + /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR setup */
9554 + /* Save current interrupt mask */
9555 + gintmsk.d32 =
9556 + dwc_read_reg32(&global_regs->gintmsk);
9557 +
9558 + /*
9559 + * Disable all interrupts
9560 + * while we muck with the
9561 + * hardware directly
9562 + */
9563 + dwc_write_reg32(&global_regs->gintmsk,
9564 + 0);
9565 +
9566 + /* 15 second delay per the test spec */
9567 + mdelay(15000);
9568 +
9569 + /* Send the Setup packet */
9570 + do_setup();
9571 +
9572 + /*
9573 + * 15 second delay so nothing
9574 + * else happens for awhile.
9575 + */
9576 + mdelay(15000);
9577 +
9578 + /* Restore interrupts */
9579 + dwc_write_reg32(&global_regs->gintmsk,
9580 + gintmsk.d32);
9581 + } else if (t == 8) {
9582 + /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR execute */
9583 + /* Save current interrupt mask */
9584 + gintmsk.d32 =
9585 + dwc_read_reg32(&global_regs->gintmsk);
9586 +
9587 + /*
9588 + * Disable all interrupts
9589 + * while we muck with the
9590 + * hardware directly
9591 + */
9592 + dwc_write_reg32(&global_regs->gintmsk,
9593 + 0);
9594 +
9595 + /* Send the Setup packet */
9596 + do_setup();
9597 +
9598 + /* 15 second delay so nothing else happens for awhile */
9599 + mdelay(15000);
9600 +
9601 + /* Send the In and Ack packets */
9602 + do_in_ack();
9603 +
9604 + /* 15 second delay so nothing else happens for awhile */
9605 + mdelay(15000);
9606 +
9607 + /* Restore interrupts */
9608 + dwc_write_reg32(&global_regs->gintmsk,
9609 + gintmsk.d32);
9610 + }
9611 + }
9612 + break;
9613 +#endif /* DWC_HS_ELECT_TST */
9614 +
9615 + case USB_PORT_FEAT_INDICATOR:
9616 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9617 + "SetPortFeature - USB_PORT_FEAT_INDICATOR\n");
9618 + /* Not supported */
9619 + break;
9620 + default:
9621 + retval = -EINVAL;
9622 + DWC_ERROR("DWC OTG HCD - "
9623 + "SetPortFeature request %xh "
9624 + "unknown or unsupported\n", _wValue);
9625 + break;
9626 + }
9627 + break;
9628 + default:
9629 +error:
9630 + retval = -EINVAL;
9631 + DWC_WARN("DWC OTG HCD - Unknown hub control request type or "
9632 + "invalid typeReq: %xh wIndex: %xh wValue: %xh\n",
9633 + _typeReq, _wIndex, _wValue);
9634 + break;
9635 + }
9636 +
9637 + spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags);
9638 +
9639 + return retval;
9640 +}
9641 +
9642 +/**
9643 + * Assigns transactions from a QTD to a free host channel and initializes the
9644 + * host channel to perform the transactions. The host channel is removed from
9645 + * the free list.
9646 + *
9647 + * @hcd: The HCD state structure.
9648 + * @_qh: Transactions from the first QTD for this QH are selected and
9649 + * assigned to a free host channel.
9650 + */
9651 +static void assign_and_init_hc(struct dwc_otg_hcd *hcd, struct dwc_otg_qh *_qh)
9652 +{
9653 + struct dwc_hc *hc;
9654 + struct dwc_otg_qtd *qtd;
9655 + struct urb *urb;
9656 +
9657 + DWC_DEBUGPL(DBG_HCDV, "%s(%p,%p)\n", __func__, hcd, _qh);
9658 +
9659 + hc = list_entry(hcd->free_hc_list.next, struct dwc_hc, hc_list_entry);
9660 +
9661 + /* Remove the host channel from the free list. */
9662 + list_del_init(&hc->hc_list_entry);
9663 +
9664 + qtd = list_entry(_qh->qtd_list.next, struct dwc_otg_qtd,
9665 + qtd_list_entry);
9666 + urb = qtd->urb;
9667 + _qh->channel = hc;
9668 + _qh->qtd_in_process = qtd;
9669 +
9670 + /*
9671 + * Use usb_pipedevice to determine device address. This address is
9672 + * 0 before the SET_ADDRESS command and the correct address afterward.
9673 + */
9674 + hc->dev_addr = usb_pipedevice(urb->pipe);
9675 + hc->ep_num = usb_pipeendpoint(urb->pipe);
9676 +
9677 + if (urb->dev->speed == USB_SPEED_LOW)
9678 + hc->speed = DWC_OTG_EP_SPEED_LOW;
9679 + else if (urb->dev->speed == USB_SPEED_FULL)
9680 + hc->speed = DWC_OTG_EP_SPEED_FULL;
9681 + else
9682 + hc->speed = DWC_OTG_EP_SPEED_HIGH;
9683 +
9684 + hc->max_packet = dwc_max_packet(_qh->maxp);
9685 +
9686 + hc->xfer_started = 0;
9687 + hc->halt_status = DWC_OTG_HC_XFER_NO_HALT_STATUS;
9688 + hc->error_state = (qtd->error_count > 0);
9689 + hc->halt_on_queue = 0;
9690 + hc->halt_pending = 0;
9691 + hc->requests = 0;
9692 +
9693 + /*
9694 + * The following values may be modified in the transfer type section
9695 + * below. The xfer_len value may be reduced when the transfer is
9696 + * started to accommodate the max widths of the XferSize and PktCnt
9697 + * fields in the HCTSIZn register.
9698 + */
9699 + hc->do_ping = _qh->ping_state;
9700 + hc->ep_is_in = (usb_pipein(urb->pipe) != 0);
9701 + hc->data_pid_start = _qh->data_toggle;
9702 + hc->multi_count = 1;
9703 +
9704 + if (hcd->core_if->dma_enable) {
9705 +#ifdef CONFIG_CPU_CAVIUM_OCTEON
9706 + const uint64_t USBN_DMA0_INB_CHN0 =
9707 + CVMX_USBNX_DMA0_INB_CHN0(hcd->core_if->usb_num);
9708 +#endif /* CONFIG_CPU_CAVIUM_OCTEON */
9709 + hc->xfer_buff =
9710 + (uint8_t *) (unsigned long)urb->transfer_dma +
9711 + urb->actual_length;
9712 +#ifdef CONFIG_CPU_CAVIUM_OCTEON
9713 + /* Octeon uses external DMA */
9714 + wmb();
9715 + cvmx_write_csr(USBN_DMA0_INB_CHN0 + hc->hc_num * 8,
9716 + (unsigned long)hc->xfer_buff);
9717 + cvmx_read_csr(USBN_DMA0_INB_CHN0 + hc->hc_num * 8);
9718 + DWC_DEBUGPL(DBG_HCDV,
9719 + "IN: hc->hc_num = %d, hc->xfer_buff = %p\n",
9720 + hc->hc_num, hc->xfer_buff);
9721 +#endif /* CONFIG_CPU_CAVIUM_OCTEON */
9722 + } else {
9723 + hc->xfer_buff =
9724 + (uint8_t *) urb->transfer_buffer + urb->actual_length;
9725 + }
9726 + hc->xfer_len = urb->transfer_buffer_length - urb->actual_length;
9727 + hc->xfer_count = 0;
9728 +
9729 + /*
9730 + * Set the split attributes
9731 + */
9732 + hc->do_split = 0;
9733 + if (_qh->do_split) {
9734 + hc->do_split = 1;
9735 + hc->xact_pos = qtd->isoc_split_pos;
9736 + hc->complete_split = qtd->complete_split;
9737 + hc->hub_addr = urb->dev->tt->hub->devnum;
9738 + hc->port_addr = urb->dev->ttport;
9739 + }
9740 +
9741 + switch (usb_pipetype(urb->pipe)) {
9742 + case PIPE_CONTROL:
9743 + hc->ep_type = DWC_OTG_EP_TYPE_CONTROL;
9744 + switch (qtd->control_phase) {
9745 + case DWC_OTG_CONTROL_SETUP:
9746 + DWC_DEBUGPL(DBG_HCDV, " Control setup transaction\n");
9747 + hc->do_ping = 0;
9748 + hc->ep_is_in = 0;
9749 + hc->data_pid_start = DWC_OTG_HC_PID_SETUP;
9750 + if (hcd->core_if->dma_enable) {
9751 + hc->xfer_buff =
9752 + (uint8_t *) (unsigned long)urb->setup_dma;
9753 + } else {
9754 + hc->xfer_buff = (uint8_t *) urb->setup_packet;
9755 + }
9756 + hc->xfer_len = 8;
9757 + break;
9758 + case DWC_OTG_CONTROL_DATA:
9759 + DWC_DEBUGPL(DBG_HCDV, " Control data transaction\n");
9760 + hc->data_pid_start = qtd->data_toggle;
9761 + break;
9762 + case DWC_OTG_CONTROL_STATUS:
9763 + /*
9764 + * Direction is opposite of data direction or IN if no
9765 + * data.
9766 + */
9767 + DWC_DEBUGPL(DBG_HCDV, " Control status transaction\n");
9768 + if (urb->transfer_buffer_length == 0) {
9769 + hc->ep_is_in = 1;
9770 + } else {
9771 + hc->ep_is_in =
9772 + (usb_pipein(urb->pipe) != USB_DIR_IN);
9773 + }
9774 + if (hc->ep_is_in)
9775 + hc->do_ping = 0;
9776 + hc->data_pid_start = DWC_OTG_HC_PID_DATA1;
9777 + hc->xfer_len = 0;
9778 + if (hcd->core_if->dma_enable) {
9779 + hc->xfer_buff =
9780 + (uint8_t *) (unsigned long)hcd->
9781 + status_buf_dma;
9782 + } else {
9783 + hc->xfer_buff = (uint8_t *) hcd->status_buf;
9784 + }
9785 + break;
9786 + }
9787 + break;
9788 + case PIPE_BULK:
9789 + hc->ep_type = DWC_OTG_EP_TYPE_BULK;
9790 + break;
9791 + case PIPE_INTERRUPT:
9792 + hc->ep_type = DWC_OTG_EP_TYPE_INTR;
9793 + break;
9794 + case PIPE_ISOCHRONOUS:
9795 + {
9796 + struct usb_iso_packet_descriptor *frame_desc;
9797 + frame_desc =
9798 + &urb->iso_frame_desc[qtd->isoc_frame_index];
9799 + hc->ep_type = DWC_OTG_EP_TYPE_ISOC;
9800 + if (hcd->core_if->dma_enable) {
9801 + hc->xfer_buff =
9802 + (uint8_t *) (unsigned long)urb->
9803 + transfer_dma;
9804 + } else {
9805 + hc->xfer_buff =
9806 + (uint8_t *) urb->transfer_buffer;
9807 + }
9808 + hc->xfer_buff +=
9809 + frame_desc->offset + qtd->isoc_split_offset;
9810 + hc->xfer_len =
9811 + frame_desc->length - qtd->isoc_split_offset;
9812 +
9813 + if (hc->xact_pos == DWC_HCSPLIT_XACTPOS_ALL) {
9814 + if (hc->xfer_len <= 188) {
9815 + hc->xact_pos = DWC_HCSPLIT_XACTPOS_ALL;
9816 + } else {
9817 + hc->xact_pos =
9818 + DWC_HCSPLIT_XACTPOS_BEGIN;
9819 + }
9820 + }
9821 + }
9822 + break;
9823 + }
9824 +
9825 + if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
9826 + hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
9827 + /*
9828 + * This value may be modified when the transfer is started to
9829 + * reflect the actual transfer length.
9830 + */
9831 + hc->multi_count = dwc_hb_mult(_qh->maxp);
9832 + }
9833 +
9834 + dwc_otg_hc_init(hcd->core_if, hc);
9835 + hc->qh = _qh;
9836 +}
9837 +
9838 +/**
9839 + * This function selects transactions from the HCD transfer schedule and
9840 + * assigns them to available host channels. It is called from HCD interrupt
9841 + * handler functions.
9842 + *
9843 + * @hcd: The HCD state structure.
9844 + *
9845 + * Returns The types of new transactions that were assigned to host channels.
9846 + */
9847 +enum dwc_otg_transaction_type dwc_otg_hcd_select_transactions(struct dwc_otg_hcd
9848 + *hcd)
9849 +{
9850 + struct list_head *qh_ptr;
9851 + struct dwc_otg_qh *qh;
9852 + int num_channels;
9853 + enum dwc_otg_transaction_type ret_val = DWC_OTG_TRANSACTION_NONE;
9854 +
9855 +#ifdef DEBUG_SOF
9856 + DWC_DEBUGPL(DBG_HCD, " Select Transactions\n");
9857 +#endif
9858 +
9859 + /* Process entries in the periodic ready list. */
9860 + qh_ptr = hcd->periodic_sched_ready.next;
9861 + while (qh_ptr != &hcd->periodic_sched_ready &&
9862 + !list_empty(&hcd->free_hc_list)) {
9863 +
9864 + qh = list_entry(qh_ptr, struct dwc_otg_qh, qh_list_entry);
9865 + assign_and_init_hc(hcd, qh);
9866 +
9867 + /*
9868 + * Move the QH from the periodic ready schedule to the
9869 + * periodic assigned schedule.
9870 + */
9871 + qh_ptr = qh_ptr->next;
9872 + list_move(&qh->qh_list_entry, &hcd->periodic_sched_assigned);
9873 +
9874 + ret_val = DWC_OTG_TRANSACTION_PERIODIC;
9875 + }
9876 +
9877 + /*
9878 + * Process entries in the inactive portion of the non-periodic
9879 + * schedule. Some free host channels may not be used if they are
9880 + * reserved for periodic transfers.
9881 + */
9882 + qh_ptr = hcd->non_periodic_sched_inactive.next;
9883 + num_channels = hcd->core_if->core_params->host_channels;
9884 + while (qh_ptr != &hcd->non_periodic_sched_inactive &&
9885 + (hcd->non_periodic_channels <
9886 + num_channels - hcd->periodic_channels) &&
9887 + !list_empty(&hcd->free_hc_list)) {
9888 +
9889 + qh = list_entry(qh_ptr, struct dwc_otg_qh, qh_list_entry);
9890 + assign_and_init_hc(hcd, qh);
9891 +
9892 + /*
9893 + * Move the QH from the non-periodic inactive schedule to the
9894 + * non-periodic active schedule.
9895 + */
9896 + qh_ptr = qh_ptr->next;
9897 + list_move(&qh->qh_list_entry, &hcd->non_periodic_sched_active);
9898 +
9899 + if (ret_val == DWC_OTG_TRANSACTION_NONE)
9900 + ret_val = DWC_OTG_TRANSACTION_NON_PERIODIC;
9901 + else
9902 + ret_val = DWC_OTG_TRANSACTION_ALL;
9903 +
9904 + hcd->non_periodic_channels++;
9905 + }
9906 +
9907 + return ret_val;
9908 +}
9909 +
9910 +/**
9911 + * Attempts to queue a single transaction request for a host channel
9912 + * associated with either a periodic or non-periodic transfer. This function
9913 + * assumes that there is space available in the appropriate request queue. For
9914 + * an OUT transfer or SETUP transaction in Slave mode, it checks whether space
9915 + * is available in the appropriate Tx FIFO.
9916 + *
9917 + * @hcd: The HCD state structure.
9918 + * @_hc: Host channel descriptor associated with either a periodic or
9919 + * non-periodic transfer.
9920 + * @_fifo_dwords_avail: Number of DWORDs available in the periodic Tx
9921 + * FIFO for periodic transfers or the non-periodic Tx FIFO for non-periodic
9922 + * transfers.
9923 + *
9924 + * Returns 1 if a request is queued and more requests may be needed to
9925 + * complete the transfer, 0 if no more requests are required for this
9926 + * transfer, -1 if there is insufficient space in the Tx FIFO.
9927 + */
9928 +static int queue_transaction(struct dwc_otg_hcd *hcd,
9929 + struct dwc_hc *_hc, uint16_t _fifo_dwords_avail)
9930 +{
9931 + int retval;
9932 +
9933 + if (hcd->core_if->dma_enable) {
9934 + if (!_hc->xfer_started) {
9935 + dwc_otg_hc_start_transfer(hcd->core_if, _hc);
9936 + _hc->qh->ping_state = 0;
9937 + }
9938 + retval = 0;
9939 + } else if (_hc->halt_pending) {
9940 + /* Don't queue a request if the channel has been halted. */
9941 + retval = 0;
9942 + } else if (_hc->halt_on_queue) {
9943 + dwc_otg_hc_halt(hcd->core_if, _hc, _hc->halt_status);
9944 + retval = 0;
9945 + } else if (_hc->do_ping) {
9946 + if (!_hc->xfer_started)
9947 + dwc_otg_hc_start_transfer(hcd->core_if, _hc);
9948 + retval = 0;
9949 + } else if (!_hc->ep_is_in ||
9950 + _hc->data_pid_start == DWC_OTG_HC_PID_SETUP) {
9951 + if ((_fifo_dwords_avail * 4) >= _hc->max_packet) {
9952 + if (!_hc->xfer_started) {
9953 + dwc_otg_hc_start_transfer(hcd->core_if, _hc);
9954 + retval = 1;
9955 + } else {
9956 + retval =
9957 + dwc_otg_hc_continue_transfer(hcd->core_if,
9958 + _hc);
9959 + }
9960 + } else {
9961 + retval = -1;
9962 + }
9963 + } else {
9964 + if (!_hc->xfer_started) {
9965 + dwc_otg_hc_start_transfer(hcd->core_if, _hc);
9966 + retval = 1;
9967 + } else {
9968 + retval =
9969 + dwc_otg_hc_continue_transfer(hcd->core_if, _hc);
9970 + }
9971 + }
9972 +
9973 + return retval;
9974 +}
9975 +
9976 +/**
9977 + * Processes active non-periodic channels and queues transactions for these
9978 + * channels to the DWC_otg controller. After queueing transactions, the NP Tx
9979 + * FIFO Empty interrupt is enabled if there are more transactions to queue as
9980 + * NP Tx FIFO or request queue space becomes available. Otherwise, the NP Tx
9981 + * FIFO Empty interrupt is disabled.
9982 + */
9983 +static void process_non_periodic_channels(struct dwc_otg_hcd *hcd)
9984 +{
9985 + union gnptxsts_data tx_status;
9986 + struct list_head *orig_qh_ptr;
9987 + struct dwc_otg_qh *qh;
9988 + int status;
9989 + int no_queue_space = 0;
9990 + int no_fifo_space = 0;
9991 + int more_to_do = 0;
9992 +
9993 + struct dwc_otg_core_global_regs *global_regs =
9994 + hcd->core_if->core_global_regs;
9995 +
9996 + DWC_DEBUGPL(DBG_HCDV, "Queue non-periodic transactions\n");
9997 +#ifdef DEBUG
9998 + tx_status.d32 = dwc_read_reg32(&global_regs->gnptxsts);
9999 + DWC_DEBUGPL(DBG_HCDV,
10000 + " NP Tx Req Queue Space Avail (before queue): %d\n",
10001 + tx_status.b.nptxqspcavail);
10002 + DWC_DEBUGPL(DBG_HCDV, " NP Tx FIFO Space Avail (before queue): %d\n",
10003 + tx_status.b.nptxfspcavail);
10004 +#endif
10005 + /*
10006 + * Keep track of the starting point. Skip over the start-of-list
10007 + * entry.
10008 + */
10009 + if (hcd->non_periodic_qh_ptr == &hcd->non_periodic_sched_active)
10010 + hcd->non_periodic_qh_ptr = hcd->non_periodic_qh_ptr->next;
10011 +
10012 + orig_qh_ptr = hcd->non_periodic_qh_ptr;
10013 +
10014 + /*
10015 + * Process once through the active list or until no more space is
10016 + * available in the request queue or the Tx FIFO.
10017 + */
10018 + do {
10019 + tx_status.d32 = dwc_read_reg32(&global_regs->gnptxsts);
10020 + if (!hcd->core_if->dma_enable
10021 + && tx_status.b.nptxqspcavail == 0) {
10022 + no_queue_space = 1;
10023 + break;
10024 + }
10025 +
10026 + qh = list_entry(hcd->non_periodic_qh_ptr, struct dwc_otg_qh,
10027 + qh_list_entry);
10028 + status =
10029 + queue_transaction(hcd, qh->channel,
10030 + tx_status.b.nptxfspcavail);
10031 +
10032 + if (status > 0) {
10033 + more_to_do = 1;
10034 + } else if (status < 0) {
10035 + no_fifo_space = 1;
10036 + break;
10037 + }
10038 +
10039 + /* Advance to next QH, skipping start-of-list entry. */
10040 + hcd->non_periodic_qh_ptr = hcd->non_periodic_qh_ptr->next;
10041 + if (hcd->non_periodic_qh_ptr ==
10042 + &hcd->non_periodic_sched_active) {
10043 + hcd->non_periodic_qh_ptr =
10044 + hcd->non_periodic_qh_ptr->next;
10045 + }
10046 +
10047 + } while (hcd->non_periodic_qh_ptr != orig_qh_ptr);
10048 +
10049 + if (!hcd->core_if->dma_enable) {
10050 + union gintmsk_data intr_mask = {.d32 = 0 };
10051 + intr_mask.b.nptxfempty = 1;
10052 +
10053 +#ifdef DEBUG
10054 + tx_status.d32 = dwc_read_reg32(&global_regs->gnptxsts);
10055 + DWC_DEBUGPL(DBG_HCDV,
10056 + " NP Tx Req Queue Space Avail (after queue): %d\n",
10057 + tx_status.b.nptxqspcavail);
10058 + DWC_DEBUGPL(DBG_HCDV,
10059 + " NP Tx FIFO Space Avail (after queue): %d\n",
10060 + tx_status.b.nptxfspcavail);
10061 +#endif
10062 + if (no_queue_space || no_fifo_space) {
10063 + /*
10064 + * May need to queue more transactions as the request
10065 + * queue or Tx FIFO empties. Enable the non-periodic
10066 + * Tx FIFO empty interrupt. (Always use the half-empty
10067 + * level to ensure that new requests are loaded as
10068 + * soon as possible.)
10069 + */
10070 + dwc_modify_reg32(&global_regs->gintmsk, 0,
10071 + intr_mask.d32);
10072 + } else {
10073 + /*
10074 + * Disable the Tx FIFO empty interrupt since there are
10075 + * no more transactions that need to be queued right
10076 + * now. This function is called from interrupt
10077 + * handlers to queue more transactions as transfer
10078 + * states change.
10079 + */
10080 + dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32,
10081 + 0);
10082 + if (more_to_do) {
10083 + /* When not using DMA, many USB
10084 + * devices cause excessive loads on
10085 + * the serial bus simply because they
10086 + * continuously poll the device for
10087 + * status. Here we use the timer to
10088 + * rate limit how fast we can get the
10089 + * the NP TX fifo empty interrupt. We
10090 + * leave the interrupt disable until
10091 + * the timer fires and reenables it */
10092 +
10093 + /* We'll rate limit the interrupt at
10094 + * 20000 per second. Making this
10095 + * faster improves USB performance but
10096 + * uses more CPU */
10097 + hrtimer_start_range_ns(&hcd->poll_rate_limit,
10098 + ktime_set(0, 50000),
10099 + 5000, HRTIMER_MODE_REL);
10100 + }
10101 + }
10102 + }
10103 +}
10104 +
10105 +/**
10106 + * Processes periodic channels for the next frame and queues transactions for
10107 + * these channels to the DWC_otg controller. After queueing transactions, the
10108 + * Periodic Tx FIFO Empty interrupt is enabled if there are more transactions
10109 + * to queue as Periodic Tx FIFO or request queue space becomes available.
10110 + * Otherwise, the Periodic Tx FIFO Empty interrupt is disabled.
10111 + */
10112 +static void process_periodic_channels(struct dwc_otg_hcd *hcd)
10113 +{
10114 + union hptxsts_data tx_status;
10115 + struct list_head *qh_ptr;
10116 + struct dwc_otg_qh *qh;
10117 + int status;
10118 + int no_queue_space = 0;
10119 + int no_fifo_space = 0;
10120 +
10121 + struct dwc_otg_host_global_regs *host_regs;
10122 + host_regs = hcd->core_if->host_if->host_global_regs;
10123 +
10124 + DWC_DEBUGPL(DBG_HCDV, "Queue periodic transactions\n");
10125 +#ifdef DEBUG
10126 + tx_status.d32 = dwc_read_reg32(&host_regs->hptxsts);
10127 + DWC_DEBUGPL(DBG_HCDV,
10128 + " P Tx Req Queue Space Avail (before queue): %d\n",
10129 + tx_status.b.ptxqspcavail);
10130 + DWC_DEBUGPL(DBG_HCDV, " P Tx FIFO Space Avail (before queue): %d\n",
10131 + tx_status.b.ptxfspcavail);
10132 +#endif
10133 +
10134 + qh_ptr = hcd->periodic_sched_assigned.next;
10135 + while (qh_ptr != &hcd->periodic_sched_assigned) {
10136 + tx_status.d32 = dwc_read_reg32(&host_regs->hptxsts);
10137 + if (tx_status.b.ptxqspcavail == 0) {
10138 + no_queue_space = 1;
10139 + break;
10140 + }
10141 +
10142 + qh = list_entry(qh_ptr, struct dwc_otg_qh, qh_list_entry);
10143 +
10144 + /*
10145 + * Set a flag if we're queuing high-bandwidth in slave mode.
10146 + * The flag prevents any halts to get into the request queue in
10147 + * the middle of multiple high-bandwidth packets getting queued.
10148 + */
10149 + if ((!hcd->core_if->dma_enable) &&
10150 + (qh->channel->multi_count > 1)) {
10151 + hcd->core_if->queuing_high_bandwidth = 1;
10152 + }
10153 +
10154 + status =
10155 + queue_transaction(hcd, qh->channel,
10156 + tx_status.b.ptxfspcavail);
10157 + if (status < 0) {
10158 + no_fifo_space = 1;
10159 + break;
10160 + }
10161 +
10162 + /*
10163 + * In Slave mode, stay on the current transfer until there is
10164 + * nothing more to do or the high-bandwidth request count is
10165 + * reached. In DMA mode, only need to queue one request. The
10166 + * controller automatically handles multiple packets for
10167 + * high-bandwidth transfers.
10168 + */
10169 + if (hcd->core_if->dma_enable ||
10170 + (status == 0 ||
10171 + qh->channel->requests == qh->channel->multi_count)) {
10172 + qh_ptr = qh_ptr->next;
10173 + /*
10174 + * Move the QH from the periodic assigned schedule to
10175 + * the periodic queued schedule.
10176 + */
10177 + list_move(&qh->qh_list_entry,
10178 + &hcd->periodic_sched_queued);
10179 +
10180 + /* done queuing high bandwidth */
10181 + hcd->core_if->queuing_high_bandwidth = 0;
10182 + }
10183 + }
10184 +
10185 + if (!hcd->core_if->dma_enable) {
10186 + struct dwc_otg_core_global_regs *global_regs;
10187 + union gintmsk_data intr_mask = {.d32 = 0 };
10188 +
10189 + global_regs = hcd->core_if->core_global_regs;
10190 + intr_mask.b.ptxfempty = 1;
10191 +#ifdef DEBUG
10192 + tx_status.d32 = dwc_read_reg32(&host_regs->hptxsts);
10193 + DWC_DEBUGPL(DBG_HCDV,
10194 + " P Tx Req Queue Space Avail (after queue): %d\n",
10195 + tx_status.b.ptxqspcavail);
10196 + DWC_DEBUGPL(DBG_HCDV,
10197 + " P Tx FIFO Space Avail (after queue): %d\n",
10198 + tx_status.b.ptxfspcavail);
10199 +#endif
10200 + if (!(list_empty(&hcd->periodic_sched_assigned)) ||
10201 + no_queue_space || no_fifo_space) {
10202 + /*
10203 + * May need to queue more transactions as the request
10204 + * queue or Tx FIFO empties. Enable the periodic Tx
10205 + * FIFO empty interrupt. (Always use the half-empty
10206 + * level to ensure that new requests are loaded as
10207 + * soon as possible.)
10208 + */
10209 + dwc_modify_reg32(&global_regs->gintmsk, 0,
10210 + intr_mask.d32);
10211 + } else {
10212 + /*
10213 + * Disable the Tx FIFO empty interrupt since there are
10214 + * no more transactions that need to be queued right
10215 + * now. This function is called from interrupt
10216 + * handlers to queue more transactions as transfer
10217 + * states change.
10218 + */
10219 + dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32,
10220 + 0);
10221 + }
10222 + }
10223 +}
10224 +
10225 +/**
10226 + * This function processes the currently active host channels and queues
10227 + * transactions for these channels to the DWC_otg controller. It is called
10228 + * from HCD interrupt handler functions.
10229 + *
10230 + * @hcd: The HCD state structure.
10231 + * @_tr_type: The type(s) of transactions to queue (non-periodic,
10232 + * periodic, or both).
10233 + */
10234 +void dwc_otg_hcd_queue_transactions(struct dwc_otg_hcd *hcd,
10235 + enum dwc_otg_transaction_type _tr_type)
10236 +{
10237 +#ifdef DEBUG_SOF
10238 + DWC_DEBUGPL(DBG_HCD, "Queue Transactions\n");
10239 +#endif
10240 + /* Process host channels associated with periodic transfers. */
10241 + if ((_tr_type == DWC_OTG_TRANSACTION_PERIODIC ||
10242 + _tr_type == DWC_OTG_TRANSACTION_ALL) &&
10243 + !list_empty(&hcd->periodic_sched_assigned)) {
10244 +
10245 + process_periodic_channels(hcd);
10246 + }
10247 +
10248 + /* Process host channels associated with non-periodic transfers. */
10249 + if ((_tr_type == DWC_OTG_TRANSACTION_NON_PERIODIC ||
10250 + _tr_type == DWC_OTG_TRANSACTION_ALL)) {
10251 + if (!list_empty(&hcd->non_periodic_sched_active)) {
10252 + process_non_periodic_channels(hcd);
10253 + } else {
10254 + /*
10255 + * Ensure NP Tx FIFO empty interrupt is disabled when
10256 + * there are no non-periodic transfers to process.
10257 + */
10258 + union gintmsk_data gintmsk = {.d32 = 0 };
10259 + gintmsk.b.nptxfempty = 1;
10260 + dwc_modify_reg32(&hcd->core_if->core_global_regs->
10261 + gintmsk, gintmsk.d32, 0);
10262 + }
10263 + }
10264 +}
10265 +
10266 +/**
10267 + * Sets the final status of an URB and returns it to the device driver. Any
10268 + * required cleanup of the URB is performed.
10269 + */
10270 +void dwc_otg_hcd_complete_urb(struct dwc_otg_hcd *hcd, struct urb *urb,
10271 + int status)
10272 +{
10273 +#ifdef DEBUG
10274 + if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
10275 + DWC_PRINT("%s: urb %p, device %d, ep %d %s, status=%d\n",
10276 + __func__, urb, usb_pipedevice(urb->pipe),
10277 + usb_pipeendpoint(urb->pipe),
10278 + usb_pipein(urb->pipe) ? "IN" : "OUT", status);
10279 + if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
10280 + int i;
10281 + for (i = 0; i < urb->number_of_packets; i++) {
10282 + DWC_PRINT(" ISO Desc %d status: %d\n",
10283 + i, urb->iso_frame_desc[i].status);
10284 + }
10285 + }
10286 + }
10287 +#endif
10288 +
10289 + urb->status = status;
10290 + urb->hcpriv = NULL;
10291 +
10292 + usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(hcd), urb, status);
10293 +}
10294 +
10295 +/*
10296 + * Returns the Queue Head for an URB.
10297 + */
10298 +struct dwc_otg_qh *dwc_urb_to_qh(struct urb *urb)
10299 +{
10300 + struct usb_host_endpoint *ep = dwc_urb_to_endpoint(urb);
10301 + return ep->hcpriv;
10302 +}
10303 +
10304 +#ifdef DEBUG
10305 +void dwc_print_setup_data(uint8_t *setup)
10306 +{
10307 + int i;
10308 + if (CHK_DEBUG_LEVEL(DBG_HCD)) {
10309 + DWC_PRINT("Setup Data = MSB ");
10310 + for (i = 7; i >= 0; i--)
10311 + DWC_PRINT("%02x ", setup[i]);
10312 + DWC_PRINT("\n");
10313 + DWC_PRINT(" bmRequestType Tranfer = %s\n",
10314 + (setup[0] & 0x80) ? "Device-to-Host" :
10315 + "Host-to-Device");
10316 + DWC_PRINT(" bmRequestType Type = ");
10317 + switch ((setup[0] & 0x60) >> 5) {
10318 + case 0:
10319 + DWC_PRINT("Standard\n");
10320 + break;
10321 + case 1:
10322 + DWC_PRINT("Class\n");
10323 + break;
10324 + case 2:
10325 + DWC_PRINT("Vendor\n");
10326 + break;
10327 + case 3:
10328 + DWC_PRINT("Reserved\n");
10329 + break;
10330 + }
10331 + DWC_PRINT(" bmRequestType Recipient = ");
10332 + switch (setup[0] & 0x1f) {
10333 + case 0:
10334 + DWC_PRINT("Device\n");
10335 + break;
10336 + case 1:
10337 + DWC_PRINT("Interface\n");
10338 + break;
10339 + case 2:
10340 + DWC_PRINT("Endpoint\n");
10341 + break;
10342 + case 3:
10343 + DWC_PRINT("Other\n");
10344 + break;
10345 + default:
10346 + DWC_PRINT("Reserved\n");
10347 + break;
10348 + }
10349 + DWC_PRINT(" bRequest = 0x%0x\n", setup[1]);
10350 + DWC_PRINT(" wValue = 0x%0x\n", *((uint16_t *) &setup[2]));
10351 + DWC_PRINT(" wIndex = 0x%0x\n", *((uint16_t *) &setup[4]));
10352 + DWC_PRINT(" wLength = 0x%0x\n\n", *((uint16_t *) &setup[6]));
10353 + }
10354 +}
10355 +#endif
10356 +
10357 +void dwc_otg_hcd_dump_frrem(struct dwc_otg_hcd *hcd)
10358 +{
10359 +#ifdef DEBUG
10360 + DWC_PRINT("Frame remaining at SOF:\n");
10361 + DWC_PRINT(" samples %u, accum %lu, avg %lu\n",
10362 + hcd->frrem_samples, hcd->frrem_accum,
10363 + (hcd->frrem_samples > 0) ?
10364 + hcd->frrem_accum / hcd->frrem_samples : 0);
10365 +
10366 + DWC_PRINT("\n");
10367 + DWC_PRINT("Frame remaining at start_transfer (uframe 7):\n");
10368 + DWC_PRINT(" samples %u, accum %lu, avg %lu\n",
10369 + hcd->core_if->hfnum_7_samples,
10370 + hcd->core_if->hfnum_7_frrem_accum,
10371 + (hcd->core_if->hfnum_7_samples >
10372 + 0) ? hcd->core_if->hfnum_7_frrem_accum /
10373 + hcd->core_if->hfnum_7_samples : 0);
10374 + DWC_PRINT("Frame remaining at start_transfer (uframe 0):\n");
10375 + DWC_PRINT(" samples %u, accum %lu, avg %lu\n",
10376 + hcd->core_if->hfnum_0_samples,
10377 + hcd->core_if->hfnum_0_frrem_accum,
10378 + (hcd->core_if->hfnum_0_samples >
10379 + 0) ? hcd->core_if->hfnum_0_frrem_accum /
10380 + hcd->core_if->hfnum_0_samples : 0);
10381 + DWC_PRINT("Frame remaining at start_transfer (uframe 1-6):\n");
10382 + DWC_PRINT(" samples %u, accum %lu, avg %lu\n",
10383 + hcd->core_if->hfnum_other_samples,
10384 + hcd->core_if->hfnum_other_frrem_accum,
10385 + (hcd->core_if->hfnum_other_samples >
10386 + 0) ? hcd->core_if->hfnum_other_frrem_accum /
10387 + hcd->core_if->hfnum_other_samples : 0);
10388 +
10389 + DWC_PRINT("\n");
10390 + DWC_PRINT("Frame remaining at sample point A (uframe 7):\n");
10391 + DWC_PRINT(" samples %u, accum %lu, avg %lu\n",
10392 + hcd->hfnum_7_samples_a, hcd->hfnum_7_frrem_accum_a,
10393 + (hcd->hfnum_7_samples_a > 0) ?
10394 + hcd->hfnum_7_frrem_accum_a / hcd->hfnum_7_samples_a : 0);
10395 + DWC_PRINT("Frame remaining at sample point A (uframe 0):\n");
10396 + DWC_PRINT(" samples %u, accum %lu, avg %lu\n",
10397 + hcd->hfnum_0_samples_a, hcd->hfnum_0_frrem_accum_a,
10398 + (hcd->hfnum_0_samples_a > 0) ?
10399 + hcd->hfnum_0_frrem_accum_a / hcd->hfnum_0_samples_a : 0);
10400 + DWC_PRINT("Frame remaining at sample point A (uframe 1-6):\n");
10401 + DWC_PRINT(" samples %u, accum %lu, avg %lu\n",
10402 + hcd->hfnum_other_samples_a, hcd->hfnum_other_frrem_accum_a,
10403 + (hcd->hfnum_other_samples_a > 0) ?
10404 + hcd->hfnum_other_frrem_accum_a /
10405 + hcd->hfnum_other_samples_a : 0);
10406 +
10407 + DWC_PRINT("\n");
10408 + DWC_PRINT("Frame remaining at sample point B (uframe 7):\n");
10409 + DWC_PRINT(" samples %u, accum %lu, avg %lu\n",
10410 + hcd->hfnum_7_samples_b, hcd->hfnum_7_frrem_accum_b,
10411 + (hcd->hfnum_7_samples_b > 0) ?
10412 + hcd->hfnum_7_frrem_accum_b / hcd->hfnum_7_samples_b : 0);
10413 + DWC_PRINT("Frame remaining at sample point B (uframe 0):\n");
10414 + DWC_PRINT(" samples %u, accum %lu, avg %lu\n",
10415 + hcd->hfnum_0_samples_b, hcd->hfnum_0_frrem_accum_b,
10416 + (hcd->hfnum_0_samples_b > 0) ?
10417 + hcd->hfnum_0_frrem_accum_b / hcd->hfnum_0_samples_b : 0);
10418 + DWC_PRINT("Frame remaining at sample point B (uframe 1-6):\n");
10419 + DWC_PRINT(" samples %u, accum %lu, avg %lu\n",
10420 + hcd->hfnum_other_samples_b, hcd->hfnum_other_frrem_accum_b,
10421 + (hcd->hfnum_other_samples_b > 0) ?
10422 + hcd->hfnum_other_frrem_accum_b /
10423 + hcd->hfnum_other_samples_b : 0);
10424 +#endif
10425 +}
10426 +
10427 +void dwc_otg_hcd_dump_state(struct dwc_otg_hcd *hcd)
10428 +{
10429 +#ifdef DEBUG
10430 + int num_channels;
10431 + int i;
10432 + union gnptxsts_data np_tx_status;
10433 + union hptxsts_data p_tx_status;
10434 +
10435 + num_channels = hcd->core_if->core_params->host_channels;
10436 + DWC_PRINT("\n");
10437 + DWC_PRINT
10438 + ("************************************************************\n");
10439 + DWC_PRINT("HCD State:\n");
10440 + DWC_PRINT(" Num channels: %d\n", num_channels);
10441 + for (i = 0; i < num_channels; i++) {
10442 + struct dwc_hc *hc = hcd->hc_ptr_array[i];
10443 + DWC_PRINT(" Channel %d:\n", i);
10444 + DWC_PRINT(" dev_addr: %d, ep_num: %d, ep_is_in: %d\n",
10445 + hc->dev_addr, hc->ep_num, hc->ep_is_in);
10446 + DWC_PRINT(" speed: %d\n", hc->speed);
10447 + DWC_PRINT(" ep_type: %d\n", hc->ep_type);
10448 + DWC_PRINT(" max_packet: %d\n", hc->max_packet);
10449 + DWC_PRINT(" data_pid_start: %d\n", hc->data_pid_start);
10450 + DWC_PRINT(" multi_count: %d\n", hc->multi_count);
10451 + DWC_PRINT(" xfer_started: %d\n", hc->xfer_started);
10452 + DWC_PRINT(" xfer_buff: %p\n", hc->xfer_buff);
10453 + DWC_PRINT(" xfer_len: %d\n", hc->xfer_len);
10454 + DWC_PRINT(" xfer_count: %d\n", hc->xfer_count);
10455 + DWC_PRINT(" halt_on_queue: %d\n", hc->halt_on_queue);
10456 + DWC_PRINT(" halt_pending: %d\n", hc->halt_pending);
10457 + DWC_PRINT(" halt_status: %d\n", hc->halt_status);
10458 + DWC_PRINT(" do_split: %d\n", hc->do_split);
10459 + DWC_PRINT(" complete_split: %d\n", hc->complete_split);
10460 + DWC_PRINT(" hub_addr: %d\n", hc->hub_addr);
10461 + DWC_PRINT(" port_addr: %d\n", hc->port_addr);
10462 + DWC_PRINT(" xact_pos: %d\n", hc->xact_pos);
10463 + DWC_PRINT(" requests: %d\n", hc->requests);
10464 + DWC_PRINT(" qh: %p\n", hc->qh);
10465 + if (hc->xfer_started) {
10466 + union hfnum_data hfnum;
10467 + union hcchar_data hcchar;
10468 + union hctsiz_data hctsiz;
10469 + union hcint_data hcint;
10470 + union hcintmsk_data hcintmsk;
10471 + hfnum.d32 =
10472 + dwc_read_reg32(&hcd->core_if->host_if->
10473 + host_global_regs->hfnum);
10474 + hcchar.d32 =
10475 + dwc_read_reg32(&hcd->core_if->host_if->hc_regs[i]->
10476 + hcchar);
10477 + hctsiz.d32 =
10478 + dwc_read_reg32(&hcd->core_if->host_if->hc_regs[i]->
10479 + hctsiz);
10480 + hcint.d32 =
10481 + dwc_read_reg32(&hcd->core_if->host_if->hc_regs[i]->
10482 + hcint);
10483 + hcintmsk.d32 =
10484 + dwc_read_reg32(&hcd->core_if->host_if->hc_regs[i]->
10485 + hcintmsk);
10486 + DWC_PRINT(" hfnum: 0x%08x\n", hfnum.d32);
10487 + DWC_PRINT(" hcchar: 0x%08x\n", hcchar.d32);
10488 + DWC_PRINT(" hctsiz: 0x%08x\n", hctsiz.d32);
10489 + DWC_PRINT(" hcint: 0x%08x\n", hcint.d32);
10490 + DWC_PRINT(" hcintmsk: 0x%08x\n", hcintmsk.d32);
10491 + }
10492 + if (hc->xfer_started && (hc->qh != NULL)
10493 + && (hc->qh->qtd_in_process != NULL)) {
10494 + struct dwc_otg_qtd *qtd;
10495 + struct urb *urb;
10496 + qtd = hc->qh->qtd_in_process;
10497 + urb = qtd->urb;
10498 + DWC_PRINT(" URB Info:\n");
10499 + DWC_PRINT(" qtd: %p, urb: %p\n", qtd, urb);
10500 + if (urb != NULL) {
10501 + DWC_PRINT(" Dev: %d, EP: %d %s\n",
10502 + usb_pipedevice(urb->pipe),
10503 + usb_pipeendpoint(urb->pipe),
10504 + usb_pipein(urb->pipe) ? "IN" : "OUT");
10505 + DWC_PRINT(" Max packet size: %d\n",
10506 + usb_maxpacket(urb->dev, urb->pipe,
10507 + usb_pipeout(urb->
10508 + pipe)));
10509 + DWC_PRINT(" transfer_buffer: %p\n",
10510 + urb->transfer_buffer);
10511 + DWC_PRINT(" transfer_dma: %p\n",
10512 + (void *)urb->transfer_dma);
10513 + DWC_PRINT(" transfer_buffer_length: %d\n",
10514 + urb->transfer_buffer_length);
10515 + DWC_PRINT(" actual_length: %d\n",
10516 + urb->actual_length);
10517 + }
10518 + }
10519 + }
10520 + DWC_PRINT(" non_periodic_channels: %d\n", hcd->non_periodic_channels);
10521 + DWC_PRINT(" periodic_channels: %d\n", hcd->periodic_channels);
10522 + DWC_PRINT(" periodic_usecs: %d\n", hcd->periodic_usecs);
10523 + np_tx_status.d32 =
10524 + dwc_read_reg32(&hcd->core_if->core_global_regs->gnptxsts);
10525 + DWC_PRINT(" NP Tx Req Queue Space Avail: %d\n",
10526 + np_tx_status.b.nptxqspcavail);
10527 + DWC_PRINT(" NP Tx FIFO Space Avail: %d\n",
10528 + np_tx_status.b.nptxfspcavail);
10529 + p_tx_status.d32 =
10530 + dwc_read_reg32(&hcd->core_if->host_if->host_global_regs->hptxsts);
10531 + DWC_PRINT(" P Tx Req Queue Space Avail: %d\n",
10532 + p_tx_status.b.ptxqspcavail);
10533 + DWC_PRINT(" P Tx FIFO Space Avail: %d\n", p_tx_status.b.ptxfspcavail);
10534 + dwc_otg_hcd_dump_frrem(hcd);
10535 + dwc_otg_dump_global_registers(hcd->core_if);
10536 + dwc_otg_dump_host_registers(hcd->core_if);
10537 + DWC_PRINT
10538 + ("************************************************************\n");
10539 + DWC_PRINT("\n");
10540 +#endif
10541 +}
10542 +#endif /* DWC_DEVICE_ONLY */
10543 diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd.h b/drivers/usb/host/dwc_otg/dwc_otg_hcd.h
10544 new file mode 100644
10545 index 0000000..6dcf1f5
10546 --- /dev/null
10547 +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.h
10548 @@ -0,0 +1,661 @@
10549 +/* ==========================================================================
10550 + *
10551 + * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
10552 + * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
10553 + * otherwise expressly agreed to in writing between Synopsys and you.
10554 + *
10555 + * The Software IS NOT an item of Licensed Software or Licensed Product under
10556 + * any End User Software License Agreement or Agreement for Licensed Product
10557 + * with Synopsys or any supplement thereto. You are permitted to use and
10558 + * redistribute this Software in source and binary forms, with or without
10559 + * modification, provided that redistributions of source code must retain this
10560 + * notice. You may not view, use, disclose, copy or distribute this file or
10561 + * any information contained herein except pursuant to this license grant from
10562 + * Synopsys. If you do not agree with this notice, including the disclaimer
10563 + * below, then you are not authorized to use the Software.
10564 + *
10565 + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
10566 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
10567 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
10568 + * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
10569 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
10570 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
10571 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
10572 + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
10573 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
10574 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
10575 + * DAMAGE.
10576 + * ========================================================================== */
10577 +#ifndef DWC_DEVICE_ONLY
10578 +#if !defined(__DWC_HCD_H__)
10579 +#define __DWC_HCD_H__
10580 +
10581 +#include <linux/list.h>
10582 +#include <linux/usb.h>
10583 +#include <linux/hrtimer.h>
10584 +
10585 +#include <../drivers/usb/core/hcd.h>
10586 +
10587 +struct dwc_otg_device;
10588 +
10589 +#include "dwc_otg_cil.h"
10590 +
10591 +/**
10592 + *
10593 + * This file contains the structures, constants, and interfaces for
10594 + * the Host Contoller Driver (HCD).
10595 + *
10596 + * The Host Controller Driver (HCD) is responsible for translating requests
10597 + * from the USB Driver into the appropriate actions on the DWC_otg controller.
10598 + * It isolates the USBD from the specifics of the controller by providing an
10599 + * API to the USBD.
10600 + */
10601 +
10602 +/**
10603 + * Phases for control transfers.
10604 + */
10605 +enum dwc_otg_control_phase {
10606 + DWC_OTG_CONTROL_SETUP,
10607 + DWC_OTG_CONTROL_DATA,
10608 + DWC_OTG_CONTROL_STATUS
10609 +};
10610 +
10611 +/** Transaction types. */
10612 +enum dwc_otg_transaction_type {
10613 + DWC_OTG_TRANSACTION_NONE,
10614 + DWC_OTG_TRANSACTION_PERIODIC,
10615 + DWC_OTG_TRANSACTION_NON_PERIODIC,
10616 + DWC_OTG_TRANSACTION_ALL
10617 +};
10618 +
10619 +struct dwc_otg_qh;
10620 +
10621 +/*
10622 + * A Queue Transfer Descriptor (QTD) holds the state of a bulk, control,
10623 + * interrupt, or isochronous transfer. A single QTD is created for each URB
10624 + * (of one of these types) submitted to the HCD. The transfer associated with
10625 + * a QTD may require one or multiple transactions.
10626 + *
10627 + * A QTD is linked to a Queue Head, which is entered in either the
10628 + * non-periodic or periodic schedule for execution. When a QTD is chosen for
10629 + * execution, some or all of its transactions may be executed. After
10630 + * execution, the state of the QTD is updated. The QTD may be retired if all
10631 + * its transactions are complete or if an error occurred. Otherwise, it
10632 + * remains in the schedule so more transactions can be executed later.
10633 + */
10634 +struct dwc_otg_qtd {
10635 + /*
10636 + * Determines the PID of the next data packet for the data phase of
10637 + * control transfers. Ignored for other transfer types.<br>
10638 + * One of the following values:
10639 + * - DWC_OTG_HC_PID_DATA0
10640 + * - DWC_OTG_HC_PID_DATA1
10641 + */
10642 + uint8_t data_toggle;
10643 +
10644 + /** Current phase for control transfers (Setup, Data, or Status). */
10645 + enum dwc_otg_control_phase control_phase;
10646 +
10647 + /** Keep track of the current split type
10648 + * for FS/LS endpoints on a HS Hub */
10649 + uint8_t complete_split;
10650 +
10651 + /** How many bytes transferred during SSPLIT OUT */
10652 + uint32_t ssplit_out_xfer_count;
10653 +
10654 + /**
10655 + * Holds the number of bus errors that have occurred for a transaction
10656 + * within this transfer.
10657 + */
10658 + uint8_t error_count;
10659 +
10660 + /**
10661 + * Index of the next frame descriptor for an isochronous transfer. A
10662 + * frame descriptor describes the buffer position and length of the
10663 + * data to be transferred in the next scheduled (micro)frame of an
10664 + * isochronous transfer. It also holds status for that transaction.
10665 + * The frame index starts at 0.
10666 + */
10667 + int isoc_frame_index;
10668 +
10669 + /** Position of the ISOC split on full/low speed */
10670 + uint8_t isoc_split_pos;
10671 +
10672 + /** Position of the ISOC split in the buffer for the current frame */
10673 + uint16_t isoc_split_offset;
10674 +
10675 + /** URB for this transfer */
10676 + struct urb *urb;
10677 +
10678 + /* The queue head for this transfer. */
10679 + struct dwc_otg_qh *qh;
10680 +
10681 + /** This list of QTDs */
10682 + struct list_head qtd_list_entry;
10683 +
10684 +};
10685 +
10686 +/**
10687 + * A Queue Head (QH) holds the static characteristics of an endpoint and
10688 + * maintains a list of transfers (QTDs) for that endpoint. A QH structure may
10689 + * be entered in either the non-periodic or periodic schedule.
10690 + */
10691 +struct dwc_otg_qh {
10692 + /**
10693 + * Endpoint type.
10694 + * One of the following values:
10695 + * - USB_ENDPOINT_XFER_CONTROL
10696 + * - USB_ENDPOINT_XFER_ISOC
10697 + * - USB_ENDPOINT_XFER_BULK
10698 + * - USB_ENDPOINT_XFER_INT
10699 + */
10700 + uint8_t ep_type;
10701 + uint8_t ep_is_in;
10702 +
10703 + /** wMaxPacketSize Field of Endpoint Descriptor. */
10704 + uint16_t maxp;
10705 +
10706 + /**
10707 + * Determines the PID of the next data packet for non-control
10708 + * transfers. Ignored for control transfers.<br>
10709 + * One of the following values:
10710 + * - DWC_OTG_HC_PID_DATA0
10711 + * - DWC_OTG_HC_PID_DATA1
10712 + */
10713 + uint8_t data_toggle;
10714 +
10715 + /** Ping state if 1. */
10716 + uint8_t ping_state;
10717 +
10718 + /**
10719 + * List of QTDs for this QH.
10720 + */
10721 + struct list_head qtd_list;
10722 +
10723 + /** Host channel currently processing transfers for this QH. */
10724 + struct dwc_hc *channel;
10725 +
10726 + /** QTD currently assigned to a host channel for this QH. */
10727 + struct dwc_otg_qtd *qtd_in_process;
10728 +
10729 + /** Full/low speed endpoint on high-speed hub requires split. */
10730 + uint8_t do_split;
10731 +
10732 + /** @name Periodic schedule information */
10733 + /** @{ */
10734 +
10735 + /** Bandwidth in microseconds per (micro)frame. */
10736 + uint8_t usecs;
10737 +
10738 + /** Interval between transfers in (micro)frames. */
10739 + uint16_t interval;
10740 +
10741 + /**
10742 + * (micro)frame to initialize a periodic transfer. The transfer
10743 + * executes in the following (micro)frame.
10744 + */
10745 + uint16_t sched_frame;
10746 +
10747 + /** (micro)frame at which last start split was initialized. */
10748 + uint16_t start_split_frame;
10749 +
10750 + /** @} */
10751 +
10752 + /** Entry for QH in either the periodic or non-periodic schedule. */
10753 + struct list_head qh_list_entry;
10754 +};
10755 +
10756 +/**
10757 + * This structure holds the state of the HCD, including the non-periodic and
10758 + * periodic schedules.
10759 + */
10760 +struct dwc_otg_hcd {
10761 +
10762 + /** DWC OTG Core Interface Layer */
10763 + struct dwc_otg_core_if *core_if;
10764 +
10765 + /** Internal DWC HCD Flags */
10766 + union dwc_otg_hcd_internal_flags {
10767 + uint32_t d32;
10768 + struct {
10769 +#ifdef __BIG_ENDIAN_BITFIELD
10770 + unsigned reserved:26;
10771 + unsigned port_over_current_change:1;
10772 + unsigned port_suspend_change:1;
10773 + unsigned port_enable_change:1;
10774 + unsigned port_reset_change:1;
10775 + unsigned port_connect_status:1;
10776 + unsigned port_connect_status_change:1;
10777 +#else
10778 + unsigned port_connect_status_change:1;
10779 + unsigned port_connect_status:1;
10780 + unsigned port_reset_change:1;
10781 + unsigned port_enable_change:1;
10782 + unsigned port_suspend_change:1;
10783 + unsigned port_over_current_change:1;
10784 + unsigned reserved:26;
10785 +#endif
10786 + } b;
10787 + } flags;
10788 +
10789 + /**
10790 + * Inactive items in the non-periodic schedule. This is a list of
10791 + * Queue Heads. Transfers associated with these Queue Heads are not
10792 + * currently assigned to a host channel.
10793 + */
10794 + struct list_head non_periodic_sched_inactive;
10795 +
10796 + /**
10797 + * Active items in the non-periodic schedule. This is a list of
10798 + * Queue Heads. Transfers associated with these Queue Heads are
10799 + * currently assigned to a host channel.
10800 + */
10801 + struct list_head non_periodic_sched_active;
10802 +
10803 + /**
10804 + * Pointer to the next Queue Head to process in the active
10805 + * non-periodic schedule.
10806 + */
10807 + struct list_head *non_periodic_qh_ptr;
10808 +
10809 + /**
10810 + * Inactive items in the periodic schedule. This is a list of QHs for
10811 + * periodic transfers that are _not_ scheduled for the next frame.
10812 + * Each QH in the list has an interval counter that determines when it
10813 + * needs to be scheduled for execution. This scheduling mechanism
10814 + * allows only a simple calculation for periodic bandwidth used (i.e.
10815 + * must assume that all periodic transfers may need to execute in the
10816 + * same frame). However, it greatly simplifies scheduling and should
10817 + * be sufficient for the vast majority of OTG hosts, which need to
10818 + * connect to a small number of peripherals at one time.
10819 + *
10820 + * Items move from this list to periodic_sched_ready when the QH
10821 + * interval counter is 0 at SOF.
10822 + */
10823 + struct list_head periodic_sched_inactive;
10824 +
10825 + /**
10826 + * List of periodic QHs that are ready for execution in the next
10827 + * frame, but have not yet been assigned to host channels.
10828 + *
10829 + * Items move from this list to periodic_sched_assigned as host
10830 + * channels become available during the current frame.
10831 + */
10832 + struct list_head periodic_sched_ready;
10833 +
10834 + /**
10835 + * List of periodic QHs to be executed in the next frame that are
10836 + * assigned to host channels.
10837 + *
10838 + * Items move from this list to periodic_sched_queued as the
10839 + * transactions for the QH are queued to the DWC_otg controller.
10840 + */
10841 + struct list_head periodic_sched_assigned;
10842 +
10843 + /**
10844 + * List of periodic QHs that have been queued for execution.
10845 + *
10846 + * Items move from this list to either periodic_sched_inactive or
10847 + * periodic_sched_ready when the channel associated with the transfer
10848 + * is released. If the interval for the QH is 1, the item moves to
10849 + * periodic_sched_ready because it must be rescheduled for the next
10850 + * frame. Otherwise, the item moves to periodic_sched_inactive.
10851 + */
10852 + struct list_head periodic_sched_queued;
10853 +
10854 + /**
10855 + * Total bandwidth claimed so far for periodic transfers. This value
10856 + * is in microseconds per (micro)frame. The assumption is that all
10857 + * periodic transfers may occur in the same (micro)frame.
10858 + */
10859 + uint16_t periodic_usecs;
10860 +
10861 + /**
10862 + * Frame number read from the core at SOF. The value ranges from 0 to
10863 + * DWC_HFNUM_MAX_FRNUM.
10864 + */
10865 + uint16_t frame_number;
10866 +
10867 + /**
10868 + * Free host channels in the controller. This is a list of
10869 + * struct dwc_hc items.
10870 + */
10871 + struct list_head free_hc_list;
10872 +
10873 + /**
10874 + * Number of host channels assigned to periodic transfers. Currently
10875 + * assuming that there is a dedicated host channel for each periodic
10876 + * transaction and at least one host channel available for
10877 + * non-periodic transactions.
10878 + */
10879 + int periodic_channels;
10880 +
10881 + /**
10882 + * Number of host channels assigned to non-periodic transfers.
10883 + */
10884 + int non_periodic_channels;
10885 +
10886 + /**
10887 + * Array of pointers to the host channel descriptors. Allows accessing
10888 + * a host channel descriptor given the host channel number. This is
10889 + * useful in interrupt handlers.
10890 + */
10891 + struct dwc_hc *hc_ptr_array[MAX_EPS_CHANNELS];
10892 +
10893 + /**
10894 + * Buffer to use for any data received during the status phase of a
10895 + * control transfer. Normally no data is transferred during the status
10896 + * phase. This buffer is used as a bit bucket.
10897 + */
10898 + uint8_t *status_buf;
10899 +
10900 + /**
10901 + * DMA address for status_buf.
10902 + */
10903 + dma_addr_t status_buf_dma;
10904 +#define DWC_OTG_HCD_STATUS_BUF_SIZE 64
10905 +
10906 + /**
10907 + * Structure to allow starting the HCD in a non-interrupt context
10908 + * during an OTG role change.
10909 + */
10910 + struct work_struct start_work;
10911 +
10912 + /**
10913 + * Connection timer. An OTG host must display a message if the device
10914 + * does not connect. Started when the VBus power is turned on via
10915 + * sysfs attribute "buspower".
10916 + */
10917 + struct timer_list conn_timer;
10918 +
10919 + /* Tasket to do a reset */
10920 + struct tasklet_struct *reset_tasklet;
10921 +
10922 + struct hrtimer poll_rate_limit;
10923 +
10924 + spinlock_t global_lock;
10925 +
10926 +#ifdef DEBUG
10927 + uint32_t frrem_samples;
10928 + uint64_t frrem_accum;
10929 +
10930 + uint32_t hfnum_7_samples_a;
10931 + uint64_t hfnum_7_frrem_accum_a;
10932 + uint32_t hfnum_0_samples_a;
10933 + uint64_t hfnum_0_frrem_accum_a;
10934 + uint32_t hfnum_other_samples_a;
10935 + uint64_t hfnum_other_frrem_accum_a;
10936 +
10937 + uint32_t hfnum_7_samples_b;
10938 + uint64_t hfnum_7_frrem_accum_b;
10939 + uint32_t hfnum_0_samples_b;
10940 + uint64_t hfnum_0_frrem_accum_b;
10941 + uint32_t hfnum_other_samples_b;
10942 + uint64_t hfnum_other_frrem_accum_b;
10943 +#endif
10944 +
10945 +};
10946 +
10947 +/** Gets the dwc_otg_hcd from a struct usb_hcd */
10948 +static inline struct dwc_otg_hcd *hcd_to_dwc_otg_hcd(struct usb_hcd *hcd)
10949 +{
10950 + return (struct dwc_otg_hcd *)(hcd->hcd_priv);
10951 +}
10952 +
10953 +/** Gets the struct usb_hcd that contains a struct dwc_otg_hcd. */
10954 +static inline struct usb_hcd *dwc_otg_hcd_to_hcd(struct dwc_otg_hcd
10955 + *dwc_otg_hcd)
10956 +{
10957 + return container_of((void *)dwc_otg_hcd, struct usb_hcd, hcd_priv);
10958 +}
10959 +
10960 +/** @name HCD Create/Destroy Functions */
10961 +/** @{ */
10962 +extern int __init dwc_otg_hcd_init(struct device *_dev);
10963 +extern void dwc_otg_hcd_remove(struct device *_dev);
10964 +/** @} */
10965 +
10966 +/** @name Linux HC Driver API Functions */
10967 +
10968 +extern int dwc_otg_hcd_start(struct usb_hcd *hcd);
10969 +extern void dwc_otg_hcd_stop(struct usb_hcd *hcd);
10970 +extern int dwc_otg_hcd_get_frame_number(struct usb_hcd *hcd);
10971 +extern void dwc_otg_hcd_free(struct usb_hcd *hcd);
10972 +extern int dwc_otg_hcd_urb_enqueue(struct usb_hcd *hcd,
10973 + struct urb *urb, unsigned mem_flags);
10974 +extern int dwc_otg_hcd_urb_dequeue(struct usb_hcd *hcd,
10975 + struct urb *urb, int status);
10976 +extern void dwc_otg_hcd_endpoint_disable(struct usb_hcd *hcd,
10977 + struct usb_host_endpoint *ep);
10978 +extern irqreturn_t dwc_otg_hcd_irq(struct usb_hcd *hcd);
10979 +extern int dwc_otg_hcd_hub_status_data(struct usb_hcd *hcd, char *buf);
10980 +extern int dwc_otg_hcd_hub_control(struct usb_hcd *hcd,
10981 + u16 typeReq,
10982 + u16 wValue,
10983 + u16 wIndex, char *buf, u16 wLength);
10984 +
10985 +
10986 +/** @name Transaction Execution Functions */
10987 +extern enum dwc_otg_transaction_type dwc_otg_hcd_select_transactions(struct
10988 + dwc_otg_hcd
10989 + *hcd);
10990 +extern void dwc_otg_hcd_queue_transactions(struct dwc_otg_hcd *hcd,
10991 + enum dwc_otg_transaction_type tr_type);
10992 +extern void dwc_otg_hcd_complete_urb(struct dwc_otg_hcd *hcd, struct urb *urb,
10993 + int status);
10994 +
10995 +/** @name Interrupt Handler Functions */
10996 +extern int32_t dwc_otg_hcd_handle_intr(struct dwc_otg_hcd *dwc_otg_hcd);
10997 +extern int32_t dwc_otg_hcd_handle_sof_intr(struct dwc_otg_hcd *dwc_otg_hcd);
10998 +extern int32_t dwc_otg_hcd_handle_rx_status_q_level_intr(struct dwc_otg_hcd
10999 + *dwc_otg_hcd);
11000 +extern int32_t dwc_otg_hcd_handle_np_tx_fifo_empty_intr(struct dwc_otg_hcd
11001 + *dwc_otg_hcd);
11002 +extern int32_t dwc_otg_hcd_handle_perio_tx_fifo_empty_intr(struct dwc_otg_hcd
11003 + *dwc_otg_hcd);
11004 +extern int32_t dwc_otg_hcd_handle_incomplete_periodic_intr(struct dwc_otg_hcd
11005 + *dwc_otg_hcd);
11006 +extern int32_t dwc_otg_hcd_handle_port_intr(struct dwc_otg_hcd *dwc_otg_hcd);
11007 +extern int32_t dwc_otg_hcd_handle_conn_id_status_change_intr(struct dwc_otg_hcd
11008 + *dwc_otg_hcd);
11009 +extern int32_t dwc_otg_hcd_handle_disconnect_intr(struct dwc_otg_hcd
11010 + *dwc_otg_hcd);
11011 +extern int32_t dwc_otg_hcd_handle_hc_intr(struct dwc_otg_hcd *dwc_otg_hcd);
11012 +extern int32_t dwc_otg_hcd_handle_hc_n_intr(struct dwc_otg_hcd *dwc_otg_hcd,
11013 + uint32_t num);
11014 +extern int32_t dwc_otg_hcd_handle_session_req_intr(struct dwc_otg_hcd
11015 + *dwc_otg_hcd);
11016 +extern int32_t dwc_otg_hcd_handle_wakeup_detected_intr(struct dwc_otg_hcd
11017 + *dwc_otg_hcd);
11018 +
11019 +/** @name Schedule Queue Functions */
11020 +
11021 +/* Implemented in dwc_otg_hcd_queue.c */
11022 +extern struct dwc_otg_qh *dwc_otg_hcd_qh_create(struct dwc_otg_hcd *hcd,
11023 + struct urb *urb);
11024 +extern void dwc_otg_hcd_qh_init(struct dwc_otg_hcd *hcd, struct dwc_otg_qh *qh,
11025 + struct urb *urb);
11026 +extern void dwc_otg_hcd_qh_free(struct dwc_otg_qh *qh);
11027 +extern int dwc_otg_hcd_qh_add(struct dwc_otg_hcd *hcd, struct dwc_otg_qh *qh);
11028 +extern void dwc_otg_hcd_qh_remove(struct dwc_otg_hcd *hcd, struct dwc_otg_qh *qh);
11029 +extern void dwc_otg_hcd_qh_deactivate(struct dwc_otg_hcd *hcd,
11030 + struct dwc_otg_qh *qh, int sched_csplit);
11031 +
11032 +/** Remove and free a QH */
11033 +static inline void dwc_otg_hcd_qh_remove_and_free(struct dwc_otg_hcd *hcd,
11034 + struct dwc_otg_qh *qh)
11035 +{
11036 + dwc_otg_hcd_qh_remove(hcd, qh);
11037 + dwc_otg_hcd_qh_free(qh);
11038 +}
11039 +
11040 +/** Allocates memory for a QH structure.
11041 + * Returns Returns the memory allocate or NULL on error. */
11042 +static inline struct dwc_otg_qh *dwc_otg_hcd_qh_alloc(void)
11043 +{
11044 + return kmalloc(sizeof(struct dwc_otg_qh), GFP_ATOMIC);
11045 +}
11046 +
11047 +extern struct dwc_otg_qtd *dwc_otg_hcd_qtd_create(struct urb *urb);
11048 +extern void dwc_otg_hcd_qtd_init(struct dwc_otg_qtd *qtd, struct urb *urb);
11049 +extern int dwc_otg_hcd_qtd_add(struct dwc_otg_qtd *qtd,
11050 + struct dwc_otg_hcd *dwc_otg_hcd);
11051 +
11052 +/** Allocates memory for a QTD structure.
11053 + * Returns Returns the memory allocate or NULL on error. */
11054 +static inline struct dwc_otg_qtd *dwc_otg_hcd_qtd_alloc(void)
11055 +{
11056 + return kmalloc(sizeof(struct dwc_otg_qtd), GFP_ATOMIC);
11057 +}
11058 +
11059 +/**
11060 + * Frees the memory for a QTD structure. QTD should already be removed from
11061 + * list.
11062 + * @qtd: QTD to free.
11063 + */
11064 +static inline void dwc_otg_hcd_qtd_free(struct dwc_otg_qtd *qtd)
11065 +{
11066 + kfree(qtd);
11067 +}
11068 +
11069 +/**
11070 + * Removes a QTD from list.
11071 + * @qtd: QTD to remove from list.
11072 + */
11073 +static inline void dwc_otg_hcd_qtd_remove(struct dwc_otg_qtd *qtd)
11074 +{
11075 + list_del(&qtd->qtd_list_entry);
11076 +}
11077 +
11078 +/** Remove and free a QTD */
11079 +static inline void dwc_otg_hcd_qtd_remove_and_free(struct dwc_otg_qtd *qtd)
11080 +{
11081 + dwc_otg_hcd_qtd_remove(qtd);
11082 + dwc_otg_hcd_qtd_free(qtd);
11083 +}
11084 +
11085 +/** @name Internal Functions */
11086 +struct dwc_otg_qh *dwc_urb_to_qh(struct urb *urb);
11087 +void dwc_otg_hcd_dump_frrem(struct dwc_otg_hcd *hcd);
11088 +void dwc_otg_hcd_dump_state(struct dwc_otg_hcd *hcd);
11089 +
11090 +/** Gets the usb_host_endpoint associated with an URB. */
11091 +static inline struct usb_host_endpoint *dwc_urb_to_endpoint(struct urb *urb)
11092 +{
11093 + struct usb_device *dev = urb->dev;
11094 + int ep_num = usb_pipeendpoint(urb->pipe);
11095 +
11096 + if (usb_pipein(urb->pipe))
11097 + return dev->ep_in[ep_num];
11098 + else
11099 + return dev->ep_out[ep_num];
11100 +}
11101 +
11102 +/*
11103 + * Gets the endpoint number from a bEndpointAddress argument. The endpoint is
11104 + * qualified with its direction (possible 32 endpoints per device).
11105 + */
11106 +#define dwc_ep_addr_to_endpoint(_bEndpointAddress_) \
11107 + ((_bEndpointAddress_ & USB_ENDPOINT_NUMBER_MASK) | \
11108 + ((_bEndpointAddress_ & USB_DIR_IN) != 0) << 4)
11109 +
11110 +/** Gets the QH that contains the list_head */
11111 +#define dwc_list_to_qh(_list_head_ptr_) \
11112 + (container_of(_list_head_ptr_, struct dwc_otg_qh, qh_list_entry))
11113 +
11114 +/** Gets the QTD that contains the list_head */
11115 +#define dwc_list_to_qtd(_list_head_ptr_) \
11116 + (container_of(_list_head_ptr_, struct dwc_otg_qtd, qtd_list_entry))
11117 +
11118 +/** Check if QH is non-periodic */
11119 +#define dwc_qh_is_non_per(_qh_ptr_) \
11120 + ((_qh_ptr_->ep_type == USB_ENDPOINT_XFER_BULK) || \
11121 + (_qh_ptr_->ep_type == USB_ENDPOINT_XFER_CONTROL))
11122 +
11123 +/** High bandwidth multiplier as encoded in highspeed endpoint descriptors */
11124 +#define dwc_hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
11125 +
11126 +/** Packet size for any kind of endpoint descriptor */
11127 +#define dwc_max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff)
11128 +
11129 +/**
11130 + * Returns true if frame1 is less than or equal to frame2. The comparison is
11131 + * done modulo DWC_HFNUM_MAX_FRNUM. This accounts for the rollover of the
11132 + * frame number when the max frame number is reached.
11133 + */
11134 +static inline int dwc_frame_num_le(uint16_t frame1, uint16_t frame2)
11135 +{
11136 + return ((frame2 - frame1) & DWC_HFNUM_MAX_FRNUM) <=
11137 + (DWC_HFNUM_MAX_FRNUM >> 1);
11138 +}
11139 +
11140 +/**
11141 + * Returns true if frame1 is greater than frame2. The comparison is done
11142 + * modulo DWC_HFNUM_MAX_FRNUM. This accounts for the rollover of the frame
11143 + * number when the max frame number is reached.
11144 + */
11145 +static inline int dwc_frame_num_gt(uint16_t frame1, uint16_t frame2)
11146 +{
11147 + return (frame1 != frame2) &&
11148 + (((frame1 - frame2) & DWC_HFNUM_MAX_FRNUM) <
11149 + (DWC_HFNUM_MAX_FRNUM >> 1));
11150 +}
11151 +
11152 +/**
11153 + * Increments frame by the amount specified by inc. The addition is done
11154 + * modulo DWC_HFNUM_MAX_FRNUM. Returns the incremented value.
11155 + */
11156 +static inline uint16_t dwc_frame_num_inc(uint16_t frame, uint16_t inc)
11157 +{
11158 + return (frame + inc) & DWC_HFNUM_MAX_FRNUM;
11159 +}
11160 +
11161 +static inline uint16_t dwc_full_frame_num(uint16_t frame)
11162 +{
11163 + return (frame & DWC_HFNUM_MAX_FRNUM) >> 3;
11164 +}
11165 +
11166 +static inline uint16_t dwc_micro_frame_num(uint16_t frame)
11167 +{
11168 + return frame & 0x7;
11169 +}
11170 +
11171 +#ifdef DEBUG
11172 +/**
11173 + * Macro to sample the remaining PHY clocks left in the current frame. This
11174 + * may be used during debugging to determine the average time it takes to
11175 + * execute sections of code. There are two possible sample points, "a" and
11176 + * "b", so the letter argument must be one of these values.
11177 + *
11178 + * To dump the average sample times, read the "hcd_frrem" sysfs attribute. For
11179 + * example, "cat /sys/devices/lm0/hcd_frrem".
11180 + */
11181 +#define dwc_sample_frrem(_hcd, _qh, _letter) \
11182 +{ \
11183 + union hfnum_data hfnum; \
11184 + struct dwc_otg_qtd *qtd; \
11185 + qtd = list_entry(_qh->qtd_list.next, struct dwc_otg_qtd, qtd_list_entry); \
11186 + if (usb_pipeint(qtd->urb->pipe) && qh->start_split_frame != 0 && !qtd->complete_split) { \
11187 + hfnum.d32 = dwc_read_reg32(&_hcd->core_if->host_if->host_global_regs->hfnum); \
11188 + switch (hfnum.b.frnum & 0x7) { \
11189 + case 7: \
11190 + _hcd->hfnum_7_samples_##_letter++; \
11191 + _hcd->hfnum_7_frrem_accum_##_letter += hfnum.b.frrem; \
11192 + break; \
11193 + case 0: \
11194 + _hcd->hfnum_0_samples_##_letter++; \
11195 + _hcd->hfnum_0_frrem_accum_##_letter += hfnum.b.frrem; \
11196 + break; \
11197 + default: \
11198 + _hcd->hfnum_other_samples_##_letter++; \
11199 + _hcd->hfnum_other_frrem_accum_##_letter += \
11200 + hfnum.b.frrem; \
11201 + break; \
11202 + } \
11203 + } \
11204 +}
11205 +#else
11206 +#define dwc_sample_frrem(hcd, qh, letter)
11207 +#endif
11208 +#endif
11209 +#endif /* DWC_DEVICE_ONLY */
11210 diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
11211 new file mode 100644
11212 index 0000000..2c4266f
11213 --- /dev/null
11214 +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
11215 @@ -0,0 +1,1890 @@
11216 +/* ==========================================================================
11217 + *
11218 + * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
11219 + * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
11220 + * otherwise expressly agreed to in writing between Synopsys and you.
11221 + *
11222 + * The Software IS NOT an item of Licensed Software or Licensed Product under
11223 + * any End User Software License Agreement or Agreement for Licensed Product
11224 + * with Synopsys or any supplement thereto. You are permitted to use and
11225 + * redistribute this Software in source and binary forms, with or without
11226 + * modification, provided that redistributions of source code must retain this
11227 + * notice. You may not view, use, disclose, copy or distribute this file or
11228 + * any information contained herein except pursuant to this license grant from
11229 + * Synopsys. If you do not agree with this notice, including the disclaimer
11230 + * below, then you are not authorized to use the Software.
11231 + *
11232 + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
11233 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
11234 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
11235 + * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
11236 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
11237 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
11238 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
11239 + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
11240 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
11241 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
11242 + * DAMAGE.
11243 + * ========================================================================== */
11244 +#ifndef DWC_DEVICE_ONLY
11245 +
11246 +#include "dwc_otg_driver.h"
11247 +#include "dwc_otg_hcd.h"
11248 +#include "dwc_otg_regs.h"
11249 +
11250 +/*
11251 + * This file contains the implementation of the HCD Interrupt handlers.
11252 + */
11253 +
11254 +/* This function handles interrupts for the HCD. */
11255 +int32_t dwc_otg_hcd_handle_intr(struct dwc_otg_hcd *dwc_otg_hcd)
11256 +{
11257 + int retval = 0;
11258 +
11259 + struct dwc_otg_core_if *core_if = dwc_otg_hcd->core_if;
11260 + union gintsts_data gintsts;
11261 +#ifdef DEBUG
11262 + struct dwc_otg_core_global_regs *global_regs =
11263 + core_if->core_global_regs;
11264 +#endif
11265 +
11266 + /* Check if HOST Mode */
11267 + if (dwc_otg_is_host_mode(core_if)) {
11268 + gintsts.d32 = dwc_otg_read_core_intr(core_if);
11269 + if (!gintsts.d32)
11270 + return 0;
11271 +#ifdef DEBUG
11272 + /* Don't print debug message in the interrupt handler on SOF */
11273 +# ifndef DEBUG_SOF
11274 + if (gintsts.d32 != DWC_SOF_INTR_MASK)
11275 +# endif
11276 + DWC_DEBUGPL(DBG_HCD, "\n");
11277 +#endif
11278 +
11279 +#ifdef DEBUG
11280 +# ifndef DEBUG_SOF
11281 + if (gintsts.d32 != DWC_SOF_INTR_MASK)
11282 +# endif
11283 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Interrupt Detected "
11284 + "gintsts&gintmsk=0x%08x\n",
11285 + gintsts.d32);
11286 +#endif
11287 +
11288 + if (gintsts.b.sofintr)
11289 + retval |= dwc_otg_hcd_handle_sof_intr(dwc_otg_hcd);
11290 +
11291 + if (gintsts.b.rxstsqlvl)
11292 + retval |=
11293 + dwc_otg_hcd_handle_rx_status_q_level_intr(dwc_otg_hcd);
11294 +
11295 + if (gintsts.b.nptxfempty)
11296 + retval |=
11297 + dwc_otg_hcd_handle_np_tx_fifo_empty_intr(dwc_otg_hcd);
11298 +
11299 + if (gintsts.b.i2cintr)
11300 + ;/** @todo Implement i2cintr handler. */
11301 +
11302 + if (gintsts.b.portintr)
11303 + retval |= dwc_otg_hcd_handle_port_intr(dwc_otg_hcd);
11304 +
11305 + if (gintsts.b.hcintr)
11306 + retval |= dwc_otg_hcd_handle_hc_intr(dwc_otg_hcd);
11307 +
11308 + if (gintsts.b.ptxfempty) {
11309 + retval |=
11310 + dwc_otg_hcd_handle_perio_tx_fifo_empty_intr
11311 + (dwc_otg_hcd);
11312 + }
11313 +#ifdef DEBUG
11314 +# ifndef DEBUG_SOF
11315 + if (gintsts.d32 != DWC_SOF_INTR_MASK)
11316 +# endif
11317 + {
11318 + DWC_DEBUGPL(DBG_HCD,
11319 + "DWC OTG HCD Finished Servicing Interrupts\n");
11320 + DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD gintsts=0x%08x\n",
11321 + dwc_read_reg32(&global_regs->gintsts));
11322 + DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD gintmsk=0x%08x\n",
11323 + dwc_read_reg32(&global_regs->gintmsk));
11324 + }
11325 +#endif
11326 +
11327 +#ifdef DEBUG
11328 +# ifndef DEBUG_SOF
11329 + if (gintsts.d32 != DWC_SOF_INTR_MASK)
11330 +# endif
11331 + DWC_DEBUGPL(DBG_HCD, "\n");
11332 +#endif
11333 +
11334 + }
11335 +
11336 + return retval;
11337 +}
11338 +
11339 +#ifdef DWC_TRACK_MISSED_SOFS
11340 +#warning Compiling code to track missed SOFs
11341 +#define FRAME_NUM_ARRAY_SIZE 1000
11342 +/**
11343 + * This function is for debug only.
11344 + */
11345 +static inline void track_missed_sofs(uint16_t _curr_frame_number)
11346 +{
11347 + static uint16_t frame_num_array[FRAME_NUM_ARRAY_SIZE];
11348 + static uint16_t last_frame_num_array[FRAME_NUM_ARRAY_SIZE];
11349 + static int frame_num_idx;
11350 + static uint16_t last_frame_num = DWC_HFNUM_MAX_FRNUM;
11351 + static int dumped_frame_num_array;
11352 +
11353 + if (frame_num_idx < FRAME_NUM_ARRAY_SIZE) {
11354 + if ((((last_frame_num + 1) & DWC_HFNUM_MAX_FRNUM) !=
11355 + _curr_frame_number)) {
11356 + frame_num_array[frame_num_idx] = _curr_frame_number;
11357 + last_frame_num_array[frame_num_idx++] = last_frame_num;
11358 + }
11359 + } else if (!dumped_frame_num_array) {
11360 + int i;
11361 + printk(KERN_EMERG USB_DWC "Frame Last Frame\n");
11362 + printk(KERN_EMERG USB_DWC "----- ----------\n");
11363 + for (i = 0; i < FRAME_NUM_ARRAY_SIZE; i++) {
11364 + printk(KERN_EMERG USB_DWC "0x%04x 0x%04x\n",
11365 + frame_num_array[i], last_frame_num_array[i]);
11366 + }
11367 + dumped_frame_num_array = 1;
11368 + }
11369 + last_frame_num = _curr_frame_number;
11370 +}
11371 +#endif
11372 +
11373 +/**
11374 + * Handles the start-of-frame interrupt in host mode. Non-periodic
11375 + * transactions may be queued to the DWC_otg controller for the current
11376 + * (micro)frame. Periodic transactions may be queued to the controller for the
11377 + * next (micro)frame.
11378 + */
11379 +int32_t dwc_otg_hcd_handle_sof_intr(struct dwc_otg_hcd *hcd)
11380 +{
11381 + union hfnum_data hfnum;
11382 + struct list_head *qh_entry;
11383 + struct dwc_otg_qh *qh;
11384 + enum dwc_otg_transaction_type tr_type;
11385 + union gintsts_data gintsts = {.d32 = 0 };
11386 +
11387 + hfnum.d32 =
11388 + dwc_read_reg32(&hcd->core_if->host_if->host_global_regs->hfnum);
11389 +
11390 +#ifdef DEBUG_SOF
11391 + DWC_DEBUGPL(DBG_HCD, "--Start of Frame Interrupt--\n");
11392 +#endif
11393 +
11394 + hcd->frame_number = hfnum.b.frnum;
11395 +
11396 +#ifdef DEBUG
11397 + hcd->frrem_accum += hfnum.b.frrem;
11398 + hcd->frrem_samples++;
11399 +#endif
11400 +
11401 +#ifdef DWC_TRACK_MISSED_SOFS
11402 + track_missed_sofs(hcd->frame_number);
11403 +#endif
11404 +
11405 + /* Determine whether any periodic QHs should be executed. */
11406 + qh_entry = hcd->periodic_sched_inactive.next;
11407 + while (qh_entry != &hcd->periodic_sched_inactive) {
11408 + qh = list_entry(qh_entry, struct dwc_otg_qh, qh_list_entry);
11409 + qh_entry = qh_entry->next;
11410 + if (dwc_frame_num_le(qh->sched_frame, hcd->frame_number)) {
11411 + /*
11412 + * Move QH to the ready list to be executed next
11413 + * (micro)frame.
11414 + */
11415 + list_move(&qh->qh_list_entry,
11416 + &hcd->periodic_sched_ready);
11417 + }
11418 + }
11419 +
11420 + tr_type = dwc_otg_hcd_select_transactions(hcd);
11421 + if (tr_type != DWC_OTG_TRANSACTION_NONE) {
11422 + dwc_otg_hcd_queue_transactions(hcd, tr_type);
11423 + } else if (list_empty(&hcd->periodic_sched_inactive) &&
11424 + list_empty(&hcd->periodic_sched_ready) &&
11425 + list_empty(&hcd->periodic_sched_assigned) &&
11426 + list_empty(&hcd->periodic_sched_queued)) {
11427 + /*
11428 + * We don't have USB data to send. Unfortunately the
11429 + * Synopsis block continues to generate interrupts at
11430 + * about 8k/sec. In order not waste time on these
11431 + * useless interrupts, we're going to disable the SOF
11432 + * interrupt. It will be re-enabled when a new packet
11433 + * is enqueued in dwc_otg_hcd_urb_enqueue()
11434 + */
11435 + dwc_modify_reg32(&hcd->core_if->core_global_regs->gintmsk,
11436 + DWC_SOF_INTR_MASK, 0);
11437 + }
11438 +
11439 + /* Clear interrupt */
11440 + gintsts.b.sofintr = 1;
11441 + dwc_write_reg32(&hcd->core_if->core_global_regs->gintsts, gintsts.d32);
11442 +
11443 + return 1;
11444 +}
11445 +
11446 +/* Handles the Rx Status Queue Level Interrupt, which indicates that
11447 + * there is at least one packet in the Rx FIFO. The packets are moved
11448 + * from the FIFO to memory if the DWC_otg controller is operating in
11449 + * Slave mode. */
11450 +int32_t
11451 +dwc_otg_hcd_handle_rx_status_q_level_intr(struct dwc_otg_hcd *dwc_otg_hcd)
11452 +{
11453 + union host_grxsts_data grxsts;
11454 + struct dwc_hc *hc = NULL;
11455 +
11456 + DWC_DEBUGPL(DBG_HCD, "--RxStsQ Level Interrupt--\n");
11457 +
11458 + grxsts.d32 =
11459 + dwc_read_reg32(&dwc_otg_hcd->core_if->core_global_regs->grxstsp);
11460 +
11461 + hc = dwc_otg_hcd->hc_ptr_array[grxsts.b.chnum];
11462 +
11463 + /* Packet Status */
11464 + DWC_DEBUGPL(DBG_HCDV, " Ch num = %d\n", grxsts.b.chnum);
11465 + DWC_DEBUGPL(DBG_HCDV, " Count = %d\n", grxsts.b.bcnt);
11466 + DWC_DEBUGPL(DBG_HCDV, " DPID = %d, hc.dpid = %d\n", grxsts.b.dpid,
11467 + hc->data_pid_start);
11468 + DWC_DEBUGPL(DBG_HCDV, " PStatus = %d\n", grxsts.b.pktsts);
11469 +
11470 + switch (grxsts.b.pktsts) {
11471 + case DWC_GRXSTS_PKTSTS_IN:
11472 + /* Read the data into the host buffer. */
11473 + if (grxsts.b.bcnt > 0) {
11474 + dwc_otg_read_packet(dwc_otg_hcd->core_if,
11475 + hc->xfer_buff, grxsts.b.bcnt);
11476 +
11477 + /* Update the HC fields for the next packet received. */
11478 + hc->xfer_count += grxsts.b.bcnt;
11479 + hc->xfer_buff += grxsts.b.bcnt;
11480 + }
11481 +
11482 + case DWC_GRXSTS_PKTSTS_IN_XFER_COMP:
11483 + case DWC_GRXSTS_PKTSTS_DATA_TOGGLE_ERR:
11484 + case DWC_GRXSTS_PKTSTS_CH_HALTED:
11485 + /* Handled in interrupt, just ignore data */
11486 + break;
11487 + default:
11488 + DWC_ERROR("RX_STS_Q Interrupt: Unknown status %d\n",
11489 + grxsts.b.pktsts);
11490 + break;
11491 + }
11492 +
11493 + return 1;
11494 +}
11495 +
11496 +/* This interrupt occurs when the non-periodic Tx FIFO is
11497 + * half-empty. More data packets may be written to the FIFO for OUT
11498 + * transfers. More requests may be written to the non-periodic request
11499 + * queue for IN transfers. This interrupt is enabled only in Slave
11500 + * mode. */
11501 +int32_t dwc_otg_hcd_handle_np_tx_fifo_empty_intr(struct dwc_otg_hcd *
11502 + dwc_otg_hcd)
11503 +{
11504 + DWC_DEBUGPL(DBG_HCD, "--Non-Periodic TxFIFO Empty Interrupt--\n");
11505 + dwc_otg_hcd_queue_transactions(dwc_otg_hcd,
11506 + DWC_OTG_TRANSACTION_NON_PERIODIC);
11507 + return 1;
11508 +}
11509 +
11510 +/* This interrupt occurs when the periodic Tx FIFO is half-empty. More
11511 + * data packets may be written to the FIFO for OUT transfers. More
11512 + * requests may be written to the periodic request queue for IN
11513 + * transfers. This interrupt is enabled only in Slave mode. */
11514 +int32_t dwc_otg_hcd_handle_perio_tx_fifo_empty_intr(struct dwc_otg_hcd *
11515 + dwc_otg_hcd)
11516 +{
11517 + DWC_DEBUGPL(DBG_HCD, "--Periodic TxFIFO Empty Interrupt--\n");
11518 + dwc_otg_hcd_queue_transactions(dwc_otg_hcd,
11519 + DWC_OTG_TRANSACTION_PERIODIC);
11520 + return 1;
11521 +}
11522 +
11523 +/* There are multiple conditions that can cause a port interrupt. This
11524 + * function determines which interrupt conditions have occurred and
11525 + * handles them appropriately. */
11526 +int32_t dwc_otg_hcd_handle_port_intr(struct dwc_otg_hcd *dwc_otg_hcd)
11527 +{
11528 + int retval = 0;
11529 + union hprt0_data hprt0;
11530 + union hprt0_data hprt0_modify;
11531 +
11532 + hprt0.d32 = dwc_read_reg32(dwc_otg_hcd->core_if->host_if->hprt0);
11533 + hprt0_modify.d32 =
11534 + dwc_read_reg32(dwc_otg_hcd->core_if->host_if->hprt0);
11535 +
11536 + /* Clear appropriate bits in HPRT0 to clear the interrupt bit in
11537 + * GINTSTS */
11538 +
11539 + hprt0_modify.b.prtena = 0;
11540 + hprt0_modify.b.prtconndet = 0;
11541 + hprt0_modify.b.prtenchng = 0;
11542 + hprt0_modify.b.prtovrcurrchng = 0;
11543 +
11544 + /* Port Connect Detected
11545 + * Set flag and clear if detected */
11546 + if (hprt0.b.prtconndet) {
11547 + DWC_DEBUGPL(DBG_HCD, "--Port Interrupt HPRT0=0x%08x "
11548 + "Port Connect Detected--\n", hprt0.d32);
11549 + dwc_otg_hcd->flags.b.port_connect_status_change = 1;
11550 + dwc_otg_hcd->flags.b.port_connect_status = 1;
11551 + hprt0_modify.b.prtconndet = 1;
11552 +
11553 + /* B-Device has connected, Delete the connection timer. */
11554 + del_timer(&dwc_otg_hcd->conn_timer);
11555 +
11556 + /* The Hub driver asserts a reset when it sees port connect
11557 + * status change flag */
11558 + retval |= 1;
11559 + }
11560 +
11561 + /* Port Enable Changed
11562 + * Clear if detected - Set internal flag if disabled */
11563 + if (hprt0.b.prtenchng) {
11564 + DWC_DEBUGPL(DBG_HCD, " --Port Interrupt HPRT0=0x%08x "
11565 + "Port Enable Changed--\n", hprt0.d32);
11566 + hprt0_modify.b.prtenchng = 1;
11567 + if (hprt0.b.prtena == 1) {
11568 + int do_reset = 0;
11569 + struct dwc_otg_core_params *params =
11570 + dwc_otg_hcd->core_if->core_params;
11571 + struct dwc_otg_core_global_regs *global_regs =
11572 + dwc_otg_hcd->core_if->core_global_regs;
11573 + struct dwc_otg_host_if *host_if =
11574 + dwc_otg_hcd->core_if->host_if;
11575 +
11576 + /* Check if we need to adjust the PHY clock speed for
11577 + * low power and adjust it */
11578 + if (params->host_support_fs_ls_low_power) {
11579 + union gusbcfg_data usbcfg;
11580 +
11581 + usbcfg.d32 =
11582 + dwc_read_reg32(&global_regs->gusbcfg);
11583 +
11584 + if ((hprt0.b.prtspd == DWC_HPRT0_PRTSPD_LOW_SPEED)
11585 + || (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_FULL_SPEED)) {
11586 + /*
11587 + * Low power
11588 + */
11589 + union hcfg_data hcfg;
11590 + if (usbcfg.b.phylpwrclksel == 0) {
11591 + /* Set PHY low power clock select for FS/LS devices */
11592 + usbcfg.b.phylpwrclksel = 1;
11593 + dwc_write_reg32(&global_regs->gusbcfg,
11594 + usbcfg.d32);
11595 + do_reset = 1;
11596 + }
11597 +
11598 + hcfg.d32 =
11599 + dwc_read_reg32(&host_if->host_global_regs->hcfg);
11600 +
11601 + if ((hprt0.b.prtspd ==
11602 + DWC_HPRT0_PRTSPD_LOW_SPEED)
11603 + && (params->
11604 + host_ls_low_power_phy_clk ==
11605 + DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ)) {
11606 + /* 6 MHZ */
11607 + DWC_DEBUGPL(DBG_CIL,
11608 + "FS_PHY programming HCFG to 6 MHz (Low Power)\n");
11609 + if (hcfg.b.fslspclksel !=
11610 + DWC_HCFG_6_MHZ) {
11611 + hcfg.b.fslspclksel =
11612 + DWC_HCFG_6_MHZ;
11613 + dwc_write_reg32(&host_if->host_global_regs->hcfg,
11614 + hcfg.d32);
11615 + do_reset = 1;
11616 + }
11617 + } else {
11618 + /* 48 MHZ */
11619 + DWC_DEBUGPL(DBG_CIL,
11620 + "FS_PHY programming HCFG to 48 MHz ()\n");
11621 + if (hcfg.b.fslspclksel !=
11622 + DWC_HCFG_48_MHZ) {
11623 + hcfg.b.fslspclksel = DWC_HCFG_48_MHZ;
11624 + dwc_write_reg32(&host_if->host_global_regs->hcfg,
11625 + hcfg.d32);
11626 + do_reset = 1;
11627 + }
11628 + }
11629 + } else {
11630 + /*
11631 + * Not low power
11632 + */
11633 + if (usbcfg.b.phylpwrclksel == 1) {
11634 + usbcfg.b.phylpwrclksel = 0;
11635 + dwc_write_reg32(&global_regs->gusbcfg,
11636 + usbcfg.d32);
11637 + do_reset = 1;
11638 + }
11639 + }
11640 + if (do_reset)
11641 + tasklet_schedule(dwc_otg_hcd->reset_tasklet);
11642 + }
11643 + if (!do_reset)
11644 + /*
11645 + * Port has been enabled set the reset
11646 + * change flag
11647 + */
11648 + dwc_otg_hcd->flags.b.port_reset_change = 1;
11649 + } else {
11650 + dwc_otg_hcd->flags.b.port_enable_change = 1;
11651 + }
11652 + retval |= 1;
11653 + }
11654 +
11655 + /** Overcurrent Change Interrupt */
11656 + if (hprt0.b.prtovrcurrchng) {
11657 + DWC_DEBUGPL(DBG_HCD, " --Port Interrupt HPRT0=0x%08x "
11658 + "Port Overcurrent Changed--\n", hprt0.d32);
11659 + dwc_otg_hcd->flags.b.port_over_current_change = 1;
11660 + hprt0_modify.b.prtovrcurrchng = 1;
11661 + retval |= 1;
11662 + }
11663 +
11664 + /* Clear Port Interrupts */
11665 + dwc_write_reg32(dwc_otg_hcd->core_if->host_if->hprt0,
11666 + hprt0_modify.d32);
11667 +
11668 + return retval;
11669 +}
11670 +
11671 +/** This interrupt indicates that one or more host channels has a pending
11672 + * interrupt. There are multiple conditions that can cause each host channel
11673 + * interrupt. This function determines which conditions have occurred for each
11674 + * host channel interrupt and handles them appropriately. */
11675 +int32_t dwc_otg_hcd_handle_hc_intr(struct dwc_otg_hcd *dwc_otg_hcd)
11676 +{
11677 + int i;
11678 + int retval = 0;
11679 + union haint_data haint;
11680 +
11681 + /* Clear appropriate bits in HCINTn to clear the interrupt bit in
11682 + * GINTSTS */
11683 +
11684 + haint.d32 = dwc_otg_read_host_all_channels_intr(dwc_otg_hcd->core_if);
11685 +
11686 + for (i = 0; i < dwc_otg_hcd->core_if->core_params->host_channels; i++) {
11687 + if (haint.b2.chint & (1 << i))
11688 + retval |= dwc_otg_hcd_handle_hc_n_intr(dwc_otg_hcd, i);
11689 + }
11690 +
11691 + return retval;
11692 +}
11693 +
11694 +/* Macro used to clear one channel interrupt */
11695 +#define clear_hc_int(_hc_regs_, _intr_) \
11696 +do { \
11697 + union hcint_data hcint_clear = {.d32 = 0}; \
11698 + hcint_clear.b._intr_ = 1; \
11699 + dwc_write_reg32(&((_hc_regs_)->hcint), hcint_clear.d32); \
11700 +} while (0)
11701 +
11702 +/*
11703 + * Macro used to disable one channel interrupt. Channel interrupts are
11704 + * disabled when the channel is halted or released by the interrupt handler.
11705 + * There is no need to handle further interrupts of that type until the
11706 + * channel is re-assigned. In fact, subsequent handling may cause crashes
11707 + * because the channel structures are cleaned up when the channel is released.
11708 + */
11709 +#define disable_hc_int(_hc_regs_, _intr_) \
11710 + do { \
11711 + union hcintmsk_data hcintmsk = {.d32 = 0}; \
11712 + hcintmsk.b._intr_ = 1; \
11713 + dwc_modify_reg32(&((_hc_regs_)->hcintmsk), hcintmsk.d32, 0); \
11714 + } while (0)
11715 +
11716 +/**
11717 + * Gets the actual length of a transfer after the transfer halts. _halt_status
11718 + * holds the reason for the halt.
11719 + *
11720 + * For IN transfers where _halt_status is DWC_OTG_HC_XFER_COMPLETE,
11721 + * *_short_read is set to 1 upon return if less than the requested
11722 + * number of bytes were transferred. Otherwise, *_short_read is set to 0 upon
11723 + * return. _short_read may also be NULL on entry, in which case it remains
11724 + * unchanged.
11725 + */
11726 +static uint32_t get_actual_xfer_length(struct dwc_hc *hc,
11727 + struct dwc_otg_hc_regs *hc_regs,
11728 + struct dwc_otg_qtd *qtd,
11729 + enum dwc_otg_halt_status _halt_status,
11730 + int *_short_read)
11731 +{
11732 + union hctsiz_data hctsiz;
11733 + uint32_t length;
11734 +
11735 + if (_short_read != NULL)
11736 + *_short_read = 0;
11737 +
11738 + hctsiz.d32 = dwc_read_reg32(&hc_regs->hctsiz);
11739 +
11740 + if (_halt_status == DWC_OTG_HC_XFER_COMPLETE) {
11741 + if (hc->ep_is_in) {
11742 + length = hc->xfer_len - hctsiz.b.xfersize;
11743 + if (_short_read != NULL)
11744 + *_short_read = (hctsiz.b.xfersize != 0);
11745 + } else if (hc->qh->do_split) {
11746 + length = qtd->ssplit_out_xfer_count;
11747 + } else {
11748 + length = hc->xfer_len;
11749 + }
11750 + } else {
11751 + /*
11752 + * Must use the hctsiz.pktcnt field to determine how much data
11753 + * has been transferred. This field reflects the number of
11754 + * packets that have been transferred via the USB. This is
11755 + * always an integral number of packets if the transfer was
11756 + * halted before its normal completion. (Can't use the
11757 + * hctsiz.xfersize field because that reflects the number of
11758 + * bytes transferred via the AHB, not the USB).
11759 + */
11760 + length =
11761 + (hc->start_pkt_count - hctsiz.b.pktcnt) * hc->max_packet;
11762 + }
11763 +
11764 + return length;
11765 +}
11766 +
11767 +/**
11768 + * Updates the state of the URB after a Transfer Complete interrupt on the
11769 + * host channel. Updates the actual_length field of the URB based on the
11770 + * number of bytes transferred via the host channel. Sets the URB status
11771 + * if the data transfer is finished.
11772 + *
11773 + * Returns 1 if the data transfer specified by the URB is completely finished,
11774 + * 0 otherwise.
11775 + */
11776 +static int update_urb_state_xfer_comp(struct dwc_hc *hc,
11777 + struct dwc_otg_hc_regs *hc_regs,
11778 + struct urb *urb, struct dwc_otg_qtd *qtd)
11779 +{
11780 + int xfer_done = 0;
11781 + int short_read = 0;
11782 +
11783 + urb->actual_length += get_actual_xfer_length(hc, hc_regs, qtd,
11784 + DWC_OTG_HC_XFER_COMPLETE,
11785 + &short_read);
11786 +
11787 + if (short_read || (urb->actual_length == urb->transfer_buffer_length)) {
11788 + xfer_done = 1;
11789 + if (short_read && (urb->transfer_flags & URB_SHORT_NOT_OK))
11790 + urb->status = -EREMOTEIO;
11791 + else
11792 + urb->status = 0;
11793 + }
11794 +#ifdef DEBUG
11795 + {
11796 + union hctsiz_data hctsiz;
11797 + hctsiz.d32 = dwc_read_reg32(&hc_regs->hctsiz);
11798 + DWC_DEBUGPL(DBG_HCDV, "DWC_otg: %s: %s, channel %d\n",
11799 + __func__, (hc->ep_is_in ? "IN" : "OUT"),
11800 + hc->hc_num);
11801 + DWC_DEBUGPL(DBG_HCDV, " hc->xfer_len %d\n", hc->xfer_len);
11802 + DWC_DEBUGPL(DBG_HCDV, " hctsiz.xfersize %d\n",
11803 + hctsiz.b.xfersize);
11804 + DWC_DEBUGPL(DBG_HCDV, " urb->transfer_buffer_length %d\n",
11805 + urb->transfer_buffer_length);
11806 + DWC_DEBUGPL(DBG_HCDV, " urb->actual_length %d\n",
11807 + urb->actual_length);
11808 + DWC_DEBUGPL(DBG_HCDV, " short_read %d, xfer_done %d\n",
11809 + short_read, xfer_done);
11810 + }
11811 +#endif
11812 +
11813 + return xfer_done;
11814 +}
11815 +
11816 +/*
11817 + * Save the starting data toggle for the next transfer. The data toggle is
11818 + * saved in the QH for non-control transfers and it's saved in the QTD for
11819 + * control transfers.
11820 + */
11821 +static void save_data_toggle(struct dwc_hc *hc,
11822 + struct dwc_otg_hc_regs *hc_regs,
11823 + struct dwc_otg_qtd *qtd)
11824 +{
11825 + union hctsiz_data hctsiz;
11826 + hctsiz.d32 = dwc_read_reg32(&hc_regs->hctsiz);
11827 +
11828 + if (hc->ep_type != DWC_OTG_EP_TYPE_CONTROL) {
11829 + struct dwc_otg_qh *qh = hc->qh;
11830 + if (hctsiz.b.pid == DWC_HCTSIZ_DATA0)
11831 + qh->data_toggle = DWC_OTG_HC_PID_DATA0;
11832 + else
11833 + qh->data_toggle = DWC_OTG_HC_PID_DATA1;
11834 + } else {
11835 + if (hctsiz.b.pid == DWC_HCTSIZ_DATA0)
11836 + qtd->data_toggle = DWC_OTG_HC_PID_DATA0;
11837 + else
11838 + qtd->data_toggle = DWC_OTG_HC_PID_DATA1;
11839 + }
11840 +}
11841 +
11842 +/**
11843 + * Frees the first QTD in the QH's list if free_qtd is 1. For non-periodic
11844 + * QHs, removes the QH from the active non-periodic schedule. If any QTDs are
11845 + * still linked to the QH, the QH is added to the end of the inactive
11846 + * non-periodic schedule. For periodic QHs, removes the QH from the periodic
11847 + * schedule if no more QTDs are linked to the QH.
11848 + */
11849 +static void deactivate_qh(struct dwc_otg_hcd *hcd,
11850 + struct dwc_otg_qh *qh, int free_qtd)
11851 +{
11852 + int continue_split = 0;
11853 + struct dwc_otg_qtd *qtd;
11854 +
11855 + DWC_DEBUGPL(DBG_HCDV, " %s(%p,%p,%d)\n", __func__, hcd, qh, free_qtd);
11856 +
11857 + qtd = list_entry(qh->qtd_list.next, struct dwc_otg_qtd, qtd_list_entry);
11858 +
11859 + if (qtd->complete_split) {
11860 + continue_split = 1;
11861 + } else if ((qtd->isoc_split_pos == DWC_HCSPLIT_XACTPOS_MID) ||
11862 + (qtd->isoc_split_pos == DWC_HCSPLIT_XACTPOS_END)) {
11863 + continue_split = 1;
11864 + }
11865 +
11866 + if (free_qtd) {
11867 + dwc_otg_hcd_qtd_remove_and_free(qtd);
11868 + continue_split = 0;
11869 + }
11870 +
11871 + qh->channel = NULL;
11872 + qh->qtd_in_process = NULL;
11873 + dwc_otg_hcd_qh_deactivate(hcd, qh, continue_split);
11874 +}
11875 +
11876 +/**
11877 + * Updates the state of an Isochronous URB when the transfer is stopped for
11878 + * any reason. The fields of the current entry in the frame descriptor array
11879 + * are set based on the transfer state and the input _halt_status. Completes
11880 + * the Isochronous URB if all the URB frames have been completed.
11881 + *
11882 + * Returns DWC_OTG_HC_XFER_COMPLETE if there are more frames remaining to be
11883 + * transferred in the URB. Otherwise return DWC_OTG_HC_XFER_URB_COMPLETE.
11884 + */
11885 +static enum dwc_otg_halt_status
11886 +update_isoc_urb_state(struct dwc_otg_hcd *hcd,
11887 + struct dwc_hc *hc,
11888 + struct dwc_otg_hc_regs *hc_regs,
11889 + struct dwc_otg_qtd *qtd,
11890 + enum dwc_otg_halt_status halt_status)
11891 +{
11892 + struct urb *urb = qtd->urb;
11893 + enum dwc_otg_halt_status ret_val = halt_status;
11894 + struct usb_iso_packet_descriptor *frame_desc;
11895 +
11896 + frame_desc = &urb->iso_frame_desc[qtd->isoc_frame_index];
11897 + switch (halt_status) {
11898 + case DWC_OTG_HC_XFER_COMPLETE:
11899 + frame_desc->status = 0;
11900 + frame_desc->actual_length =
11901 + get_actual_xfer_length(hc, hc_regs, qtd,
11902 + halt_status, NULL);
11903 + break;
11904 + case DWC_OTG_HC_XFER_FRAME_OVERRUN:
11905 + urb->error_count++;
11906 + if (hc->ep_is_in)
11907 + frame_desc->status = -ENOSR;
11908 + else
11909 + frame_desc->status = -ECOMM;
11910 + frame_desc->actual_length = 0;
11911 + break;
11912 + case DWC_OTG_HC_XFER_BABBLE_ERR:
11913 + urb->error_count++;
11914 + frame_desc->status = -EOVERFLOW;
11915 + /* Don't need to update actual_length in this case. */
11916 + break;
11917 + case DWC_OTG_HC_XFER_XACT_ERR:
11918 + urb->error_count++;
11919 + frame_desc->status = -EPROTO;
11920 + frame_desc->actual_length =
11921 + get_actual_xfer_length(hc, hc_regs, qtd,
11922 + halt_status, NULL);
11923 + break;
11924 + default:
11925 + DWC_ERROR("%s: Unhandled halt_status (%d)\n", __func__,
11926 + halt_status);
11927 + BUG();
11928 + break;
11929 + }
11930 +
11931 + if (++qtd->isoc_frame_index == urb->number_of_packets) {
11932 + /*
11933 + * urb->status is not used for isoc transfers.
11934 + * The individual frame_desc statuses are used instead.
11935 + */
11936 + dwc_otg_hcd_complete_urb(hcd, urb, 0);
11937 + qtd->urb = NULL;
11938 + ret_val = DWC_OTG_HC_XFER_URB_COMPLETE;
11939 + } else {
11940 + ret_val = DWC_OTG_HC_XFER_COMPLETE;
11941 + }
11942 +
11943 + return ret_val;
11944 +}
11945 +
11946 +/**
11947 + * Releases a host channel for use by other transfers. Attempts to select and
11948 + * queue more transactions since at least one host channel is available.
11949 + *
11950 + * @hcd: The HCD state structure.
11951 + * @hc: The host channel to release.
11952 + * @qtd: The QTD associated with the host channel. This QTD may be freed
11953 + * if the transfer is complete or an error has occurred.
11954 + * @_halt_status: Reason the channel is being released. This status
11955 + * determines the actions taken by this function.
11956 + */
11957 +static void release_channel(struct dwc_otg_hcd *hcd,
11958 + struct dwc_hc *hc,
11959 + struct dwc_otg_qtd *qtd,
11960 + enum dwc_otg_halt_status halt_status)
11961 +{
11962 + enum dwc_otg_transaction_type tr_type;
11963 + int free_qtd;
11964 +
11965 + DWC_DEBUGPL(DBG_HCDV, " %s: channel %d, halt_status %d\n",
11966 + __func__, hc->hc_num, halt_status);
11967 +
11968 + switch (halt_status) {
11969 + case DWC_OTG_HC_XFER_URB_COMPLETE:
11970 + free_qtd = 1;
11971 + break;
11972 + case DWC_OTG_HC_XFER_AHB_ERR:
11973 + case DWC_OTG_HC_XFER_STALL:
11974 + case DWC_OTG_HC_XFER_BABBLE_ERR:
11975 + free_qtd = 1;
11976 + break;
11977 + case DWC_OTG_HC_XFER_XACT_ERR:
11978 + if (qtd->error_count >= 3) {
11979 + DWC_DEBUGPL(DBG_HCDV,
11980 + " Complete URB with transaction error\n");
11981 + free_qtd = 1;
11982 + qtd->urb->status = -EPROTO;
11983 + dwc_otg_hcd_complete_urb(hcd, qtd->urb, -EPROTO);
11984 + qtd->urb = NULL;
11985 + } else {
11986 + free_qtd = 0;
11987 + }
11988 + break;
11989 + case DWC_OTG_HC_XFER_URB_DEQUEUE:
11990 + /*
11991 + * The QTD has already been removed and the QH has been
11992 + * deactivated. Don't want to do anything except release the
11993 + * host channel and try to queue more transfers.
11994 + */
11995 + goto cleanup;
11996 + case DWC_OTG_HC_XFER_NO_HALT_STATUS:
11997 + DWC_ERROR("%s: No halt_status, channel %d\n", __func__,
11998 + hc->hc_num);
11999 + free_qtd = 0;
12000 + break;
12001 + default:
12002 + free_qtd = 0;
12003 + break;
12004 + }
12005 +
12006 + deactivate_qh(hcd, hc->qh, free_qtd);
12007 +
12008 +cleanup:
12009 + /*
12010 + * Release the host channel for use by other transfers. The cleanup
12011 + * function clears the channel interrupt enables and conditions, so
12012 + * there's no need to clear the Channel Halted interrupt separately.
12013 + */
12014 + dwc_otg_hc_cleanup(hcd->core_if, hc);
12015 + list_add_tail(&hc->hc_list_entry, &hcd->free_hc_list);
12016 +
12017 + switch (hc->ep_type) {
12018 + case DWC_OTG_EP_TYPE_CONTROL:
12019 + case DWC_OTG_EP_TYPE_BULK:
12020 + hcd->non_periodic_channels--;
12021 + break;
12022 +
12023 + default:
12024 + /*
12025 + * Don't release reservations for periodic channels here.
12026 + * That's done when a periodic transfer is descheduled (i.e.
12027 + * when the QH is removed from the periodic schedule).
12028 + */
12029 + break;
12030 + }
12031 +
12032 + /* Try to queue more transfers now that there's a free channel. */
12033 + tr_type = dwc_otg_hcd_select_transactions(hcd);
12034 + if (tr_type != DWC_OTG_TRANSACTION_NONE)
12035 + dwc_otg_hcd_queue_transactions(hcd, tr_type);
12036 +}
12037 +
12038 +/**
12039 + * Halts a host channel. If the channel cannot be halted immediately because
12040 + * the request queue is full, this function ensures that the FIFO empty
12041 + * interrupt for the appropriate queue is enabled so that the halt request can
12042 + * be queued when there is space in the request queue.
12043 + *
12044 + * This function may also be called in DMA mode. In that case, the channel is
12045 + * simply released since the core always halts the channel automatically in
12046 + * DMA mode.
12047 + */
12048 +static void halt_channel(struct dwc_otg_hcd *hcd,
12049 + struct dwc_hc *hc,
12050 + struct dwc_otg_qtd *qtd,
12051 + enum dwc_otg_halt_status halt_status)
12052 +{
12053 + if (hcd->core_if->dma_enable) {
12054 + release_channel(hcd, hc, qtd, halt_status);
12055 + return;
12056 + }
12057 +
12058 + /* Slave mode processing... */
12059 + dwc_otg_hc_halt(hcd->core_if, hc, halt_status);
12060 +
12061 + if (hc->halt_on_queue) {
12062 + union gintmsk_data gintmsk = {.d32 = 0 };
12063 + struct dwc_otg_core_global_regs *global_regs;
12064 + global_regs = hcd->core_if->core_global_regs;
12065 +
12066 + if (hc->ep_type == DWC_OTG_EP_TYPE_CONTROL ||
12067 + hc->ep_type == DWC_OTG_EP_TYPE_BULK) {
12068 + /*
12069 + * Make sure the Non-periodic Tx FIFO empty interrupt
12070 + * is enabled so that the non-periodic schedule will
12071 + * be processed.
12072 + */
12073 + gintmsk.b.nptxfempty = 1;
12074 + dwc_modify_reg32(&global_regs->gintmsk, 0, gintmsk.d32);
12075 + } else {
12076 + /*
12077 + * Move the QH from the periodic queued schedule to
12078 + * the periodic assigned schedule. This allows the
12079 + * halt to be queued when the periodic schedule is
12080 + * processed.
12081 + */
12082 + list_move(&hc->qh->qh_list_entry,
12083 + &hcd->periodic_sched_assigned);
12084 +
12085 + /*
12086 + * Make sure the Periodic Tx FIFO Empty interrupt is
12087 + * enabled so that the periodic schedule will be
12088 + * processed.
12089 + */
12090 + gintmsk.b.ptxfempty = 1;
12091 + dwc_modify_reg32(&global_regs->gintmsk, 0, gintmsk.d32);
12092 + }
12093 + }
12094 +}
12095 +
12096 +/**
12097 + * Performs common cleanup for non-periodic transfers after a Transfer
12098 + * Complete interrupt. This function should be called after any endpoint type
12099 + * specific handling is finished to release the host channel.
12100 + */
12101 +static void complete_non_periodic_xfer(struct dwc_otg_hcd *hcd,
12102 + struct dwc_hc *hc,
12103 + struct dwc_otg_hc_regs *hc_regs,
12104 + struct dwc_otg_qtd *qtd,
12105 + enum dwc_otg_halt_status halt_status)
12106 +{
12107 + union hcint_data hcint;
12108 +
12109 + qtd->error_count = 0;
12110 +
12111 + hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
12112 + if (hcint.b.nyet) {
12113 + /*
12114 + * Got a NYET on the last transaction of the transfer. This
12115 + * means that the endpoint should be in the PING state at the
12116 + * beginning of the next transfer.
12117 + */
12118 + hc->qh->ping_state = 1;
12119 + clear_hc_int(hc_regs, nyet);
12120 + }
12121 +
12122 + /*
12123 + * Always halt and release the host channel to make it available for
12124 + * more transfers. There may still be more phases for a control
12125 + * transfer or more data packets for a bulk transfer at this point,
12126 + * but the host channel is still halted. A channel will be reassigned
12127 + * to the transfer when the non-periodic schedule is processed after
12128 + * the channel is released. This allows transactions to be queued
12129 + * properly via dwc_otg_hcd_queue_transactions, which also enables the
12130 + * Tx FIFO Empty interrupt if necessary.
12131 + */
12132 + if (hc->ep_is_in) {
12133 + /*
12134 + * IN transfers in Slave mode require an explicit disable to
12135 + * halt the channel. (In DMA mode, this call simply releases
12136 + * the channel.)
12137 + */
12138 + halt_channel(hcd, hc, qtd, halt_status);
12139 + } else {
12140 + /*
12141 + * The channel is automatically disabled by the core for OUT
12142 + * transfers in Slave mode.
12143 + */
12144 + release_channel(hcd, hc, qtd, halt_status);
12145 + }
12146 +}
12147 +
12148 +/**
12149 + * Performs common cleanup for periodic transfers after a Transfer Complete
12150 + * interrupt. This function should be called after any endpoint type specific
12151 + * handling is finished to release the host channel.
12152 + */
12153 +static void complete_periodic_xfer(struct dwc_otg_hcd *hcd,
12154 + struct dwc_hc *hc,
12155 + struct dwc_otg_hc_regs *hc_regs,
12156 + struct dwc_otg_qtd *qtd,
12157 + enum dwc_otg_halt_status halt_status)
12158 +{
12159 + union hctsiz_data hctsiz;
12160 + qtd->error_count = 0;
12161 +
12162 + hctsiz.d32 = dwc_read_reg32(&hc_regs->hctsiz);
12163 + if (!hc->ep_is_in || hctsiz.b.pktcnt == 0) {
12164 + /* Core halts channel in these cases. */
12165 + release_channel(hcd, hc, qtd, halt_status);
12166 + } else {
12167 + /* Flush any outstanding requests from the Tx queue. */
12168 + halt_channel(hcd, hc, qtd, halt_status);
12169 + }
12170 +}
12171 +
12172 +/**
12173 + * Handles a host channel Transfer Complete interrupt. This handler may be
12174 + * called in either DMA mode or Slave mode.
12175 + */
12176 +static int32_t handle_hc_xfercomp_intr(struct dwc_otg_hcd *hcd,
12177 + struct dwc_hc *hc,
12178 + struct dwc_otg_hc_regs *hc_regs,
12179 + struct dwc_otg_qtd *qtd)
12180 +{
12181 + int urb_xfer_done;
12182 + enum dwc_otg_halt_status halt_status = DWC_OTG_HC_XFER_COMPLETE;
12183 + struct urb *urb = qtd->urb;
12184 + int pipe_type = usb_pipetype(urb->pipe);
12185 +
12186 + DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
12187 + "Transfer Complete--\n", hc->hc_num);
12188 +
12189 + /*
12190 + * Handle xfer complete on CSPLIT.
12191 + */
12192 + if (hc->qh->do_split)
12193 + qtd->complete_split = 0;
12194 +
12195 + /* Update the QTD and URB states. */
12196 + switch (pipe_type) {
12197 + case PIPE_CONTROL:
12198 + switch (qtd->control_phase) {
12199 + case DWC_OTG_CONTROL_SETUP:
12200 + if (urb->transfer_buffer_length > 0)
12201 + qtd->control_phase = DWC_OTG_CONTROL_DATA;
12202 + else
12203 + qtd->control_phase = DWC_OTG_CONTROL_STATUS;
12204 + DWC_DEBUGPL(DBG_HCDV,
12205 + " Control setup transaction done\n");
12206 + halt_status = DWC_OTG_HC_XFER_COMPLETE;
12207 + break;
12208 + case DWC_OTG_CONTROL_DATA:{
12209 + urb_xfer_done =
12210 + update_urb_state_xfer_comp(hc, hc_regs,
12211 + urb, qtd);
12212 + if (urb_xfer_done) {
12213 + qtd->control_phase =
12214 + DWC_OTG_CONTROL_STATUS;
12215 + DWC_DEBUGPL(DBG_HCDV,
12216 + " Control data transfer done\n");
12217 + } else {
12218 + save_data_toggle(hc, hc_regs, qtd);
12219 + }
12220 + halt_status = DWC_OTG_HC_XFER_COMPLETE;
12221 + break;
12222 + }
12223 + case DWC_OTG_CONTROL_STATUS:
12224 + DWC_DEBUGPL(DBG_HCDV, " Control transfer complete\n");
12225 + if (urb->status == -EINPROGRESS)
12226 + urb->status = 0;
12227 + dwc_otg_hcd_complete_urb(hcd, urb, urb->status);
12228 + qtd->urb = NULL;
12229 + halt_status = DWC_OTG_HC_XFER_URB_COMPLETE;
12230 + break;
12231 + }
12232 +
12233 + complete_non_periodic_xfer(hcd, hc, hc_regs, qtd,
12234 + halt_status);
12235 + break;
12236 + case PIPE_BULK:
12237 + DWC_DEBUGPL(DBG_HCDV, " Bulk transfer complete\n");
12238 + urb_xfer_done =
12239 + update_urb_state_xfer_comp(hc, hc_regs, urb, qtd);
12240 + if (urb_xfer_done) {
12241 + dwc_otg_hcd_complete_urb(hcd, urb, urb->status);
12242 + qtd->urb = NULL;
12243 + halt_status = DWC_OTG_HC_XFER_URB_COMPLETE;
12244 + } else {
12245 + halt_status = DWC_OTG_HC_XFER_COMPLETE;
12246 + }
12247 +
12248 + save_data_toggle(hc, hc_regs, qtd);
12249 + complete_non_periodic_xfer(hcd, hc, hc_regs, qtd,
12250 + halt_status);
12251 + break;
12252 + case PIPE_INTERRUPT:
12253 + DWC_DEBUGPL(DBG_HCDV, " Interrupt transfer complete\n");
12254 + update_urb_state_xfer_comp(hc, hc_regs, urb, qtd);
12255 +
12256 + /*
12257 + * Interrupt URB is done on the first transfer complete
12258 + * interrupt.
12259 + */
12260 + dwc_otg_hcd_complete_urb(hcd, urb, urb->status);
12261 + qtd->urb = NULL;
12262 + save_data_toggle(hc, hc_regs, qtd);
12263 + complete_periodic_xfer(hcd, hc, hc_regs, qtd,
12264 + DWC_OTG_HC_XFER_URB_COMPLETE);
12265 + break;
12266 + case PIPE_ISOCHRONOUS:
12267 + DWC_DEBUGPL(DBG_HCDV, " Isochronous transfer complete\n");
12268 + if (qtd->isoc_split_pos == DWC_HCSPLIT_XACTPOS_ALL) {
12269 + halt_status =
12270 + update_isoc_urb_state(hcd, hc, hc_regs, qtd,
12271 + DWC_OTG_HC_XFER_COMPLETE);
12272 + }
12273 + complete_periodic_xfer(hcd, hc, hc_regs, qtd, halt_status);
12274 + break;
12275 + }
12276 +
12277 + disable_hc_int(hc_regs, xfercompl);
12278 +
12279 + return 1;
12280 +}
12281 +
12282 +/**
12283 + * Handles a host channel STALL interrupt. This handler may be called in
12284 + * either DMA mode or Slave mode.
12285 + */
12286 +static int32_t handle_hc_stall_intr(struct dwc_otg_hcd *hcd,
12287 + struct dwc_hc *hc,
12288 + struct dwc_otg_hc_regs *hc_regs,
12289 + struct dwc_otg_qtd *qtd)
12290 +{
12291 + struct urb *urb = qtd->urb;
12292 + int pipe_type = usb_pipetype(urb->pipe);
12293 +
12294 + DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
12295 + "STALL Received--\n", hc->hc_num);
12296 +
12297 + if (pipe_type == PIPE_CONTROL) {
12298 + dwc_otg_hcd_complete_urb(hcd, qtd->urb, -EPIPE);
12299 + qtd->urb = NULL;
12300 + }
12301 +
12302 + if (pipe_type == PIPE_BULK || pipe_type == PIPE_INTERRUPT) {
12303 + dwc_otg_hcd_complete_urb(hcd, qtd->urb, -EPIPE);
12304 + qtd->urb = NULL;
12305 + /*
12306 + * USB protocol requires resetting the data toggle for bulk
12307 + * and interrupt endpoints when a CLEAR_FEATURE(ENDPOINT_HALT)
12308 + * setup command is issued to the endpoint. Anticipate the
12309 + * CLEAR_FEATURE command since a STALL has occurred and reset
12310 + * the data toggle now.
12311 + */
12312 + hc->qh->data_toggle = 0;
12313 + }
12314 +
12315 + halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_STALL);
12316 +
12317 + disable_hc_int(hc_regs, stall);
12318 +
12319 + return 1;
12320 +}
12321 +
12322 +/*
12323 + * Updates the state of the URB when a transfer has been stopped due to an
12324 + * abnormal condition before the transfer completes. Modifies the
12325 + * actual_length field of the URB to reflect the number of bytes that have
12326 + * actually been transferred via the host channel.
12327 + */
12328 +static void update_urb_state_xfer_intr(struct dwc_hc *hc,
12329 + struct dwc_otg_hc_regs *hc_regs,
12330 + struct urb *urb,
12331 + struct dwc_otg_qtd *qtd,
12332 + enum dwc_otg_halt_status halt_status)
12333 +{
12334 + uint32_t bytes_transferred = get_actual_xfer_length(hc, hc_regs, qtd,
12335 + halt_status, NULL);
12336 + urb->actual_length += bytes_transferred;
12337 +
12338 +#ifdef DEBUG
12339 + {
12340 + union hctsiz_data hctsiz;
12341 + hctsiz.d32 = dwc_read_reg32(&hc_regs->hctsiz);
12342 + DWC_DEBUGPL(DBG_HCDV, "DWC_otg: %s: %s, channel %d\n",
12343 + __func__, (hc->ep_is_in ? "IN" : "OUT"),
12344 + hc->hc_num);
12345 + DWC_DEBUGPL(DBG_HCDV, " hc->start_pkt_count %d\n",
12346 + hc->start_pkt_count);
12347 + DWC_DEBUGPL(DBG_HCDV, " hctsiz.pktcnt %d\n", hctsiz.b.pktcnt);
12348 + DWC_DEBUGPL(DBG_HCDV, " hc->max_packet %d\n",
12349 + hc->max_packet);
12350 + DWC_DEBUGPL(DBG_HCDV, " bytes_transferred %d\n",
12351 + bytes_transferred);
12352 + DWC_DEBUGPL(DBG_HCDV, " urb->actual_length %d\n",
12353 + urb->actual_length);
12354 + DWC_DEBUGPL(DBG_HCDV, " urb->transfer_buffer_length %d\n",
12355 + urb->transfer_buffer_length);
12356 + }
12357 +#endif
12358 +}
12359 +
12360 +/**
12361 + * Handles a host channel NAK interrupt. This handler may be called in either
12362 + * DMA mode or Slave mode.
12363 + */
12364 +static int32_t handle_hc_nak_intr(struct dwc_otg_hcd *hcd,
12365 + struct dwc_hc *hc,
12366 + struct dwc_otg_hc_regs *hc_regs,
12367 + struct dwc_otg_qtd *qtd)
12368 +{
12369 + DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
12370 + "NAK Received--\n", hc->hc_num);
12371 +
12372 + /*
12373 + * Handle NAK for IN/OUT SSPLIT/CSPLIT transfers, bulk, control, and
12374 + * interrupt. Re-start the SSPLIT transfer.
12375 + */
12376 + if (hc->do_split) {
12377 + if (hc->complete_split)
12378 + qtd->error_count = 0;
12379 + qtd->complete_split = 0;
12380 + halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NAK);
12381 + goto handle_nak_done;
12382 + }
12383 +
12384 + switch (usb_pipetype(qtd->urb->pipe)) {
12385 + case PIPE_CONTROL:
12386 + case PIPE_BULK:
12387 + if (hcd->core_if->dma_enable && hc->ep_is_in) {
12388 + /*
12389 + * NAK interrupts are enabled on bulk/control IN
12390 + * transfers in DMA mode for the sole purpose of
12391 + * resetting the error count after a transaction error
12392 + * occurs. The core will continue transferring data.
12393 + */
12394 + qtd->error_count = 0;
12395 + goto handle_nak_done;
12396 + }
12397 +
12398 + /*
12399 + * NAK interrupts normally occur during OUT transfers in DMA
12400 + * or Slave mode. For IN transfers, more requests will be
12401 + * queued as request queue space is available.
12402 + */
12403 + qtd->error_count = 0;
12404 +
12405 + if (!hc->qh->ping_state) {
12406 + update_urb_state_xfer_intr(hc, hc_regs, qtd->urb,
12407 + qtd, DWC_OTG_HC_XFER_NAK);
12408 + save_data_toggle(hc, hc_regs, qtd);
12409 + if (qtd->urb->dev->speed == USB_SPEED_HIGH)
12410 + hc->qh->ping_state = 1;
12411 + }
12412 +
12413 + /*
12414 + * Halt the channel so the transfer can be re-started from
12415 + * the appropriate point or the PING protocol will
12416 + * start/continue.
12417 + */
12418 + halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NAK);
12419 + break;
12420 + case PIPE_INTERRUPT:
12421 + qtd->error_count = 0;
12422 + halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NAK);
12423 + break;
12424 + case PIPE_ISOCHRONOUS:
12425 + /* Should never get called for isochronous transfers. */
12426 + BUG();
12427 + break;
12428 + }
12429 +
12430 +handle_nak_done:
12431 + disable_hc_int(hc_regs, nak);
12432 +
12433 + return 1;
12434 +}
12435 +
12436 +/**
12437 + * Handles a host channel ACK interrupt. This interrupt is enabled when
12438 + * performing the PING protocol in Slave mode, when errors occur during
12439 + * either Slave mode or DMA mode, and during Start Split transactions.
12440 + */
12441 +static int32_t handle_hc_ack_intr(struct dwc_otg_hcd *hcd,
12442 + struct dwc_hc *hc,
12443 + struct dwc_otg_hc_regs *hc_regs,
12444 + struct dwc_otg_qtd *qtd)
12445 +{
12446 + DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
12447 + "ACK Received--\n", hc->hc_num);
12448 +
12449 + if (hc->do_split) {
12450 + /*
12451 + * Handle ACK on SSPLIT.
12452 + * ACK should not occur in CSPLIT.
12453 + */
12454 + if ((!hc->ep_is_in)
12455 + && (hc->data_pid_start != DWC_OTG_HC_PID_SETUP)) {
12456 + qtd->ssplit_out_xfer_count = hc->xfer_len;
12457 + }
12458 + if (!(hc->ep_type == DWC_OTG_EP_TYPE_ISOC && !hc->ep_is_in)) {
12459 + /* Don't need complete for isochronous out transfers. */
12460 + qtd->complete_split = 1;
12461 + }
12462 +
12463 + /* ISOC OUT */
12464 + if ((hc->ep_type == DWC_OTG_EP_TYPE_ISOC) && !hc->ep_is_in) {
12465 + switch (hc->xact_pos) {
12466 + case DWC_HCSPLIT_XACTPOS_ALL:
12467 + break;
12468 + case DWC_HCSPLIT_XACTPOS_END:
12469 + qtd->isoc_split_pos = DWC_HCSPLIT_XACTPOS_ALL;
12470 + qtd->isoc_split_offset = 0;
12471 + break;
12472 + case DWC_HCSPLIT_XACTPOS_BEGIN:
12473 + case DWC_HCSPLIT_XACTPOS_MID:
12474 + /*
12475 + * For BEGIN or MID, calculate the length for
12476 + * the next microframe to determine the correct
12477 + * SSPLIT token, either MID or END.
12478 + */
12479 + do {
12480 + struct usb_iso_packet_descriptor
12481 + *frame_desc;
12482 +
12483 + frame_desc =
12484 + &qtd->urb->iso_frame_desc[qtd->isoc_frame_index];
12485 + qtd->isoc_split_offset += 188;
12486 +
12487 + if ((frame_desc->length -
12488 + qtd->isoc_split_offset) <= 188) {
12489 + qtd->isoc_split_pos =
12490 + DWC_HCSPLIT_XACTPOS_END;
12491 + } else {
12492 + qtd->isoc_split_pos =
12493 + DWC_HCSPLIT_XACTPOS_MID;
12494 + }
12495 +
12496 + } while (0);
12497 + break;
12498 + }
12499 + } else {
12500 + halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_ACK);
12501 + }
12502 + } else {
12503 + qtd->error_count = 0;
12504 +
12505 + if (hc->qh->ping_state) {
12506 + hc->qh->ping_state = 0;
12507 + /*
12508 + * Halt the channel so the transfer can be re-started
12509 + * from the appropriate point. This only happens in
12510 + * Slave mode. In DMA mode, the ping_state is cleared
12511 + * when the transfer is started because the core
12512 + * automatically executes the PING, then the transfer.
12513 + */
12514 + halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_ACK);
12515 + }
12516 + }
12517 +
12518 + /*
12519 + * If the ACK occurred when _not_ in the PING state, let the channel
12520 + * continue transferring data after clearing the error count.
12521 + */
12522 +
12523 + disable_hc_int(hc_regs, ack);
12524 +
12525 + return 1;
12526 +}
12527 +
12528 +/**
12529 + * Handles a host channel NYET interrupt. This interrupt should only occur on
12530 + * Bulk and Control OUT endpoints and for complete split transactions. If a
12531 + * NYET occurs at the same time as a Transfer Complete interrupt, it is
12532 + * handled in the xfercomp interrupt handler, not here. This handler may be
12533 + * called in either DMA mode or Slave mode.
12534 + */
12535 +static int32_t handle_hc_nyet_intr(struct dwc_otg_hcd *hcd,
12536 + struct dwc_hc *hc,
12537 + struct dwc_otg_hc_regs *hc_regs,
12538 + struct dwc_otg_qtd *qtd)
12539 +{
12540 + DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
12541 + "NYET Received--\n", hc->hc_num);
12542 +
12543 + /*
12544 + * NYET on CSPLIT
12545 + * re-do the CSPLIT immediately on non-periodic
12546 + */
12547 + if ((hc->do_split) && (hc->complete_split)) {
12548 + if ((hc->ep_type == DWC_OTG_EP_TYPE_INTR) ||
12549 + (hc->ep_type == DWC_OTG_EP_TYPE_ISOC)) {
12550 + int frnum =
12551 + dwc_otg_hcd_get_frame_number(dwc_otg_hcd_to_hcd
12552 + (hcd));
12553 +
12554 + if (dwc_full_frame_num(frnum) !=
12555 + dwc_full_frame_num(hc->qh->sched_frame)) {
12556 + /*
12557 + * No longer in the same full speed frame.
12558 + * Treat this as a transaction error.
12559 + */
12560 +#if 0
12561 + /** @todo Fix system performance so this can
12562 + * be treated as an error. Right now complete
12563 + * splits cannot be scheduled precisely enough
12564 + * due to other system activity, so this error
12565 + * occurs regularly in Slave mode.
12566 + */
12567 + qtd->error_count++;
12568 +#endif
12569 + qtd->complete_split = 0;
12570 + halt_channel(hcd, hc, qtd,
12571 + DWC_OTG_HC_XFER_XACT_ERR);
12572 + /** @todo add support for isoc release */
12573 + goto handle_nyet_done;
12574 + }
12575 + }
12576 +
12577 + halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NYET);
12578 + goto handle_nyet_done;
12579 + }
12580 +
12581 + hc->qh->ping_state = 1;
12582 + qtd->error_count = 0;
12583 +
12584 + update_urb_state_xfer_intr(hc, hc_regs, qtd->urb, qtd,
12585 + DWC_OTG_HC_XFER_NYET);
12586 + save_data_toggle(hc, hc_regs, qtd);
12587 +
12588 + /*
12589 + * Halt the channel and re-start the transfer so the PING
12590 + * protocol will start.
12591 + */
12592 + halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NYET);
12593 +
12594 +handle_nyet_done:
12595 + disable_hc_int(hc_regs, nyet);
12596 + return 1;
12597 +}
12598 +
12599 +/**
12600 + * Handles a host channel babble interrupt. This handler may be called in
12601 + * either DMA mode or Slave mode.
12602 + */
12603 +static int32_t handle_hc_babble_intr(struct dwc_otg_hcd *hcd,
12604 + struct dwc_hc *hc,
12605 + struct dwc_otg_hc_regs *hc_regs,
12606 + struct dwc_otg_qtd *qtd)
12607 +{
12608 + DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
12609 + "Babble Error--\n", hc->hc_num);
12610 + if (hc->ep_type != DWC_OTG_EP_TYPE_ISOC) {
12611 + dwc_otg_hcd_complete_urb(hcd, qtd->urb, -EOVERFLOW);
12612 + qtd->urb = NULL;
12613 + halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_BABBLE_ERR);
12614 + } else {
12615 + enum dwc_otg_halt_status halt_status;
12616 + halt_status = update_isoc_urb_state(hcd, hc, hc_regs, qtd,
12617 + DWC_OTG_HC_XFER_BABBLE_ERR);
12618 + halt_channel(hcd, hc, qtd, halt_status);
12619 + }
12620 + disable_hc_int(hc_regs, bblerr);
12621 + return 1;
12622 +}
12623 +
12624 +/**
12625 + * Handles a host channel AHB error interrupt. This handler is only called in
12626 + * DMA mode.
12627 + */
12628 +static int32_t handle_hc_ahberr_intr(struct dwc_otg_hcd *hcd,
12629 + struct dwc_hc *hc,
12630 + struct dwc_otg_hc_regs *hc_regs,
12631 + struct dwc_otg_qtd *qtd)
12632 +{
12633 + union hcchar_data hcchar;
12634 + union hcsplt_data hcsplt;
12635 + union hctsiz_data hctsiz;
12636 + uint32_t hcdma;
12637 + struct urb *urb = qtd->urb;
12638 +
12639 + DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
12640 + "AHB Error--\n", hc->hc_num);
12641 +
12642 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
12643 + hcsplt.d32 = dwc_read_reg32(&hc_regs->hcsplt);
12644 + hctsiz.d32 = dwc_read_reg32(&hc_regs->hctsiz);
12645 + hcdma = dwc_read_reg32(&hc_regs->hcdma);
12646 +
12647 + DWC_ERROR("AHB ERROR, Channel %d\n", hc->hc_num);
12648 + DWC_ERROR(" hcchar 0x%08x, hcsplt 0x%08x\n", hcchar.d32, hcsplt.d32);
12649 + DWC_ERROR(" hctsiz 0x%08x, hcdma 0x%08x\n", hctsiz.d32, hcdma);
12650 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD URB Enqueue\n");
12651 + DWC_ERROR(" Device address: %d\n", usb_pipedevice(urb->pipe));
12652 + DWC_ERROR(" Endpoint: %d, %s\n", usb_pipeendpoint(urb->pipe),
12653 + (usb_pipein(urb->pipe) ? "IN" : "OUT"));
12654 + DWC_ERROR(" Endpoint type: %s\n",
12655 + ({
12656 + char *pipetype;
12657 + switch (usb_pipetype(urb->pipe)) {
12658 + case PIPE_CONTROL:
12659 + pipetype = "CONTROL";
12660 + break;
12661 + case PIPE_BULK:
12662 + pipetype = "BULK";
12663 + break;
12664 + case PIPE_INTERRUPT:
12665 + pipetype = "INTERRUPT";
12666 + break;
12667 + case PIPE_ISOCHRONOUS:
12668 + pipetype = "ISOCHRONOUS";
12669 + break;
12670 + default:
12671 + pipetype = "UNKNOWN";
12672 + break;
12673 + }
12674 + pipetype;
12675 + }));
12676 + DWC_ERROR(" Speed: %s\n",
12677 + ({
12678 + char *speed;
12679 + switch (urb->dev->speed) {
12680 + case USB_SPEED_HIGH:
12681 + speed = "HIGH";
12682 + break;
12683 + case USB_SPEED_FULL:
12684 + speed = "FULL";
12685 + break;
12686 + case USB_SPEED_LOW:
12687 + speed = "LOW";
12688 + break;
12689 + default:
12690 + speed = "UNKNOWN";
12691 + break;
12692 + }
12693 + speed;
12694 + }));
12695 + DWC_ERROR(" Max packet size: %d\n",
12696 + usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)));
12697 + DWC_ERROR(" Data buffer length: %d\n", urb->transfer_buffer_length);
12698 + DWC_ERROR(" Transfer buffer: %p, Transfer DMA: 0x%llx\n",
12699 + urb->transfer_buffer, (unsigned long long)urb->transfer_dma);
12700 + DWC_ERROR(" Setup buffer: %p, Setup DMA: 0x%llx\n",
12701 + urb->setup_packet, (unsigned long long)urb->setup_dma);
12702 + DWC_ERROR(" Interval: %d\n", urb->interval);
12703 +
12704 + dwc_otg_hcd_complete_urb(hcd, urb, -EIO);
12705 + qtd->urb = NULL;
12706 +
12707 + /*
12708 + * Force a channel halt. Don't call halt_channel because that won't
12709 + * write to the HCCHARn register in DMA mode to force the halt.
12710 + */
12711 + dwc_otg_hc_halt(hcd->core_if, hc, DWC_OTG_HC_XFER_AHB_ERR);
12712 +
12713 + disable_hc_int(hc_regs, ahberr);
12714 + return 1;
12715 +}
12716 +
12717 +/**
12718 + * Handles a host channel transaction error interrupt. This handler may be
12719 + * called in either DMA mode or Slave mode.
12720 + */
12721 +static int32_t handle_hc_xacterr_intr(struct dwc_otg_hcd *hcd,
12722 + struct dwc_hc *hc,
12723 + struct dwc_otg_hc_regs *hc_regs,
12724 + struct dwc_otg_qtd *qtd)
12725 +{
12726 + DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
12727 + "Transaction Error--\n", hc->hc_num);
12728 +
12729 + switch (usb_pipetype(qtd->urb->pipe)) {
12730 + case PIPE_CONTROL:
12731 + case PIPE_BULK:
12732 + qtd->error_count++;
12733 + if (!hc->qh->ping_state) {
12734 + update_urb_state_xfer_intr(hc, hc_regs, qtd->urb,
12735 + qtd,
12736 + DWC_OTG_HC_XFER_XACT_ERR);
12737 + save_data_toggle(hc, hc_regs, qtd);
12738 + if (!hc->ep_is_in
12739 + && qtd->urb->dev->speed == USB_SPEED_HIGH) {
12740 + hc->qh->ping_state = 1;
12741 + }
12742 + }
12743 +
12744 + /*
12745 + * Halt the channel so the transfer can be re-started from
12746 + * the appropriate point or the PING protocol will start.
12747 + */
12748 + halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_XACT_ERR);
12749 + break;
12750 + case PIPE_INTERRUPT:
12751 + qtd->error_count++;
12752 + if ((hc->do_split) && (hc->complete_split))
12753 + qtd->complete_split = 0;
12754 + halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_XACT_ERR);
12755 + break;
12756 + case PIPE_ISOCHRONOUS:
12757 + {
12758 + enum dwc_otg_halt_status halt_status;
12759 + halt_status =
12760 + update_isoc_urb_state(hcd, hc, hc_regs, qtd,
12761 + DWC_OTG_HC_XFER_XACT_ERR);
12762 +
12763 + halt_channel(hcd, hc, qtd, halt_status);
12764 + }
12765 + break;
12766 + }
12767 +
12768 + disable_hc_int(hc_regs, xacterr);
12769 +
12770 + return 1;
12771 +}
12772 +
12773 +/**
12774 + * Handles a host channel frame overrun interrupt. This handler may be called
12775 + * in either DMA mode or Slave mode.
12776 + */
12777 +static int32_t handle_hc_frmovrun_intr(struct dwc_otg_hcd *hcd,
12778 + struct dwc_hc *hc,
12779 + struct dwc_otg_hc_regs *hc_regs,
12780 + struct dwc_otg_qtd *qtd)
12781 +{
12782 + enum dwc_otg_halt_status halt_status;
12783 + DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
12784 + "Frame Overrun--\n", hc->hc_num);
12785 +
12786 + switch (usb_pipetype(qtd->urb->pipe)) {
12787 + case PIPE_CONTROL:
12788 + case PIPE_BULK:
12789 + break;
12790 + case PIPE_INTERRUPT:
12791 + halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_FRAME_OVERRUN);
12792 + break;
12793 + case PIPE_ISOCHRONOUS:
12794 + halt_status =
12795 + update_isoc_urb_state(hcd, hc, hc_regs, qtd,
12796 + DWC_OTG_HC_XFER_FRAME_OVERRUN);
12797 + halt_channel(hcd, hc, qtd, halt_status);
12798 + break;
12799 + }
12800 +
12801 + disable_hc_int(hc_regs, frmovrun);
12802 +
12803 + return 1;
12804 +}
12805 +
12806 +/**
12807 + * Handles a host channel data toggle error interrupt. This handler may be
12808 + * called in either DMA mode or Slave mode.
12809 + */
12810 +static int32_t handle_hc_datatglerr_intr(struct dwc_otg_hcd *hcd,
12811 + struct dwc_hc *hc,
12812 + struct dwc_otg_hc_regs *hc_regs,
12813 + struct dwc_otg_qtd *qtd)
12814 +{
12815 + DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
12816 + "Data Toggle Error--\n", hc->hc_num);
12817 +
12818 + if (hc->ep_is_in) {
12819 + qtd->error_count = 0;
12820 + } else {
12821 + DWC_ERROR("Data Toggle Error on OUT transfer,"
12822 + "channel %d\n", hc->hc_num);
12823 + }
12824 +
12825 + disable_hc_int(hc_regs, datatglerr);
12826 +
12827 + return 1;
12828 +}
12829 +
12830 +#ifdef DEBUG
12831 +/**
12832 + * This function is for debug only. It checks that a valid halt status is set
12833 + * and that HCCHARn.chdis is clear. If there's a problem, corrective action is
12834 + * taken and a warning is issued.
12835 + * Returns 1 if halt status is ok, 0 otherwise.
12836 + */
12837 +static inline int halt_status_ok(struct dwc_otg_hcd *hcd,
12838 + struct dwc_hc *hc,
12839 + struct dwc_otg_hc_regs *hc_regs,
12840 + struct dwc_otg_qtd *qtd)
12841 +{
12842 + union hcchar_data hcchar;
12843 + union hctsiz_data hctsiz;
12844 + union hcint_data hcint;
12845 + union hcintmsk_data hcintmsk;
12846 + union hcsplt_data hcsplt;
12847 +
12848 + if (hc->halt_status == DWC_OTG_HC_XFER_NO_HALT_STATUS) {
12849 + /*
12850 + * This code is here only as a check. This condition should
12851 + * never happen. Ignore the halt if it does occur.
12852 + */
12853 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
12854 + hctsiz.d32 = dwc_read_reg32(&hc_regs->hctsiz);
12855 + hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
12856 + hcintmsk.d32 = dwc_read_reg32(&hc_regs->hcintmsk);
12857 + hcsplt.d32 = dwc_read_reg32(&hc_regs->hcsplt);
12858 + DWC_WARN
12859 + ("%s: hc->halt_status == DWC_OTG_HC_XFER_NO_HALT_STATUS, "
12860 + "channel %d, hcchar 0x%08x, hctsiz 0x%08x, "
12861 + "hcint 0x%08x, hcintmsk 0x%08x, "
12862 + "hcsplt 0x%08x, qtd->complete_split %d\n", __func__,
12863 + hc->hc_num, hcchar.d32, hctsiz.d32, hcint.d32,
12864 + hcintmsk.d32, hcsplt.d32, qtd->complete_split);
12865 +
12866 + DWC_WARN("%s: no halt status, channel %d, ignoring interrupt\n",
12867 + __func__, hc->hc_num);
12868 + DWC_WARN("\n");
12869 + clear_hc_int(hc_regs, chhltd);
12870 + return 0;
12871 + }
12872 +
12873 + /*
12874 + * This code is here only as a check. hcchar.chdis should
12875 + * never be set when the halt interrupt occurs. Halt the
12876 + * channel again if it does occur.
12877 + */
12878 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
12879 + if (hcchar.b.chdis) {
12880 + DWC_WARN("%s: hcchar.chdis set unexpectedly, "
12881 + "hcchar 0x%08x, trying to halt again\n",
12882 + __func__, hcchar.d32);
12883 + clear_hc_int(hc_regs, chhltd);
12884 + hc->halt_pending = 0;
12885 + halt_channel(hcd, hc, qtd, hc->halt_status);
12886 + return 0;
12887 + }
12888 +
12889 + return 1;
12890 +}
12891 +#endif
12892 +
12893 +/**
12894 + * Handles a host Channel Halted interrupt in DMA mode. This handler
12895 + * determines the reason the channel halted and proceeds accordingly.
12896 + */
12897 +static void handle_hc_chhltd_intr_dma(struct dwc_otg_hcd *hcd,
12898 + struct dwc_hc *hc,
12899 + struct dwc_otg_hc_regs *hc_regs,
12900 + struct dwc_otg_qtd *qtd)
12901 +{
12902 + union hcint_data hcint;
12903 + union hcintmsk_data hcintmsk;
12904 +
12905 + if (hc->halt_status == DWC_OTG_HC_XFER_URB_DEQUEUE ||
12906 + hc->halt_status == DWC_OTG_HC_XFER_AHB_ERR) {
12907 + /*
12908 + * Just release the channel. A dequeue can happen on a
12909 + * transfer timeout. In the case of an AHB Error, the channel
12910 + * was forced to halt because there's no way to gracefully
12911 + * recover.
12912 + */
12913 + release_channel(hcd, hc, qtd, hc->halt_status);
12914 + return;
12915 + }
12916 +
12917 + /* Read the HCINTn register to determine the cause for the halt. */
12918 + hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
12919 + hcintmsk.d32 = dwc_read_reg32(&hc_regs->hcintmsk);
12920 +
12921 + if (hcint.b.xfercomp) {
12922 + /*
12923 + * @todo This is here because of a possible hardware
12924 + * bug. Spec says that on SPLIT-ISOC OUT transfers in
12925 + * DMA mode that a HALT interrupt w/ACK bit set should
12926 + * occur, but I only see the XFERCOMP bit, even with
12927 + * it masked out. This is a workaround for that
12928 + * behavior. Should fix this when hardware is fixed.
12929 + */
12930 + if ((hc->ep_type == DWC_OTG_EP_TYPE_ISOC) && (!hc->ep_is_in))
12931 + handle_hc_ack_intr(hcd, hc, hc_regs, qtd);
12932 + handle_hc_xfercomp_intr(hcd, hc, hc_regs, qtd);
12933 + } else if (hcint.b.stall) {
12934 + handle_hc_stall_intr(hcd, hc, hc_regs, qtd);
12935 + } else if (hcint.b.xacterr) {
12936 + /*
12937 + * Must handle xacterr before nak or ack. Could get a xacterr
12938 + * at the same time as either of these on a BULK/CONTROL OUT
12939 + * that started with a PING. The xacterr takes precedence.
12940 + */
12941 + handle_hc_xacterr_intr(hcd, hc, hc_regs, qtd);
12942 + } else if (hcint.b.nyet) {
12943 + /*
12944 + * Must handle nyet before nak or ack. Could get a nyet at the
12945 + * same time as either of those on a BULK/CONTROL OUT that
12946 + * started with a PING. The nyet takes precedence.
12947 + */
12948 + handle_hc_nyet_intr(hcd, hc, hc_regs, qtd);
12949 + } else if (hcint.b.bblerr) {
12950 + handle_hc_babble_intr(hcd, hc, hc_regs, qtd);
12951 + } else if (hcint.b.frmovrun) {
12952 + handle_hc_frmovrun_intr(hcd, hc, hc_regs, qtd);
12953 + } else if (hcint.b.nak && !hcintmsk.b.nak) {
12954 + /*
12955 + * If nak is not masked, it's because a non-split IN transfer
12956 + * is in an error state. In that case, the nak is handled by
12957 + * the nak interrupt handler, not here. Handle nak here for
12958 + * BULK/CONTROL OUT transfers, which halt on a NAK to allow
12959 + * rewinding the buffer pointer.
12960 + */
12961 + handle_hc_nak_intr(hcd, hc, hc_regs, qtd);
12962 + } else if (hcint.b.ack && !hcintmsk.b.ack) {
12963 + /*
12964 + * If ack is not masked, it's because a non-split IN transfer
12965 + * is in an error state. In that case, the ack is handled by
12966 + * the ack interrupt handler, not here. Handle ack here for
12967 + * split transfers. Start splits halt on ACK.
12968 + */
12969 + handle_hc_ack_intr(hcd, hc, hc_regs, qtd);
12970 + } else {
12971 + if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
12972 + hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
12973 + /*
12974 + * A periodic transfer halted with no other channel
12975 + * interrupts set. Assume it was halted by the core
12976 + * because it could not be completed in its scheduled
12977 + * (micro)frame.
12978 + */
12979 +#ifdef DEBUG
12980 + DWC_PRINT("%s: Halt channel %d (assume incomplete "
12981 + "periodic transfer)\n",
12982 + __func__, hc->hc_num);
12983 +#endif
12984 + halt_channel(hcd, hc, qtd,
12985 + DWC_OTG_HC_XFER_PERIODIC_INCOMPLETE);
12986 + } else {
12987 + DWC_ERROR("%s: Channel %d, DMA Mode -- ChHltd set, "
12988 + "but reason for halting is unknown, hcint "
12989 + "0x%08x, intsts 0x%08x\n",
12990 + __func__, hc->hc_num, hcint.d32,
12991 + dwc_read_reg32(&hcd->core_if->core_global_regs->
12992 + gintsts));
12993 + }
12994 + }
12995 +}
12996 +
12997 +/**
12998 + * Handles a host channel Channel Halted interrupt.
12999 + *
13000 + * In slave mode, this handler is called only when the driver specifically
13001 + * requests a halt. This occurs during handling other host channel interrupts
13002 + * (e.g. nak, xacterr, stall, nyet, etc.).
13003 + *
13004 + * In DMA mode, this is the interrupt that occurs when the core has finished
13005 + * processing a transfer on a channel. Other host channel interrupts (except
13006 + * ahberr) are disabled in DMA mode.
13007 + */
13008 +static int32_t handle_hc_chhltd_intr(struct dwc_otg_hcd *hcd,
13009 + struct dwc_hc *hc,
13010 + struct dwc_otg_hc_regs *hc_regs,
13011 + struct dwc_otg_qtd *qtd)
13012 +{
13013 + DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
13014 + "Channel Halted--\n", hc->hc_num);
13015 +
13016 + if (hcd->core_if->dma_enable) {
13017 + handle_hc_chhltd_intr_dma(hcd, hc, hc_regs, qtd);
13018 + } else {
13019 +#ifdef DEBUG
13020 + if (!halt_status_ok(hcd, hc, hc_regs, qtd))
13021 + return 1;
13022 +#endif
13023 + release_channel(hcd, hc, qtd, hc->halt_status);
13024 + }
13025 +
13026 + return 1;
13027 +}
13028 +
13029 +/** Handles interrupt for a specific Host Channel */
13030 +int32_t dwc_otg_hcd_handle_hc_n_intr(struct dwc_otg_hcd *dwc_otg_hcd,
13031 + uint32_t _num)
13032 +{
13033 + int retval = 0;
13034 + union hcint_data hcint;
13035 + union hcintmsk_data hcintmsk;
13036 + struct dwc_hc *hc;
13037 + struct dwc_otg_hc_regs *hc_regs;
13038 + struct dwc_otg_qtd *qtd;
13039 +
13040 + DWC_DEBUGPL(DBG_HCDV, "--Host Channel Interrupt--, Channel %d\n", _num);
13041 +
13042 + hc = dwc_otg_hcd->hc_ptr_array[_num];
13043 + hc_regs = dwc_otg_hcd->core_if->host_if->hc_regs[_num];
13044 + qtd = list_entry(hc->qh->qtd_list.next, struct dwc_otg_qtd,
13045 + qtd_list_entry);
13046 +
13047 + hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
13048 + hcintmsk.d32 = dwc_read_reg32(&hc_regs->hcintmsk);
13049 + DWC_DEBUGPL(DBG_HCDV,
13050 + " hcint 0x%08x, hcintmsk 0x%08x, hcint&hcintmsk 0x%08x\n",
13051 + hcint.d32, hcintmsk.d32, (hcint.d32 & hcintmsk.d32));
13052 + hcint.d32 = hcint.d32 & hcintmsk.d32;
13053 +
13054 + if (!dwc_otg_hcd->core_if->dma_enable) {
13055 + if ((hcint.b.chhltd) && (hcint.d32 != 0x2))
13056 + hcint.b.chhltd = 0;
13057 + }
13058 +
13059 + if (hcint.b.xfercomp) {
13060 + retval |=
13061 + handle_hc_xfercomp_intr(dwc_otg_hcd, hc, hc_regs, qtd);
13062 + /*
13063 + * If NYET occurred at same time as Xfer Complete, the NYET is
13064 + * handled by the Xfer Complete interrupt handler. Don't want
13065 + * to call the NYET interrupt handler in this case.
13066 + */
13067 + hcint.b.nyet = 0;
13068 + }
13069 + if (hcint.b.chhltd)
13070 + retval |= handle_hc_chhltd_intr(dwc_otg_hcd, hc, hc_regs, qtd);
13071 +
13072 + if (hcint.b.ahberr)
13073 + retval |= handle_hc_ahberr_intr(dwc_otg_hcd, hc, hc_regs, qtd);
13074 +
13075 + if (hcint.b.stall)
13076 + retval |= handle_hc_stall_intr(dwc_otg_hcd, hc, hc_regs, qtd);
13077 +
13078 + if (hcint.b.nak)
13079 + retval |= handle_hc_nak_intr(dwc_otg_hcd, hc, hc_regs, qtd);
13080 +
13081 + if (hcint.b.ack)
13082 + retval |= handle_hc_ack_intr(dwc_otg_hcd, hc, hc_regs, qtd);
13083 +
13084 + if (hcint.b.nyet)
13085 + retval |= handle_hc_nyet_intr(dwc_otg_hcd, hc, hc_regs, qtd);
13086 +
13087 + if (hcint.b.xacterr)
13088 + retval |=
13089 + handle_hc_xacterr_intr(dwc_otg_hcd, hc, hc_regs, qtd);
13090 +
13091 + if (hcint.b.bblerr)
13092 + retval |= handle_hc_babble_intr(dwc_otg_hcd, hc, hc_regs, qtd);
13093 +
13094 + if (hcint.b.frmovrun)
13095 + retval |=
13096 + handle_hc_frmovrun_intr(dwc_otg_hcd, hc, hc_regs, qtd);
13097 +
13098 + if (hcint.b.datatglerr)
13099 + retval |=
13100 + handle_hc_datatglerr_intr(dwc_otg_hcd, hc, hc_regs, qtd);
13101 +
13102 + return retval;
13103 +}
13104 +
13105 +#endif /* DWC_DEVICE_ONLY */
13106 diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c
13107 new file mode 100644
13108 index 0000000..e4c96f2
13109 --- /dev/null
13110 +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c
13111 @@ -0,0 +1,695 @@
13112 +/* ==========================================================================
13113 + *
13114 + * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
13115 + * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
13116 + * otherwise expressly agreed to in writing between Synopsys and you.
13117 + *
13118 + * The Software IS NOT an item of Licensed Software or Licensed Product under
13119 + * any End User Software License Agreement or Agreement for Licensed Product
13120 + * with Synopsys or any supplement thereto. You are permitted to use and
13121 + * redistribute this Software in source and binary forms, with or without
13122 + * modification, provided that redistributions of source code must retain this
13123 + * notice. You may not view, use, disclose, copy or distribute this file or
13124 + * any information contained herein except pursuant to this license grant from
13125 + * Synopsys. If you do not agree with this notice, including the disclaimer
13126 + * below, then you are not authorized to use the Software.
13127 + *
13128 + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
13129 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
13130 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
13131 + * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
13132 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
13133 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
13134 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
13135 + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
13136 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
13137 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
13138 + * DAMAGE.
13139 + * ========================================================================== */
13140 +#ifndef DWC_DEVICE_ONLY
13141 +
13142 +/*
13143 + *
13144 + * This file contains the functions to manage Queue Heads and Queue
13145 + * Transfer Descriptors.
13146 + */
13147 +#include <linux/kernel.h>
13148 +#include <linux/module.h>
13149 +#include <linux/moduleparam.h>
13150 +#include <linux/init.h>
13151 +#include <linux/device.h>
13152 +#include <linux/errno.h>
13153 +#include <linux/list.h>
13154 +#include <linux/interrupt.h>
13155 +#include <linux/string.h>
13156 +
13157 +#include "dwc_otg_driver.h"
13158 +#include "dwc_otg_hcd.h"
13159 +#include "dwc_otg_regs.h"
13160 +
13161 +/**
13162 + * This function allocates and initializes a QH.
13163 + *
13164 + * @hcd: The HCD state structure for the DWC OTG controller.
13165 + * @urb: Holds the information about the device/endpoint that we need
13166 + * to initialize the QH.
13167 + *
13168 + * Returns Returns pointer to the newly allocated QH, or NULL on error. */
13169 +struct dwc_otg_qh *dwc_otg_hcd_qh_create(struct dwc_otg_hcd *hcd,
13170 + struct urb *urb)
13171 +{
13172 + struct dwc_otg_qh *qh;
13173 +
13174 + /* Allocate memory */
13175 + /** @todo add memflags argument */
13176 + qh = dwc_otg_hcd_qh_alloc();
13177 + if (qh == NULL)
13178 + return NULL;
13179 +
13180 + dwc_otg_hcd_qh_init(hcd, qh, urb);
13181 + return qh;
13182 +}
13183 +
13184 +/** Free each QTD in the QH's QTD-list then free the QH. QH should already be
13185 + * removed from a list. QTD list should already be empty if called from URB
13186 + * Dequeue.
13187 + *
13188 + * @qh: The QH to free.
13189 + */
13190 +void dwc_otg_hcd_qh_free(struct dwc_otg_qh *qh)
13191 +{
13192 + struct dwc_otg_qtd *qtd;
13193 + struct list_head *pos;
13194 +
13195 + /* Free each QTD in the QTD list */
13196 + for (pos = qh->qtd_list.next;
13197 + pos != &qh->qtd_list; pos = qh->qtd_list.next) {
13198 + list_del(pos);
13199 + qtd = dwc_list_to_qtd(pos);
13200 + dwc_otg_hcd_qtd_free(qtd);
13201 + }
13202 +
13203 + kfree(qh);
13204 + return;
13205 +}
13206 +
13207 +/** Initializes a QH structure.
13208 + *
13209 + * @hcd: The HCD state structure for the DWC OTG controller.
13210 + * @qh: The QH to init.
13211 + * @urb: Holds the information about the device/endpoint that we need
13212 + * to initialize the QH. */
13213 +#define SCHEDULE_SLOP 10
13214 +void dwc_otg_hcd_qh_init(struct dwc_otg_hcd *hcd, struct dwc_otg_qh *qh,
13215 + struct urb *urb)
13216 +{
13217 + memset(qh, 0, sizeof(struct dwc_otg_qh));
13218 +
13219 + /* Initialize QH */
13220 + switch (usb_pipetype(urb->pipe)) {
13221 + case PIPE_CONTROL:
13222 + qh->ep_type = USB_ENDPOINT_XFER_CONTROL;
13223 + break;
13224 + case PIPE_BULK:
13225 + qh->ep_type = USB_ENDPOINT_XFER_BULK;
13226 + break;
13227 + case PIPE_ISOCHRONOUS:
13228 + qh->ep_type = USB_ENDPOINT_XFER_ISOC;
13229 + break;
13230 + case PIPE_INTERRUPT:
13231 + qh->ep_type = USB_ENDPOINT_XFER_INT;
13232 + break;
13233 + }
13234 +
13235 + qh->ep_is_in = usb_pipein(urb->pipe) ? 1 : 0;
13236 +
13237 + qh->data_toggle = DWC_OTG_HC_PID_DATA0;
13238 + qh->maxp =
13239 + usb_maxpacket(urb->dev, urb->pipe, !(usb_pipein(urb->pipe)));
13240 + INIT_LIST_HEAD(&qh->qtd_list);
13241 + INIT_LIST_HEAD(&qh->qh_list_entry);
13242 + qh->channel = NULL;
13243 +
13244 + /* FS/LS Enpoint on HS Hub
13245 + * NOT virtual root hub */
13246 + qh->do_split = 0;
13247 + if (((urb->dev->speed == USB_SPEED_LOW) ||
13248 + (urb->dev->speed == USB_SPEED_FULL)) &&
13249 + (urb->dev->tt) && (urb->dev->tt->hub->devnum != 1)) {
13250 + DWC_DEBUGPL(DBG_HCD,
13251 + "QH init: EP %d: TT found at hub addr %d, for "
13252 + "port %d\n",
13253 + usb_pipeendpoint(urb->pipe),
13254 + urb->dev->tt->hub->devnum, urb->dev->ttport);
13255 + qh->do_split = 1;
13256 + }
13257 +
13258 + if (qh->ep_type == USB_ENDPOINT_XFER_INT ||
13259 + qh->ep_type == USB_ENDPOINT_XFER_ISOC) {
13260 + /* Compute scheduling parameters once and save them. */
13261 + union hprt0_data hprt;
13262 +
13263 + /* todo Account for split transfers in the bus time. */
13264 + int bytecount =
13265 + dwc_hb_mult(qh->maxp) * dwc_max_packet(qh->maxp);
13266 + /*
13267 + * The results from usb_calc_bus_time are in nanosecs,
13268 + * so divide the result by 1000 to convert to
13269 + * microsecs expected by this driver
13270 + */
13271 + qh->usecs = usb_calc_bus_time(urb->dev->speed,
13272 + usb_pipein(urb->pipe),
13273 + (qh->ep_type ==
13274 + USB_ENDPOINT_XFER_ISOC),
13275 + bytecount) / 1000;
13276 +
13277 + /* Start in a slightly future (micro)frame. */
13278 + qh->sched_frame = dwc_frame_num_inc(hcd->frame_number,
13279 + SCHEDULE_SLOP);
13280 + qh->interval = urb->interval;
13281 +#if 0
13282 + /* Increase interrupt polling rate for debugging. */
13283 + if (qh->ep_type == USB_ENDPOINT_XFER_INT)
13284 + qh->interval = 8;
13285 +#endif
13286 + hprt.d32 = dwc_read_reg32(hcd->core_if->host_if->hprt0);
13287 + if ((hprt.b.prtspd == DWC_HPRT0_PRTSPD_HIGH_SPEED) &&
13288 + ((urb->dev->speed == USB_SPEED_LOW) ||
13289 + (urb->dev->speed == USB_SPEED_FULL))) {
13290 + qh->interval *= 8;
13291 + qh->sched_frame |= 0x7;
13292 + qh->start_split_frame = qh->sched_frame;
13293 + }
13294 +
13295 + }
13296 +
13297 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD QH Initialized\n");
13298 + DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - qh = %p\n", qh);
13299 + DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - Device Address = %d\n",
13300 + urb->dev->devnum);
13301 + DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - Endpoint %d, %s\n",
13302 + usb_pipeendpoint(urb->pipe),
13303 + usb_pipein(urb->pipe) == USB_DIR_IN ? "IN" : "OUT");
13304 + DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - Speed = %s\n",
13305 + ({
13306 + char *speed;
13307 + switch (urb->dev->speed) {
13308 + case USB_SPEED_LOW:
13309 + speed = "low";
13310 + break;
13311 + case USB_SPEED_FULL:
13312 + speed = "full";
13313 + break;
13314 + case USB_SPEED_HIGH:
13315 + speed = "high";
13316 + break;
13317 + default:
13318 + speed = "?";
13319 + break;
13320 + }
13321 + speed;
13322 + }));
13323 + DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - Type = %s\n",
13324 + ({
13325 + char *type;
13326 + switch (qh->ep_type) {
13327 + case USB_ENDPOINT_XFER_ISOC:
13328 + type = "isochronous";
13329 + break;
13330 + case USB_ENDPOINT_XFER_INT:
13331 + type = "interrupt";
13332 + break;
13333 + case USB_ENDPOINT_XFER_CONTROL:
13334 + type = "control";
13335 + break;
13336 + case USB_ENDPOINT_XFER_BULK:
13337 + type = "bulk";
13338 + break;
13339 + default:
13340 + type = "?";
13341 + break;
13342 + }
13343 + type;
13344 + }));
13345 +#ifdef DEBUG
13346 + if (qh->ep_type == USB_ENDPOINT_XFER_INT) {
13347 + DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - usecs = %d\n",
13348 + qh->usecs);
13349 + DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - interval = %d\n",
13350 + qh->interval);
13351 + }
13352 +#endif
13353 +
13354 + return;
13355 +}
13356 +
13357 +/**
13358 + * Checks that a channel is available for a periodic transfer.
13359 + *
13360 + * Returns 0 if successful, negative error code otherise.
13361 + */
13362 +static int periodic_channel_available(struct dwc_otg_hcd *hcd)
13363 +{
13364 + /*
13365 + * Currently assuming that there is a dedicated host channnel for each
13366 + * periodic transaction plus at least one host channel for
13367 + * non-periodic transactions.
13368 + */
13369 + int status;
13370 + int num_channels;
13371 +
13372 + num_channels = hcd->core_if->core_params->host_channels;
13373 + if ((hcd->periodic_channels + hcd->non_periodic_channels <
13374 + num_channels) && (hcd->periodic_channels < num_channels - 1)) {
13375 + status = 0;
13376 + } else {
13377 + DWC_NOTICE
13378 + ("%s: Total channels: %d, Periodic: %d, Non-periodic: %d\n",
13379 + __func__, num_channels, hcd->periodic_channels,
13380 + hcd->non_periodic_channels);
13381 + status = -ENOSPC;
13382 + }
13383 +
13384 + return status;
13385 +}
13386 +
13387 +/**
13388 + * Checks that there is sufficient bandwidth for the specified QH in the
13389 + * periodic schedule. For simplicity, this calculation assumes that all the
13390 + * transfers in the periodic schedule may occur in the same (micro)frame.
13391 + *
13392 + * @hcd: The HCD state structure for the DWC OTG controller.
13393 + * @qh: QH containing periodic bandwidth required.
13394 + *
13395 + * Returns 0 if successful, negative error code otherwise.
13396 + */
13397 +static int check_periodic_bandwidth(struct dwc_otg_hcd *hcd,
13398 + struct dwc_otg_qh *qh)
13399 +{
13400 + int status;
13401 + uint16_t max_claimed_usecs;
13402 +
13403 + status = 0;
13404 +
13405 + if (hcd->core_if->core_params->speed == DWC_SPEED_PARAM_HIGH) {
13406 + /*
13407 + * High speed mode.
13408 + * Max periodic usecs is 80% x 125 usec = 100 usec.
13409 + */
13410 + max_claimed_usecs = 100 - qh->usecs;
13411 + } else {
13412 + /*
13413 + * Full speed mode.
13414 + * Max periodic usecs is 90% x 1000 usec = 900 usec.
13415 + */
13416 + max_claimed_usecs = 900 - qh->usecs;
13417 + }
13418 +
13419 + if (hcd->periodic_usecs > max_claimed_usecs) {
13420 + DWC_NOTICE("%s: already claimed usecs %d, required usecs %d\n",
13421 + __func__, hcd->periodic_usecs, qh->usecs);
13422 + status = -ENOSPC;
13423 + }
13424 +
13425 + return status;
13426 +}
13427 +
13428 +/**
13429 + * Checks that the max transfer size allowed in a host channel is large enough
13430 + * to handle the maximum data transfer in a single (micro)frame for a periodic
13431 + * transfer.
13432 + *
13433 + * @hcd: The HCD state structure for the DWC OTG controller.
13434 + * @qh: QH for a periodic endpoint.
13435 + *
13436 + * Returns 0 if successful, negative error code otherwise.
13437 + */
13438 +static int check_max_xfer_size(struct dwc_otg_hcd *hcd, struct dwc_otg_qh *qh)
13439 +{
13440 + int status;
13441 + uint32_t max_xfer_size;
13442 + uint32_t max_channel_xfer_size;
13443 +
13444 + status = 0;
13445 +
13446 + max_xfer_size = dwc_max_packet(qh->maxp) * dwc_hb_mult(qh->maxp);
13447 + max_channel_xfer_size = hcd->core_if->core_params->max_transfer_size;
13448 +
13449 + if (max_xfer_size > max_channel_xfer_size) {
13450 + DWC_NOTICE("%s: Periodic xfer length %d > "
13451 + "max xfer length for channel %d\n",
13452 + __func__, max_xfer_size, max_channel_xfer_size);
13453 + status = -ENOSPC;
13454 + }
13455 +
13456 + return status;
13457 +}
13458 +
13459 +/**
13460 + * Schedules an interrupt or isochronous transfer in the periodic schedule.
13461 + *
13462 + * @hcd: The HCD state structure for the DWC OTG controller.
13463 + * @qh: QH for the periodic transfer. The QH should already contain the
13464 + * scheduling information.
13465 + *
13466 + * Returns 0 if successful, negative error code otherwise.
13467 + */
13468 +static int schedule_periodic(struct dwc_otg_hcd *hcd, struct dwc_otg_qh *qh)
13469 +{
13470 + int status = 0;
13471 +
13472 + status = periodic_channel_available(hcd);
13473 + if (status) {
13474 + DWC_NOTICE("%s: No host channel available for periodic "
13475 + "transfer.\n", __func__);
13476 + return status;
13477 + }
13478 +
13479 + status = check_periodic_bandwidth(hcd, qh);
13480 + if (status) {
13481 + DWC_NOTICE("%s: Insufficient periodic bandwidth for "
13482 + "periodic transfer.\n", __func__);
13483 + return status;
13484 + }
13485 +
13486 + status = check_max_xfer_size(hcd, qh);
13487 + if (status) {
13488 + DWC_NOTICE("%s: Channel max transfer size too small "
13489 + "for periodic transfer.\n", __func__);
13490 + return status;
13491 + }
13492 +
13493 + /* Always start in the inactive schedule. */
13494 + list_add_tail(&qh->qh_list_entry, &hcd->periodic_sched_inactive);
13495 +
13496 + /* Reserve the periodic channel. */
13497 + hcd->periodic_channels++;
13498 +
13499 + /* Update claimed usecs per (micro)frame. */
13500 + hcd->periodic_usecs += qh->usecs;
13501 +
13502 + /*
13503 + * Update average periodic bandwidth claimed and # periodic
13504 + * reqs for usbfs.
13505 + */
13506 + hcd_to_bus(dwc_otg_hcd_to_hcd(hcd))->bandwidth_allocated +=
13507 + qh->usecs / qh->interval;
13508 + if (qh->ep_type == USB_ENDPOINT_XFER_INT) {
13509 + hcd_to_bus(dwc_otg_hcd_to_hcd(hcd))->bandwidth_int_reqs++;
13510 + DWC_DEBUGPL(DBG_HCD,
13511 + "Scheduled intr: qh %p, usecs %d, period %d\n", qh,
13512 + qh->usecs, qh->interval);
13513 + } else {
13514 + hcd_to_bus(dwc_otg_hcd_to_hcd(hcd))->bandwidth_isoc_reqs++;
13515 + DWC_DEBUGPL(DBG_HCD,
13516 + "Scheduled isoc: qh %p, usecs %d, period %d\n", qh,
13517 + qh->usecs, qh->interval);
13518 + }
13519 +
13520 + return status;
13521 +}
13522 +
13523 +/**
13524 + * This function adds a QH to either the non periodic or periodic schedule if
13525 + * it is not already in the schedule. If the QH is already in the schedule, no
13526 + * action is taken.
13527 + *
13528 + * Returns 0 if successful, negative error code otherwise.
13529 + */
13530 +int dwc_otg_hcd_qh_add(struct dwc_otg_hcd *hcd, struct dwc_otg_qh *qh)
13531 +{
13532 + int status = 0;
13533 +
13534 + if (!spin_is_locked(&hcd->global_lock)) {
13535 + pr_err("%s don't have hcd->global_lock", __func__);
13536 + BUG();
13537 + }
13538 +
13539 + if (!list_empty(&qh->qh_list_entry)) {
13540 + /* QH already in a schedule. */
13541 + goto done;
13542 + }
13543 +
13544 + /* Add the new QH to the appropriate schedule */
13545 + if (dwc_qh_is_non_per(qh)) {
13546 + /* Always start in the inactive schedule. */
13547 + list_add_tail(&qh->qh_list_entry,
13548 + &hcd->non_periodic_sched_inactive);
13549 + } else {
13550 + status = schedule_periodic(hcd, qh);
13551 + }
13552 +
13553 +done:
13554 + return status;
13555 +}
13556 +
13557 +/**
13558 + * Removes an interrupt or isochronous transfer from the periodic schedule.
13559 + *
13560 + * @hcd: The HCD state structure for the DWC OTG controller.
13561 + * @qh: QH for the periodic transfer.
13562 + */
13563 +static void deschedule_periodic(struct dwc_otg_hcd *hcd, struct dwc_otg_qh *qh)
13564 +{
13565 + list_del_init(&qh->qh_list_entry);
13566 +
13567 + /* Release the periodic channel reservation. */
13568 + hcd->periodic_channels--;
13569 +
13570 + /* Update claimed usecs per (micro)frame. */
13571 + hcd->periodic_usecs -= qh->usecs;
13572 +
13573 + /*
13574 + * Update average periodic bandwidth claimed and # periodic
13575 + * reqs for usbfs.
13576 + */
13577 + hcd_to_bus(dwc_otg_hcd_to_hcd(hcd))->bandwidth_allocated -=
13578 + qh->usecs / qh->interval;
13579 +
13580 + if (qh->ep_type == USB_ENDPOINT_XFER_INT) {
13581 + hcd_to_bus(dwc_otg_hcd_to_hcd(hcd))->bandwidth_int_reqs--;
13582 + DWC_DEBUGPL(DBG_HCD,
13583 + "Descheduled intr: qh %p, usecs %d, period %d\n",
13584 + qh, qh->usecs, qh->interval);
13585 + } else {
13586 + hcd_to_bus(dwc_otg_hcd_to_hcd(hcd))->bandwidth_isoc_reqs--;
13587 + DWC_DEBUGPL(DBG_HCD,
13588 + "Descheduled isoc: qh %p, usecs %d, period %d\n",
13589 + qh, qh->usecs, qh->interval);
13590 + }
13591 +}
13592 +
13593 +/**
13594 + * Removes a QH from either the non-periodic or periodic schedule. Memory is
13595 + * not freed.
13596 + *
13597 + * @hcd: The HCD state structure.
13598 + * @qh: QH to remove from schedule. */
13599 +void dwc_otg_hcd_qh_remove(struct dwc_otg_hcd *hcd, struct dwc_otg_qh *qh)
13600 +{
13601 + if (!spin_is_locked(&hcd->global_lock)) {
13602 + pr_err("%s don't have hcd->global_lock", __func__);
13603 + BUG();
13604 + }
13605 +
13606 + if (list_empty(&qh->qh_list_entry)) {
13607 + /* QH is not in a schedule. */
13608 + goto done;
13609 + }
13610 +
13611 + if (dwc_qh_is_non_per(qh)) {
13612 + if (hcd->non_periodic_qh_ptr == &qh->qh_list_entry) {
13613 + hcd->non_periodic_qh_ptr =
13614 + hcd->non_periodic_qh_ptr->next;
13615 + }
13616 + list_del_init(&qh->qh_list_entry);
13617 + } else {
13618 + deschedule_periodic(hcd, qh);
13619 + }
13620 +
13621 +done:
13622 + ;
13623 +}
13624 +
13625 +/**
13626 + * Deactivates a QH. For non-periodic QHs, removes the QH from the active
13627 + * non-periodic schedule. The QH is added to the inactive non-periodic
13628 + * schedule if any QTDs are still attached to the QH.
13629 + *
13630 + * For periodic QHs, the QH is removed from the periodic queued schedule. If
13631 + * there are any QTDs still attached to the QH, the QH is added to either the
13632 + * periodic inactive schedule or the periodic ready schedule and its next
13633 + * scheduled frame is calculated. The QH is placed in the ready schedule if
13634 + * the scheduled frame has been reached already. Otherwise it's placed in the
13635 + * inactive schedule. If there are no QTDs attached to the QH, the QH is
13636 + * completely removed from the periodic schedule.
13637 + */
13638 +void dwc_otg_hcd_qh_deactivate(struct dwc_otg_hcd *hcd, struct dwc_otg_qh *qh,
13639 + int sched_next_periodic_split)
13640 +{
13641 + uint16_t frame_number;
13642 +
13643 + if (!spin_is_locked(&hcd->global_lock)) {
13644 + pr_err("%s don't have hcd->global_lock", __func__);
13645 + BUG();
13646 + }
13647 +
13648 + if (dwc_qh_is_non_per(qh)) {
13649 + dwc_otg_hcd_qh_remove(hcd, qh);
13650 + if (!list_empty(&qh->qtd_list))
13651 + /* Add back to inactive non-periodic schedule. */
13652 + dwc_otg_hcd_qh_add(hcd, qh);
13653 + return;
13654 + }
13655 +
13656 + frame_number = dwc_otg_hcd_get_frame_number(dwc_otg_hcd_to_hcd(hcd));
13657 +
13658 + if (qh->do_split) {
13659 + /* Schedule the next continuing periodic split transfer */
13660 + if (sched_next_periodic_split) {
13661 +
13662 + qh->sched_frame = frame_number;
13663 + if (dwc_frame_num_le(frame_number,
13664 + dwc_frame_num_inc(qh->start_split_frame,
13665 + 1))) {
13666 + /*
13667 + * Allow one frame to elapse after
13668 + * start split microframe before
13669 + * scheduling complete split, but DONT
13670 + * if we are doing the next start
13671 + * split in the same frame for an ISOC
13672 + * out.
13673 + */
13674 + if ((qh->ep_type != USB_ENDPOINT_XFER_ISOC)
13675 + || (qh->ep_is_in != 0)) {
13676 + qh->sched_frame =
13677 + dwc_frame_num_inc(qh->sched_frame,
13678 + 1);
13679 + }
13680 + }
13681 + } else {
13682 + qh->sched_frame =
13683 + dwc_frame_num_inc(qh->start_split_frame,
13684 + qh->interval);
13685 + if (dwc_frame_num_le(qh->sched_frame, frame_number))
13686 + qh->sched_frame = frame_number;
13687 +
13688 + qh->sched_frame |= 0x7;
13689 + qh->start_split_frame = qh->sched_frame;
13690 + }
13691 + } else {
13692 + qh->sched_frame = dwc_frame_num_inc(qh->sched_frame,
13693 + qh->interval);
13694 + if (dwc_frame_num_le(qh->sched_frame, frame_number))
13695 + qh->sched_frame = frame_number;
13696 + }
13697 +
13698 + if (list_empty(&qh->qtd_list)) {
13699 + dwc_otg_hcd_qh_remove(hcd, qh);
13700 + } else {
13701 + /*
13702 + * Remove from periodic_sched_queued and move to
13703 + * appropriate queue.
13704 + */
13705 + if (qh->sched_frame == frame_number) {
13706 + list_move(&qh->qh_list_entry,
13707 + &hcd->periodic_sched_ready);
13708 + } else {
13709 + list_move(&qh->qh_list_entry,
13710 + &hcd->periodic_sched_inactive);
13711 + }
13712 + }
13713 +}
13714 +
13715 +/**
13716 + * This function allocates and initializes a QTD.
13717 + *
13718 + * @urb: The URB to create a QTD from. Each URB-QTD pair will end up
13719 + * pointing to each other so each pair should have a unique correlation.
13720 + *
13721 + * Returns Returns pointer to the newly allocated QTD, or NULL on error. */
13722 +struct dwc_otg_qtd *dwc_otg_hcd_qtd_create(struct urb *urb)
13723 +{
13724 + struct dwc_otg_qtd *qtd;
13725 +
13726 + qtd = dwc_otg_hcd_qtd_alloc();
13727 + if (qtd == NULL)
13728 + return NULL;
13729 +
13730 + dwc_otg_hcd_qtd_init(qtd, urb);
13731 + return qtd;
13732 +}
13733 +
13734 +/**
13735 + * Initializes a QTD structure.
13736 + *
13737 + * @qtd: The QTD to initialize.
13738 + * @urb: The URB to use for initialization.
13739 + */
13740 +void dwc_otg_hcd_qtd_init(struct dwc_otg_qtd *qtd, struct urb *urb)
13741 +{
13742 + memset(qtd, 0, sizeof(struct dwc_otg_qtd));
13743 + qtd->urb = urb;
13744 + if (usb_pipecontrol(urb->pipe)) {
13745 + /*
13746 + * The only time the QTD data toggle is used is on the data
13747 + * phase of control transfers. This phase always starts with
13748 + * DATA1.
13749 + */
13750 + qtd->data_toggle = DWC_OTG_HC_PID_DATA1;
13751 + qtd->control_phase = DWC_OTG_CONTROL_SETUP;
13752 + }
13753 +
13754 + /* start split */
13755 + qtd->complete_split = 0;
13756 + qtd->isoc_split_pos = DWC_HCSPLIT_XACTPOS_ALL;
13757 + qtd->isoc_split_offset = 0;
13758 +
13759 + /* Store the qtd ptr in the urb to reference what QTD. */
13760 + urb->hcpriv = qtd;
13761 + return;
13762 +}
13763 +
13764 +/**
13765 + * This function adds a QTD to the QTD-list of a QH. It will find the correct
13766 + * QH to place the QTD into. If it does not find a QH, then it will create a
13767 + * new QH. If the QH to which the QTD is added is not currently scheduled, it
13768 + * is placed into the proper schedule based on its EP type.
13769 + *
13770 + * @qtd: The QTD to add
13771 + * @dwc_otg_hcd: The DWC HCD structure
13772 + *
13773 + * Returns 0 if successful, negative error code otherwise.
13774 + */
13775 +int dwc_otg_hcd_qtd_add(struct dwc_otg_qtd *qtd,
13776 + struct dwc_otg_hcd *dwc_otg_hcd)
13777 +{
13778 + struct usb_host_endpoint *ep;
13779 + struct dwc_otg_qh *qh;
13780 + int retval = 0;
13781 +
13782 + struct urb *urb = qtd->urb;
13783 +
13784 + /*
13785 + * Get the QH which holds the QTD-list to insert to. Create QH if it
13786 + * doesn't exist.
13787 + */
13788 + ep = dwc_urb_to_endpoint(urb);
13789 + qh = ep->hcpriv;
13790 + if (qh == NULL) {
13791 + qh = dwc_otg_hcd_qh_create(dwc_otg_hcd, urb);
13792 + if (qh == NULL) {
13793 + retval = -ENOMEM;
13794 + goto done;
13795 + }
13796 + ep->hcpriv = qh;
13797 + }
13798 + qtd->qh = qh;
13799 + retval = dwc_otg_hcd_qh_add(dwc_otg_hcd, qh);
13800 + if (retval == 0)
13801 + list_add_tail(&qtd->qtd_list_entry, &qh->qtd_list);
13802 +done:
13803 + return retval;
13804 +}
13805 +
13806 +#endif /* DWC_DEVICE_ONLY */
13807 diff --git a/drivers/usb/host/dwc_otg/dwc_otg_octeon.c b/drivers/usb/host/dwc_otg/dwc_otg_octeon.c
13808 new file mode 100644
13809 index 0000000..5e92b3c
13810 --- /dev/null
13811 +++ b/drivers/usb/host/dwc_otg/dwc_otg_octeon.c
13812 @@ -0,0 +1,1078 @@
13813 +/* ==========================================================================
13814 + * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
13815 + * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
13816 + * otherwise expressly agreed to in writing between Synopsys and you.
13817 + *
13818 + * The Software IS NOT an item of Licensed Software or Licensed Product under
13819 + * any End User Software License Agreement or Agreement for Licensed Product
13820 + * with Synopsys or any supplement thereto. You are permitted to use and
13821 + * redistribute this Software in source and binary forms, with or without
13822 + * modification, provided that redistributions of source code must retain this
13823 + * notice. You may not view, use, disclose, copy or distribute this file or
13824 + * any information contained herein except pursuant to this license grant from
13825 + * Synopsys. If you do not agree with this notice, including the disclaimer
13826 + * below, then you are not authorized to use the Software.
13827 + *
13828 + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
13829 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
13830 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
13831 + * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
13832 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
13833 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
13834 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
13835 + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
13836 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
13837 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
13838 + * DAMAGE.
13839 + * ========================================================================== */
13840 +
13841 +#include <linux/kernel.h>
13842 +#include <linux/module.h>
13843 +#include <linux/moduleparam.h>
13844 +#include <linux/init.h>
13845 +#include <linux/device.h>
13846 +#include <linux/errno.h>
13847 +#include <linux/types.h>
13848 +#include <linux/stat.h> /* permission constants */
13849 +#include <linux/platform_device.h>
13850 +#include <linux/io.h>
13851 +
13852 +#include "dwc_otg_plat.h"
13853 +#include "dwc_otg_attr.h"
13854 +#include "dwc_otg_driver.h"
13855 +#include "dwc_otg_cil.h"
13856 +#ifndef DWC_HOST_ONLY
13857 +#include "dwc_otg_pcd.h"
13858 +#endif
13859 +#include "dwc_otg_hcd.h"
13860 +
13861 +#define DWC_DRIVER_VERSION "2.40a 10-APR-2006"
13862 +#define DWC_DRIVER_DESC "HS OTG USB Controller driver"
13863 +
13864 +static const char dwc_driver_name[] = "dwc_otg";
13865 +int dwc_errata_write_count; /* See dwc_otg_plat.h, dwc_write_reg32 */
13866 +
13867 +/*-------------------------------------------------------------------------*/
13868 +/* Encapsulate the module parameter settings */
13869 +
13870 +static struct dwc_otg_core_params dwc_otg_module_params = {
13871 + .opt = -1,
13872 + .otg_cap = -1,
13873 + .dma_enable = -1,
13874 + .dma_burst_size = -1,
13875 + .speed = -1,
13876 + .host_support_fs_ls_low_power = -1,
13877 + .host_ls_low_power_phy_clk = -1,
13878 + .enable_dynamic_fifo = -1,
13879 + .data_fifo_size = -1,
13880 + .dev_rx_fifo_size = -1,
13881 + .dev_nperio_tx_fifo_size = -1,
13882 + .dev_perio_tx_fifo_size = {-1, /* dev_perio_tx_fifo_size_1 */
13883 + -1,
13884 + -1,
13885 + -1,
13886 + -1,
13887 + -1,
13888 + -1,
13889 + -1,
13890 + -1,
13891 + -1,
13892 + -1,
13893 + -1,
13894 + -1,
13895 + -1,
13896 + -1}, /* 15 */
13897 + .host_rx_fifo_size = -1,
13898 + .host_nperio_tx_fifo_size = -1,
13899 + .host_perio_tx_fifo_size = -1,
13900 + .max_transfer_size = -1,
13901 + .max_packet_count = -1,
13902 + .host_channels = -1,
13903 + .dev_endpoints = -1,
13904 + .phy_type = -1,
13905 + .phy_utmi_width = -1,
13906 + .phy_ulpi_ddr = -1,
13907 + .phy_ulpi_ext_vbus = -1,
13908 + .i2c_enable = -1,
13909 + .ulpi_fs_ls = -1,
13910 + .ts_dline = -1,
13911 +};
13912 +
13913 +/**
13914 + * Global Debug Level Mask.
13915 + */
13916 +uint32_t g_dbg_lvl; /* 0 -> OFF */
13917 +
13918 +/**
13919 + * This function shows the Driver Version.
13920 + */
13921 +static ssize_t version_show(struct device_driver *dev, char *buf)
13922 +{
13923 + return snprintf(buf, sizeof(DWC_DRIVER_VERSION) + 2, "%s\n",
13924 + DWC_DRIVER_VERSION);
13925 +}
13926 +
13927 +static DRIVER_ATTR(version, S_IRUGO, version_show, NULL);
13928 +
13929 +/**
13930 + * This function is called during module intialization to verify that
13931 + * the module parameters are in a valid state.
13932 + */
13933 +static int check_parameters(struct dwc_otg_core_if *core_if)
13934 +{
13935 + int i;
13936 + int retval = 0;
13937 +
13938 +/* Checks if the parameter is outside of its valid range of values */
13939 +#define DWC_OTG_PARAM_TEST(_param_, _low_, _high_) \
13940 + ((dwc_otg_module_params._param_ < (_low_)) || \
13941 + (dwc_otg_module_params._param_ > (_high_)))
13942 +
13943 +/* If the parameter has been set by the user, check that the parameter value is
13944 + * within the value range of values. If not, report a module error. */
13945 +#define DWC_OTG_PARAM_ERR(_param_, _low_, _high_, _string_) \
13946 + do { \
13947 + if (dwc_otg_module_params._param_ != -1) { \
13948 + if (DWC_OTG_PARAM_TEST(_param_, (_low_), (_high_))) { \
13949 + DWC_ERROR("`%d' invalid for parameter `%s'\n", \
13950 + dwc_otg_module_params._param_, _string_); \
13951 + dwc_otg_module_params._param_ = dwc_param_##_param_##_default; \
13952 + retval++; \
13953 + } \
13954 + } \
13955 + } while (0)
13956 +
13957 + DWC_OTG_PARAM_ERR(opt, 0, 1, "opt");
13958 + DWC_OTG_PARAM_ERR(otg_cap, 0, 2, "otg_cap");
13959 + DWC_OTG_PARAM_ERR(dma_enable, 0, 1, "dma_enable");
13960 + DWC_OTG_PARAM_ERR(speed, 0, 1, "speed");
13961 + DWC_OTG_PARAM_ERR(host_support_fs_ls_low_power, 0, 1,
13962 + "host_support_fs_ls_low_power");
13963 + DWC_OTG_PARAM_ERR(host_ls_low_power_phy_clk, 0, 1,
13964 + "host_ls_low_power_phy_clk");
13965 + DWC_OTG_PARAM_ERR(enable_dynamic_fifo, 0, 1, "enable_dynamic_fifo");
13966 + DWC_OTG_PARAM_ERR(data_fifo_size, 32, 32768, "data_fifo_size");
13967 + DWC_OTG_PARAM_ERR(dev_rx_fifo_size, 16, 32768, "dev_rx_fifo_size");
13968 + DWC_OTG_PARAM_ERR(dev_nperio_tx_fifo_size, 16, 32768,
13969 + "dev_nperio_tx_fifo_size");
13970 + DWC_OTG_PARAM_ERR(host_rx_fifo_size, 16, 32768, "host_rx_fifo_size");
13971 + DWC_OTG_PARAM_ERR(host_nperio_tx_fifo_size, 16, 32768,
13972 + "host_nperio_tx_fifo_size");
13973 + DWC_OTG_PARAM_ERR(host_perio_tx_fifo_size, 16, 32768,
13974 + "host_perio_tx_fifo_size");
13975 + DWC_OTG_PARAM_ERR(max_transfer_size, 2047, 524288, "max_transfer_size");
13976 + DWC_OTG_PARAM_ERR(max_packet_count, 15, 511, "max_packet_count");
13977 + DWC_OTG_PARAM_ERR(host_channels, 1, 16, "host_channels");
13978 + DWC_OTG_PARAM_ERR(dev_endpoints, 1, 15, "dev_endpoints");
13979 + DWC_OTG_PARAM_ERR(phy_type, 0, 2, "phy_type");
13980 + DWC_OTG_PARAM_ERR(phy_ulpi_ddr, 0, 1, "phy_ulpi_ddr");
13981 + DWC_OTG_PARAM_ERR(phy_ulpi_ext_vbus, 0, 1, "phy_ulpi_ext_vbus");
13982 + DWC_OTG_PARAM_ERR(i2c_enable, 0, 1, "i2c_enable");
13983 + DWC_OTG_PARAM_ERR(ulpi_fs_ls, 0, 1, "ulpi_fs_ls");
13984 + DWC_OTG_PARAM_ERR(ts_dline, 0, 1, "ts_dline");
13985 +
13986 + if (dwc_otg_module_params.dma_burst_size != -1) {
13987 + if (DWC_OTG_PARAM_TEST(dma_burst_size, 1, 1) &&
13988 + DWC_OTG_PARAM_TEST(dma_burst_size, 4, 4) &&
13989 + DWC_OTG_PARAM_TEST(dma_burst_size, 8, 8) &&
13990 + DWC_OTG_PARAM_TEST(dma_burst_size, 16, 16) &&
13991 + DWC_OTG_PARAM_TEST(dma_burst_size, 32, 32) &&
13992 + DWC_OTG_PARAM_TEST(dma_burst_size, 64, 64) &&
13993 + DWC_OTG_PARAM_TEST(dma_burst_size, 128, 128) &&
13994 + DWC_OTG_PARAM_TEST(dma_burst_size, 256, 256)) {
13995 + DWC_ERROR
13996 + ("`%d' invalid for parameter `dma_burst_size'\n",
13997 + dwc_otg_module_params.dma_burst_size);
13998 + dwc_otg_module_params.dma_burst_size = 32;
13999 + retval++;
14000 + }
14001 + }
14002 +
14003 + if (dwc_otg_module_params.phy_utmi_width != -1) {
14004 + if (DWC_OTG_PARAM_TEST(phy_utmi_width, 8, 8) &&
14005 + DWC_OTG_PARAM_TEST(phy_utmi_width, 16, 16)) {
14006 + DWC_ERROR
14007 + ("`%d' invalid for parameter `phy_utmi_width'\n",
14008 + dwc_otg_module_params.phy_utmi_width);
14009 + dwc_otg_module_params.phy_utmi_width = 16;
14010 + retval++;
14011 + }
14012 + }
14013 +
14014 + for (i = 0; i < 15; i++) {
14015 + /* @todo should be like above */
14016 + if (dwc_otg_module_params.dev_perio_tx_fifo_size[i] !=
14017 + (unsigned)-1) {
14018 + if (DWC_OTG_PARAM_TEST
14019 + (dev_perio_tx_fifo_size[i], 4, 768)) {
14020 + DWC_ERROR
14021 + ("`%d' invalid for parameter `%s_%d'\n",
14022 + dwc_otg_module_params.
14023 + dev_perio_tx_fifo_size[i],
14024 + "dev_perio_tx_fifo_size", i);
14025 + dwc_otg_module_params.
14026 + dev_perio_tx_fifo_size[i] =
14027 + dwc_param_dev_perio_tx_fifo_size_default;
14028 + retval++;
14029 + }
14030 + }
14031 + }
14032 +
14033 + /* At this point, all module parameters that have been set by the user
14034 + * are valid, and those that have not are left unset. Now set their
14035 + * default values and/or check the parameters against the hardware
14036 + * configurations of the OTG core. */
14037 +
14038 +/* This sets the parameter to the default value if it has not been set by the
14039 + * user */
14040 +#define PARAM_SET_DEFAULT(_param_) \
14041 + ({ \
14042 + int changed = 1; \
14043 + if (dwc_otg_module_params._param_ == -1) { \
14044 + changed = 0; \
14045 + dwc_otg_module_params._param_ = dwc_param_##_param_##_default; \
14046 + } \
14047 + changed; \
14048 + })
14049 +
14050 +/* This checks the macro agains the hardware configuration to see if it is
14051 + * valid. It is possible that the default value could be invalid. In this
14052 + * case, it will report a module error if the user touched the parameter.
14053 + * Otherwise it will adjust the value without any error. */
14054 +#define PARAM_CHECK_VALID(_param_, _str_, _is_valid_, _set_valid_) \
14055 + ({ \
14056 + int changed = PARAM_SET_DEFAULT(_param_); \
14057 + int error = 0; \
14058 + if (!(_is_valid_)) { \
14059 + if (changed) { \
14060 + DWC_ERROR("`%d' invalid for parameter `%s'. Check HW configuration.\n", dwc_otg_module_params._param_, _str_); \
14061 + error = 1; \
14062 + } \
14063 + dwc_otg_module_params._param_ = (_set_valid_); \
14064 + } \
14065 + error; \
14066 + })
14067 +
14068 + /* OTG Cap */
14069 + retval += PARAM_CHECK_VALID(otg_cap, "otg_cap",
14070 + ({
14071 + int valid;
14072 + valid = 1;
14073 + switch (dwc_otg_module_params.otg_cap) {
14074 + case DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE:
14075 + if (core_if->hwcfg2.b.op_mode != DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
14076 + valid = 0;
14077 + break;
14078 + case DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE:
14079 + if ((core_if->hwcfg2.b.op_mode != DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
14080 + && (core_if->hwcfg2.b.op_mode != DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG)
14081 + && (core_if->hwcfg2.b.op_mode != DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE)
14082 + && (core_if->hwcfg2.b.op_mode != DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST))
14083 + valid = 0;
14084 + break;
14085 + case DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE:
14086 + /* always valid */
14087 + break;
14088 + }
14089 + valid;
14090 + }),
14091 + (((core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
14092 + || (core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG)
14093 + || (core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE)
14094 + || (core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST))
14095 + ?
14096 + DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE : DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE));
14097 +
14098 + retval += PARAM_CHECK_VALID(dma_enable, "dma_enable",
14099 + ((dwc_otg_module_params.
14100 + dma_enable == 1)
14101 + && (core_if->hwcfg2.b.
14102 + architecture == 0)) ? 0 : 1,
14103 + 0);
14104 +
14105 + retval += PARAM_CHECK_VALID(opt, "opt", 1, 0);
14106 +
14107 + PARAM_SET_DEFAULT(dma_burst_size);
14108 +
14109 + retval += PARAM_CHECK_VALID(host_support_fs_ls_low_power,
14110 + "host_support_fs_ls_low_power",
14111 + 1, 0);
14112 +
14113 + retval += PARAM_CHECK_VALID(enable_dynamic_fifo,
14114 + "enable_dynamic_fifo",
14115 + ((dwc_otg_module_params.enable_dynamic_fifo == 0)
14116 + || (core_if->hwcfg2.b.dynamic_fifo == 1)), 0);
14117 +
14118 + retval += PARAM_CHECK_VALID(data_fifo_size,
14119 + "data_fifo_size",
14120 + dwc_otg_module_params.data_fifo_size <= core_if->hwcfg3.b.dfifo_depth,
14121 + core_if->hwcfg3.b.dfifo_depth);
14122 +
14123 + retval += PARAM_CHECK_VALID(dev_rx_fifo_size,
14124 + "dev_rx_fifo_size",
14125 + (dwc_otg_module_params.dev_rx_fifo_size <=
14126 + dwc_read_reg32(&core_if->core_global_regs->grxfsiz)),
14127 + dwc_read_reg32(&core_if->core_global_regs->grxfsiz));
14128 +
14129 + retval += PARAM_CHECK_VALID(dev_nperio_tx_fifo_size,
14130 + "dev_nperio_tx_fifo_size",
14131 + dwc_otg_module_params.dev_nperio_tx_fifo_size <=
14132 + (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16),
14133 + dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16);
14134 +
14135 + retval += PARAM_CHECK_VALID(host_rx_fifo_size,
14136 + "host_rx_fifo_size",
14137 + dwc_otg_module_params.host_rx_fifo_size <=
14138 + dwc_read_reg32(&core_if->core_global_regs->grxfsiz),
14139 + dwc_read_reg32(&core_if->core_global_regs->grxfsiz));
14140 +
14141 + retval += PARAM_CHECK_VALID(host_nperio_tx_fifo_size,
14142 + "host_nperio_tx_fifo_size",
14143 + dwc_otg_module_params.host_nperio_tx_fifo_size <=
14144 + (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16),
14145 + dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16);
14146 +
14147 + retval += PARAM_CHECK_VALID(host_perio_tx_fifo_size,
14148 + "host_perio_tx_fifo_size",
14149 + dwc_otg_module_params.host_perio_tx_fifo_size <=
14150 + (dwc_read_reg32(&core_if->core_global_regs->hptxfsiz) >> 16),
14151 + (dwc_read_reg32(&core_if->core_global_regs->hptxfsiz) >> 16));
14152 +
14153 + retval += PARAM_CHECK_VALID(max_transfer_size,
14154 + "max_transfer_size",
14155 + dwc_otg_module_params.max_transfer_size <
14156 + (1 << (core_if->hwcfg3.b.xfer_size_cntr_width + 11)),
14157 + (1 << (core_if->hwcfg3.b.xfer_size_cntr_width + 11)) - 1);
14158 +
14159 + retval += PARAM_CHECK_VALID(max_packet_count,
14160 + "max_packet_count",
14161 + dwc_otg_module_params.max_packet_count <
14162 + (1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4)),
14163 + (1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4)) - 1);
14164 +
14165 + retval += PARAM_CHECK_VALID(host_channels,
14166 + "host_channels",
14167 + dwc_otg_module_params.host_channels <= (core_if->hwcfg2.b.num_host_chan + 1),
14168 + core_if->hwcfg2.b.num_host_chan + 1);
14169 +
14170 + retval += PARAM_CHECK_VALID(dev_endpoints,
14171 + "dev_endpoints",
14172 + dwc_otg_module_params.dev_endpoints <= core_if->hwcfg2.b.num_dev_ep,
14173 + core_if->hwcfg2.b.num_dev_ep);
14174 +
14175 +/*
14176 + * Define the following to disable the FS PHY Hardware checking. This is for
14177 + * internal testing only.
14178 + *
14179 + * #define NO_FS_PHY_HW_CHECKS
14180 + */
14181 +
14182 +#ifdef NO_FS_PHY_HW_CHECKS
14183 + retval += PARAM_CHECK_VALID(phy_type, "phy_type", 1, 0);
14184 +#else
14185 + retval += PARAM_CHECK_VALID(phy_type, "phy_type",
14186 + ({
14187 + int valid = 0;
14188 + if ((dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_UTMI) && ((core_if->hwcfg2.b.hs_phy_type == 1) || (core_if->hwcfg2.b.hs_phy_type == 3)))
14189 + valid = 1;
14190 + else if ((dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_ULPI) && ((core_if->hwcfg2.b.hs_phy_type == 2) || (core_if->hwcfg2.b.hs_phy_type == 3)))
14191 + valid = 1;
14192 + else if ((dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_FS) && (core_if->hwcfg2.b.fs_phy_type == 1))
14193 + valid = 1;
14194 + valid;
14195 + }),
14196 + ({
14197 + int set = DWC_PHY_TYPE_PARAM_FS;
14198 + if (core_if->hwcfg2.b.hs_phy_type) {
14199 + if ((core_if->hwcfg2.b.hs_phy_type == 3)
14200 + || (core_if->hwcfg2.b.hs_phy_type == 1))
14201 + set = DWC_PHY_TYPE_PARAM_UTMI;
14202 + else
14203 + set = DWC_PHY_TYPE_PARAM_ULPI;
14204 + }
14205 + set;
14206 + }));
14207 +#endif
14208 +
14209 + retval += PARAM_CHECK_VALID(speed, "speed",
14210 + dwc_otg_module_params.speed == 0
14211 + && (dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_FS) ? 0 : 1,
14212 + dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_FS ? 1 : 0);
14213 +
14214 + retval += PARAM_CHECK_VALID(host_ls_low_power_phy_clk,
14215 + "host_ls_low_power_phy_clk",
14216 + dwc_otg_module_params.host_ls_low_power_phy_clk == DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ
14217 + && (dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_FS) ? 0 : 1,
14218 + (dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_FS) ?
14219 + DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ : DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ);
14220 +
14221 + PARAM_SET_DEFAULT(phy_ulpi_ddr);
14222 + PARAM_SET_DEFAULT(phy_ulpi_ext_vbus);
14223 + PARAM_SET_DEFAULT(phy_utmi_width);
14224 + PARAM_SET_DEFAULT(ulpi_fs_ls);
14225 + PARAM_SET_DEFAULT(ts_dline);
14226 +
14227 +#ifdef NO_FS_PHY_HW_CHECKS
14228 + retval += PARAM_CHECK_VALID(i2c_enable, "i2c_enable", 1, 0);
14229 +#else
14230 + retval += PARAM_CHECK_VALID(i2c_enable, "i2c_enable",
14231 + dwc_otg_module_params.i2c_enable == 1
14232 + && (core_if->hwcfg3.b.i2c == 0) ? 0 : 1, 0);
14233 +#endif
14234 +
14235 + for (i = 0; i < 15; i++) {
14236 +
14237 + int changed = 1;
14238 + int error = 0;
14239 +
14240 + if (dwc_otg_module_params.dev_perio_tx_fifo_size[i] == -1) {
14241 + changed = 0;
14242 + dwc_otg_module_params.dev_perio_tx_fifo_size[i] =
14243 + dwc_param_dev_perio_tx_fifo_size_default;
14244 + }
14245 + if (!
14246 + (dwc_otg_module_params.dev_perio_tx_fifo_size[i] <=
14247 + (dwc_read_reg32(&core_if->core_global_regs->dptxfsiz[i])))) {
14248 + if (changed) {
14249 + DWC_ERROR("`%d' invalid for parameter "
14250 + "`dev_perio_fifo_size_%d'. "
14251 + "Check HW configuration.\n",
14252 + dwc_otg_module_params.
14253 + dev_perio_tx_fifo_size[i], i);
14254 + error = 1;
14255 + }
14256 + dwc_otg_module_params.dev_perio_tx_fifo_size[i] =
14257 + dwc_read_reg32(&core_if->core_global_regs->
14258 + dptxfsiz[i]);
14259 + }
14260 + retval += error;
14261 + }
14262 +
14263 + return retval;
14264 +}
14265 +
14266 +/**
14267 + * This function is the top level interrupt handler for the Common
14268 + * (Device and host modes) interrupts.
14269 + */
14270 +static irqreturn_t dwc_otg_common_irq(int _irq, void *_dev)
14271 +{
14272 + struct dwc_otg_device *otg_dev = _dev;
14273 + int32_t retval = IRQ_NONE;
14274 + unsigned long flags;
14275 +
14276 + spin_lock_irqsave(&otg_dev->hcd->global_lock, flags);
14277 +
14278 + retval = dwc_otg_handle_common_intr(otg_dev->core_if);
14279 +
14280 + spin_unlock_irqrestore(&otg_dev->hcd->global_lock, flags);
14281 +
14282 + return IRQ_RETVAL(retval);
14283 +}
14284 +
14285 +/**
14286 + * This function is called when a device is unregistered with the
14287 + * dwc_otg_driver. This happens, for example, when the rmmod command is
14288 + * executed. The device may or may not be electrically present. If it is
14289 + * present, the driver stops device processing. Any resources used on behalf
14290 + * of this device are freed.
14291 + *
14292 + * @dev:
14293 + */
14294 +static int dwc_otg_driver_remove(struct platform_device *pdev)
14295 +{
14296 + struct device *dev = &pdev->dev;
14297 + struct dwc_otg_device *otg_dev = dev->platform_data;
14298 + DWC_DEBUGPL(DBG_ANY, "%s(%p)\n", __func__, dev);
14299 +
14300 + if (otg_dev == NULL)
14301 + /* Memory allocation for the dwc_otg_device failed. */
14302 + return -ENOMEM;
14303 +
14304 + /*
14305 + * Free the IRQ
14306 + */
14307 + if (otg_dev->common_irq_installed)
14308 + free_irq(platform_get_irq(to_platform_device(dev), 0), otg_dev);
14309 +
14310 +#ifndef DWC_DEVICE_ONLY
14311 + if (otg_dev->hcd != NULL)
14312 + dwc_otg_hcd_remove(dev);
14313 +#endif
14314 +
14315 +#ifndef DWC_HOST_ONLY
14316 + if (otg_dev->pcd != NULL)
14317 + dwc_otg_pcd_remove(dev);
14318 +#endif
14319 + if (otg_dev->core_if != NULL)
14320 + dwc_otg_cil_remove(otg_dev->core_if);
14321 +
14322 + /*
14323 + * Remove the device attributes
14324 + */
14325 + dwc_otg_attr_remove(dev);
14326 +
14327 + /*
14328 + * Clear the platform_data pointer.
14329 + */
14330 + dev->platform_data = 0;
14331 + return 0;
14332 +}
14333 +
14334 +/**
14335 + * This function is called when an device is bound to a
14336 + * dwc_otg_driver. It creates the driver components required to
14337 + * control the device (CIL, HCD, and PCD) and it initializes the
14338 + * device. The driver components are stored in a dwc_otg_device
14339 + * structure. A reference to the dwc_otg_device is saved in the
14340 + * device. This allows the driver to access the dwc_otg_device
14341 + * structure on subsequent calls to driver methods for this device.
14342 + *
14343 + * @dev: device definition
14344 + */
14345 +static __devinit int dwc_otg_driver_probe(struct platform_device *pdev)
14346 +{
14347 + struct resource *res_base;
14348 + struct device *dev = &pdev->dev;
14349 + struct dwc_otg_device *dwc_otg_device;
14350 + int32_t snpsid;
14351 + unsigned long flags;
14352 + int irq;
14353 + int retval;
14354 +
14355 + dev_dbg(dev, "dwc_otg_driver_probe(%p)\n", dev);
14356 +
14357 + dwc_otg_device = devm_kzalloc(&pdev->dev,
14358 + sizeof(struct dwc_otg_device),
14359 + GFP_KERNEL);
14360 + if (!dwc_otg_device) {
14361 + dev_err(dev, "kmalloc of dwc_otg_device failed\n");
14362 + return -ENOMEM;
14363 + }
14364 + dwc_otg_device->reg_offset = 0xFFFFFFFF;
14365 +
14366 + /*
14367 + * Map the DWC_otg Core memory into virtual address space.
14368 + */
14369 + res_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
14370 + if (!res_base)
14371 + goto err_ports;
14372 +
14373 + dwc_otg_device->base =
14374 + devm_ioremap_nocache(&pdev->dev,
14375 + res_base->start,
14376 + res_base->end - res_base->start);
14377 +
14378 + if (!dwc_otg_device->base)
14379 + goto err_ports;
14380 +
14381 + dev_dbg(dev, "base=%p\n", dwc_otg_device->base);
14382 +
14383 + /*
14384 + * Attempt to ensure this device is really a DWC_otg Controller.
14385 + * Read and verify the SNPSID register contents. The value should be
14386 + * 0x45F42XXX, which corresponds to "OT2", as in "OTG version 2.XX".
14387 + */
14388 + snpsid =
14389 + dwc_read_reg32((uint32_t *) ((uint8_t *) dwc_otg_device->base +
14390 + 0x40));
14391 + if ((snpsid & 0xFFFFF000) != 0x4F542000) {
14392 + dev_err(dev, "Bad value for SNPSID: 0x%08x\n", snpsid);
14393 + goto err_ports;
14394 + }
14395 +
14396 + /*
14397 + * Initialize driver data to point to the global DWC_otg
14398 + * Device structure.
14399 + */
14400 + dev->platform_data = dwc_otg_device;
14401 + dev_dbg(dev, "dwc_otg_device=0x%p\n", dwc_otg_device);
14402 +
14403 + dwc_otg_device->core_if = dwc_otg_cil_init(dwc_otg_device->base,
14404 + &dwc_otg_module_params);
14405 + if (dwc_otg_device->core_if == 0) {
14406 + dev_err(dev, "CIL initialization failed!\n");
14407 + goto err_ports;
14408 + }
14409 + dwc_otg_device->core_if->usb_num = to_platform_device(dev)->id;
14410 +
14411 + /*
14412 + * Validate parameter values.
14413 + */
14414 + if (check_parameters(dwc_otg_device->core_if) != 0)
14415 + goto err_ports;
14416 +
14417 + /*
14418 + * Create Device Attributes in sysfs
14419 + */
14420 + dwc_otg_attr_create(dev);
14421 +
14422 + /*
14423 + * Disable the global interrupt until all the interrupt
14424 + * handlers are installed.
14425 + */
14426 + dwc_otg_disable_global_interrupts(dwc_otg_device->core_if);
14427 + /*
14428 + * Install the interrupt handler for the common interrupts before
14429 + * enabling common interrupts in core_init below.
14430 + */
14431 + irq = platform_get_irq(to_platform_device(dev), 0);
14432 + DWC_DEBUGPL(DBG_CIL, "registering (common) handler for irq%d\n", irq);
14433 + retval = request_irq(irq, dwc_otg_common_irq,
14434 + IRQF_SHARED, "dwc_otg", dwc_otg_device);
14435 + if (retval != 0) {
14436 + DWC_ERROR("request of irq%d failed\n", irq);
14437 + goto err_ports;
14438 + } else {
14439 + dwc_otg_device->common_irq_installed = 1;
14440 + }
14441 +
14442 + /*
14443 + * Initialize the DWC_otg core.
14444 + */
14445 + dwc_otg_core_init(dwc_otg_device->core_if);
14446 +
14447 +#ifndef DWC_HOST_ONLY
14448 + /*
14449 + * Initialize the PCD
14450 + */
14451 + retval = dwc_otg_pcd_init(dev);
14452 + if (retval != 0) {
14453 + DWC_ERROR("dwc_otg_pcd_init failed\n");
14454 + dwc_otg_device->pcd = NULL;
14455 + goto err_ports;
14456 + }
14457 +#endif
14458 +#ifndef DWC_DEVICE_ONLY
14459 + /*
14460 + * Initialize the HCD
14461 + */
14462 + retval = dwc_otg_hcd_init(dev);
14463 + if (retval != 0) {
14464 + DWC_ERROR("dwc_otg_hcd_init failed\n");
14465 + dwc_otg_device->hcd = NULL;
14466 + goto err_ports;
14467 + }
14468 +#endif
14469 +
14470 + /*
14471 + * Enable the global interrupt after all the interrupt
14472 + * handlers are installed.
14473 + */
14474 + local_irq_save(flags);
14475 + dwc_otg_enable_global_interrupts(dwc_otg_device->core_if);
14476 + local_irq_restore(flags);
14477 +
14478 + return 0;
14479 +
14480 +err_ports:
14481 + devm_kfree(&pdev->dev, dwc_otg_device);
14482 + return -ENOENT;
14483 +}
14484 +
14485 +/**
14486 + * This structure defines the methods to be called by a bus driver
14487 + * during the lifecycle of a device on that bus. Both drivers and
14488 + * devices are registered with a bus driver. The bus driver matches
14489 + * devices to drivers based on information in the device and driver
14490 + * structures.
14491 + *
14492 + * The probe function is called when the bus driver matches a device
14493 + * to this driver. The remove function is called when a device is
14494 + * unregistered with the bus driver.
14495 + */
14496 +static struct platform_driver dwc_otg_driver = {
14497 + .probe = dwc_otg_driver_probe,
14498 + .remove = dwc_otg_driver_remove,
14499 + .driver = {
14500 + .name = dwc_driver_name,
14501 + .owner = THIS_MODULE},
14502 +};
14503 +
14504 +/**
14505 + * This function is called when the dwc_otg_driver is installed with the
14506 + * insmod command. It registers the dwc_otg_driver structure with the
14507 + * appropriate bus driver. This will cause the dwc_otg_driver_probe function
14508 + * to be called. In addition, the bus driver will automatically expose
14509 + * attributes defined for the device and driver in the special sysfs file
14510 + * system.
14511 + *
14512 + * Returns
14513 + */
14514 +static int __init dwc_otg_driver_init(void)
14515 +{
14516 + int retval;
14517 +
14518 + pr_info("%s: version %s\n", dwc_driver_name, DWC_DRIVER_VERSION);
14519 +
14520 + /* Though core was configured for external dma override that with slave
14521 + mode only for CN31XX. DMA is broken in this chip */
14522 + if (OCTEON_IS_MODEL(OCTEON_CN31XX))
14523 + dwc_otg_module_params.dma_enable = 0;
14524 +
14525 + retval = platform_driver_register(&dwc_otg_driver);
14526 +
14527 + if (retval < 0) {
14528 + pr_err("%s retval=%d\n", __func__, retval);
14529 + return retval;
14530 + }
14531 + if (driver_create_file(&dwc_otg_driver.driver, &driver_attr_version))
14532 + pr_warning("DWC_OTG: Failed to create driver version file\n");
14533 +
14534 + return retval;
14535 +}
14536 +module_init(dwc_otg_driver_init);
14537 +
14538 +/**
14539 + * This function is called when the driver is removed from the kernel
14540 + * with the rmmod command. The driver unregisters itself with its bus
14541 + * driver.
14542 + *
14543 + */
14544 +static void __exit dwc_otg_driver_cleanup(void)
14545 +{
14546 + printk(KERN_DEBUG "dwc_otg_driver_cleanup()\n");
14547 +
14548 + driver_remove_file(&dwc_otg_driver.driver, &driver_attr_version);
14549 +
14550 + platform_driver_unregister(&dwc_otg_driver);
14551 +
14552 + printk(KERN_INFO "%s module removed\n", dwc_driver_name);
14553 +}
14554 +module_exit(dwc_otg_driver_cleanup);
14555 +
14556 +MODULE_DESCRIPTION(DWC_DRIVER_DESC);
14557 +MODULE_AUTHOR("Synopsys Inc.");
14558 +MODULE_LICENSE("GPL");
14559 +
14560 +module_param_named(otg_cap, dwc_otg_module_params.otg_cap, int, 0444);
14561 +MODULE_PARM_DESC(otg_cap, "OTG Capabilities 0=HNP&SRP 1=SRP Only 2=None");
14562 +module_param_named(opt, dwc_otg_module_params.opt, int, 0444);
14563 +MODULE_PARM_DESC(opt, "OPT Mode");
14564 +module_param_named(dma_enable, dwc_otg_module_params.dma_enable, int, 0444);
14565 +MODULE_PARM_DESC(dma_enable, "DMA Mode 0=Slave 1=DMA enabled");
14566 +module_param_named(dma_burst_size, dwc_otg_module_params.dma_burst_size, int,
14567 + 0444);
14568 +MODULE_PARM_DESC(dma_burst_size,
14569 + "DMA Burst Size 1, 4, 8, 16, 32, 64, 128, 256");
14570 +module_param_named(speed, dwc_otg_module_params.speed, int, 0444);
14571 +MODULE_PARM_DESC(speed, "Speed 0=High Speed 1=Full Speed");
14572 +module_param_named(host_support_fs_ls_low_power,
14573 + dwc_otg_module_params.host_support_fs_ls_low_power, int,
14574 + 0444);
14575 +MODULE_PARM_DESC(host_support_fs_ls_low_power,
14576 + "Support Low Power w/FS or LS 0=Support 1=Don't Support");
14577 +module_param_named(host_ls_low_power_phy_clk,
14578 + dwc_otg_module_params.host_ls_low_power_phy_clk, int, 0444);
14579 +MODULE_PARM_DESC(host_ls_low_power_phy_clk,
14580 + "Low Speed Low Power Clock 0=48Mhz 1=6Mhz");
14581 +module_param_named(enable_dynamic_fifo,
14582 + dwc_otg_module_params.enable_dynamic_fifo, int, 0444);
14583 +MODULE_PARM_DESC(enable_dynamic_fifo, "0=cC Setting 1=Allow Dynamic Sizing");
14584 +module_param_named(data_fifo_size, dwc_otg_module_params.data_fifo_size, int,
14585 + 0444);
14586 +MODULE_PARM_DESC(data_fifo_size,
14587 + "Total number of words in the data FIFO memory 32-32768");
14588 +module_param_named(dev_rx_fifo_size, dwc_otg_module_params.dev_rx_fifo_size,
14589 + int, 0444);
14590 +MODULE_PARM_DESC(dev_rx_fifo_size, "Number of words in the Rx FIFO 16-32768");
14591 +module_param_named(dev_nperio_tx_fifo_size,
14592 + dwc_otg_module_params.dev_nperio_tx_fifo_size, int, 0444);
14593 +MODULE_PARM_DESC(dev_nperio_tx_fifo_size,
14594 + "Number of words in the non-periodic Tx FIFO 16-32768");
14595 +module_param_named(dev_perio_tx_fifo_size_1,
14596 + dwc_otg_module_params.dev_perio_tx_fifo_size[0], int, 0444);
14597 +MODULE_PARM_DESC(dev_perio_tx_fifo_size_1,
14598 + "Number of words in the periodic Tx FIFO 4-768");
14599 +module_param_named(dev_perio_tx_fifo_size_2,
14600 + dwc_otg_module_params.dev_perio_tx_fifo_size[1], int, 0444);
14601 +MODULE_PARM_DESC(dev_perio_tx_fifo_size_2,
14602 + "Number of words in the periodic Tx FIFO 4-768");
14603 +module_param_named(dev_perio_tx_fifo_size_3,
14604 + dwc_otg_module_params.dev_perio_tx_fifo_size[2], int, 0444);
14605 +MODULE_PARM_DESC(dev_perio_tx_fifo_size_3,
14606 + "Number of words in the periodic Tx FIFO 4-768");
14607 +module_param_named(dev_perio_tx_fifo_size_4,
14608 + dwc_otg_module_params.dev_perio_tx_fifo_size[3], int, 0444);
14609 +MODULE_PARM_DESC(dev_perio_tx_fifo_size_4,
14610 + "Number of words in the periodic Tx FIFO 4-768");
14611 +module_param_named(dev_perio_tx_fifo_size_5,
14612 + dwc_otg_module_params.dev_perio_tx_fifo_size[4], int, 0444);
14613 +MODULE_PARM_DESC(dev_perio_tx_fifo_size_5,
14614 + "Number of words in the periodic Tx FIFO 4-768");
14615 +module_param_named(dev_perio_tx_fifo_size_6,
14616 + dwc_otg_module_params.dev_perio_tx_fifo_size[5], int, 0444);
14617 +MODULE_PARM_DESC(dev_perio_tx_fifo_size_6,
14618 + "Number of words in the periodic Tx FIFO 4-768");
14619 +module_param_named(dev_perio_tx_fifo_size_7,
14620 + dwc_otg_module_params.dev_perio_tx_fifo_size[6], int, 0444);
14621 +MODULE_PARM_DESC(dev_perio_tx_fifo_size_7,
14622 + "Number of words in the periodic Tx FIFO 4-768");
14623 +module_param_named(dev_perio_tx_fifo_size_8,
14624 + dwc_otg_module_params.dev_perio_tx_fifo_size[7], int, 0444);
14625 +MODULE_PARM_DESC(dev_perio_tx_fifo_size_8,
14626 + "Number of words in the periodic Tx FIFO 4-768");
14627 +module_param_named(dev_perio_tx_fifo_size_9,
14628 + dwc_otg_module_params.dev_perio_tx_fifo_size[8], int, 0444);
14629 +MODULE_PARM_DESC(dev_perio_tx_fifo_size_9,
14630 + "Number of words in the periodic Tx FIFO 4-768");
14631 +module_param_named(dev_perio_tx_fifo_size_10,
14632 + dwc_otg_module_params.dev_perio_tx_fifo_size[9], int, 0444);
14633 +MODULE_PARM_DESC(dev_perio_tx_fifo_size_10,
14634 + "Number of words in the periodic Tx FIFO 4-768");
14635 +module_param_named(dev_perio_tx_fifo_size_11,
14636 + dwc_otg_module_params.dev_perio_tx_fifo_size[10], int, 0444);
14637 +MODULE_PARM_DESC(dev_perio_tx_fifo_size_11,
14638 + "Number of words in the periodic Tx FIFO 4-768");
14639 +module_param_named(dev_perio_tx_fifo_size_12,
14640 + dwc_otg_module_params.dev_perio_tx_fifo_size[11], int, 0444);
14641 +MODULE_PARM_DESC(dev_perio_tx_fifo_size_12,
14642 + "Number of words in the periodic Tx FIFO 4-768");
14643 +module_param_named(dev_perio_tx_fifo_size_13,
14644 + dwc_otg_module_params.dev_perio_tx_fifo_size[12], int, 0444);
14645 +MODULE_PARM_DESC(dev_perio_tx_fifo_size_13,
14646 + "Number of words in the periodic Tx FIFO 4-768");
14647 +module_param_named(dev_perio_tx_fifo_size_14,
14648 + dwc_otg_module_params.dev_perio_tx_fifo_size[13], int, 0444);
14649 +MODULE_PARM_DESC(dev_perio_tx_fifo_size_14,
14650 + "Number of words in the periodic Tx FIFO 4-768");
14651 +module_param_named(dev_perio_tx_fifo_size_15,
14652 + dwc_otg_module_params.dev_perio_tx_fifo_size[14], int, 0444);
14653 +MODULE_PARM_DESC(dev_perio_tx_fifo_size_15,
14654 + "Number of words in the periodic Tx FIFO 4-768");
14655 +module_param_named(host_rx_fifo_size, dwc_otg_module_params.host_rx_fifo_size,
14656 + int, 0444);
14657 +MODULE_PARM_DESC(host_rx_fifo_size, "Number of words in the Rx FIFO 16-32768");
14658 +module_param_named(host_nperio_tx_fifo_size,
14659 + dwc_otg_module_params.host_nperio_tx_fifo_size, int, 0444);
14660 +MODULE_PARM_DESC(host_nperio_tx_fifo_size,
14661 + "Number of words in the non-periodic Tx FIFO 16-32768");
14662 +module_param_named(host_perio_tx_fifo_size,
14663 + dwc_otg_module_params.host_perio_tx_fifo_size, int, 0444);
14664 +MODULE_PARM_DESC(host_perio_tx_fifo_size,
14665 + "Number of words in the host periodic Tx FIFO 16-32768");
14666 +module_param_named(max_transfer_size, dwc_otg_module_params.max_transfer_size,
14667 + int, 0444);
14668 +/** @todo Set the max to 512K, modify checks */
14669 +MODULE_PARM_DESC(max_transfer_size,
14670 + "The maximum transfer size supported in bytes 2047-65535");
14671 +module_param_named(max_packet_count, dwc_otg_module_params.max_packet_count,
14672 + int, 0444);
14673 +MODULE_PARM_DESC(max_packet_count,
14674 + "The maximum number of packets in a transfer 15-511");
14675 +module_param_named(host_channels, dwc_otg_module_params.host_channels, int,
14676 + 0444);
14677 +MODULE_PARM_DESC(host_channels,
14678 + "The number of host channel registers to use 1-16");
14679 +module_param_named(dev_endpoints, dwc_otg_module_params.dev_endpoints, int,
14680 + 0444);
14681 +MODULE_PARM_DESC(dev_endpoints,
14682 + "The number of endpoints in addition to EP0 available "
14683 + "for device mode 1-15");
14684 +module_param_named(phy_type, dwc_otg_module_params.phy_type, int, 0444);
14685 +MODULE_PARM_DESC(phy_type, "0=Reserved 1=UTMI+ 2=ULPI");
14686 +module_param_named(phy_utmi_width, dwc_otg_module_params.phy_utmi_width, int,
14687 + 0444);
14688 +MODULE_PARM_DESC(phy_utmi_width, "Specifies the UTMI+ Data Width 8 or 16 bits");
14689 +module_param_named(phy_ulpi_ddr, dwc_otg_module_params.phy_ulpi_ddr, int, 0444);
14690 +MODULE_PARM_DESC(phy_ulpi_ddr,
14691 + "ULPI at double or single data rate 0=Single 1=Double");
14692 +module_param_named(phy_ulpi_ext_vbus, dwc_otg_module_params.phy_ulpi_ext_vbus,
14693 + int, 0444);
14694 +MODULE_PARM_DESC(phy_ulpi_ext_vbus,
14695 + "ULPI PHY using internal or external vbus 0=Internal");
14696 +module_param_named(i2c_enable, dwc_otg_module_params.i2c_enable, int, 0444);
14697 +MODULE_PARM_DESC(i2c_enable, "FS PHY Interface");
14698 +module_param_named(ulpi_fs_ls, dwc_otg_module_params.ulpi_fs_ls, int, 0444);
14699 +MODULE_PARM_DESC(ulpi_fs_ls, "ULPI PHY FS/LS mode only");
14700 +module_param_named(ts_dline, dwc_otg_module_params.ts_dline, int, 0444);
14701 +MODULE_PARM_DESC(ts_dline, "Term select Dline pulsing for all PHYs");
14702 +module_param_named(debug, g_dbg_lvl, int, 0644);
14703 +MODULE_PARM_DESC(debug, "");
14704 +
14705 +/** @page "Module Parameters"
14706 + *
14707 + * The following parameters may be specified when starting the module.
14708 + * These parameters define how the DWC_otg controller should be
14709 + * configured. Parameter values are passed to the CIL initialization
14710 + * function dwc_otg_cil_init
14711 + *
14712 + * Example: <code>modprobe dwc_otg speed=1 otg_cap=1</code>
14713 + *
14714 +
14715 + <table>
14716 + <tr><td>Parameter Name</td><td>Meaning</td></tr>
14717 +
14718 + <tr>
14719 + <td>otg_cap</td>
14720 + <td>Specifies the OTG capabilities. The driver will automatically detect the
14721 + value for this parameter if none is specified.
14722 + - 0: HNP and SRP capable (default, if available)
14723 + - 1: SRP Only capable
14724 + - 2: No HNP/SRP capable
14725 + </td></tr>
14726 +
14727 + <tr>
14728 + <td>dma_enable</td>
14729 + <td>Specifies whether to use slave or DMA mode for accessing the data FIFOs.
14730 + The driver will automatically detect the value for this parameter if none is
14731 + specified.
14732 + - 0: Slave
14733 + - 1: DMA (default, if available)
14734 + </td></tr>
14735 +
14736 + <tr>
14737 + <td>dma_burst_size</td>
14738 + <td>The DMA Burst size (applicable only for External DMA Mode).
14739 + - Values: 1, 4, 8 16, 32, 64, 128, 256 (default 32)
14740 + </td></tr>
14741 +
14742 + <tr>
14743 + <td>speed</td>
14744 + <td>Specifies the maximum speed of operation in host and device mode. The
14745 + actual speed depends on the speed of the attached device and the value of
14746 + phy_type.
14747 + - 0: High Speed (default)
14748 + - 1: Full Speed
14749 + </td></tr>
14750 +
14751 + <tr>
14752 + <td>host_support_fs_ls_low_power</td>
14753 + <td>Specifies whether low power mode is supported when attached to a Full
14754 + Speed or Low Speed device in host mode.
14755 + - 0: Don't support low power mode (default)
14756 + - 1: Support low power mode
14757 + </td></tr>
14758 +
14759 + <tr>
14760 + <td>host_ls_low_power_phy_clk</td>
14761 + <td>Specifies the PHY clock rate in low power mode when connected to a Low
14762 + Speed device in host mode. This parameter is applicable only if
14763 + HOST_SUPPORT_FS_LS_LOW_POWER is enabled.
14764 + - 0: 48 MHz (default)
14765 + - 1: 6 MHz
14766 + </td></tr>
14767 +
14768 + <tr>
14769 + <td>enable_dynamic_fifo</td>
14770 + <td> Specifies whether FIFOs may be resized by the driver software.
14771 + - 0: Use cC FIFO size parameters
14772 + - 1: Allow dynamic FIFO sizing (default)
14773 + </td></tr>
14774 +
14775 + <tr>
14776 + <td>data_fifo_size</td>
14777 + <td>Total number of 4-byte words in the data FIFO memory. This memory
14778 + includes the Rx FIFO, non-periodic Tx FIFO, and periodic Tx FIFOs.
14779 + - Values: 32 to 32768 (default 8192)
14780 +
14781 + Note: The total FIFO memory depth in the FPGA configuration is 8192.
14782 + </td></tr>
14783 +
14784 + <tr>
14785 + <td>dev_rx_fifo_size</td>
14786 + <td>Number of 4-byte words in the Rx FIFO in device mode when dynamic
14787 + FIFO sizing is enabled.
14788 + - Values: 16 to 32768 (default 1064)
14789 + </td></tr>
14790 +
14791 + <tr>
14792 + <td>dev_nperio_tx_fifo_size</td>
14793 + <td>Number of 4-byte words in the non-periodic Tx FIFO in device mode when
14794 + dynamic FIFO sizing is enabled.
14795 + - Values: 16 to 32768 (default 1024)
14796 + </td></tr>
14797 +
14798 + <tr>
14799 + <td>dev_perio_tx_fifo_size_n (n = 1 to 15)</td>
14800 + <td>Number of 4-byte words in each of the periodic Tx FIFOs in device mode
14801 + when dynamic FIFO sizing is enabled.
14802 + - Values: 4 to 768 (default 256)
14803 + </td></tr>
14804 +
14805 + <tr>
14806 + <td>host_rx_fifo_size</td>
14807 + <td>Number of 4-byte words in the Rx FIFO in host mode when dynamic FIFO
14808 + sizing is enabled.
14809 + - Values: 16 to 32768 (default 1024)
14810 + </td></tr>
14811 +
14812 + <tr>
14813 + <td>host_nperio_tx_fifo_size</td>
14814 + <td>Number of 4-byte words in the non-periodic Tx FIFO in host mode when
14815 + dynamic FIFO sizing is enabled in the core.
14816 + - Values: 16 to 32768 (default 1024)
14817 + </td></tr>
14818 +
14819 + <tr>
14820 + <td>host_perio_tx_fifo_size</td>
14821 + <td>Number of 4-byte words in the host periodic Tx FIFO when dynamic FIFO
14822 + sizing is enabled.
14823 + - Values: 16 to 32768 (default 1024)
14824 + </td></tr>
14825 +
14826 + <tr>
14827 + <td>max_transfer_size</td>
14828 + <td>The maximum transfer size supported in bytes.
14829 + - Values: 2047 to 65,535 (default 65,535)
14830 + </td></tr>
14831 +
14832 + <tr>
14833 + <td>max_packet_count</td>
14834 + <td>The maximum number of packets in a transfer.
14835 + - Values: 15 to 511 (default 511)
14836 + </td></tr>
14837 +
14838 + <tr>
14839 + <td>host_channels</td>
14840 + <td>The number of host channel registers to use.
14841 + - Values: 1 to 16 (default 12)
14842 +
14843 + Note: The FPGA configuration supports a maximum of 12 host channels.
14844 + </td></tr>
14845 +
14846 + <tr>
14847 + <td>dev_endpoints</td>
14848 + <td>The number of endpoints in addition to EP0 available for device mode
14849 + operations.
14850 + - Values: 1 to 15 (default 6 IN and OUT)
14851 +
14852 + Note: The FPGA configuration supports a maximum of 6 IN and OUT endpoints in
14853 + addition to EP0.
14854 + </td></tr>
14855 +
14856 + <tr>
14857 + <td>phy_type</td>
14858 + <td>Specifies the type of PHY interface to use. By default, the driver will
14859 + automatically detect the phy_type.
14860 + - 0: Full Speed
14861 + - 1: UTMI+ (default, if available)
14862 + - 2: ULPI
14863 + </td></tr>
14864 +
14865 + <tr>
14866 + <td>phy_utmi_width</td>
14867 + <td>Specifies the UTMI+ Data Width. This parameter is applicable for a
14868 + phy_type of UTMI+. Also, this parameter is applicable only if the
14869 + OTG_HSPHY_WIDTH cC parameter was set to "8 and 16 bits", meaning that the
14870 + core has been configured to work at either data path width.
14871 + - Values: 8 or 16 bits (default 16)
14872 + </td></tr>
14873 +
14874 + <tr>
14875 + <td>phy_ulpi_ddr</td>
14876 + <td>Specifies whether the ULPI operates at double or single data rate. This
14877 + parameter is only applicable if phy_type is ULPI.
14878 + - 0: single data rate ULPI interface with 8 bit wide data bus (default)
14879 + - 1: double data rate ULPI interface with 4 bit wide data bus
14880 + </td></tr>
14881 +
14882 + <tr>
14883 + <td>i2c_enable</td>
14884 + <td>Specifies whether to use the I2C interface for full speed PHY. This
14885 + parameter is only applicable if PHY_TYPE is FS.
14886 + - 0: Disabled (default)
14887 + - 1: Enabled
14888 + </td></tr>
14889 +
14890 +*/
14891 diff --git a/drivers/usb/host/dwc_otg/dwc_otg_plat.h b/drivers/usb/host/dwc_otg/dwc_otg_plat.h
14892 new file mode 100644
14893 index 0000000..93ef282
14894 --- /dev/null
14895 +++ b/drivers/usb/host/dwc_otg/dwc_otg_plat.h
14896 @@ -0,0 +1,236 @@
14897 +/* ==========================================================================
14898 + *
14899 + * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
14900 + * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
14901 + * otherwise expressly agreed to in writing between Synopsys and you.
14902 + *
14903 + * The Software IS NOT an item of Licensed Software or Licensed Product under
14904 + * any End User Software License Agreement or Agreement for Licensed Product
14905 + * with Synopsys or any supplement thereto. You are permitted to use and
14906 + * redistribute this Software in source and binary forms, with or without
14907 + * modification, provided that redistributions of source code must retain this
14908 + * notice. You may not view, use, disclose, copy or distribute this file or
14909 + * any information contained herein except pursuant to this license grant from
14910 + * Synopsys. If you do not agree with this notice, including the disclaimer
14911 + * below, then you are not authorized to use the Software.
14912 + *
14913 + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
14914 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14915 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
14916 + * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
14917 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
14918 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
14919 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
14920 + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
14921 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
14922 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
14923 + * DAMAGE.
14924 + * ========================================================================== */
14925 +
14926 +#if !defined(__DWC_OTG_PLAT_H__)
14927 +#define __DWC_OTG_PLAT_H__
14928 +
14929 +#include <linux/types.h>
14930 +#include <linux/slab.h>
14931 +#include <linux/list.h>
14932 +#include <linux/delay.h>
14933 +#include <linux/device.h>
14934 +#include <linux/io.h>
14935 +
14936 +#include <asm/octeon/octeon.h>
14937 +#include <asm/octeon/cvmx-usbnx-defs.h>
14938 +
14939 +#define SZ_256K 0x00040000
14940 +#ifndef CONFIG_64BIT
14941 +#define OCTEON_USB_BASE_ADDRESS 0x80016F0010000000ull
14942 +#endif
14943 +
14944 +/**
14945 + * @file
14946 + *
14947 + * This file contains the Platform Specific constants, interfaces
14948 + * (functions and macros) for Linux.
14949 + *
14950 + */
14951 +
14952 +/**
14953 + * Reads the content of a register.
14954 + *
14955 + * @_reg: address of register to read.
14956 + * Returns contents of the register.
14957 + *
14958 +
14959 + * Usage:<br>
14960 + * <code>uint32_t dev_ctl = dwc_read_reg32(&dev_regs->dctl);</code>
14961 + */
14962 +static inline uint32_t dwc_read_reg32(uint32_t *_reg)
14963 +{
14964 + uint32_t result;
14965 + /* USB device registers on Octeon are 32bit address swapped */
14966 +#ifdef CONFIG_64BIT
14967 + uint64_t address = (unsigned long)_reg ^ 4;
14968 +#else
14969 + uint64_t address = OCTEON_USB_BASE_ADDRESS | ((unsigned long)_reg ^ 4);
14970 +#endif
14971 + result = cvmx_read64_uint32(address);
14972 + return result;
14973 +};
14974 +
14975 +/**
14976 + * Writes a register with a 32 bit value.
14977 + *
14978 + * @_reg: address of register to read.
14979 + * @_value: to write to _reg.
14980 + *
14981 + * Usage:<br>
14982 + * <code>dwc_write_reg32(&dev_regs->dctl, 0); </code>
14983 + */
14984 +static inline void dwc_write_reg32(uint32_t *_reg,
14985 + const uint32_t _value)
14986 +{
14987 + /* USB device registers on Octeon are 32bit address swapped */
14988 +#ifdef CONFIG_64BIT
14989 + uint64_t address = (unsigned long)_reg ^ 4;
14990 +#else
14991 + uint64_t address = OCTEON_USB_BASE_ADDRESS | ((unsigned long)_reg ^ 4);
14992 +#endif
14993 + wmb();
14994 + cvmx_write64_uint32(address, _value);
14995 +
14996 +#ifdef CONFIG_CPU_CAVIUM_OCTEON
14997 + /* O2P/O1P pass 1 bug workaround: A read must occur for at least
14998 + every 3rd write to insure that the writes do not overrun the
14999 + USBN. */
15000 + if (OCTEON_IS_MODEL(OCTEON_CN31XX) || OCTEON_IS_MODEL(OCTEON_CN30XX)) {
15001 + extern int dwc_errata_write_count;
15002 + if (++dwc_errata_write_count > 2) {
15003 + cvmx_read_csr(CVMX_USBNX_DMA0_INB_CHN0(0));
15004 + dwc_errata_write_count = 0;
15005 + }
15006 + }
15007 +#endif
15008 +};
15009 +
15010 +/**
15011 + * This function modifies bit values in a register. Using the
15012 + * algorithm: (reg_contents & ~clear_mask) | set_mask.
15013 + *
15014 + * @_reg: address of register to read.
15015 + * @_clear_mask: bit mask to be cleared.
15016 + * @_set_mask: bit mask to be set.
15017 + *
15018 + * Usage:<br>
15019 + * <code> // Clear the SOF Interrupt Mask bit and <br>
15020 + * // set the OTG Interrupt mask bit, leaving all others as they were.
15021 + * dwc_modify_reg32(&dev_regs->gintmsk, DWC_SOF_INT, DWC_OTG_INT);</code>
15022 + */
15023 +static inline void dwc_modify_reg32(uint32_t *_reg,
15024 + const uint32_t _clear_mask,
15025 + const uint32_t _set_mask)
15026 +{
15027 + uint32_t value = dwc_read_reg32(_reg);
15028 + value &= ~_clear_mask;
15029 + value |= _set_mask;
15030 + dwc_write_reg32(_reg, value);
15031 +};
15032 +
15033 +/*
15034 + * Debugging support vanishes in non-debug builds.
15035 + */
15036 +
15037 +/**
15038 + * The Debug Level bit-mask variable.
15039 + */
15040 +extern uint32_t g_dbg_lvl;
15041 +/**
15042 + * Set the Debug Level variable.
15043 + */
15044 +static inline uint32_t SET_DEBUG_LEVEL(const uint32_t _new)
15045 +{
15046 + uint32_t old = g_dbg_lvl;
15047 + g_dbg_lvl = _new;
15048 + return old;
15049 +}
15050 +
15051 +/** When debug level has the DBG_CIL bit set, display CIL Debug messages. */
15052 +#define DBG_CIL (0x2)
15053 +/** When debug level has the DBG_CILV bit set, display CIL Verbose debug
15054 + * messages */
15055 +#define DBG_CILV (0x20)
15056 +/** When debug level has the DBG_PCD bit set, display PCD (Device) debug
15057 + * messages */
15058 +#define DBG_PCD (0x4)
15059 +/** When debug level has the DBG_PCDV set, display PCD (Device) Verbose debug
15060 + * messages */
15061 +#define DBG_PCDV (0x40)
15062 +/** When debug level has the DBG_HCD bit set, display Host debug messages */
15063 +#define DBG_HCD (0x8)
15064 +/** When debug level has the DBG_HCDV bit set, display Verbose Host debug
15065 + * messages */
15066 +#define DBG_HCDV (0x80)
15067 +/** When debug level has the DBG_HCD_URB bit set, display enqueued URBs in host
15068 + * mode. */
15069 +#define DBG_HCD_URB (0x800)
15070 +
15071 +/** When debug level has any bit set, display debug messages */
15072 +#define DBG_ANY (0xFF)
15073 +
15074 +/** All debug messages off */
15075 +#define DBG_OFF 0
15076 +
15077 +/** Prefix string for DWC_DEBUG print macros. */
15078 +#define USB_DWC "DWC_otg: "
15079 +
15080 +/**
15081 + * Print a debug message when the Global debug level variable contains
15082 + * the bit defined in <code>lvl</code>.
15083 + *
15084 + * @lvl: - Debug level, use one of the DBG_ constants above.
15085 + * @x: - like printf
15086 + *
15087 + * Example:<p>
15088 + * <code>
15089 + * DWC_DEBUGPL( DBG_ANY, "%s(%p)\n", __func__, _reg_base_addr);
15090 + * </code>
15091 + * <br>
15092 + * results in:<br>
15093 + * <code>
15094 + * usb-DWC_otg: dwc_otg_cil_init(ca867000)
15095 + * </code>
15096 + */
15097 +#ifdef DEBUG
15098 +
15099 +# define DWC_DEBUGPL(lvl, x...) \
15100 + do { \
15101 + if ((lvl)&g_dbg_lvl) \
15102 + printk(KERN_DEBUG USB_DWC x); \
15103 + } while (0)
15104 +# define DWC_DEBUGP(x...) DWC_DEBUGPL(DBG_ANY, x)
15105 +
15106 +# define CHK_DEBUG_LEVEL(level) ((level) & g_dbg_lvl)
15107 +
15108 +#else
15109 +
15110 +# define DWC_DEBUGPL(lvl, x...) do { } while (0)
15111 +# define DWC_DEBUGP(x...)
15112 +
15113 +# define CHK_DEBUG_LEVEL(level) (0)
15114 +
15115 +#endif /*DEBUG*/
15116 +/*
15117 + * Print an Error message.
15118 + */
15119 +#define DWC_ERROR(x...) printk(KERN_ERR USB_DWC x)
15120 +/*
15121 + * Print a Warning message.
15122 + */
15123 +#define DWC_WARN(x...) printk(KERN_WARNING USB_DWC x)
15124 +/*
15125 + * Print a notice (normal but significant message).
15126 + */
15127 +#define DWC_NOTICE(x...) printk(KERN_NOTICE USB_DWC x)
15128 +/*
15129 + * Basic message printing.
15130 + */
15131 +#define DWC_PRINT(x...) printk(KERN_INFO USB_DWC x)
15132 +#endif
15133 diff --git a/drivers/usb/host/dwc_otg/dwc_otg_regs.h b/drivers/usb/host/dwc_otg/dwc_otg_regs.h
15134 new file mode 100644
15135 index 0000000..34cc4f7
15136 --- /dev/null
15137 +++ b/drivers/usb/host/dwc_otg/dwc_otg_regs.h
15138 @@ -0,0 +1,2355 @@
15139 +/* ==========================================================================
15140 + *
15141 + * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
15142 + * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
15143 + * otherwise expressly agreed to in writing between Synopsys and you.
15144 + *
15145 + * The Software IS NOT an item of Licensed Software or Licensed Product under
15146 + * any End User Software License Agreement or Agreement for Licensed Product
15147 + * with Synopsys or any supplement thereto. You are permitted to use and
15148 + * redistribute this Software in source and binary forms, with or without
15149 + * modification, provided that redistributions of source code must retain this
15150 + * notice. You may not view, use, disclose, copy or distribute this file or
15151 + * any information contained herein except pursuant to this license grant from
15152 + * Synopsys. If you do not agree with this notice, including the disclaimer
15153 + * below, then you are not authorized to use the Software.
15154 + *
15155 + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
15156 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15157 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
15158 + * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
15159 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
15160 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
15161 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
15162 + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
15163 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
15164 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
15165 + * DAMAGE.
15166 + * ========================================================================== */
15167 +
15168 +#ifndef __DWC_OTG_REGS_H__
15169 +#define __DWC_OTG_REGS_H__
15170 +
15171 +/*
15172 + *
15173 + * This file contains the data structures for accessing the DWC_otg
15174 + * core registers.
15175 + *
15176 + * The application interfaces with the HS OTG core by reading from and
15177 + * writing to the Control and Status Register (CSR) space through the
15178 + * AHB Slave interface. These registers are 32 bits wide, and the
15179 + * addresses are 32-bit-block aligned.
15180 + * CSRs are classified as follows:
15181 + * - Core Global Registers
15182 + * - Device Mode Registers
15183 + * - Device Global Registers
15184 + * - Device Endpoint Specific Registers
15185 + * - Host Mode Registers
15186 + * - Host Global Registers
15187 + * - Host Port CSRs
15188 + * - Host Channel Specific Registers
15189 + *
15190 + * Only the Core Global registers can be accessed in both Device and
15191 + * Host modes. When the HS OTG core is operating in one mode, either
15192 + * Device or Host, the application must not access registers from the
15193 + * other mode. When the core switches from one mode to another, the
15194 + * registers in the new mode of operation must be reprogrammed as they
15195 + * would be after a power-on reset.
15196 + */
15197 +
15198 +/****************************************************************************/
15199 +/* DWC_otg Core registers .
15200 + * The dwc_otg_core_global_regs structure defines the size
15201 + * and relative field offsets for the Core Global registers.
15202 + */
15203 +struct dwc_otg_core_global_regs {
15204 + /* OTG Control and Status Register. Offset: 000h */
15205 + uint32_t gotgctl;
15206 + /* OTG Interrupt Register. Offset: 004h */
15207 + uint32_t gotgint;
15208 + /* Core AHB Configuration Register. Offset: 008h */
15209 + uint32_t gahbcfg;
15210 +#define DWC_GLBINTRMASK 0x0001
15211 +#define DWC_DMAENABLE 0x0020
15212 +#define DWC_NPTXEMPTYLVL_EMPTY 0x0080
15213 +#define DWC_NPTXEMPTYLVL_HALFEMPTY 0x0000
15214 +#define DWC_PTXEMPTYLVL_EMPTY 0x0100
15215 +#define DWC_PTXEMPTYLVL_HALFEMPTY 0x0000
15216 +
15217 + /* Core USB Configuration Register. Offset: 00Ch */
15218 + uint32_t gusbcfg;
15219 + /* Core Reset Register. Offset: 010h */
15220 + uint32_t grstctl;
15221 + /* Core Interrupt Register. Offset: 014h */
15222 + uint32_t gintsts;
15223 + /* Core Interrupt Mask Register. Offset: 018h */
15224 + uint32_t gintmsk;
15225 + /* Receive Status Queue Read Register (Read Only). Offset: 01Ch */
15226 + uint32_t grxstsr;
15227 + /* Receive Status Queue Read & POP Register (Read Only). Offset: 020h*/
15228 + uint32_t grxstsp;
15229 + /* Receive FIFO Size Register. Offset: 024h */
15230 + uint32_t grxfsiz;
15231 + /* Non Periodic Transmit FIFO Size Register. Offset: 028h */
15232 + uint32_t gnptxfsiz;
15233 + /*
15234 + *Non Periodic Transmit FIFO/Queue Status Register (Read
15235 + * Only). Offset: 02Ch
15236 + */
15237 + uint32_t gnptxsts;
15238 + /* I2C Access Register. Offset: 030h */
15239 + uint32_t gi2cctl;
15240 + /* PHY Vendor Control Register. Offset: 034h */
15241 + uint32_t gpvndctl;
15242 + /* General Purpose Input/Output Register. Offset: 038h */
15243 + uint32_t ggpio;
15244 + /* User ID Register. Offset: 03Ch */
15245 + uint32_t guid;
15246 + /* Synopsys ID Register (Read Only). Offset: 040h */
15247 + uint32_t gsnpsid;
15248 + /* User HW Config1 Register (Read Only). Offset: 044h */
15249 + uint32_t ghwcfg1;
15250 + /* User HW Config2 Register (Read Only). Offset: 048h */
15251 + uint32_t ghwcfg2;
15252 +#define DWC_SLAVE_ONLY_ARCH 0
15253 +#define DWC_EXT_DMA_ARCH 1
15254 +#define DWC_INT_DMA_ARCH 2
15255 +
15256 +#define DWC_MODE_HNP_SRP_CAPABLE 0
15257 +#define DWC_MODE_SRP_ONLY_CAPABLE 1
15258 +#define DWC_MODE_NO_HNP_SRP_CAPABLE 2
15259 +#define DWC_MODE_SRP_CAPABLE_DEVICE 3
15260 +#define DWC_MODE_NO_SRP_CAPABLE_DEVICE 4
15261 +#define DWC_MODE_SRP_CAPABLE_HOST 5
15262 +#define DWC_MODE_NO_SRP_CAPABLE_HOST 6
15263 +
15264 + /* User HW Config3 Register (Read Only). Offset: 04Ch */
15265 + uint32_t ghwcfg3;
15266 + /* User HW Config4 Register (Read Only). Offset: 050h*/
15267 + uint32_t ghwcfg4;
15268 + /* Reserved Offset: 054h-0FFh */
15269 + uint32_t reserved[43];
15270 + /* Host Periodic Transmit FIFO Size Register. Offset: 100h */
15271 + uint32_t hptxfsiz;
15272 + /*
15273 + * Device Periodic Transmit FIFO#n Register.
15274 + * Offset: 104h + (FIFO_Number-1)*04h,
15275 + * 1 <= FIFO Number <= 15 (1<=n<=15).
15276 + */
15277 + uint32_t dptxfsiz[15];
15278 +};
15279 +
15280 +/*
15281 + * This union represents the bit fields of the Core OTG Control
15282 + * and Status Register (GOTGCTL). Set the bits using the bit
15283 + * fields then write the d32 value to the register.
15284 + */
15285 +union gotgctl_data {
15286 + /* raw register data */
15287 + uint32_t d32;
15288 + /* register bits */
15289 + struct {
15290 +#ifdef __BIG_ENDIAN_BITFIELD
15291 + unsigned reserved21_31:11;
15292 + unsigned currmod:1;
15293 + unsigned bsesvld:1;
15294 + unsigned asesvld:1;
15295 + unsigned reserved17:1;
15296 + unsigned conidsts:1;
15297 + unsigned reserved12_15:4;
15298 + unsigned devhnpen:1;
15299 + unsigned hstsethnpen:1;
15300 + unsigned hnpreq:1;
15301 + unsigned hstnegscs:1;
15302 + unsigned reserved2_7:6;
15303 + unsigned sesreq:1;
15304 + unsigned sesreqscs:1;
15305 +#else
15306 + unsigned sesreqscs:1;
15307 + unsigned sesreq:1;
15308 + unsigned reserved2_7:6;
15309 + unsigned hstnegscs:1;
15310 + unsigned hnpreq:1;
15311 + unsigned hstsethnpen:1;
15312 + unsigned devhnpen:1;
15313 + unsigned reserved12_15:4;
15314 + unsigned conidsts:1;
15315 + unsigned reserved17:1;
15316 + unsigned asesvld:1;
15317 + unsigned bsesvld:1;
15318 + unsigned currmod:1;
15319 + unsigned reserved21_31:11;
15320 +#endif
15321 + } b;
15322 +};
15323 +
15324 +/*
15325 + * This union represents the bit fields of the Core OTG Interrupt Register
15326 + * (GOTGINT). Set/clear the bits using the bit fields then write the d32
15327 + * value to the register.
15328 + */
15329 +union gotgint_data {
15330 + /* raw register data */
15331 + uint32_t d32;
15332 + /* register bits */
15333 + struct {
15334 +#ifdef __BIG_ENDIAN_BITFIELD
15335 + unsigned reserved31_20:12;
15336 + unsigned debdone:1;
15337 + unsigned adevtoutchng:1;
15338 + unsigned hstnegdet:1;
15339 + unsigned reserver10_16:7;
15340 + unsigned hstnegsucstschng:1;
15341 + unsigned sesreqsucstschng:1;
15342 + unsigned reserved3_7:5;
15343 + unsigned sesenddet:1;
15344 + unsigned reserved0_1:2;
15345 +#else
15346 +
15347 + /* Current Mode */
15348 + unsigned reserved0_1:2;
15349 +
15350 + /* Session End Detected */
15351 + unsigned sesenddet:1;
15352 +
15353 + unsigned reserved3_7:5;
15354 +
15355 + /* Session Request Success Status Change */
15356 + unsigned sesreqsucstschng:1;
15357 + /* Host Negotiation Success Status Change */
15358 + unsigned hstnegsucstschng:1;
15359 +
15360 + unsigned reserver10_16:7;
15361 +
15362 + /* Host Negotiation Detected */
15363 + unsigned hstnegdet:1;
15364 + /* A-Device Timeout Change */
15365 + unsigned adevtoutchng:1;
15366 + /* Debounce Done */
15367 + unsigned debdone:1;
15368 +
15369 + unsigned reserved31_20:12;
15370 +#endif
15371 + } b;
15372 +};
15373 +
15374 +/*
15375 + * This union represents the bit fields of the Core AHB Configuration
15376 + * Register (GAHBCFG). Set/clear the bits using the bit fields then
15377 + * write the d32 value to the register.
15378 + */
15379 +union gahbcfg_data {
15380 + /* raw register data */
15381 + uint32_t d32;
15382 + /* register bits */
15383 + struct {
15384 +#define DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY 0
15385 +#define DWC_GAHBCFG_TXFEMPTYLVL_EMPTY 1
15386 +#define DWC_GAHBCFG_DMAENABLE 1
15387 +#define DWC_GAHBCFG_INT_DMA_BURST_INCR16 7
15388 +#define DWC_GAHBCFG_INT_DMA_BURST_INCR8 5
15389 +#define DWC_GAHBCFG_INT_DMA_BURST_INCR4 3
15390 +#define DWC_GAHBCFG_INT_DMA_BURST_INCR 1
15391 +#define DWC_GAHBCFG_INT_DMA_BURST_SINGLE 0
15392 +#define DWC_GAHBCFG_GLBINT_ENABLE 1
15393 +
15394 +#ifdef __BIG_ENDIAN_BITFIELD
15395 + unsigned reserved9_31:23;
15396 + unsigned ptxfemplvl:1;
15397 + unsigned nptxfemplvl:1;
15398 + unsigned reserved:1;
15399 + unsigned dmaenable:1;
15400 + unsigned hburstlen:4;
15401 + unsigned glblintrmsk:1;
15402 +#else
15403 + unsigned glblintrmsk:1;
15404 + unsigned hburstlen:4;
15405 + unsigned dmaenable:1;
15406 + unsigned reserved:1;
15407 + unsigned nptxfemplvl:1;
15408 + unsigned ptxfemplvl:1;
15409 + unsigned reserved9_31:23;
15410 +#endif
15411 + } b;
15412 +};
15413 +
15414 +/*
15415 + * This union represents the bit fields of the Core USB Configuration
15416 + * Register (GUSBCFG). Set the bits using the bit fields then write
15417 + * the d32 value to the register.
15418 + */
15419 +union gusbcfg_data {
15420 + /* raw register data */
15421 + uint32_t d32;
15422 + /* register bits */
15423 + struct {
15424 +#ifdef __BIG_ENDIAN_BITFIELD
15425 + unsigned reserved:9;
15426 + unsigned term_sel_dl_pulse:1;
15427 + unsigned ulpi_int_vbus_indicator:1;
15428 + unsigned ulpi_ext_vbus_drv:1;
15429 + unsigned ulpi_clk_sus_m:1;
15430 + unsigned ulpi_auto_res:1;
15431 + unsigned ulpi_fsls:1;
15432 + unsigned otgutmifssel:1;
15433 + unsigned phylpwrclksel:1;
15434 + unsigned nptxfrwnden:1;
15435 + unsigned usbtrdtim:4;
15436 + unsigned hnpcap:1;
15437 + unsigned srpcap:1;
15438 + unsigned ddrsel:1;
15439 + unsigned physel:1;
15440 + unsigned fsintf:1;
15441 + unsigned ulpi_utmi_sel:1;
15442 + unsigned phyif:1;
15443 + unsigned toutcal:3;
15444 +#else
15445 + unsigned toutcal:3;
15446 + unsigned phyif:1;
15447 + unsigned ulpi_utmi_sel:1;
15448 + unsigned fsintf:1;
15449 + unsigned physel:1;
15450 + unsigned ddrsel:1;
15451 + unsigned srpcap:1;
15452 + unsigned hnpcap:1;
15453 + unsigned usbtrdtim:4;
15454 + unsigned nptxfrwnden:1;
15455 + unsigned phylpwrclksel:1;
15456 + unsigned otgutmifssel:1;
15457 + unsigned ulpi_fsls:1;
15458 + unsigned ulpi_auto_res:1;
15459 + unsigned ulpi_clk_sus_m:1;
15460 + unsigned ulpi_ext_vbus_drv:1;
15461 + unsigned ulpi_int_vbus_indicator:1;
15462 + unsigned term_sel_dl_pulse:1;
15463 + unsigned reserved:9;
15464 +#endif
15465 + } b;
15466 +};
15467 +
15468 +/*
15469 + * This union represents the bit fields of the Core Reset Register
15470 + * (GRSTCTL). Set/clear the bits using the bit fields then write the
15471 + * d32 value to the register.
15472 + */
15473 +union grstctl_data {
15474 + /* raw register data */
15475 + uint32_t d32;
15476 + /* register bits */
15477 + struct {
15478 +#ifdef __BIG_ENDIAN_BITFIELD
15479 + unsigned ahbidle:1;
15480 + unsigned dmareq:1;
15481 + unsigned reserved11_29:19;
15482 + unsigned txfnum:5;
15483 + unsigned txfflsh:1;
15484 + unsigned rxfflsh:1;
15485 + unsigned intknqflsh:1;
15486 + unsigned hstfrm:1;
15487 + unsigned hsftrst:1;
15488 + unsigned csftrst:1;
15489 +#else
15490 +
15491 + /*
15492 + * Core Soft Reset (CSftRst) (Device and Host)
15493 + *
15494 + * The application can flush the control logic in the
15495 + * entire core using this bit. This bit resets the
15496 + * pipelines in the AHB Clock domain as well as the
15497 + * PHY Clock domain.
15498 + *
15499 + * The state machines are reset to an IDLE state, the
15500 + * control bits in the CSRs are cleared, all the
15501 + * transmit FIFOs and the receive FIFO are flushed.
15502 + *
15503 + * The status mask bits that control the generation of
15504 + * the interrupt, are cleared, to clear the
15505 + * interrupt. The interrupt status bits are not
15506 + * cleared, so the application can get the status of
15507 + * any events that occurred in the core after it has
15508 + * set this bit.
15509 + *
15510 + * Any transactions on the AHB are terminated as soon
15511 + * as possible following the protocol. Any
15512 + * transactions on the USB are terminated immediately.
15513 + *
15514 + * The configuration settings in the CSRs are
15515 + * unchanged, so the software doesn't have to
15516 + * reprogram these registers (Device
15517 + * Configuration/Host Configuration/Core System
15518 + * Configuration/Core PHY Configuration).
15519 + *
15520 + * The application can write to this bit, any time it
15521 + * wants to reset the core. This is a self clearing
15522 + * bit and the core clears this bit after all the
15523 + * necessary logic is reset in the core, which may
15524 + * take several clocks, depending on the current state
15525 + * of the core.
15526 + */
15527 + unsigned csftrst:1;
15528 + /*
15529 + * Hclk Soft Reset
15530 + *
15531 + * The application uses this bit to reset the control logic in
15532 + * the AHB clock domain. Only AHB clock domain pipelines are
15533 + * reset.
15534 + */
15535 + unsigned hsftrst:1;
15536 + /*
15537 + * Host Frame Counter Reset (Host Only)<br>
15538 + *
15539 + * The application can reset the (micro)frame number
15540 + * counter inside the core, using this bit. When the
15541 + * (micro)frame counter is reset, the subsequent SOF
15542 + * sent out by the core, will have a (micro)frame
15543 + * number of 0.
15544 + */
15545 + unsigned hstfrm:1;
15546 + /*
15547 + * In Token Sequence Learning Queue Flush
15548 + * (INTknQFlsh) (Device Only)
15549 + */
15550 + unsigned intknqflsh:1;
15551 + /*
15552 + * RxFIFO Flush (RxFFlsh) (Device and Host)
15553 + *
15554 + * The application can flush the entire Receive FIFO
15555 + * using this bit. <p>The application must first
15556 + * ensure that the core is not in the middle of a
15557 + * transaction. <p>The application should write into
15558 + * this bit, only after making sure that neither the
15559 + * DMA engine is reading from the RxFIFO nor the MAC
15560 + * is writing the data in to the FIFO. <p>The
15561 + * application should wait until the bit is cleared
15562 + * before performing any other operations. This bit
15563 + * will takes 8 clocks (slowest of PHY or AHB clock)
15564 + * to clear.
15565 + */
15566 + unsigned rxfflsh:1;
15567 + /*
15568 + * TxFIFO Flush (TxFFlsh) (Device and Host).
15569 + *
15570 + * This bit is used to selectively flush a single or
15571 + * all transmit FIFOs. The application must first
15572 + * ensure that the core is not in the middle of a
15573 + * transaction. <p>The application should write into
15574 + * this bit, only after making sure that neither the
15575 + * DMA engine is writing into the TxFIFO nor the MAC
15576 + * is reading the data out of the FIFO. <p>The
15577 + * application should wait until the core clears this
15578 + * bit, before performing any operations. This bit
15579 + * will takes 8 clocks (slowest of PHY or AHB clock)
15580 + * to clear.
15581 + */
15582 + unsigned txfflsh:1;
15583 +
15584 + /*
15585 + * TxFIFO Number (TxFNum) (Device and Host).
15586 + *
15587 + * This is the FIFO number which needs to be flushed,
15588 + * using the TxFIFO Flush bit. This field should not
15589 + * be changed until the TxFIFO Flush bit is cleared by
15590 + * the core.
15591 + * - 0x0:Non Periodic TxFIFO Flush
15592 + * - 0x1:Periodic TxFIFO #1 Flush in device mode
15593 + * or Periodic TxFIFO in host mode
15594 + * - 0x2:Periodic TxFIFO #2 Flush in device mode.
15595 + * - ...
15596 + * - 0xF:Periodic TxFIFO #15 Flush in device mode
15597 + * - 0x10: Flush all the Transmit NonPeriodic and
15598 + * Transmit Periodic FIFOs in the core
15599 + */
15600 + unsigned txfnum:5;
15601 + /* Reserved */
15602 + unsigned reserved11_29:19;
15603 + /*
15604 + * DMA Request Signal. Indicated DMA request is in
15605 + * probress. Used for debug purpose.
15606 + */
15607 + unsigned dmareq:1;
15608 + /*
15609 + * AHB Master Idle. Indicates the AHB Master State
15610 + * Machine is in IDLE condition.
15611 + */
15612 + unsigned ahbidle:1;
15613 +#endif
15614 + } b;
15615 +};
15616 +
15617 +/*
15618 + * This union represents the bit fields of the Core Interrupt Mask
15619 + * Register (GINTMSK). Set/clear the bits using the bit fields then
15620 + * write the d32 value to the register.
15621 + */
15622 +union gintmsk_data {
15623 + /* raw register data */
15624 + uint32_t d32;
15625 + /* register bits */
15626 + struct {
15627 +#ifdef __BIG_ENDIAN_BITFIELD
15628 + unsigned wkupintr:1;
15629 + unsigned sessreqintr:1;
15630 + unsigned disconnect:1;
15631 + unsigned conidstschng:1;
15632 + unsigned reserved27:1;
15633 + unsigned ptxfempty:1;
15634 + unsigned hcintr:1;
15635 + unsigned portintr:1;
15636 + unsigned reserved22_23:2;
15637 + unsigned incomplisoout:1;
15638 + unsigned incomplisoin:1;
15639 + unsigned outepintr:1;
15640 + unsigned inepintr:1;
15641 + unsigned epmismatch:1;
15642 + unsigned reserved16:1;
15643 + unsigned eopframe:1;
15644 + unsigned isooutdrop:1;
15645 + unsigned enumdone:1;
15646 + unsigned usbreset:1;
15647 + unsigned usbsuspend:1;
15648 + unsigned erlysuspend:1;
15649 + unsigned i2cintr:1;
15650 + unsigned reserved8:1;
15651 + unsigned goutnakeff:1;
15652 + unsigned ginnakeff:1;
15653 + unsigned nptxfempty:1;
15654 + unsigned rxstsqlvl:1;
15655 + unsigned sofintr:1;
15656 + unsigned otgintr:1;
15657 + unsigned modemismatch:1;
15658 + unsigned reserved0:1;
15659 +#else
15660 + unsigned reserved0:1;
15661 + unsigned modemismatch:1;
15662 + unsigned otgintr:1;
15663 + unsigned sofintr:1;
15664 + unsigned rxstsqlvl:1;
15665 + unsigned nptxfempty:1;
15666 + unsigned ginnakeff:1;
15667 + unsigned goutnakeff:1;
15668 + unsigned reserved8:1;
15669 + unsigned i2cintr:1;
15670 + unsigned erlysuspend:1;
15671 + unsigned usbsuspend:1;
15672 + unsigned usbreset:1;
15673 + unsigned enumdone:1;
15674 + unsigned isooutdrop:1;
15675 + unsigned eopframe:1;
15676 + unsigned reserved16:1;
15677 + unsigned epmismatch:1;
15678 + unsigned inepintr:1;
15679 + unsigned outepintr:1;
15680 + unsigned incomplisoin:1;
15681 + unsigned incomplisoout:1;
15682 + unsigned reserved22_23:2;
15683 + unsigned portintr:1;
15684 + unsigned hcintr:1;
15685 + unsigned ptxfempty:1;
15686 + unsigned reserved27:1;
15687 + unsigned conidstschng:1;
15688 + unsigned disconnect:1;
15689 + unsigned sessreqintr:1;
15690 + unsigned wkupintr:1;
15691 +#endif
15692 + } b;
15693 +};
15694 +
15695 +/*
15696 + * This union represents the bit fields of the Core Interrupt Register
15697 + * (GINTSTS). Set/clear the bits using the bit fields then write the
15698 + * d32 value to the register.
15699 + */
15700 +union gintsts_data {
15701 + /* raw register data */
15702 + uint32_t d32;
15703 +#define DWC_SOF_INTR_MASK 0x0008
15704 +
15705 + /* register bits */
15706 + struct {
15707 +#define DWC_HOST_MODE 1
15708 +#ifdef __BIG_ENDIAN_BITFIELD
15709 + unsigned wkupintr:1;
15710 + unsigned sessreqintr:1;
15711 + unsigned disconnect:1;
15712 + unsigned conidstschng:1;
15713 + unsigned reserved27:1;
15714 + unsigned ptxfempty:1;
15715 + unsigned hcintr:1;
15716 + unsigned portintr:1;
15717 + unsigned reserved22_23:2;
15718 + unsigned incomplisoout:1;
15719 + unsigned incomplisoin:1;
15720 + unsigned outepintr:1;
15721 + unsigned inepint:1;
15722 + unsigned epmismatch:1;
15723 + unsigned intokenrx:1;
15724 + unsigned eopframe:1;
15725 + unsigned isooutdrop:1;
15726 + unsigned enumdone:1;
15727 + unsigned usbreset:1;
15728 + unsigned usbsuspend:1;
15729 + unsigned erlysuspend:1;
15730 + unsigned i2cintr:1;
15731 + unsigned reserved8:1;
15732 + unsigned goutnakeff:1;
15733 + unsigned ginnakeff:1;
15734 + unsigned nptxfempty:1;
15735 + unsigned rxstsqlvl:1;
15736 + unsigned sofintr:1;
15737 + unsigned otgintr:1;
15738 + unsigned modemismatch:1;
15739 + unsigned curmode:1;
15740 +#else
15741 + unsigned curmode:1;
15742 + unsigned modemismatch:1;
15743 + unsigned otgintr:1;
15744 + unsigned sofintr:1;
15745 + unsigned rxstsqlvl:1;
15746 + unsigned nptxfempty:1;
15747 + unsigned ginnakeff:1;
15748 + unsigned goutnakeff:1;
15749 + unsigned reserved8:1;
15750 + unsigned i2cintr:1;
15751 + unsigned erlysuspend:1;
15752 + unsigned usbsuspend:1;
15753 + unsigned usbreset:1;
15754 + unsigned enumdone:1;
15755 + unsigned isooutdrop:1;
15756 + unsigned eopframe:1;
15757 + unsigned intokenrx:1;
15758 + unsigned epmismatch:1;
15759 + unsigned inepint:1;
15760 + unsigned outepintr:1;
15761 + unsigned incomplisoin:1;
15762 + unsigned incomplisoout:1;
15763 + unsigned reserved22_23:2;
15764 + unsigned portintr:1;
15765 + unsigned hcintr:1;
15766 + unsigned ptxfempty:1;
15767 + unsigned reserved27:1;
15768 + unsigned conidstschng:1;
15769 + unsigned disconnect:1;
15770 + unsigned sessreqintr:1;
15771 + unsigned wkupintr:1;
15772 +#endif
15773 + } b;
15774 +};
15775 +
15776 +/*
15777 + * This union represents the bit fields in the Device Receive Status Read and
15778 + * Pop Registers (GRXSTSR, GRXSTSP) Read the register into the d32
15779 + * element then read out the bits using the bit elements.
15780 + */
15781 +union device_grxsts_data {
15782 + /* raw register data */
15783 + uint32_t d32;
15784 + /* register bits */
15785 + struct {
15786 +#define DWC_DSTS_SETUP_UPDT 0x6 /* SETUP Packet */
15787 +#define DWC_DSTS_SETUP_COMP 0x4 /* Setup Phase Complete */
15788 +#define DWC_DSTS_GOUT_NAK 0x1 /* Global OUT NAK */
15789 +#define DWC_STS_XFER_COMP 0x3 /* OUT Data Transfer Complete */
15790 +#define DWC_STS_DATA_UPDT 0x2 /* OUT Data Packet */
15791 +
15792 +#ifdef __BIG_ENDIAN_BITFIELD
15793 + unsigned reserved:7;
15794 + unsigned fn:4;
15795 + unsigned pktsts:4;
15796 + unsigned dpid:2;
15797 + unsigned bcnt:11;
15798 + unsigned epnum:4;
15799 +#else
15800 + unsigned epnum:4;
15801 + unsigned bcnt:11;
15802 + unsigned dpid:2;
15803 + unsigned pktsts:4;
15804 + unsigned fn:4;
15805 + unsigned reserved:7;
15806 +#endif
15807 + } b;
15808 +};
15809 +
15810 +/*
15811 + * This union represents the bit fields in the Host Receive Status Read and
15812 + * Pop Registers (GRXSTSR, GRXSTSP) Read the register into the d32
15813 + * element then read out the bits using the bit elements.
15814 + */
15815 +union host_grxsts_data {
15816 + /* raw register data */
15817 + uint32_t d32;
15818 + /* register bits */
15819 + struct {
15820 +#define DWC_GRXSTS_PKTSTS_CH_HALTED 0x7
15821 +#define DWC_GRXSTS_PKTSTS_DATA_TOGGLE_ERR 0x5
15822 +#define DWC_GRXSTS_PKTSTS_IN_XFER_COMP 0x3
15823 +#define DWC_GRXSTS_PKTSTS_IN 0x2
15824 +
15825 +#ifdef __BIG_ENDIAN_BITFIELD
15826 + unsigned reserved:11;
15827 + unsigned pktsts:4;
15828 + unsigned dpid:2;
15829 + unsigned bcnt:11;
15830 + unsigned chnum:4;
15831 +#else
15832 + unsigned chnum:4;
15833 + unsigned bcnt:11;
15834 + unsigned dpid:2;
15835 + unsigned pktsts:4;
15836 + unsigned reserved:11;
15837 +#endif
15838 + } b;
15839 +};
15840 +
15841 +/*
15842 + * This union represents the bit fields in the FIFO Size Registers (HPTXFSIZ,
15843 + * GNPTXFSIZ, DPTXFSIZn). Read the register into the d32 element then
15844 + * read out the bits using the bit elements.
15845 + */
15846 +union fifosize_data {
15847 + /* raw register data */
15848 + uint32_t d32;
15849 + /* register bits */
15850 + struct {
15851 +#ifdef __BIG_ENDIAN_BITFIELD
15852 + unsigned depth:16;
15853 + unsigned startaddr:16;
15854 +#else
15855 + unsigned startaddr:16;
15856 + unsigned depth:16;
15857 +#endif
15858 + } b;
15859 +};
15860 +
15861 +/*
15862 + * This union represents the bit fields in the Non-Periodic Transmit
15863 + * FIFO/Queue Status Register (GNPTXSTS). Read the register into the
15864 + * d32 element then read out the bits using the bit
15865 + * elements.
15866 + */
15867 +union gnptxsts_data {
15868 + /* raw register data */
15869 + uint32_t d32;
15870 + /* register bits */
15871 + struct {
15872 +#ifdef __BIG_ENDIAN_BITFIELD
15873 + unsigned reserved:1;
15874 + unsigned nptxqtop_chnep:4;
15875 + unsigned nptxqtop_token:2;
15876 + unsigned nptxqtop_terminate:1;
15877 + unsigned nptxqspcavail:8;
15878 + unsigned nptxfspcavail:16;
15879 +#else
15880 + unsigned nptxfspcavail:16;
15881 + unsigned nptxqspcavail:8;
15882 + /*
15883 + * Top of the Non-Periodic Transmit Request Queue
15884 + * - bit 24 - Terminate (Last entry for the selected
15885 + * channel/EP)
15886 + * - bits 26:25 - Token Type
15887 + * - 2'b00 - IN/OUT
15888 + * - 2'b01 - Zero Length OUT
15889 + * - 2'b10 - PING/Complete Split
15890 + * - 2'b11 - Channel Halt
15891 + * - bits 30:27 - Channel/EP Number
15892 + */
15893 + unsigned nptxqtop_terminate:1;
15894 + unsigned nptxqtop_token:2;
15895 + unsigned nptxqtop_chnep:4;
15896 + unsigned reserved:1;
15897 +#endif
15898 + } b;
15899 +};
15900 +
15901 +/*
15902 + * This union represents the bit fields in the I2C Control Register
15903 + * (I2CCTL). Read the register into the d32 element then read out the
15904 + * bits using the bit elements.
15905 + */
15906 +union gi2cctl_data {
15907 + /* raw register data */
15908 + uint32_t d32;
15909 + /* register bits */
15910 + struct {
15911 +#ifdef __BIG_ENDIAN_BITFIELD
15912 + unsigned bsydne:1;
15913 + unsigned rw:1;
15914 + unsigned reserved:2;
15915 + unsigned i2cdevaddr:2;
15916 + unsigned i2csuspctl:1;
15917 + unsigned ack:1;
15918 + unsigned i2cen:1;
15919 + unsigned addr:7;
15920 + unsigned regaddr:8;
15921 + unsigned rwdata:8;
15922 +#else
15923 + unsigned rwdata:8;
15924 + unsigned regaddr:8;
15925 + unsigned addr:7;
15926 + unsigned i2cen:1;
15927 + unsigned ack:1;
15928 + unsigned i2csuspctl:1;
15929 + unsigned i2cdevaddr:2;
15930 + unsigned reserved:2;
15931 + unsigned rw:1;
15932 + unsigned bsydne:1;
15933 +#endif
15934 + } b;
15935 +};
15936 +
15937 +/*
15938 + * This union represents the bit fields in the User HW Config1
15939 + * Register. Read the register into the d32 element then read
15940 + * out the bits using the bit elements.
15941 + */
15942 +union hwcfg1_data {
15943 + /* raw register data */
15944 + uint32_t d32;
15945 + /* register bits */
15946 + struct {
15947 +#ifdef __BIG_ENDIAN_BITFIELD
15948 + unsigned ep_dir15:2;
15949 + unsigned ep_dir14:2;
15950 + unsigned ep_dir13:2;
15951 + unsigned ep_dir12:2;
15952 + unsigned ep_dir11:2;
15953 + unsigned ep_dir10:2;
15954 + unsigned ep_dir9:2;
15955 + unsigned ep_dir8:2;
15956 + unsigned ep_dir7:2;
15957 + unsigned ep_dir6:2;
15958 + unsigned ep_dir5:2;
15959 + unsigned ep_dir4:2;
15960 + unsigned ep_dir3:2;
15961 + unsigned ep_dir2:2;
15962 + unsigned ep_dir1:2;
15963 + unsigned ep_dir0:2;
15964 +#else
15965 + unsigned ep_dir0:2;
15966 + unsigned ep_dir1:2;
15967 + unsigned ep_dir2:2;
15968 + unsigned ep_dir3:2;
15969 + unsigned ep_dir4:2;
15970 + unsigned ep_dir5:2;
15971 + unsigned ep_dir6:2;
15972 + unsigned ep_dir7:2;
15973 + unsigned ep_dir8:2;
15974 + unsigned ep_dir9:2;
15975 + unsigned ep_dir10:2;
15976 + unsigned ep_dir11:2;
15977 + unsigned ep_dir12:2;
15978 + unsigned ep_dir13:2;
15979 + unsigned ep_dir14:2;
15980 + unsigned ep_dir15:2;
15981 +#endif
15982 + } b;
15983 +};
15984 +
15985 +/*
15986 + * This union represents the bit fields in the User HW Config2
15987 + * Register. Read the register into the d32 element then read
15988 + * out the bits using the bit elements.
15989 + */
15990 +union hwcfg2_data {
15991 + /* raw register data */
15992 + uint32_t d32;
15993 + /* register bits */
15994 + struct {
15995 +#define DWC_HWCFG2_HS_PHY_TYPE_UTMI_ULPI 3
15996 +#define DWC_HWCFG2_HS_PHY_TYPE_ULPI 2
15997 +#define DWC_HWCFG2_HS_PHY_TYPE_UTMI 1
15998 +#define DWC_HWCFG2_HS_PHY_TYPE_NOT_SUPPORTED 0
15999 +#define DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST 6
16000 +#define DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST 5
16001 +#define DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE 4
16002 +#define DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE 3
16003 +#define DWC_HWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE_OTG 2
16004 +#define DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG 1
16005 +#define DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG 0
16006 +
16007 +#ifdef __BIG_ENDIAN_BITFIELD
16008 + unsigned reserved31:1;
16009 + unsigned dev_token_q_depth:5;
16010 + unsigned host_perio_tx_q_depth:2;
16011 + unsigned nonperio_tx_q_depth:2;
16012 + unsigned rx_status_q_depth:2;
16013 + unsigned dynamic_fifo:1;
16014 + unsigned perio_ep_supported:1;
16015 + unsigned num_host_chan:4;
16016 + unsigned num_dev_ep:4;
16017 + unsigned fs_phy_type:2;
16018 + unsigned hs_phy_type:2;
16019 + unsigned point2point:1;
16020 + unsigned architecture:2;
16021 + unsigned op_mode:3;
16022 +#else
16023 + unsigned op_mode:3;
16024 + unsigned architecture:2;
16025 + unsigned point2point:1;
16026 + unsigned hs_phy_type:2;
16027 + unsigned fs_phy_type:2;
16028 + unsigned num_dev_ep:4;
16029 + unsigned num_host_chan:4;
16030 + unsigned perio_ep_supported:1;
16031 + unsigned dynamic_fifo:1;
16032 + unsigned rx_status_q_depth:2;
16033 + unsigned nonperio_tx_q_depth:2;
16034 + unsigned host_perio_tx_q_depth:2;
16035 + unsigned dev_token_q_depth:5;
16036 + unsigned reserved31:1;
16037 +#endif
16038 + } b;
16039 +};
16040 +
16041 +/**
16042 + * This union represents the bit fields in the User HW Config3
16043 + * Register. Read the register into the d32 element then read
16044 + * out the bits using the bit elements.
16045 + */
16046 +union hwcfg3_data {
16047 + /* raw register data */
16048 + uint32_t d32;
16049 + /* register bits */
16050 + struct {
16051 + /* GHWCFG3 */
16052 +#ifdef __BIG_ENDIAN_BITFIELD
16053 + unsigned dfifo_depth:16;
16054 + unsigned reserved15_13:3;
16055 + unsigned ahb_phy_clock_synch:1;
16056 + unsigned synch_reset_type:1;
16057 + unsigned optional_features:1;
16058 + unsigned vendor_ctrl_if:1;
16059 + unsigned i2c:1;
16060 + unsigned otg_func:1;
16061 + unsigned packet_size_cntr_width:3;
16062 + unsigned xfer_size_cntr_width:4;
16063 +#else
16064 + unsigned xfer_size_cntr_width:4;
16065 + unsigned packet_size_cntr_width:3;
16066 + unsigned otg_func:1;
16067 + unsigned i2c:1;
16068 + unsigned vendor_ctrl_if:1;
16069 + unsigned optional_features:1;
16070 + unsigned synch_reset_type:1;
16071 + unsigned ahb_phy_clock_synch:1;
16072 + unsigned reserved15_13:3;
16073 + unsigned dfifo_depth:16;
16074 +#endif
16075 + } b;
16076 +};
16077 +
16078 +/**
16079 + * This union represents the bit fields in the User HW Config4
16080 + * Register. Read the register into the d32 element then read
16081 + * out the bits using the bit elements.
16082 + */
16083 +union hwcfg4_data {
16084 + /* raw register data */
16085 + uint32_t d32;
16086 + /* register bits */
16087 + struct {
16088 +#ifdef __BIG_ENDIAN_BITFIELD
16089 + unsigned reserved31_25:7;
16090 + unsigned session_end_filt_en:1;
16091 + unsigned b_valid_filt_en:1;
16092 + unsigned a_valid_filt_en:1;
16093 + unsigned vbus_valid_filt_en:1;
16094 + unsigned iddig_filt_en:1;
16095 + unsigned num_dev_mode_ctrl_ep:4;
16096 + unsigned utmi_phy_data_width:2;
16097 + unsigned min_ahb_freq:9;
16098 + unsigned power_optimiz:1;
16099 + unsigned num_dev_perio_in_ep:4;
16100 +#else
16101 + unsigned num_dev_perio_in_ep:4;
16102 + unsigned power_optimiz:1;
16103 + unsigned min_ahb_freq:9;
16104 + unsigned utmi_phy_data_width:2;
16105 + unsigned num_dev_mode_ctrl_ep:4;
16106 + unsigned iddig_filt_en:1;
16107 + unsigned vbus_valid_filt_en:1;
16108 + unsigned a_valid_filt_en:1;
16109 + unsigned b_valid_filt_en:1;
16110 + unsigned session_end_filt_en:1;
16111 + unsigned reserved31_25:7;
16112 +#endif
16113 + } b;
16114 +};
16115 +
16116 +
16117 +/*
16118 + * Device Global Registers. Offsets 800h-BFFh
16119 + *
16120 + * The following structures define the size and relative field offsets
16121 + * for the Device Mode Registers.
16122 + *
16123 + * These registers are visible only in Device mode and must not be
16124 + * accessed in Host mode, as the results are unknown.
16125 + */
16126 +struct dwc_otg_dev_global_regs {
16127 + /* Device Configuration Register. Offset 800h */
16128 + uint32_t dcfg;
16129 + /* Device Control Register. Offset: 804h */
16130 + uint32_t dctl;
16131 + /* Device Status Register (Read Only). Offset: 808h */
16132 + uint32_t dsts;
16133 + /* Reserved. Offset: 80Ch */
16134 + uint32_t unused;
16135 + /*
16136 + * Device IN Endpoint Common Interrupt Mask Register. Offset: 810h
16137 + */
16138 + uint32_t diepmsk;
16139 + /*
16140 + * Device OUT Endpoint Common Interrupt Mask
16141 + * Register. Offset: 814h
16142 + */
16143 + uint32_t doepmsk;
16144 + /*
16145 + * Device All Endpoints Interrupt Register. Offset: 818h
16146 + */
16147 + uint32_t daint;
16148 + /*
16149 + * Device All Endpoints Interrupt Mask Register. Offset:
16150 + * 81Ch
16151 + */
16152 + uint32_t daintmsk;
16153 + /*
16154 + * Device IN Token Queue Read Register-1 (Read Only).
16155 + * Offset: 820h
16156 + */
16157 + uint32_t dtknqr1;
16158 + /*
16159 + * Device IN Token Queue Read Register-2 (Read Only).
16160 + * Offset: 824h
16161 + */
16162 + uint32_t dtknqr2;
16163 + /*
16164 + * Device VBUS discharge Register. Offset: 828h
16165 + */
16166 + uint32_t dvbusdis;
16167 + /*
16168 + * Device VBUS Pulse Register. Offset: 82Ch
16169 + */
16170 + uint32_t dvbuspulse;
16171 + /*
16172 + * Device IN Token Queue Read Register-3 (Read Only).
16173 + * Offset: 830h
16174 + */
16175 + uint32_t dtknqr3;
16176 + /*
16177 + * Device IN Token Queue Read Register-4 (Read Only).
16178 + * Offset: 834h
16179 + */
16180 + uint32_t dtknqr4;
16181 +};
16182 +
16183 +/*
16184 + * This union represents the bit fields in the Device Configuration
16185 + * Register. Read the register into the d32 member then
16186 + * set/clear the bits using the bit elements. Write the
16187 + * d32 member to the dcfg register.
16188 + */
16189 +union dcfg_data {
16190 + /* raw register data */
16191 + uint32_t d32;
16192 + /* register bits */
16193 + struct {
16194 +#define DWC_DCFG_FRAME_INTERVAL_95 3
16195 +#define DWC_DCFG_FRAME_INTERVAL_90 2
16196 +#define DWC_DCFG_FRAME_INTERVAL_85 1
16197 +#define DWC_DCFG_FRAME_INTERVAL_80 0
16198 +#define DWC_DCFG_SEND_STALL 1
16199 +
16200 +#ifdef __BIG_ENDIAN_BITFIELD
16201 + unsigned reserved9:10;
16202 + unsigned epmscnt:4;
16203 + unsigned reserved13_17:5;
16204 + unsigned perfrint:2;
16205 + unsigned devaddr:7;
16206 + unsigned reserved3:1;
16207 + unsigned nzstsouthshk:1;
16208 + unsigned devspd:2;
16209 +#else
16210 +
16211 + /* Device Speed */
16212 + unsigned devspd:2;
16213 + /* Non Zero Length Status OUT Handshake */
16214 + unsigned nzstsouthshk:1;
16215 + unsigned reserved3:1;
16216 + /* Device Addresses */
16217 + unsigned devaddr:7;
16218 + /* Periodic Frame Interval */
16219 + unsigned perfrint:2;
16220 + unsigned reserved13_17:5;
16221 + /* In Endpoint Mis-match count */
16222 + unsigned epmscnt:4;
16223 + unsigned reserved9:10;
16224 +#endif
16225 + } b;
16226 +};
16227 +
16228 +/**
16229 + * This union represents the bit fields in the Device Control
16230 + * Register. Read the register into the d32 member then
16231 + * set/clear the bits using the bit elements.
16232 + */
16233 +union dctl_data {
16234 + /* raw register data */
16235 + uint32_t d32;
16236 + /* register bits */
16237 + struct {
16238 +#ifdef __BIG_ENDIAN_BITFIELD
16239 + unsigned reserved:21;
16240 + unsigned cgoutnak:1;
16241 + unsigned sgoutnak:1;
16242 + unsigned cgnpinnak:1;
16243 + unsigned sgnpinnak:1;
16244 + unsigned tstctl:3;
16245 + unsigned goutnaksts:1;
16246 + unsigned gnpinnaksts:1;
16247 + unsigned sftdiscon:1;
16248 + unsigned rmtwkupsig:1;
16249 +#else
16250 +
16251 + /* Remote Wakeup */
16252 + unsigned rmtwkupsig:1;
16253 + /* Soft Disconnect */
16254 + unsigned sftdiscon:1;
16255 + /* Global Non-Periodic IN NAK Status */
16256 + unsigned gnpinnaksts:1;
16257 + /* Global OUT NAK Status */
16258 + unsigned goutnaksts:1;
16259 + /* Test Control */
16260 + unsigned tstctl:3;
16261 + /* Set Global Non-Periodic IN NAK */
16262 + unsigned sgnpinnak:1;
16263 + /* Clear Global Non-Periodic IN NAK */
16264 + unsigned cgnpinnak:1;
16265 + /* Set Global OUT NAK */
16266 + unsigned sgoutnak:1;
16267 + /* Clear Global OUT NAK */
16268 + unsigned cgoutnak:1;
16269 +
16270 + unsigned reserved:21;
16271 +#endif
16272 + } b;
16273 +};
16274 +
16275 +/*
16276 + * This union represents the bit fields in the Device Status
16277 + * Register. Read the register into the d32 member then
16278 + * set/clear the bits using the bit elements.
16279 + */
16280 +union dsts_data {
16281 + /* raw register data */
16282 + uint32_t d32;
16283 + /* register bits */
16284 + struct {
16285 +#define DWC_DSTS_ENUMSPD_FS_PHY_48MHZ 3
16286 +#define DWC_DSTS_ENUMSPD_LS_PHY_6MHZ 2
16287 +#define DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ 1
16288 +#define DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ 0
16289 +
16290 +#ifdef __BIG_ENDIAN_BITFIELD
16291 + unsigned reserved22_31:10;
16292 + unsigned soffn:14;
16293 + unsigned reserved4_7:4;
16294 + unsigned errticerr:1;
16295 + unsigned enumspd:2;
16296 + unsigned suspsts:1;
16297 +#else
16298 +
16299 + /* Suspend Status */
16300 + unsigned suspsts:1;
16301 + /* Enumerated Speed */
16302 + unsigned enumspd:2;
16303 + /* Erratic Error */
16304 + unsigned errticerr:1;
16305 + unsigned reserved4_7:4;
16306 + /* Frame or Microframe Number of the received SOF */
16307 + unsigned soffn:14;
16308 + unsigned reserved22_31:10;
16309 +#endif
16310 + } b;
16311 +};
16312 +
16313 +/**
16314 + * This union represents the bit fields in the Device IN EP Interrupt
16315 + * Register and the Device IN EP Common Mask Register.
16316 + *
16317 + * It also represents the bit fields in the Device IN EP Common
16318 + * Interrupt Mask Register.
16319 +
16320 + * - Read the register into the d32 member then set/clear the
16321 + * bits using the bit elements.
16322 + */
16323 +union diepint_data {
16324 + /* raw register data */
16325 + uint32_t d32;
16326 + /* register bits */
16327 + struct {
16328 +#ifdef __BIG_ENDIAN_BITFIELD
16329 + unsigned reserved07_31:25;
16330 + unsigned inepnakeff:1;
16331 + unsigned intknepmis:1;
16332 + unsigned intktxfemp:1;
16333 + unsigned timeout:1;
16334 + unsigned ahberr:1;
16335 + unsigned epdisabled:1;
16336 + unsigned xfercompl:1;
16337 +#else
16338 +
16339 +y /* Transfer complete mask */
16340 + unsigned xfercompl:1;
16341 + /* Endpoint disable mask */
16342 + unsigned epdisabled:1;
16343 + /* AHB Error mask */
16344 + unsigned ahberr:1;
16345 + /* TimeOUT Handshake mask (non-ISOC EPs) */
16346 + unsigned timeout:1;
16347 + /* IN Token received with TxF Empty mask */
16348 + unsigned intktxfemp:1;
16349 + /* IN Token Received with EP mismatch mask */
16350 + unsigned intknepmis:1;
16351 + /* IN Endpoint HAK Effective mask */
16352 + unsigned inepnakeff:1;
16353 + unsigned reserved07_31:25;
16354 +#endif
16355 + } b;
16356 +};
16357 +
16358 +/**
16359 + * This union represents the bit fields in the Device OUT EP Interrupt
16360 + * Registerand Device OUT EP Common Interrupt Mask Register.
16361 + *
16362 + * It also represents the bit fields in the Device OUT EP Common
16363 + * Interrupt Mask Register.
16364 + *
16365 + * - Read the register into the d32 member then set/clear the
16366 + * bits using the bit elements.
16367 + */
16368 +union doepint_data {
16369 + /* raw register data */
16370 + uint32_t d32;
16371 + /* register bits */
16372 + struct {
16373 +#ifdef __BIG_ENDIAN_BITFIELD
16374 + unsigned reserved04_31:28;
16375 + unsigned setup:1;
16376 + unsigned ahberr:1;
16377 + unsigned epdisabled:1;
16378 + unsigned xfercompl:1;
16379 +#else
16380 +
16381 + /* Transfer complete */
16382 + unsigned xfercompl:1;
16383 + /* Endpoint disable */
16384 + unsigned epdisabled:1;
16385 + /* AHB Error */
16386 + unsigned ahberr:1;
16387 + /* Setup Phase Done (contorl EPs) */
16388 + unsigned setup:1;
16389 + unsigned reserved04_31:28;
16390 +#endif
16391 + } b;
16392 +};
16393 +
16394 +/*
16395 + * This union represents the bit fields in the Device All EP Interrupt
16396 + * and Mask Registers.
16397 + * - Read the register into the d32 member then set/clear the
16398 + * bits using the bit elements.
16399 + */
16400 +union daint_data {
16401 + /* raw register data */
16402 + uint32_t d32;
16403 + /* register bits */
16404 + struct {
16405 +#ifdef __BIG_ENDIAN_BITFIELD
16406 + unsigned out:16;
16407 + unsigned in:16;
16408 +#else
16409 +
16410 + /* IN Endpoint bits */
16411 + unsigned in:16;
16412 + /* OUT Endpoint bits */
16413 + unsigned out:16;
16414 +#endif
16415 + } ep;
16416 + struct {
16417 +#ifdef __BIG_ENDIAN_BITFIELD
16418 + unsigned outep15:1;
16419 + unsigned outep14:1;
16420 + unsigned outep13:1;
16421 + unsigned outep12:1;
16422 + unsigned outep11:1;
16423 + unsigned outep10:1;
16424 + unsigned outep9:1;
16425 + unsigned outep8:1;
16426 + unsigned outep7:1;
16427 + unsigned outep6:1;
16428 + unsigned outep5:1;
16429 + unsigned outep4:1;
16430 + unsigned outep3:1;
16431 + unsigned outep2:1;
16432 + unsigned outep1:1;
16433 + unsigned outep0:1;
16434 + unsigned inep15:1;
16435 + unsigned inep14:1;
16436 + unsigned inep13:1;
16437 + unsigned inep12:1;
16438 + unsigned inep11:1;
16439 + unsigned inep10:1;
16440 + unsigned inep9:1;
16441 + unsigned inep8:1;
16442 + unsigned inep7:1;
16443 + unsigned inep6:1;
16444 + unsigned inep5:1;
16445 + unsigned inep4:1;
16446 + unsigned inep3:1;
16447 + unsigned inep2:1;
16448 + unsigned inep1:1;
16449 + unsigned inep0:1;
16450 +#else
16451 +
16452 + /* IN Endpoint bits */
16453 + unsigned inep0:1;
16454 + unsigned inep1:1;
16455 + unsigned inep2:1;
16456 + unsigned inep3:1;
16457 + unsigned inep4:1;
16458 + unsigned inep5:1;
16459 + unsigned inep6:1;
16460 + unsigned inep7:1;
16461 + unsigned inep8:1;
16462 + unsigned inep9:1;
16463 + unsigned inep10:1;
16464 + unsigned inep11:1;
16465 + unsigned inep12:1;
16466 + unsigned inep13:1;
16467 + unsigned inep14:1;
16468 + unsigned inep15:1;
16469 + /* OUT Endpoint bits */
16470 + unsigned outep0:1;
16471 + unsigned outep1:1;
16472 + unsigned outep2:1;
16473 + unsigned outep3:1;
16474 + unsigned outep4:1;
16475 + unsigned outep5:1;
16476 + unsigned outep6:1;
16477 + unsigned outep7:1;
16478 + unsigned outep8:1;
16479 + unsigned outep9:1;
16480 + unsigned outep10:1;
16481 + unsigned outep11:1;
16482 + unsigned outep12:1;
16483 + unsigned outep13:1;
16484 + unsigned outep14:1;
16485 + unsigned outep15:1;
16486 +#endif
16487 + } b;
16488 +};
16489 +
16490 +/*
16491 + * This union represents the bit fields in the Device IN Token Queue
16492 + * Read Registers.
16493 + * - Read the register into the d32 member.
16494 + * - READ-ONLY Register
16495 + */
16496 +union dtknq1_data {
16497 + /* raw register data */
16498 + uint32_t d32;
16499 + /* register bits */
16500 + struct {
16501 +#ifdef __BIG_ENDIAN_BITFIELD
16502 + unsigned epnums0_5:24;
16503 + unsigned wrap_bit:1;
16504 + unsigned reserved05_06:2;
16505 + unsigned intknwptr:5;
16506 +#else
16507 +
16508 + /* In Token Queue Write Pointer */
16509 + unsigned intknwptr:5;
16510 + /* Reserved */
16511 + unsigned reserved05_06:2;
16512 + /* write pointer has wrapped. */
16513 + unsigned wrap_bit:1;
16514 + /* EP Numbers of IN Tokens 0 ... 4 */
16515 + unsigned epnums0_5:24;
16516 +#endif
16517 + } b;
16518 +};
16519 +
16520 +/*
16521 + * Device Logical IN Endpoint-Specific Registers. Offsets
16522 + * 900h-AFCh
16523 + *
16524 + * There will be one set of endpoint registers per logical endpoint
16525 + * implemented.
16526 + *
16527 + * These registers are visible only in Device mode and must not be
16528 + * accessed in Host mode, as the results are unknown.
16529 + */
16530 +struct dwc_otg_dev_in_ep_regs {
16531 + /*
16532 + * Device IN Endpoint Control Register. Offset:900h +
16533 + * (ep_num * 20h) + 00h
16534 + */
16535 + uint32_t diepctl;
16536 + /* Reserved. Offset:900h + (ep_num * 20h) + 04h */
16537 + uint32_t reserved04;
16538 + /*
16539 + * Device IN Endpoint Interrupt Register. Offset:900h +
16540 + * (ep_num * 20h) + 08h
16541 + */
16542 + uint32_t diepint;
16543 + /* Reserved. Offset:900h + (ep_num * 20h) + 0Ch */
16544 + uint32_t reserved0C;
16545 + /*
16546 + * Device IN Endpoint Transfer Size
16547 + * Register. Offset:900h + (ep_num * 20h) + 10h
16548 + */
16549 + uint32_t dieptsiz;
16550 + /*
16551 + * Device IN Endpoint DMA Address Register. Offset:900h +
16552 + * (ep_num * 20h) + 14h
16553 + */
16554 + uint32_t diepdma;
16555 + /*
16556 + * Reserved. Offset:900h + (ep_num * 20h) + 18h - 900h +
16557 + * (ep_num * 20h) + 1Ch
16558 + */
16559 + uint32_t reserved18[2];
16560 +};
16561 +
16562 +/**
16563 + * Device Logical OUT Endpoint-Specific Registers. Offsets:
16564 + * B00h-CFCh
16565 + *
16566 + * There will be one set of endpoint registers per logical endpoint
16567 + * implemented.
16568 + *
16569 + * These registers are visible only in Device mode and must not be
16570 + * accessed in Host mode, as the results are unknown.
16571 + */
16572 +struct dwc_otg_dev_out_ep_regs {
16573 + /*
16574 + * Device OUT Endpoint Control Register. Offset:B00h +
16575 + * (ep_num * 20h) + 00h
16576 + */
16577 + uint32_t doepctl;
16578 + /*
16579 + * Device OUT Endpoint Frame number Register. Offset:
16580 + * B00h + (ep_num * 20h) + 04h
16581 + */
16582 + uint32_t doepfn;
16583 + /*
16584 + * Device OUT Endpoint Interrupt Register. Offset:B00h +
16585 + * (ep_num * 20h) + 08h
16586 + */
16587 + uint32_t doepint;
16588 + /*
16589 + * Reserved. Offset:B00h + (ep_num * 20h) + 0Ch */
16590 + uint32_t reserved0C;
16591 + /*
16592 + * Device OUT Endpoint Transfer Size Register. Offset:
16593 + * B00h + (ep_num * 20h) + 10h
16594 + */
16595 + uint32_t doeptsiz;
16596 + /*
16597 + * Device OUT Endpoint DMA Address Register. Offset:B00h
16598 + * + (ep_num * 20h) + 14h
16599 + */
16600 + uint32_t doepdma;
16601 + /*
16602 + * Reserved. Offset:B00h + (ep_num * 20h) + 18h - B00h +
16603 + * (ep_num * 20h) + 1Ch
16604 + */
16605 + uint32_t unused[2];
16606 +};
16607 +
16608 +/*
16609 + * This union represents the bit fields in the Device EP Control
16610 + * Register. Read the register into the d32 member then
16611 + * set/clear the bits using the bit elements.
16612 + */
16613 +union depctl_data {
16614 + /* raw register data */
16615 + uint32_t d32;
16616 + /* register bits */
16617 + struct {
16618 +#define DWC_DEP0CTL_MPS_64 0
16619 +#define DWC_DEP0CTL_MPS_32 1
16620 +#define DWC_DEP0CTL_MPS_16 2
16621 +#define DWC_DEP0CTL_MPS_8 3
16622 +
16623 +#ifdef __BIG_ENDIAN_BITFIELD
16624 + unsigned mps:11;
16625 + unsigned epena:1;
16626 + unsigned epdis:1;
16627 + unsigned setd1pid:1;
16628 + unsigned setd0pid:1;
16629 + unsigned snak:1;
16630 + unsigned cnak:1;
16631 + unsigned txfnum:4;
16632 + unsigned stall:1;
16633 + unsigned snp:1;
16634 + unsigned eptype:2;
16635 + unsigned naksts:1;
16636 + unsigned dpid:1;
16637 + unsigned usbactep:1;
16638 + unsigned nextep:4;
16639 +#else
16640 +
16641 + /*
16642 + * Maximum Packet Size
16643 + * IN/OUT EPn
16644 + * IN/OUT EP0 - 2 bits
16645 + * 2'b00: 64 Bytes
16646 + * 2'b01: 32
16647 + * 2'b10: 16
16648 + * 2'b11: 8
16649 + */
16650 + unsigned mps:11;
16651 + /*
16652 + * Next Endpoint
16653 + * IN EPn/IN EP0
16654 + * OUT EPn/OUT EP0 - reserved
16655 + */
16656 + unsigned nextep:4;
16657 +
16658 + /* USB Active Endpoint */
16659 + unsigned usbactep:1;
16660 +
16661 + /*
16662 + * Endpoint DPID (INTR/Bulk IN and OUT endpoints)
16663 + * This field contains the PID of the packet going to
16664 + * be received or transmitted on this endpoint. The
16665 + * application should program the PID of the first
16666 + * packet going to be received or transmitted on this
16667 + * endpoint , after the endpoint is
16668 + * activated. Application use the SetD1PID and
16669 + * SetD0PID fields of this register to program either
16670 + * D0 or D1 PID.
16671 + *
16672 + * The encoding for this field is
16673 + * - 0: D0
16674 + * - 1: D1
16675 + */
16676 + unsigned dpid:1;
16677 +
16678 + /* NAK Status */
16679 + unsigned naksts:1;
16680 +
16681 + /*
16682 + * Endpoint Type
16683 + * 2'b00: Control
16684 + * 2'b01: Isochronous
16685 + * 2'b10: Bulk
16686 + * 2'b11: Interrupt
16687 + */
16688 + unsigned eptype:2;
16689 +
16690 + /*
16691 + * Snoop Mode
16692 + * OUT EPn/OUT EP0
16693 + * IN EPn/IN EP0 - reserved
16694 + */
16695 + unsigned snp:1;
16696 +
16697 + /* Stall Handshake */
16698 + unsigned stall:1;
16699 +
16700 + /*
16701 + * Tx Fifo Number
16702 + * IN EPn/IN EP0
16703 + * OUT EPn/OUT EP0 - reserved
16704 + */
16705 + unsigned txfnum:4;
16706 +
16707 + /* Clear NAK */
16708 + unsigned cnak:1;
16709 + /* Set NAK */
16710 + unsigned snak:1;
16711 + /*
16712 + * Set DATA0 PID (INTR/Bulk IN and OUT endpoints)
16713 + * Writing to this field sets the Endpoint DPID (DPID)
16714 + * field in this register to DATA0. Set Even
16715 + * (micro)frame (SetEvenFr) (ISO IN and OUT Endpoints)
16716 + * Writing to this field sets the Even/Odd
16717 + * (micro)frame (EO_FrNum) field to even (micro)
16718 + * frame.
16719 + */
16720 + unsigned setd0pid:1;
16721 + /*
16722 + * Set DATA1 PID (INTR/Bulk IN and OUT endpoints)
16723 + * Writing to this field sets the Endpoint DPID (DPID)
16724 + * field in this register to DATA1 Set Odd
16725 + * (micro)frame (SetOddFr) (ISO IN and OUT Endpoints)
16726 + * Writing to this field sets the Even/Odd
16727 + * (micro)frame (EO_FrNum) field to odd (micro) frame.
16728 + */
16729 + unsigned setd1pid:1;
16730 +
16731 + /* Endpoint Disable */
16732 + unsigned epdis:1;
16733 + /* Endpoint Enable */
16734 + unsigned epena:1;
16735 +#endif
16736 + } b;
16737 +};
16738 +
16739 +/*
16740 + * This union represents the bit fields in the Device EP Transfer
16741 + * Size Register. Read the register into the d32 member then
16742 + * set/clear the bits using the bit elements.
16743 + */
16744 +union deptsiz_data {
16745 + /* raw register data */
16746 + uint32_t d32;
16747 + /* register bits */
16748 + struct {
16749 +#ifdef __BIG_ENDIAN_BITFIELD
16750 + unsigned reserved:1;
16751 + unsigned mc:2;
16752 + unsigned pktcnt:10;
16753 + unsigned xfersize:19;
16754 +#else
16755 +
16756 + /* Transfer size */
16757 + unsigned xfersize:19;
16758 + /* Packet Count */
16759 + unsigned pktcnt:10;
16760 + /* Multi Count - Periodic IN endpoints */
16761 + unsigned mc:2;
16762 + unsigned reserved:1;
16763 +#endif
16764 + } b;
16765 +};
16766 +
16767 +/*
16768 + * This union represents the bit fields in the Device EP 0 Transfer
16769 + * Size Register. Read the register into the d32 member then
16770 + * set/clear the bits using the bit elements.
16771 + */
16772 +union deptsiz0_data {
16773 + /* raw register data */
16774 + uint32_t d32;
16775 + /* register bits */
16776 + struct {
16777 +#ifdef __BIG_ENDIAN_BITFIELD
16778 + unsigned reserved31:1;
16779 + unsigned supcnt:2;
16780 + unsigned reserved20_28:9;
16781 + unsigned pktcnt:1;
16782 + unsigned reserved7_18:12;
16783 + unsigned xfersize:7;
16784 +#else
16785 +
16786 + /* Transfer size */
16787 + unsigned xfersize:7;
16788 + /* Reserved */
16789 + unsigned reserved7_18:12;
16790 + /* Packet Count */
16791 + unsigned pktcnt:1;
16792 + /* Reserved */
16793 + unsigned reserved20_28:9;
16794 + /* Setup Packet Count (DOEPTSIZ0 Only) */
16795 + unsigned supcnt:2;
16796 + unsigned reserved31:1;
16797 +#endif
16798 + } b;
16799 +};
16800 +
16801 +/** Maximum number of Periodic FIFOs */
16802 +#define MAX_PERIO_FIFOS 15
16803 +
16804 +/** Maximum number of Endpoints/HostChannels */
16805 +#define MAX_EPS_CHANNELS 16
16806 +
16807 +/*
16808 + * The dwc_otg_dev_if structure contains information needed to manage
16809 + * the DWC_otg controller acting in device mode. It represents the
16810 + * programming view of the device-specific aspects of the controller.
16811 + */
16812 +struct dwc_otg_dev_if {
16813 + /*
16814 + * Pointer to device Global registers.
16815 + * Device Global Registers starting at offset 800h
16816 + */
16817 + struct dwc_otg_dev_global_regs *dev_global_regs;
16818 +#define DWC_DEV_GLOBAL_REG_OFFSET 0x800
16819 +
16820 + /*
16821 + * Device Logical IN Endpoint-Specific Registers 900h-AFCh
16822 + */
16823 + struct dwc_otg_dev_in_ep_regs *in_ep_regs[MAX_EPS_CHANNELS];
16824 +#define DWC_DEV_IN_EP_REG_OFFSET 0x900
16825 +#define DWC_EP_REG_OFFSET 0x20
16826 +
16827 + /* Device Logical OUT Endpoint-Specific Registers B00h-CFCh */
16828 + struct dwc_otg_dev_out_ep_regs *out_ep_regs[MAX_EPS_CHANNELS];
16829 +#define DWC_DEV_OUT_EP_REG_OFFSET 0xB00
16830 +
16831 + /* Device configuration information */
16832 + uint8_t speed; /* Device Speed 0: Unknown, 1: LS, 2:FS, 3: HS */
16833 + uint8_t num_eps; /* Number of EPs range: 1-16 (includes EP0) */
16834 + uint8_t num_perio_eps; /* # of Periodic EP range: 0-15 */
16835 +
16836 + /* Size of periodic FIFOs (Bytes) */
16837 + uint16_t perio_tx_fifo_size[MAX_PERIO_FIFOS];
16838 +
16839 +};
16840 +
16841 +
16842 +/* Host Mode Register Structures */
16843 +
16844 +/*
16845 + * The Host Global Registers structure defines the size and relative
16846 + * field offsets for the Host Mode Global Registers. Host Global
16847 + * Registers offsets 400h-7FFh.
16848 + */
16849 +struct dwc_otg_host_global_regs {
16850 + /* Host Configuration Register. Offset: 400h */
16851 + uint32_t hcfg;
16852 + /* Host Frame Interval Register. Offset: 404h */
16853 + uint32_t hfir;
16854 + /* Host Frame Number / Frame Remaining Register. Offset: 408h */
16855 + uint32_t hfnum;
16856 + /* Reserved. Offset: 40Ch */
16857 + uint32_t reserved40C;
16858 + /* Host Periodic Transmit FIFO/ Queue Status Register. Offset: 410h */
16859 + uint32_t hptxsts;
16860 + /* Host All Channels Interrupt Register. Offset: 414h */
16861 + uint32_t haint;
16862 + /* Host All Channels Interrupt Mask Register. Offset: 418h */
16863 + uint32_t haintmsk;
16864 +};
16865 +
16866 +/*
16867 + * This union represents the bit fields in the Host Configuration Register.
16868 + * Read the register into the d32 member then set/clear the bits using
16869 + * the bit elements. Write the d32 member to the hcfg register.
16870 + */
16871 +union hcfg_data {
16872 + /** raw register data */
16873 + uint32_t d32;
16874 +
16875 + /** register bits */
16876 + struct {
16877 +#define DWC_HCFG_6_MHZ 2
16878 +#define DWC_HCFG_48_MHZ 1
16879 +#define DWC_HCFG_30_60_MHZ 0
16880 +
16881 +#ifdef __BIG_ENDIAN_BITFIELD
16882 + unsigned reserved:29;
16883 + unsigned fslssupp:1;
16884 + unsigned fslspclksel:2;
16885 +#else
16886 +
16887 + /* FS/LS Phy Clock Select */
16888 + unsigned fslspclksel:2;
16889 + /* FS/LS Only Support */
16890 + unsigned fslssupp:1;
16891 + unsigned reserved:29;
16892 +#endif
16893 + } b;
16894 +};
16895 +
16896 +/**
16897 + * This union represents the bit fields in the Host Frame Remaing/Number
16898 + * Register.
16899 + */
16900 +union hfir_data {
16901 + /* raw register data */
16902 + uint32_t d32;
16903 +
16904 + /* register bits */
16905 + struct {
16906 +#ifdef __BIG_ENDIAN_BITFIELD
16907 + unsigned reserved:16;
16908 + unsigned frint:16;
16909 +#else
16910 + unsigned frint:16;
16911 + unsigned reserved:16;
16912 +#endif
16913 + } b;
16914 +};
16915 +
16916 +/**
16917 + * This union represents the bit fields in the Host Frame Remaing/Number
16918 + * Register.
16919 + */
16920 +union hfnum_data {
16921 + /* raw register data */
16922 + uint32_t d32;
16923 +
16924 + /* register bits */
16925 + struct {
16926 +#define DWC_HFNUM_MAX_FRNUM 0x3FFF
16927 +
16928 +#ifdef __BIG_ENDIAN_BITFIELD
16929 + unsigned frrem:16;
16930 + unsigned frnum:16;
16931 +#else
16932 + unsigned frnum:16;
16933 + unsigned frrem:16;
16934 +#endif
16935 + } b;
16936 +};
16937 +
16938 +union hptxsts_data {
16939 + /* raw register data */
16940 + uint32_t d32;
16941 +
16942 + /* register bits */
16943 + struct {
16944 +#ifdef __BIG_ENDIAN_BITFIELD
16945 + unsigned ptxqtop_odd:1;
16946 + unsigned ptxqtop_chnum:4;
16947 + unsigned ptxqtop_token:2;
16948 + unsigned ptxqtop_terminate:1;
16949 + unsigned ptxqspcavail:8;
16950 + unsigned ptxfspcavail:16;
16951 +#else
16952 + unsigned ptxfspcavail:16;
16953 + unsigned ptxqspcavail:8;
16954 + /*
16955 + * Top of the Periodic Transmit Request Queue
16956 + * - bit 24 - Terminate (last entry for the selected channel)
16957 + * - bits 26:25 - Token Type
16958 + * - 2'b00 - Zero length
16959 + * - 2'b01 - Ping
16960 + * - 2'b10 - Disable
16961 + * - bits 30:27 - Channel Number
16962 + * - bit 31 - Odd/even microframe
16963 + */
16964 + unsigned ptxqtop_terminate:1;
16965 + unsigned ptxqtop_token:2;
16966 + unsigned ptxqtop_chnum:4;
16967 + unsigned ptxqtop_odd:1;
16968 +#endif
16969 + } b;
16970 +};
16971 +
16972 +/**
16973 + * This union represents the bit fields in the Host Port Control and Status
16974 + * Register. Read the register into the d32 member then set/clear the
16975 + * bits using the bit elements. Write the d32 member to the
16976 + * hprt0 register.
16977 + */
16978 +union hprt0_data {
16979 + /** raw register data */
16980 + uint32_t d32;
16981 + /** register bits */
16982 + struct {
16983 +#define DWC_HPRT0_PRTSPD_LOW_SPEED 2
16984 +#define DWC_HPRT0_PRTSPD_FULL_SPEED 1
16985 +#define DWC_HPRT0_PRTSPD_HIGH_SPEED 0
16986 +
16987 +#ifdef __BIG_ENDIAN_BITFIELD
16988 + unsigned reserved19_31:13;
16989 + unsigned prtspd:2;
16990 + unsigned prttstctl:4;
16991 + unsigned prtpwr:1;
16992 + unsigned prtlnsts:2;
16993 + unsigned reserved9:1;
16994 + unsigned prtrst:1;
16995 + unsigned prtsusp:1;
16996 + unsigned prtres:1;
16997 + unsigned prtovrcurrchng:1;
16998 + unsigned prtovrcurract:1;
16999 + unsigned prtenchng:1;
17000 + unsigned prtena:1;
17001 + unsigned prtconndet:1;
17002 + unsigned prtconnsts:1;
17003 +#else
17004 + unsigned prtconnsts:1;
17005 + unsigned prtconndet:1;
17006 + unsigned prtena:1;
17007 + unsigned prtenchng:1;
17008 + unsigned prtovrcurract:1;
17009 + unsigned prtovrcurrchng:1;
17010 + unsigned prtres:1;
17011 + unsigned prtsusp:1;
17012 + unsigned prtrst:1;
17013 + unsigned reserved9:1;
17014 + unsigned prtlnsts:2;
17015 + unsigned prtpwr:1;
17016 + unsigned prttstctl:4;
17017 + unsigned prtspd:2;
17018 + unsigned reserved19_31:13;
17019 +#endif
17020 + } b;
17021 +};
17022 +
17023 +/**
17024 + * This union represents the bit fields in the Host All Interrupt
17025 + * Register.
17026 + */
17027 +union haint_data {
17028 + /** raw register data */
17029 + uint32_t d32;
17030 + /** register bits */
17031 + struct {
17032 +#ifdef __BIG_ENDIAN_BITFIELD
17033 + unsigned reserved:16;
17034 + unsigned ch15:1;
17035 + unsigned ch14:1;
17036 + unsigned ch13:1;
17037 + unsigned ch12:1;
17038 + unsigned ch11:1;
17039 + unsigned ch10:1;
17040 + unsigned ch9:1;
17041 + unsigned ch8:1;
17042 + unsigned ch7:1;
17043 + unsigned ch6:1;
17044 + unsigned ch5:1;
17045 + unsigned ch4:1;
17046 + unsigned ch3:1;
17047 + unsigned ch2:1;
17048 + unsigned ch1:1;
17049 + unsigned ch0:1;
17050 +#else
17051 + unsigned ch0:1;
17052 + unsigned ch1:1;
17053 + unsigned ch2:1;
17054 + unsigned ch3:1;
17055 + unsigned ch4:1;
17056 + unsigned ch5:1;
17057 + unsigned ch6:1;
17058 + unsigned ch7:1;
17059 + unsigned ch8:1;
17060 + unsigned ch9:1;
17061 + unsigned ch10:1;
17062 + unsigned ch11:1;
17063 + unsigned ch12:1;
17064 + unsigned ch13:1;
17065 + unsigned ch14:1;
17066 + unsigned ch15:1;
17067 + unsigned reserved:16;
17068 +#endif
17069 + } b;
17070 + struct {
17071 +#ifdef __BIG_ENDIAN_BITFIELD
17072 + unsigned reserved:16;
17073 + unsigned chint:16;
17074 +#else
17075 + unsigned chint:16;
17076 + unsigned reserved:16;
17077 +#endif
17078 + } b2;
17079 +};
17080 +
17081 +/**
17082 + * This union represents the bit fields in the Host All Interrupt
17083 + * Register.
17084 + */
17085 +union haintmsk_data {
17086 + /** raw register data */
17087 + uint32_t d32;
17088 + /** register bits */
17089 + struct {
17090 +#ifdef __BIG_ENDIAN_BITFIELD
17091 + unsigned reserved:16;
17092 + unsigned ch15:1;
17093 + unsigned ch14:1;
17094 + unsigned ch13:1;
17095 + unsigned ch12:1;
17096 + unsigned ch11:1;
17097 + unsigned ch10:1;
17098 + unsigned ch9:1;
17099 + unsigned ch8:1;
17100 + unsigned ch7:1;
17101 + unsigned ch6:1;
17102 + unsigned ch5:1;
17103 + unsigned ch4:1;
17104 + unsigned ch3:1;
17105 + unsigned ch2:1;
17106 + unsigned ch1:1;
17107 + unsigned ch0:1;
17108 +#else
17109 + unsigned ch0:1;
17110 + unsigned ch1:1;
17111 + unsigned ch2:1;
17112 + unsigned ch3:1;
17113 + unsigned ch4:1;
17114 + unsigned ch5:1;
17115 + unsigned ch6:1;
17116 + unsigned ch7:1;
17117 + unsigned ch8:1;
17118 + unsigned ch9:1;
17119 + unsigned ch10:1;
17120 + unsigned ch11:1;
17121 + unsigned ch12:1;
17122 + unsigned ch13:1;
17123 + unsigned ch14:1;
17124 + unsigned ch15:1;
17125 + unsigned reserved:16;
17126 +#endif
17127 + } b;
17128 + struct {
17129 +#ifdef __BIG_ENDIAN_BITFIELD
17130 + unsigned reserved:16;
17131 + unsigned chint:16;
17132 +#else
17133 + unsigned chint:16;
17134 + unsigned reserved:16;
17135 +#endif
17136 + } b2;
17137 +};
17138 +
17139 +/*
17140 + * Host Channel Specific Registers. 500h-5FCh
17141 + */
17142 +struct dwc_otg_hc_regs {
17143 + /*
17144 + * Host Channel 0 Characteristic Register.
17145 + * Offset: 500h + (chan_num * 20h) + 00h
17146 + */
17147 + uint32_t hcchar;
17148 + /*
17149 + * Host Channel 0 Split Control Register.
17150 + * Offset: 500h + (chan_num * 20h) + 04h
17151 + */
17152 + uint32_t hcsplt;
17153 + /*
17154 + * Host Channel 0 Interrupt Register.
17155 + * Offset: 500h + (chan_num * 20h) + 08h
17156 + */
17157 + uint32_t hcint;
17158 + /*
17159 + * Host Channel 0 Interrupt Mask Register.
17160 + * Offset: 500h + (chan_num * 20h) + 0Ch
17161 + */
17162 + uint32_t hcintmsk;
17163 + /*
17164 + * Host Channel 0 Transfer Size Register.
17165 + * Offset: 500h + (chan_num * 20h) + 10h
17166 + */
17167 + uint32_t hctsiz;
17168 + /*
17169 + * Host Channel 0 DMA Address Register.
17170 + * Offset: 500h + (chan_num * 20h) + 14h
17171 + */
17172 + uint32_t hcdma;
17173 + /*
17174 + * Reserved.
17175 + * Offset: 500h + (chan_num * 20h) + 18h -
17176 + * 500h + (chan_num * 20h) + 1Ch
17177 + */
17178 + uint32_t reserved[2];
17179 +};
17180 +
17181 +/**
17182 + * This union represents the bit fields in the Host Channel Characteristics
17183 + * Register. Read the register into the d32 member then set/clear the
17184 + * bits using the bit elements. Write the d32 member to the
17185 + * hcchar register.
17186 + */
17187 +union hcchar_data {
17188 + /** raw register data */
17189 + uint32_t d32;
17190 +
17191 + /** register bits */
17192 + struct {
17193 +#ifdef __BIG_ENDIAN_BITFIELD
17194 + unsigned chen:1;
17195 + unsigned chdis:1;
17196 + unsigned oddfrm:1;
17197 + unsigned devaddr:7;
17198 + unsigned multicnt:2;
17199 + unsigned eptype:2;
17200 + unsigned lspddev:1;
17201 + unsigned reserved:1;
17202 + unsigned epdir:1;
17203 + unsigned epnum:4;
17204 + unsigned mps:11;
17205 +#else
17206 +
17207 + /* Maximum packet size in bytes */
17208 + unsigned mps:11;
17209 +
17210 + /* Endpoint number */
17211 + unsigned epnum:4;
17212 +
17213 + /* 0: OUT, 1: IN */
17214 + unsigned epdir:1;
17215 +
17216 + unsigned reserved:1;
17217 +
17218 + /* 0: Full/high speed device, 1: Low speed device */
17219 + unsigned lspddev:1;
17220 +
17221 + /* 0: Control, 1: Isoc, 2: Bulk, 3: Intr */
17222 + unsigned eptype:2;
17223 +
17224 + /* Packets per frame for periodic transfers. 0 is reserved. */
17225 + unsigned multicnt:2;
17226 +
17227 + /* Device address */
17228 + unsigned devaddr:7;
17229 +
17230 + /*
17231 + * Frame to transmit periodic transaction.
17232 + * 0: even, 1: odd
17233 + */
17234 + unsigned oddfrm:1;
17235 +
17236 + /* Channel disable */
17237 + unsigned chdis:1;
17238 +
17239 + /* Channel enable */
17240 + unsigned chen:1;
17241 +#endif
17242 + } b;
17243 +};
17244 +
17245 +union hcsplt_data {
17246 + /* raw register data */
17247 + uint32_t d32;
17248 +
17249 + /* register bits */
17250 + struct {
17251 +#define DWC_HCSPLIT_XACTPOS_ALL 3
17252 +#define DWC_HCSPLIT_XACTPOS_BEGIN 2
17253 +#define DWC_HCSPLIT_XACTPOS_END 1
17254 +#define DWC_HCSPLIT_XACTPOS_MID 0
17255 +
17256 +#ifdef __BIG_ENDIAN_BITFIELD
17257 + unsigned spltena:1;
17258 + unsigned reserved:14;
17259 + unsigned compsplt:1;
17260 + unsigned xactpos:2;
17261 + unsigned hubaddr:7;
17262 + unsigned prtaddr:7;
17263 +#else
17264 +
17265 + /* Port Address */
17266 + unsigned prtaddr:7;
17267 +
17268 + /* Hub Address */
17269 + unsigned hubaddr:7;
17270 +
17271 + /* Transaction Position */
17272 + unsigned xactpos:2;
17273 +
17274 + /* Do Complete Split */
17275 + unsigned compsplt:1;
17276 +
17277 + /* Reserved */
17278 + unsigned reserved:14;
17279 +
17280 + /* Split Enble */
17281 + unsigned spltena:1;
17282 +#endif
17283 + } b;
17284 +};
17285 +
17286 +/**
17287 + * This union represents the bit fields in the Host All Interrupt
17288 + * Register.
17289 + */
17290 +union hcint_data {
17291 + /* raw register data */
17292 + uint32_t d32;
17293 + /* register bits */
17294 + struct {
17295 +#ifdef __BIG_ENDIAN_BITFIELD
17296 + unsigned reserved:21;
17297 + unsigned datatglerr:1;
17298 + unsigned frmovrun:1;
17299 + unsigned bblerr:1;
17300 + unsigned xacterr:1;
17301 + unsigned nyet:1;
17302 + unsigned ack:1;
17303 + unsigned nak:1;
17304 + unsigned stall:1;
17305 + unsigned ahberr:1;
17306 + unsigned chhltd:1;
17307 + unsigned xfercomp:1;
17308 +#else
17309 +
17310 + /* Transfer Complete */
17311 + unsigned xfercomp:1;
17312 + /* Channel Halted */
17313 + unsigned chhltd:1;
17314 + /* AHB Error */
17315 + unsigned ahberr:1;
17316 + /* STALL Response Received */
17317 + unsigned stall:1;
17318 + /* NAK Response Received */
17319 + unsigned nak:1;
17320 + /* ACK Response Received */
17321 + unsigned ack:1;
17322 + /* NYET Response Received */
17323 + unsigned nyet:1;
17324 + /* Transaction Err */
17325 + unsigned xacterr:1;
17326 + /* Babble Error */
17327 + unsigned bblerr:1;
17328 + /* Frame Overrun */
17329 + unsigned frmovrun:1;
17330 + /* Data Toggle Error */
17331 + unsigned datatglerr:1;
17332 + /* Reserved */
17333 + unsigned reserved:21;
17334 +#endif
17335 + } b;
17336 +};
17337 +
17338 +/**
17339 + * This union represents the bit fields in the Host Channel Transfer Size
17340 + * Register. Read the register into the d32 member then set/clear the
17341 + * bits using the bit elements. Write the d32 member to the
17342 + * hcchar register.
17343 + */
17344 +union hctsiz_data {
17345 + /* raw register data */
17346 + uint32_t d32;
17347 +
17348 + /* register bits */
17349 + struct {
17350 +#define DWC_HCTSIZ_SETUP 3
17351 +#define DWC_HCTSIZ_MDATA 3
17352 +#define DWC_HCTSIZ_DATA2 1
17353 +#define DWC_HCTSIZ_DATA1 2
17354 +#define DWC_HCTSIZ_DATA0 0
17355 +
17356 +#ifdef __BIG_ENDIAN_BITFIELD
17357 + unsigned dopng:1;
17358 + unsigned pid:2;
17359 + unsigned pktcnt:10;
17360 + unsigned xfersize:19;
17361 +#else
17362 +
17363 + /* Total transfer size in bytes */
17364 + unsigned xfersize:19;
17365 +
17366 + /* Data packets to transfer */
17367 + unsigned pktcnt:10;
17368 +
17369 + /*
17370 + * Packet ID for next data packet
17371 + * 0: DATA0
17372 + * 1: DATA2
17373 + * 2: DATA1
17374 + * 3: MDATA (non-Control), SETUP (Control)
17375 + */
17376 + unsigned pid:2;
17377 +
17378 + /* Do PING protocol when 1 */
17379 + unsigned dopng:1;
17380 +#endif
17381 + } b;
17382 +};
17383 +
17384 +/**
17385 + * This union represents the bit fields in the Host Channel Interrupt Mask
17386 + * Register. Read the register into the d32 member then set/clear the
17387 + * bits using the bit elements. Write the d32 member to the
17388 + * hcintmsk register.
17389 + */
17390 +union hcintmsk_data {
17391 + /** raw register data */
17392 + uint32_t d32;
17393 +
17394 + /** register bits */
17395 + struct {
17396 +#ifdef __BIG_ENDIAN_BITFIELD
17397 + unsigned reserved:21;
17398 + unsigned datatglerr:1;
17399 + unsigned frmovrun:1;
17400 + unsigned bblerr:1;
17401 + unsigned xacterr:1;
17402 + unsigned nyet:1;
17403 + unsigned ack:1;
17404 + unsigned nak:1;
17405 + unsigned stall:1;
17406 + unsigned ahberr:1;
17407 + unsigned chhltd:1;
17408 + unsigned xfercompl:1;
17409 +#else
17410 + unsigned xfercompl:1;
17411 + unsigned chhltd:1;
17412 + unsigned ahberr:1;
17413 + unsigned stall:1;
17414 + unsigned nak:1;
17415 + unsigned ack:1;
17416 + unsigned nyet:1;
17417 + unsigned xacterr:1;
17418 + unsigned bblerr:1;
17419 + unsigned frmovrun:1;
17420 + unsigned datatglerr:1;
17421 + unsigned reserved:21;
17422 +#endif
17423 + } b;
17424 +};
17425 +
17426 +/** OTG Host Interface Structure.
17427 + *
17428 + * The OTG Host Interface Structure structure contains information
17429 + * needed to manage the DWC_otg controller acting in host mode. It
17430 + * represents the programming view of the host-specific aspects of the
17431 + * controller.
17432 + */
17433 +struct dwc_otg_host_if {
17434 + /* Host Global Registers starting at offset 400h.*/
17435 + struct dwc_otg_host_global_regs *host_global_regs;
17436 +#define DWC_OTG_HOST_GLOBAL_REG_OFFSET 0x400
17437 +
17438 + /* Host Port 0 Control and Status Register */
17439 + uint32_t *hprt0;
17440 +#define DWC_OTG_HOST_PORT_REGS_OFFSET 0x440
17441 +
17442 + /* Host Channel Specific Registers at offsets 500h-5FCh. */
17443 + struct dwc_otg_hc_regs *hc_regs[MAX_EPS_CHANNELS];
17444 +#define DWC_OTG_HOST_CHAN_REGS_OFFSET 0x500
17445 +#define DWC_OTG_CHAN_REGS_OFFSET 0x20
17446 +
17447 + /* Host configuration information */
17448 + /* Number of Host Channels (range: 1-16) */
17449 + uint8_t num_host_channels;
17450 + /* Periodic EPs supported (0: no, 1: yes) */
17451 + uint8_t perio_eps_supported;
17452 + /* Periodic Tx FIFO Size (Only 1 host periodic Tx FIFO) */
17453 + uint16_t perio_tx_fifo_size;
17454 +
17455 +};
17456 +
17457 +/**
17458 + * This union represents the bit fields in the Power and Clock Gating Control
17459 + * Register. Read the register into the d32 member then set/clear the
17460 + * bits using the bit elements.
17461 + */
17462 +union pcgcctl_data {
17463 + /* raw register data */
17464 + uint32_t d32;
17465 +
17466 + /* register bits */
17467 + struct {
17468 +#ifdef __BIG_ENDIAN_BITFIELD
17469 + unsigned reserved:27;
17470 + unsigned physuspended:1;
17471 + unsigned rstpdwnmodule:1;
17472 + unsigned pwrclmp:1;
17473 + unsigned gatehclk:1;
17474 + unsigned stoppclk:1;
17475 +#else
17476 +
17477 + /* Stop Pclk */
17478 + unsigned stoppclk:1;
17479 + /* Gate Hclk */
17480 + unsigned gatehclk:1;
17481 + /* Power Clamp */
17482 + unsigned pwrclmp:1;
17483 + /* Reset Power Down Modules */
17484 + unsigned rstpdwnmodule:1;
17485 + /* PHY Suspended */
17486 + unsigned physuspended:1;
17487 +
17488 + unsigned reserved:27;
17489 +#endif
17490 + } b;
17491 +};
17492 +
17493 +#endif
17494 --
17495 1.6.0.6
17496
This page took 0.826777 seconds and 5 git commands to generate.