1 Signed-off-by: David Daney <ddaney@caviumnetworks.com>
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
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
15 * Copyright (C) 2008 Wind River Systems
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>
25 +#include <asm/time.h>
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>
32 static struct octeon_cf_data octeon_cf_data;
34 @@ -247,6 +253,105 @@ out:
36 device_initcall(octeon_mgmt_device_init);
39 +static int __init octeon_usb_device_init(void)
41 + int p_rtype_ref_clk = 2;
42 + int number_usb_ports;
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;
53 + number_usb_ports = 1;
56 + for (usb_port = 0; usb_port < number_usb_ports; usb_port++) {
58 + union cvmx_usbnx_clk_ctl usbn_clk_ctl;
59 + struct platform_device *pdev;
60 + struct resource usb_resource[2];
63 + * Divide the core clock down such that USB is as
64 + * close as possible to 125Mhz.
66 + divisor = DIV_ROUND_UP(mips_hpt_frequency, 125000000);
67 + /* Lower than 4 doesn't seem to work properly */
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;
78 + if (cvmx_sysinfo_get()->board_type !=
79 + CVMX_BOARD_TYPE_BBGW_REF)
80 + usbn_clk_ctl.cn56xx.p_rtype = p_rtype_ref_clk;
82 + usbn_clk_ctl.cn56xx.p_rtype = 0;
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);
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;
97 + if (cvmx_sysinfo_get()->board_type !=
98 + CVMX_BOARD_TYPE_BBGW_REF)
99 + usbn_clk_ctl.cn56xx.p_rtype = p_rtype_ref_clk;
101 + usbn_clk_ctl.cn56xx.p_rtype = 0;
103 + usbn_clk_ctl.s.prst = 1;
104 + cvmx_write_csr(CVMX_USBNX_CLK_CTL(usb_port), usbn_clk_ctl.u64);
108 + usbn_clk_ctl.s.hrst = 1;
109 + cvmx_write_csr(CVMX_USBNX_CLK_CTL(usb_port), usbn_clk_ctl.u64);
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;
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;
123 + pdev = platform_device_register_simple("dwc_otg",
127 + pr_err("dwc_otg: Failed to allocate platform device "
128 + "for USB%d\n", usb_port);
135 +device_initcall(octeon_usb_device_init);
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
142 index 0000000..c1e078e
144 +++ b/arch/mips/include/asm/octeon/cvmx-usbcx-defs.h
146 +/***********************license start***************
147 + * Author: Cavium Networks
149 + * Contact: support@caviumnetworks.com
150 + * This file is part of the OCTEON SDK
152 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
169 + * This file may also be available under a different license from Cavium.
170 + * Contact Cavium Networks for more information
171 + ***********************license end**************************************/
173 +#ifndef __CVMX_USBCX_DEFS_H__
174 +#define __CVMX_USBCX_DEFS_H__
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))
281 +union cvmx_usbcx_daint {
283 + struct cvmx_usbcx_daint_s {
284 + uint32_t outepint:16;
285 + uint32_t inepint:16;
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;
296 +union cvmx_usbcx_daintmsk {
298 + struct cvmx_usbcx_daintmsk_s {
299 + uint32_t outepmsk:16;
300 + uint32_t inepmsk:16;
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;
311 +union cvmx_usbcx_dcfg {
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;
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;
332 +union cvmx_usbcx_dctl {
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;
342 + uint32_t goutnaksts:1;
343 + uint32_t gnpinnaksts:1;
344 + uint32_t sftdiscon:1;
345 + uint32_t rmtwkupsig:1;
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;
356 +union cvmx_usbcx_diepctlx {
358 + struct cvmx_usbcx_diepctlx_s {
361 + uint32_t setd1pid:1;
362 + uint32_t setd0pid:1;
367 + uint32_t reserved_20_20:1;
371 + uint32_t usbactep:1;
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;
384 +union cvmx_usbcx_diepintx {
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;
393 + uint32_t epdisbld:1;
394 + uint32_t xfercompl:1;
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;
405 +union cvmx_usbcx_diepmsk {
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;
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;
426 +union cvmx_usbcx_dieptsizx {
428 + struct cvmx_usbcx_dieptsizx_s {
429 + uint32_t reserved_31_31:1;
431 + uint32_t pktcnt:10;
432 + uint32_t xfersize:19;
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;
443 +union cvmx_usbcx_doepctlx {
445 + struct cvmx_usbcx_doepctlx_s {
448 + uint32_t setd1pid:1;
449 + uint32_t setd0pid:1;
452 + uint32_t reserved_22_25:4;
458 + uint32_t usbactep:1;
459 + uint32_t reserved_11_14:4;
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;
471 +union cvmx_usbcx_doepintx {
473 + struct cvmx_usbcx_doepintx_s {
474 + uint32_t reserved_5_31:27;
475 + uint32_t outtknepdis:1;
478 + uint32_t epdisbld:1;
479 + uint32_t xfercompl:1;
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;
490 +union cvmx_usbcx_doepmsk {
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;
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;
509 +union cvmx_usbcx_doeptsizx {
511 + struct cvmx_usbcx_doeptsizx_s {
512 + uint32_t reserved_31_31:1;
514 + uint32_t pktcnt:10;
515 + uint32_t xfersize:19;
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;
526 +union cvmx_usbcx_dptxfsizx {
528 + struct cvmx_usbcx_dptxfsizx_s {
529 + uint32_t dptxfsize:16;
530 + uint32_t dptxfstaddr:16;
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;
541 +union cvmx_usbcx_dsts {
543 + struct cvmx_usbcx_dsts_s {
544 + uint32_t reserved_22_31:10;
546 + uint32_t reserved_4_7:4;
547 + uint32_t errticerr:1;
548 + uint32_t enumspd:2;
549 + uint32_t suspsts:1;
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;
560 +union cvmx_usbcx_dtknqr1 {
562 + struct cvmx_usbcx_dtknqr1_s {
564 + uint32_t wrapbit:1;
565 + uint32_t reserved_5_6:2;
566 + uint32_t intknwptr:5;
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;
577 +union cvmx_usbcx_dtknqr2 {
579 + struct cvmx_usbcx_dtknqr2_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;
591 +union cvmx_usbcx_dtknqr3 {
593 + struct cvmx_usbcx_dtknqr3_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;
605 +union cvmx_usbcx_dtknqr4 {
607 + struct cvmx_usbcx_dtknqr4_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;
619 +union cvmx_usbcx_gahbcfg {
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;
627 + uint32_t hbstlen:4;
628 + uint32_t glblintrmsk:1;
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;
639 +union cvmx_usbcx_ghwcfg1 {
641 + struct cvmx_usbcx_ghwcfg1_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;
653 +union cvmx_usbcx_ghwcfg2 {
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;
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;
680 +union cvmx_usbcx_ghwcfg3 {
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;
691 + uint32_t pktsizewidth:3;
692 + uint32_t xfersizewidth:4;
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;
703 +union cvmx_usbcx_ghwcfg4 {
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;
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;
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;
743 +union cvmx_usbcx_gintmsk {
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;
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;
775 + uint32_t otgintmsk:1;
776 + uint32_t modemismsk:1;
777 + uint32_t reserved_0_0:1;
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;
788 +union cvmx_usbcx_gintsts {
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;
799 + uint32_t reserved_23_23:1;
800 + uint32_t fetsusp:1;
801 + uint32_t incomplp:1;
802 + uint32_t incompisoin:1;
806 + uint32_t reserved_16_16:1;
808 + uint32_t isooutdrop:1;
809 + uint32_t enumdone:1;
811 + uint32_t usbsusp:1;
812 + uint32_t erlysusp:1;
814 + uint32_t ulpickint:1;
815 + uint32_t goutnakeff:1;
816 + uint32_t ginnakeff:1;
817 + uint32_t nptxfemp:1;
821 + uint32_t modemis:1;
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;
833 +union cvmx_usbcx_gnptxfsiz {
835 + struct cvmx_usbcx_gnptxfsiz_s {
836 + uint32_t nptxfdep:16;
837 + uint32_t nptxfstaddr:16;
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;
848 +union cvmx_usbcx_gnptxsts {
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;
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;
865 +union cvmx_usbcx_gotgctl {
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;
877 + uint32_t hstnegscs:1;
878 + uint32_t reserved_2_7:6;
880 + uint32_t sesreqscs:1;
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;
891 +union cvmx_usbcx_gotgint {
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;
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;
914 +union cvmx_usbcx_grstctl {
916 + struct cvmx_usbcx_grstctl_s {
917 + uint32_t ahbidle:1;
919 + uint32_t reserved_11_29:19;
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;
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;
937 +union cvmx_usbcx_grxfsiz {
939 + struct cvmx_usbcx_grxfsiz_s {
940 + uint32_t reserved_16_31:16;
941 + uint32_t rxfdep:16;
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;
952 +union cvmx_usbcx_grxstspd {
954 + struct cvmx_usbcx_grxstspd_s {
955 + uint32_t reserved_25_31:7;
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;
971 +union cvmx_usbcx_grxstsph {
973 + struct cvmx_usbcx_grxstsph_s {
974 + uint32_t reserved_21_31:11;
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;
989 +union cvmx_usbcx_grxstsrd {
991 + struct cvmx_usbcx_grxstsrd_s {
992 + uint32_t reserved_25_31:7;
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;
1008 +union cvmx_usbcx_grxstsrh {
1010 + struct cvmx_usbcx_grxstsrh_s {
1011 + uint32_t reserved_21_31:11;
1012 + uint32_t pktsts:4;
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;
1026 +union cvmx_usbcx_gsnpsid {
1028 + struct cvmx_usbcx_gsnpsid_s {
1029 + uint32_t synopsysid:32;
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;
1040 +union cvmx_usbcx_gusbcfg {
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;
1055 + uint32_t toutcal:3;
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;
1066 +union cvmx_usbcx_haint {
1068 + struct cvmx_usbcx_haint_s {
1069 + uint32_t reserved_16_31:16;
1070 + uint32_t haint:16;
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;
1081 +union cvmx_usbcx_haintmsk {
1083 + struct cvmx_usbcx_haintmsk_s {
1084 + uint32_t reserved_16_31:16;
1085 + uint32_t haintmsk:16;
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;
1096 +union cvmx_usbcx_hccharx {
1098 + struct cvmx_usbcx_hccharx_s {
1101 + uint32_t oddfrm:1;
1102 + uint32_t devaddr:7;
1104 + uint32_t eptype:2;
1105 + uint32_t lspddev:1;
1106 + uint32_t reserved_16_16:1;
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;
1120 +union cvmx_usbcx_hcfg {
1122 + struct cvmx_usbcx_hcfg_s {
1123 + uint32_t reserved_3_31:29;
1124 + uint32_t fslssupp:1;
1125 + uint32_t fslspclksel:2;
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;
1136 +union cvmx_usbcx_hcintx {
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;
1148 + uint32_t ahberr:1;
1149 + uint32_t chhltd:1;
1150 + uint32_t xfercompl:1;
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;
1161 +union cvmx_usbcx_hcintmskx {
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;
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;
1186 +union cvmx_usbcx_hcspltx {
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;
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;
1205 +union cvmx_usbcx_hctsizx {
1207 + struct cvmx_usbcx_hctsizx_s {
1210 + uint32_t pktcnt:10;
1211 + uint32_t xfersize:19;
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;
1222 +union cvmx_usbcx_hfir {
1224 + struct cvmx_usbcx_hfir_s {
1225 + uint32_t reserved_16_31:16;
1226 + uint32_t frint:16;
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;
1237 +union cvmx_usbcx_hfnum {
1239 + struct cvmx_usbcx_hfnum_s {
1240 + uint32_t frrem:16;
1241 + uint32_t frnum:16;
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;
1252 +union cvmx_usbcx_hprt {
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;
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;
1280 +union cvmx_usbcx_hptxfsiz {
1282 + struct cvmx_usbcx_hptxfsiz_s {
1283 + uint32_t ptxfsize:16;
1284 + uint32_t ptxfstaddr:16;
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;
1295 +union cvmx_usbcx_hptxsts {
1297 + struct cvmx_usbcx_hptxsts_s {
1298 + uint32_t ptxqtop:8;
1299 + uint32_t ptxqspcavail:8;
1300 + uint32_t ptxfspcavail:16;
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;
1311 +union cvmx_usbcx_nptxdfifox {
1313 + struct cvmx_usbcx_nptxdfifox_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;
1325 +union cvmx_usbcx_pcgcctl {
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;
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;
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
1349 +++ b/arch/mips/include/asm/octeon/cvmx-usbnx-defs.h
1351 +/***********************license start***************
1352 + * Author: Cavium Networks
1354 + * Contact: support@caviumnetworks.com
1355 + * This file is part of the OCTEON SDK
1357 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
1374 + * This file may also be available under a different license from Cavium.
1375 + * Contact Cavium Networks for more information
1376 + ***********************license end**************************************/
1378 +#ifndef __CVMX_USBNX_DEFS_H__
1379 +#define __CVMX_USBNX_DEFS_H__
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))
1428 +union cvmx_usbnx_bist_status {
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;
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;
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;
1454 +union cvmx_usbnx_clk_ctl {
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;
1468 + uint64_t enable:1;
1471 + uint64_t divide:3;
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;
1485 + uint64_t enable:1;
1488 + uint64_t divide:3;
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;
1503 + uint64_t enable:1;
1506 + uint64_t divide:3;
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;
1514 +union cvmx_usbnx_ctl_status {
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;
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;
1533 +union cvmx_usbnx_dma0_inb_chn0 {
1535 + struct cvmx_usbnx_dma0_inb_chn0_s {
1536 + uint64_t reserved_36_63:28;
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;
1548 +union cvmx_usbnx_dma0_inb_chn1 {
1550 + struct cvmx_usbnx_dma0_inb_chn1_s {
1551 + uint64_t reserved_36_63:28;
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;
1563 +union cvmx_usbnx_dma0_inb_chn2 {
1565 + struct cvmx_usbnx_dma0_inb_chn2_s {
1566 + uint64_t reserved_36_63:28;
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;
1578 +union cvmx_usbnx_dma0_inb_chn3 {
1580 + struct cvmx_usbnx_dma0_inb_chn3_s {
1581 + uint64_t reserved_36_63:28;
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;
1593 +union cvmx_usbnx_dma0_inb_chn4 {
1595 + struct cvmx_usbnx_dma0_inb_chn4_s {
1596 + uint64_t reserved_36_63:28;
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;
1608 +union cvmx_usbnx_dma0_inb_chn5 {
1610 + struct cvmx_usbnx_dma0_inb_chn5_s {
1611 + uint64_t reserved_36_63:28;
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;
1623 +union cvmx_usbnx_dma0_inb_chn6 {
1625 + struct cvmx_usbnx_dma0_inb_chn6_s {
1626 + uint64_t reserved_36_63:28;
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;
1638 +union cvmx_usbnx_dma0_inb_chn7 {
1640 + struct cvmx_usbnx_dma0_inb_chn7_s {
1641 + uint64_t reserved_36_63:28;
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;
1653 +union cvmx_usbnx_dma0_outb_chn0 {
1655 + struct cvmx_usbnx_dma0_outb_chn0_s {
1656 + uint64_t reserved_36_63:28;
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;
1668 +union cvmx_usbnx_dma0_outb_chn1 {
1670 + struct cvmx_usbnx_dma0_outb_chn1_s {
1671 + uint64_t reserved_36_63:28;
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;
1683 +union cvmx_usbnx_dma0_outb_chn2 {
1685 + struct cvmx_usbnx_dma0_outb_chn2_s {
1686 + uint64_t reserved_36_63:28;
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;
1698 +union cvmx_usbnx_dma0_outb_chn3 {
1700 + struct cvmx_usbnx_dma0_outb_chn3_s {
1701 + uint64_t reserved_36_63:28;
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;
1713 +union cvmx_usbnx_dma0_outb_chn4 {
1715 + struct cvmx_usbnx_dma0_outb_chn4_s {
1716 + uint64_t reserved_36_63:28;
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;
1728 +union cvmx_usbnx_dma0_outb_chn5 {
1730 + struct cvmx_usbnx_dma0_outb_chn5_s {
1731 + uint64_t reserved_36_63:28;
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;
1743 +union cvmx_usbnx_dma0_outb_chn6 {
1745 + struct cvmx_usbnx_dma0_outb_chn6_s {
1746 + uint64_t reserved_36_63:28;
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;
1758 +union cvmx_usbnx_dma0_outb_chn7 {
1760 + struct cvmx_usbnx_dma0_outb_chn7_s {
1761 + uint64_t reserved_36_63:28;
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;
1773 +union cvmx_usbnx_dma_test {
1775 + struct cvmx_usbnx_dma_test_s {
1776 + uint64_t reserved_40_63:24;
1779 + uint64_t f_addr:18;
1780 + uint64_t count:11;
1781 + uint64_t channel:5;
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;
1793 +union cvmx_usbnx_int_enb {
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;
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;
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;
1880 +union cvmx_usbnx_int_sum {
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;
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;
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;
1967 +union cvmx_usbnx_usbp_ctl_status {
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;
1987 + uint64_t txpreemphasistune:1;
1988 + uint64_t dma_bmode:1;
1989 + uint64_t usbc_end:1;
1990 + uint64_t usbp_bist: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;
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;
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;
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;
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;
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;
2088 + uint64_t txpreemphasistune:1;
2089 + uint64_t dma_bmode:1;
2090 + uint64_t usbc_end:1;
2091 + uint64_t usbp_bist: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;
2107 + struct cvmx_usbnx_usbp_ctl_status_cn50xx cn56xxp1;
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>
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
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
2157 To compile this driver a module, choose M here: the module
2158 will be called "hwa-hc".
2161 + tristate "Cavium Octeon USB"
2162 + depends on USB && CPU_CAVIUM_OCTEON
2164 + The Cavium Octeon on-chip USB controller. To compile this
2165 + driver as a module, choose M here: the module will be called
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
2174 obj-$(CONFIG_USB_WHCI_HCD) += whci/
2175 +obj-$(CONFIG_USB_DWC_OTG) += dwc_otg/
2177 obj-$(CONFIG_PCI) += pci-quirks.o
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
2183 +++ b/drivers/usb/host/dwc_otg/Kbuild
2186 +# Makefile for DWC_otg Highspeed USB controller driver
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
2194 +EXTRA_CFLAGS += -DDWC_HOST_ONLY
2195 +obj-$(CONFIG_USB_DWC_OTG) += dwc_otg.o
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
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
2205 +++ b/drivers/usb/host/dwc_otg/dwc_otg_attr.c
2207 +/* ==========================================================================
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.
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.
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
2234 + * ========================================================================== */
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.
2244 +/** @page "Linux Module Attributes"
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.
2251 + The following table shows the attributes.
2254 + <td><b> Name</b></td>
2255 + <td><b> Description</b></td>
2256 + <td><b> Access</b></td>
2261 + <td> Returns the current mode: 0 for device mode, 1 for host mode</td>
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>
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>
2281 + <td> Initiates the Host Negotiation Protocol. Read returns the status.</td>
2282 + <td> Read/Write</td>
2287 + <td> Initiates the Session Request Protocol. Read returns the status.</td>
2288 + <td> Read/Write</td>
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>
2298 + <td> bussuspend </td>
2299 + <td> Suspends the USB bus.</td>
2300 + <td> Read/Write</td>
2304 + <td> busconnected </td>
2305 + <td> Gets the connection status of the bus</td>
2310 + <td> gotgctl </td>
2311 + <td> Gets or sets the Core Control Status Register.</td>
2312 + <td> Read/Write</td>
2316 + <td> gusbcfg </td>
2317 + <td> Gets or sets the Core USB Configuration Register</td>
2318 + <td> Read/Write</td>
2322 + <td> grxfsiz </td>
2323 + <td> Gets or sets the Receive FIFO Size Register</td>
2324 + <td> Read/Write</td>
2328 + <td> gnptxfsiz </td>
2329 + <td> Gets or sets the non-periodic Transmit Size Register</td>
2330 + <td> Read/Write</td>
2334 + <td> gpvndctl </td>
2335 + <td> Gets or sets the PHY Vendor Control Register</td>
2336 + <td> Read/Write</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>
2348 + <td> Gets or sets the value of the User ID Register</td>
2349 + <td> Read/Write</td>
2353 + <td> gsnpsid </td>
2354 + <td> Gets the value of the Synopsys ID Regester</td>
2359 + <td> devspeed </td>
2360 + <td> Gets or sets the device speed setting in the DCFG register</td>
2361 + <td> Read/Write</td>
2365 + <td> enumspeed </td>
2366 + <td> Gets the device enumeration Speed.</td>
2371 + <td> hptxfsiz </td>
2372 + <td> Gets the value of the Host Periodic Transmit FIFO</td>
2378 + <td> Gets or sets the value in the Host Port Control and Status Register</td>
2379 + <td> Read/Write</td>
2383 + <td> regoffset </td>
2384 + <td> Sets the register offset for the next Register Access</td>
2385 + <td> Read/Write</td>
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>
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>
2404 + <td> regdump </td>
2405 + <td> Dumps the contents of core registers.</td>
2410 + <td> hcddump </td>
2411 + <td> Dumps the current HCD state.</td>
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>
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).
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).
2443 + To get the current mode:
2444 + cat /sys/devices/lm0/mode
2446 + To power down the USB:
2447 + echo 0 > /sys/devices/lm0/buspower
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 */
2459 +#include <asm/io.h>
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"
2467 +#include "dwc_otg_hcd.h"
2470 + * MACROs for defining sysfs attribute
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, \
2478 + struct dwc_otg_device *otg_dev = _dev->platform_data; \
2480 + val = dwc_read_reg32(_addr_); \
2481 + val = (val & (_mask_)) >> _shift_; \
2482 + return sprintf(buf, "%s = 0x%x\n", _string_, val); \
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) \
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_; \
2497 + "Storing Address=%p Set=0x%08x Clear=0x%08x\n", \
2498 + _addr_, set, clear); \
2499 + dwc_modify_reg32(_addr_, clear, set); \
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);
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);
2519 + * MACROs for defining sysfs attribute for 32-bit registers
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, \
2526 + struct dwc_otg_device *otg_dev = _dev->platform_data; \
2528 + val = dwc_read_reg32(_addr_); \
2529 + return sprintf(buf, "%s = 0x%08x\n", _string_, val); \
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) \
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); \
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);
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);
2555 + * Show the register offset of the Register Access.
2557 +static ssize_t regoffset_show(struct device *_dev,
2558 + struct device_attribute *attr, char *buf)
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);
2566 + * Set the register offset for the next Register Access Read/Write
2568 +static ssize_t regoffset_store(struct device *_dev,
2569 + struct device_attribute *attr, const char *buf,
2572 + struct dwc_otg_device *otg_dev = _dev->platform_data;
2573 + uint32_t offset = simple_strtoul(buf, NULL, 16);
2575 + if (offset < SZ_256K)
2576 + otg_dev->reg_offset = offset;
2578 + dev_err(_dev, "invalid offset\n");
2583 +DEVICE_ATTR(regoffset, S_IRUGO | S_IWUSR, regoffset_show, regoffset_store);
2586 + * Show the value of the register at the offset in the reg_offset
2589 +static ssize_t regvalue_show(struct device *_dev, struct device_attribute *attr,
2592 + struct dwc_otg_device *otg_dev = _dev->platform_data;
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);
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,
2607 + dev_err(_dev, "Invalid offset (0x%0x)\n", otg_dev->reg_offset);
2608 + return sprintf(buf, "invalid offset\n");
2613 + * Store the value in the register at the offset in the reg_offset
2617 +static ssize_t regvalue_store(struct device *_dev,
2618 + struct device_attribute *attr, const char *buf,
2621 + struct dwc_otg_device *otg_dev = _dev->platform_data;
2623 + uint32_t val = simple_strtoul(buf, NULL, 16);
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);
2630 + dwc_write_reg32(addr, val);
2632 + dev_err(_dev, "Invalid Register Offset (0x%08x)\n",
2633 + otg_dev->reg_offset);
2638 +DEVICE_ATTR(regvalue, S_IRUGO | S_IWUSR, regvalue_show, regvalue_store);
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");
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");
2656 +DWC_OTG_DEVICE_ATTR_BITFIELD_RO(busconnected, otg_dev->core_if->host_if->hprt0,
2657 + 0x01, 0, "Bus Connected");
2659 +DWC_OTG_DEVICE_ATTR_REG32_RW(gotgctl,
2660 + &(otg_dev->core_if->core_global_regs->gotgctl),
2662 +DWC_OTG_DEVICE_ATTR_REG32_RW(gusbcfg,
2663 + &(otg_dev->core_if->core_global_regs->gusbcfg),
2665 +DWC_OTG_DEVICE_ATTR_REG32_RW(grxfsiz,
2666 + &(otg_dev->core_if->core_global_regs->grxfsiz),
2668 +DWC_OTG_DEVICE_ATTR_REG32_RW(gnptxfsiz,
2669 + &(otg_dev->core_if->core_global_regs->gnptxfsiz),
2671 +DWC_OTG_DEVICE_ATTR_REG32_RW(gpvndctl,
2672 + &(otg_dev->core_if->core_global_regs->gpvndctl),
2674 +DWC_OTG_DEVICE_ATTR_REG32_RW(ggpio,
2675 + &(otg_dev->core_if->core_global_regs->ggpio),
2677 +DWC_OTG_DEVICE_ATTR_REG32_RW(guid, &(otg_dev->core_if->core_global_regs->guid),
2679 +DWC_OTG_DEVICE_ATTR_REG32_RO(gsnpsid,
2680 + &(otg_dev->core_if->core_global_regs->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");
2689 +DWC_OTG_DEVICE_ATTR_REG32_RO(hptxfsiz,
2690 + &(otg_dev->core_if->core_global_regs->hptxfsiz),
2692 +DWC_OTG_DEVICE_ATTR_REG32_RW(hprt0, otg_dev->core_if->host_if->hprt0, "HPRT0");
2695 + * @todo Add code to initiate the HNP.
2698 + * Show the HNP status bit
2700 +static ssize_t hnp_show(struct device *_dev, struct device_attribute *attr,
2703 + struct dwc_otg_device *otg_dev = _dev->platform_data;
2704 + union gotgctl_data val;
2706 + dwc_read_reg32(&(otg_dev->core_if->core_global_regs->gotgctl));
2707 + return sprintf(buf, "HstNegScs = 0x%x\n", val.b.hstnegscs);
2711 + * Set the HNP Request bit
2713 +static ssize_t hnp_store(struct device *_dev, struct device_attribute *attr,
2714 + const char *buf, size_t count)
2716 + struct dwc_otg_device *otg_dev = _dev->platform_data;
2717 + uint32_t in = simple_strtoul(buf, NULL, 16);
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);
2728 +DEVICE_ATTR(hnp, 0644, hnp_show, hnp_store);
2731 + * @todo Add code to initiate the SRP.
2734 + * Show the SRP status bit
2736 +static ssize_t srp_show(struct device *_dev, struct device_attribute *attr,
2739 +#ifndef DWC_HOST_ONLY
2740 + struct dwc_otg_device *otg_dev = _dev->platform_data;
2741 + union gotgctl_data val;
2743 + dwc_read_reg32(&(otg_dev->core_if->core_global_regs->gotgctl));
2744 + return sprintf(buf, "SesReqScs = 0x%x\n", val.b.sesreqscs);
2746 + return sprintf(buf, "Host Only Mode!\n");
2751 + * Set the SRP Request bit
2753 +static ssize_t srp_store(struct device *_dev, struct device_attribute *attr,
2754 + const char *buf, size_t count)
2756 +#ifndef DWC_HOST_ONLY
2757 + struct dwc_otg_device *otg_dev = _dev->platform_data;
2758 + dwc_otg_pcd_initiate_srp(otg_dev->pcd);
2763 +DEVICE_ATTR(srp, 0644, srp_show, srp_store);
2766 + * @todo Need to do more for power on/off?
2769 + * Show the Bus Power status
2771 +static ssize_t buspower_show(struct device *_dev, struct device_attribute *attr,
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);
2781 + * Set the Bus Power status
2783 +static ssize_t buspower_store(struct device *_dev,
2784 + struct device_attribute *attr, const char *buf,
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;
2792 + mem.d32 = dwc_read_reg32(addr);
2793 + mem.b.prtpwr = on;
2795 + dwc_write_reg32(addr, mem.d32);
2800 +DEVICE_ATTR(buspower, 0644, buspower_show, buspower_store);
2803 + * @todo Need to do more for suspend?
2806 + * Show the Bus Suspend status
2808 +static ssize_t bussuspend_show(struct device *_dev,
2809 + struct device_attribute *attr, char *buf)
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);
2818 + * Set the Bus Suspend status
2820 +static ssize_t bussuspend_store(struct device *_dev,
2821 + struct device_attribute *attr, const char *buf,
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);
2835 +DEVICE_ATTR(bussuspend, 0644, bussuspend_show, bussuspend_store);
2838 + * Show the status of Remote Wakeup.
2840 +static ssize_t remote_wakeup_show(struct device *_dev,
2841 + struct device_attribute *attr, char *buf)
2843 +#ifndef DWC_HOST_ONLY
2844 + struct dwc_otg_device *otg_dev = _dev->platform_data;
2845 + union dctl_data val;
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);
2851 + return sprintf(buf, "Host Only Mode!\n");
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
2861 +static ssize_t remote_wakeup_store(struct device *_dev,
2862 + struct device_attribute *attr,
2863 + const char *buf, size_t count)
2865 +#ifndef DWC_HOST_ONLY
2866 + uint32_t val = simple_strtoul(buf, NULL, 16);
2867 + struct dwc_otg_device *otg_dev = _dev->platform_data;
2869 + dwc_otg_pcd_remote_wakeup(otg_dev->pcd, 1);
2871 + dwc_otg_pcd_remote_wakeup(otg_dev->pcd, 0);
2876 +DEVICE_ATTR(remote_wakeup, S_IRUGO | S_IWUSR, remote_wakeup_show,
2877 + remote_wakeup_store);
2880 + * Dump global registers and either host or device registers (depending on the
2881 + * current mode of the core).
2883 +static ssize_t regdump_show(struct device *_dev, struct device_attribute *attr,
2886 + struct dwc_otg_device *otg_dev = _dev->platform_data;
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);
2892 + dwc_otg_dump_dev_registers(otg_dev->core_if);
2894 + return sprintf(buf, "Register Dump\n");
2897 +DEVICE_ATTR(regdump, S_IRUGO | S_IWUSR, regdump_show, 0);
2900 + * Dump the current hcd state.
2902 +static ssize_t hcddump_show(struct device *_dev, struct device_attribute *attr,
2905 +#ifndef DWC_DEVICE_ONLY
2906 + struct dwc_otg_device *otg_dev = _dev->platform_data;
2907 + dwc_otg_hcd_dump_state(otg_dev->hcd);
2909 + return sprintf(buf, "HCD Dump\n");
2912 +DEVICE_ATTR(hcddump, S_IRUGO | S_IWUSR, hcddump_show, 0);
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.
2919 +static ssize_t hcd_frrem_show(struct device *_dev,
2920 + struct device_attribute *attr, char *buf)
2922 +#ifndef DWC_DEVICE_ONLY
2923 + struct dwc_otg_device *otg_dev = _dev->platform_data;
2924 + dwc_otg_hcd_dump_frrem(otg_dev->hcd);
2926 + return sprintf(buf, "HCD Dump Frame Remaining\n");
2929 +DEVICE_ATTR(hcd_frrem, S_IRUGO | S_IWUSR, hcd_frrem_show, 0);
2932 + * Displays the time required to read the GNPTXFSIZ register many times (the
2933 + * output shows the number of times the register is read).
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)
2942 + int start_jiffies;
2943 + struct dwc_otg_device *otg_dev = _dev->platform_data;
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);
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);
2957 +DEVICE_ATTR(rd_reg_test, S_IRUGO | S_IWUSR, rd_reg_test_show, 0);
2960 + * Displays the time required to write the GNPTXFSIZ register many times (the
2961 + * output shows the number of times the register is written).
2963 +static ssize_t wr_reg_test_show(struct device *_dev,
2964 + struct device_attribute *attr, char *buf)
2968 + int start_jiffies;
2969 + struct dwc_otg_device *otg_dev = _dev->platform_data;
2972 + pr_info("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n",
2973 + HZ, MSEC_PER_JIFFIE, loops_per_jiffy);
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,
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);
2987 +DEVICE_ATTR(wr_reg_test, S_IRUGO | S_IWUSR, wr_reg_test_show, 0);
2990 + * Create the device files
2992 +void dwc_otg_attr_create(struct device *dev)
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);
3024 + pr_err("DWC_OTG: Creating some device files failed\n");
3028 + * Remove the device files
3030 +void dwc_otg_attr_remove(struct device *dev)
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);
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
3065 +++ b/drivers/usb/host/dwc_otg/dwc_otg_attr.h
3067 +/* ==========================================================================
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.
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.
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
3094 + * ========================================================================== */
3096 +#if !defined(__DWC_OTG_ATTR_H__)
3097 +#define __DWC_OTG_ATTR_H__
3100 + * This file contains the interface to the Linux device attributes.
3102 +extern struct device_attribute dev_attr_regoffset;
3103 +extern struct device_attribute dev_attr_regvalue;
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;
3126 +void dwc_otg_attr_create(struct device *dev);
3127 +void dwc_otg_attr_remove(struct device *dev);
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
3134 +++ b/drivers/usb/host/dwc_otg/dwc_otg_cil.c
3136 +/* ==========================================================================
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.
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.
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
3163 + * ========================================================================== */
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.
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
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
3190 +#include <asm/unaligned.h>
3192 +#include <linux/jiffies.h>
3195 +#include "dwc_otg_plat.h"
3196 +#include "dwc_otg_regs.h"
3197 +#include "dwc_otg_cil.h"
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
3208 + * @reg_base_addr: Base address of DWC_otg core registers
3209 + * @core_params: Pointer to the core configuration parameters
3212 +struct dwc_otg_core_if *dwc_otg_cil_init(const uint32_t *reg_base_addr,
3213 + struct dwc_otg_core_params *core_params)
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;
3221 + DWC_DEBUGPL(DBG_CILV, "%s(%p,%p)\n", __func__, reg_base_addr,
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");
3230 + memset(core_if, 0, sizeof(struct dwc_otg_core_if));
3232 + core_if->core_params = core_params;
3233 + core_if->core_global_regs =
3234 + (struct dwc_otg_core_global_regs *)reg_base;
3236 + * Allocate the Device Mode structures.
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 "
3246 + dev_if->dev_global_regs =
3247 + (struct dwc_otg_dev_global_regs *) (reg_base +
3248 + DWC_DEV_GLOBAL_REG_OFFSET);
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));
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);
3263 + dev_if->speed = 0; /* unknown */
3264 + dev_if->num_eps = MAX_EPS_CHANNELS;
3265 + dev_if->num_perio_eps = 0;
3267 + core_if->dev_if = dev_if;
3269 + * Allocate the Host Mode structures.
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");
3280 + host_if->host_global_regs = (struct dwc_otg_host_global_regs *)
3281 + (reg_base + DWC_OTG_HOST_GLOBAL_REG_OFFSET);
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);
3291 + host_if->num_host_channels = MAX_EPS_CHANNELS;
3292 + core_if->host_if = host_if;
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]);
3302 + core_if->pcgcctl = (uint32_t *) (reg_base + DWC_OTG_PCGCCTL_OFFSET);
3305 + * Store the contents of the hardware configuration registers here for
3306 + * easy access later.
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);
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);
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);
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);
3340 + * Set the SRP sucess bit for FS-I2c
3342 + core_if->srp_success = 0;
3343 + core_if->srp_timer_started = 0;
3349 + * This function frees the structures allocated by dwc_otg_cil_init().
3351 + * @core_if: The core interface pointer returned from
3352 + * dwc_otg_cil_init().
3355 +void dwc_otg_cil_remove(struct dwc_otg_core_if *core_if)
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);
3361 + kfree(core_if->dev_if);
3362 + kfree(core_if->host_if);
3368 + * This function enables the controller's Global Interrupt in the AHB Config
3371 + * @core_if: Programming view of DWC_otg controller.
3373 +extern void dwc_otg_enable_global_interrupts(struct dwc_otg_core_if *core_if)
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);
3381 + * This function disables the controller's Global Interrupt in the AHB Config
3384 + * @core_if: Programming view of DWC_otg controller.
3386 +extern void dwc_otg_disable_global_interrupts(struct dwc_otg_core_if *core_if)
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);
3394 + * This function initializes the commmon interrupts, used in both
3395 + * device and host modes.
3397 + * @core_if: Programming view of the DWC_otg controller
3400 +static void dwc_otg_enable_common_interrupts(struct dwc_otg_core_if *core_if)
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);
3410 + * Enable the interrupts in the GINTMSK.
3412 + intr_mask.b.modemismatch = 1;
3413 + intr_mask.b.otgintr = 1;
3414 + if (!core_if->dma_enable)
3415 + intr_mask.b.rxstsqlvl = 1;
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);
3426 + * Initializes the FSLSPClkSel field of the HCFG register depending on the PHY
3429 +static void init_fslspclksel(struct dwc_otg_core_if *core_if)
3432 + union hcfg_data hcfg;
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;
3441 + /* High speed PHY running at full speed or high speed */
3442 + val = DWC_HCFG_30_60_MHZ;
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);
3452 + * Initializes the DevSpd field of the DCFG register depending on the PHY type
3453 + * and the enumeration speed of the device.
3455 +static void init_devspd(struct dwc_otg_core_if *core_if)
3458 + union dcfg_data dcfg;
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 */
3466 + } else if (core_if->core_params->speed == DWC_SPEED_PARAM_FULL) {
3467 + /* High speed PHY running at full speed */
3470 + /* High speed PHY running at high speed */
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);
3481 + * This function initializes the DWC_otg controller registers and
3482 + * prepares the core for device mode or host mode operation.
3484 + * @core_if: Programming view of the DWC_otg controller
3487 +void dwc_otg_core_init(struct dwc_otg_core_if *core_if)
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;
3492 + union gahbcfg_data ahbcfg = {.d32 = 0 };
3493 + union gusbcfg_data usbcfg = {.d32 = 0 };
3494 + union gi2cctl_data i2cctl = {.d32 = 0 };
3496 + DWC_DEBUGPL(DBG_CILV, "dwc_otg_core_init(%p)\n", core_if);
3498 + /* Common Initialization */
3500 + usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
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;
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);
3512 + /* Reset the Controller */
3513 + dwc_otg_core_reset(core_if);
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;
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]);
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;
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);
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 */
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);
3553 + /* Reset after a PHY select */
3554 + dwc_otg_core_reset(core_if);
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
3560 + if (dwc_otg_is_host_mode(core_if))
3561 + init_fslspclksel(core_if);
3563 + init_devspd(core_if);
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);
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);
3582 + /* endif speed == DWC_SPEED_PARAM_FULL */
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;
3597 + core_if->core_params->phy_ulpi_ddr;
3599 + /* UTMI+ interface */
3600 + if (core_if->core_params->phy_utmi_width == 16)
3601 + usbcfg.b.phyif = 1;
3603 + usbcfg.b.phyif = 0;
3605 + dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
3607 + /* Reset after setting the PHY parameters */
3608 + dwc_otg_core_reset(core_if);
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);
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);
3627 + /* Program the GAHBCFG Register. */
3628 + switch (core_if->hwcfg2.b.architecture) {
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;
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);
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);
3650 + ahbcfg.b.dmaenable = core_if->dma_enable;
3651 + dwc_write_reg32(&global_regs->gahbcfg, ahbcfg.d32);
3654 + * Program the GUSBCFG register.
3656 + usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
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);
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);
3672 + case DWC_MODE_NO_HNP_SRP_CAPABLE:
3673 + usbcfg.b.hnpcap = 0;
3674 + usbcfg.b.srpcap = 0;
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);
3683 + case DWC_MODE_NO_SRP_CAPABLE_DEVICE:
3684 + usbcfg.b.hnpcap = 0;
3685 + usbcfg.b.srpcap = 0;
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);
3694 + case DWC_MODE_NO_SRP_CAPABLE_HOST:
3695 + usbcfg.b.hnpcap = 0;
3696 + usbcfg.b.srpcap = 0;
3700 + dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
3702 + /* Enable common interrupts */
3703 + dwc_otg_enable_common_interrupts(core_if);
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;
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);
3720 + * This function enables the Device mode interrupts.
3722 + * @core_if: Programming view of DWC_otg controller
3724 +void dwc_otg_enable_device_interrupts(struct dwc_otg_core_if *core_if)
3726 + union gintmsk_data intr_mask = {.d32 = 0 };
3727 + struct dwc_otg_core_global_regs *global_regs = core_if->core_global_regs;
3729 + DWC_DEBUGPL(DBG_CIL, "%s()\n", __func__);
3731 + /* Disable all interrupts. */
3732 + dwc_write_reg32(&global_regs->gintmsk, 0);
3734 + /* Clear any pending interrupts */
3735 + dwc_write_reg32(&global_regs->gintsts, 0xFFFFFFFF);
3737 + /* Enable the common interrupts */
3738 + dwc_otg_enable_common_interrupts(core_if);
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;
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;
3755 + dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
3757 + DWC_DEBUGPL(DBG_CIL, "%s() gintmsk=%0x\n", __func__,
3758 + dwc_read_reg32(&global_regs->gintmsk));
3762 + * This function initializes the DWC_otg controller registers for
3765 + * @core_if: Programming view of DWC_otg controller
3768 +void dwc_otg_core_dev_init(struct dwc_otg_core_if *core_if)
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 };
3776 + uint32_t rx_fifo_size;
3777 + union fifosize_data nptxfifosize;
3778 +#ifdef USE_PERIODIC_EP
3779 + union fifosize_data ptxfifosize;
3782 + /* Restart the Phy Clock */
3783 + dwc_write_reg32(core_if->pcgcctl, 0);
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);
3791 + /* Configure data FIFO sizes */
3792 + if (core_if->hwcfg2.b.dynamic_fifo && params->enable_dynamic_fifo) {
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);
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));
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));
3818 +#ifdef USE_PERIODIC_EP
3819 + /**@todo NGS: Fix Periodic FIFO Sizing! */
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.
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],
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;
3841 + /* Flush the FIFOs */
3842 + dwc_otg_flush_tx_fifo(core_if, 0x10); /* all Tx FIFOs */
3843 + dwc_otg_flush_rx_fifo(core_if);
3845 + /* Flush the Learning Queue. */
3846 + resetctl.b.intknqflsh = 1;
3847 + dwc_write_reg32(&core_if->core_global_regs->grstctl, resetctl.d32);
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);
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) {
3860 + depctl.b.epdis = 1;
3861 + depctl.b.snak = 1;
3865 + dwc_write_reg32(&dev_if->in_ep_regs[i]->diepctl, depctl.d32);
3867 + depctl.d32 = dwc_read_reg32(&dev_if->out_ep_regs[i]->doepctl);
3868 + if (depctl.b.epena) {
3870 + depctl.b.epdis = 1;
3871 + depctl.b.snak = 1;
3875 + dwc_write_reg32(&dev_if->out_ep_regs[i]->doepctl, depctl.d32);
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);
3885 + dwc_otg_enable_device_interrupts(core_if);
3889 + * This function enables the Host mode interrupts.
3891 + * @core_if: Programming view of DWC_otg controller
3893 +void dwc_otg_enable_host_interrupts(struct dwc_otg_core_if *core_if)
3895 + struct dwc_otg_core_global_regs *global_regs = core_if->core_global_regs;
3896 + union gintmsk_data intr_mask = {.d32 = 0 };
3898 + DWC_DEBUGPL(DBG_CIL, "%s()\n", __func__);
3900 + /* Disable all interrupts. */
3901 + dwc_write_reg32(&global_regs->gintmsk, 0);
3903 + /* Clear any pending interrupts. */
3904 + dwc_write_reg32(&global_regs->gintsts, 0xFFFFFFFF);
3906 + /* Enable the common interrupts */
3907 + dwc_otg_enable_common_interrupts(core_if);
3910 + * Enable host mode interrupts without disturbing common
3913 + intr_mask.b.sofintr = 1;
3914 + intr_mask.b.portintr = 1;
3915 + intr_mask.b.hcintr = 1;
3917 + dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
3921 + * This function disables the Host Mode interrupts.
3923 + * @core_if: Programming view of DWC_otg controller
3925 +void dwc_otg_disable_host_interrupts(struct dwc_otg_core_if *core_if)
3927 + struct dwc_otg_core_global_regs *global_regs = core_if->core_global_regs;
3928 + union gintmsk_data intr_mask = {.d32 = 0 };
3930 + DWC_DEBUGPL(DBG_CILV, "%s()\n", __func__);
3933 + * Disable host mode interrupts without disturbing common
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;
3942 + dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, 0);
3946 + * The FIFOs are established based on a default percentage of the
3947 + * total FIFO depth. This function converts the percentage into the
3951 +static inline uint32_t fifo_percentage(uint16_t total_fifo_size,
3952 + int32_t percentage)
3954 + /* 16-byte aligned */
3955 + return ((total_fifo_size * percentage) / 100) & (-1 << 3);
3959 + * This function initializes the DWC_otg controller registers for
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.
3966 + * @core_if: Programming view of DWC_otg controller
3969 +void dwc_otg_core_host_init(struct dwc_otg_core_if *core_if)
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;
3978 + union hcchar_data hcchar;
3979 + union hcfg_data hcfg;
3980 + struct dwc_otg_hc_regs *hc_regs;
3982 + union gotgctl_data gotgctl = {.d32 = 0 };
3984 + DWC_DEBUGPL(DBG_CILV, "%s(%p)\n", __func__, core_if);
3986 + /* Restart the Phy Clock */
3987 + dwc_write_reg32(core_if->pcgcctl, 0);
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);
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);
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));
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));
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));
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);
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);
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);
4062 + /* Halt all channels to put them into a known state. */
4063 + for (i = 0; i < num_channels; i++) {
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);
4073 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
4074 + if (++count > 1000) {
4076 + ("%s: Unable to clear halt on channel %d\n",
4080 + } while (hcchar.b.chen);
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);
4094 + dwc_otg_enable_host_interrupts(core_if);
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.
4103 + * @core_if: Programming view of DWC_otg controller
4104 + * @hc: Information needed to initialize the host channel
4106 +void dwc_otg_hc_init(struct dwc_otg_core_if *core_if, struct dwc_hc *hc)
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;
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];
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);
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;
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;
4148 + hc_intr_mask.b.nak = 1;
4149 + hc_intr_mask.b.nyet = 1;
4151 + hc_intr_mask.b.ack = 1;
4154 + if (hc->do_split) {
4155 + hc_intr_mask.b.nak = 1;
4156 + if (hc->complete_split)
4157 + hc_intr_mask.b.nyet = 1;
4159 + hc_intr_mask.b.ack = 1;
4162 + if (hc->error_state)
4163 + hc_intr_mask.b.ack = 1;
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;
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;
4181 + hc_intr_mask.b.ack = 1;
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;
4189 + if (hc->ep_is_in) {
4190 + hc_intr_mask.b.xacterr = 1;
4191 + hc_intr_mask.b.bblerr = 1;
4196 + dwc_write_reg32(&hc_regs->hcintmsk, hc_intr_mask.d32);
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);
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);
4207 + * Program the HCCHARn register with the endpoint characteristics for
4208 + * the current transfer.
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;
4218 + dwc_write_reg32(&host_if->hc_regs[hc_num]->hcchar, hcchar.d32);
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);
4230 + * Program the HCSPLIT register for SPLITs
4233 + if (hc->do_split) {
4234 + DWC_DEBUGPL(DBG_HCDV, "Programming HC %d with split --> %s\n",
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);
4250 + dwc_write_reg32(&host_if->hc_regs[hc_num]->hcsplt, hcsplt.d32);
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
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.
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.
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.
4277 + * @core_if: Controller register interface.
4278 + * @hc: Host channel to halt.
4279 + * @halt_status: Reason for halting the channel.
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)
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;
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;
4295 + WARN_ON(halt_status == DWC_OTG_HC_XFER_NO_HALT_STATUS);
4297 + if (halt_status == DWC_OTG_HC_XFER_URB_DEQUEUE ||
4298 + halt_status == DWC_OTG_HC_XFER_AHB_ERR) {
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.
4305 + union hcintmsk_data hcintmsk;
4307 + hcintmsk.b.chhltd = 1;
4308 + dwc_write_reg32(&hc_regs->hcintmsk, hcintmsk.d32);
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.
4315 + dwc_write_reg32(&hc_regs->hcint, ~hcintmsk.d32);
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
4322 + hc->halt_status = halt_status;
4324 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
4325 + if (hcchar.b.chen == 0) {
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
4341 + if (hc->halt_pending) {
4343 + * A halt has already been issued for this channel. This might
4344 + * happen when a transfer is aborted by a higher level in
4349 + ("*** %s: Channel %d, hc->halt_pending already set ***\n",
4350 + __func__, hc->hc_num);
4352 +/* dwc_otg_dump_global_registers(core_if); */
4353 +/* dwc_otg_dump_host_registers(core_if); */
4358 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
4359 + hcchar.b.chen = 1;
4360 + hcchar.b.chdis = 1;
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;
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;
4379 + dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
4381 + hc->halt_status = halt_status;
4383 + if (hcchar.b.chen) {
4384 + hc->halt_pending = 1;
4385 + hc->halt_on_queue = 0;
4387 + hc->halt_on_queue = 1;
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);
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.
4403 + * @core_if: Programming view of DWC_otg controller.
4404 + * @hc: Identifies the host channel to clean up.
4406 +void dwc_otg_hc_cleanup(struct dwc_otg_core_if *core_if, struct dwc_hc *hc)
4408 + struct dwc_otg_hc_regs *hc_regs;
4410 + hc->xfer_started = 0;
4413 + * Clear channel interrupt enables and any unhandled channel interrupt
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);
4421 + del_timer(&core_if->hc_xfer_timer[hc->hc_num]);
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);
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.
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
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)
4447 + if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
4448 + hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
4449 + union hfnum_data hfnum;
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;
4455 + if (hc->ep_type == DWC_OTG_EP_TYPE_INTR && hc->do_split
4456 + && !hc->complete_split) {
4457 + switch (hfnum.b.frnum & 0x7) {
4459 + core_if->hfnum_7_samples++;
4460 + core_if->hfnum_7_frrem_accum += hfnum.b.frrem;
4463 + core_if->hfnum_0_samples++;
4464 + core_if->hfnum_0_frrem_accum += hfnum.b.frrem;
4467 + core_if->hfnum_other_samples++;
4468 + core_if->hfnum_other_frrem_accum +=
4478 +static void hc_xfer_timeout(unsigned long _ptr)
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]);
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.
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
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.
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.
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
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.
4519 +void dwc_otg_hc_start_transfer(struct dwc_otg_core_if *core_if,
4520 + struct dwc_hc *hc)
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];
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;
4537 + hctsiz.b.dopng = 1;
4541 + if (hc->do_split) {
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 */
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;
4554 + hctsiz.b.xfersize = hc->xfer_len;
4557 + * Ensure that the transfer length and packet count will fit
4558 + * in the widths allocated for them in the HCTSIZn register.
4560 + if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
4561 + hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
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.)
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) {
4575 + * Make sure that xfer_len is a multiple of
4576 + * max packet size.
4578 + hc->xfer_len = max_hc_xfer_size - hc->max_packet + 1;
4581 + if (hc->xfer_len > 0) {
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;
4590 + /* Need 1 packet for transfer length of 0. */
4594 + if (hc->ep_is_in) {
4596 + * Always program an integral # of max packets
4597 + * for IN transfers.
4599 + hc->xfer_len = num_packets * hc->max_packet;
4602 + if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
4603 + hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
4605 + * Make sure that the multi_count field matches the
4606 + * actual transfer length.
4608 + hc->multi_count = num_packets;
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;
4623 + hc->data_pid_start =
4624 + DWC_OTG_HC_PID_DATA2;
4627 + if (hc->multi_count == 1) {
4628 + hc->data_pid_start =
4629 + DWC_OTG_HC_PID_DATA0;
4631 + hc->data_pid_start =
4632 + DWC_OTG_HC_PID_MDATA;
4636 + hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
4640 + hctsiz.b.xfersize = hc->xfer_len;
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);
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);
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);
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);
4666 + dwc_write_reg32(&hc_regs->hcdma,
4667 + (uint32_t) (long)hc->xfer_buff);
4668 +#endif /* CONFIG_CPU_CAVIUM_OCTEON */
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);
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);
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);
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);
4695 + hc->xfer_started = 1;
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);
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]);
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.
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.
4726 + * Returns 1 if a new request is queued, 0 if no more requests are required
4727 + * for this transfer.
4729 +int dwc_otg_hc_continue_transfer(struct dwc_otg_core_if *core_if,
4730 + struct dwc_hc *hc)
4732 + DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
4734 + if (hc->do_split) {
4735 + /* SPLITs always queue just once per channel */
4737 + } else if (hc->data_pid_start == DWC_OTG_HC_PID_SETUP) {
4738 + /* SETUPs are queued only once since they can't be NAKed. */
4740 + } else if (hc->ep_is_in) {
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
4753 + union hcchar_data hcchar;
4754 + struct dwc_otg_hc_regs *hc_regs =
4755 + core_if->host_if->hc_regs[hc->hc_num];
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",
4763 + dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
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;
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);
4779 + /* Load OUT packet into the appropriate Tx FIFO. */
4780 + dwc_otg_hc_write_packet(core_if, hc);
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.
4793 +void dwc_otg_hc_do_ping(struct dwc_otg_core_if *core_if, struct dwc_hc *hc)
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];
4799 + DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
4802 + hctsiz.b.dopng = 1;
4803 + hctsiz.b.pktcnt = 1;
4804 + dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
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);
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
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.
4822 +void dwc_otg_hc_write_packet(struct dwc_otg_core_if *core_if, struct dwc_hc *hc)
4825 + uint32_t remaining_count;
4826 + uint32_t byte_count;
4827 + uint32_t dword_count;
4829 + uint32_t *data_buff = (uint32_t *) (hc->xfer_buff);
4830 + uint32_t *data_fifo = core_if->data_fifo[hc->hc_num];
4832 + remaining_count = hc->xfer_len - hc->xfer_count;
4833 + if (remaining_count > hc->max_packet)
4834 + byte_count = hc->max_packet;
4836 + byte_count = remaining_count;
4838 + dword_count = (byte_count + 3) / 4;
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);
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));
4850 + hc->xfer_count += byte_count;
4851 + hc->xfer_buff += byte_count;
4855 + * Gets the current USB frame number. This is the frame number from the last
4858 +uint32_t dwc_otg_get_frame_number(struct dwc_otg_core_if *core_if)
4860 + union dsts_data dsts;
4861 + dsts.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts);
4863 + /* read current frame/microfreme number from DSTS register */
4864 + return dsts.b.soffn;
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.
4872 + * @core_if: Programming view of DWC_otg controller.
4873 + * @dest: Destination buffer for packet data.
4875 +void dwc_otg_read_setup_packet(struct dwc_otg_core_if *core_if, uint32_t *dest)
4877 + /* Get the 8 bytes of a setup transaction data */
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]);
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.
4889 + * @core_if: Programming view of DWC_otg controller.
4890 + * @ep: The EP0 data.
4892 +void dwc_otg_ep0_activate(struct dwc_otg_core_if *core_if, struct dwc_ep *ep)
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 };
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);
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;
4912 + case DWC_DSTS_ENUMSPD_LS_PHY_6MHZ:
4913 + diepctl.b.mps = DWC_DEP0CTL_MPS_8;
4917 + dwc_write_reg32(&dev_if->in_ep_regs[0]->diepctl, diepctl.d32);
4919 + /* Enable OUT EP for receive */
4920 + doepctl.b.epena = 1;
4921 + dwc_write_reg32(&dev_if->out_ep_regs[0]->doepctl, doepctl.d32);
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));
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));
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.
4940 + * @core_if: Programming view of DWC_otg controller.
4941 + * @ep: The EP to activate.
4943 +void dwc_otg_ep_activate(struct dwc_otg_core_if *core_if, struct dwc_ep *ep)
4945 + struct dwc_otg_dev_if *dev_if = core_if->dev_if;
4946 + union depctl_data depctl;
4948 + union daint_data daintmsk = {.d32 = 0 };
4950 + DWC_DEBUGPL(DBG_PCDV, "%s() EP%d-%s\n", __func__, ep->num,
4951 + (ep->is_in ? "IN" : "OUT"));
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;
4958 + addr = &dev_if->out_ep_regs[ep->num]->doepctl;
4959 + daintmsk.ep.out = 1 << ep->num;
4962 + /* If the EP is already active don't change the EP Control
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;
4970 + if (ep->type != DWC_OTG_EP_TYPE_ISOC)
4971 + depctl.b.setd0pid = 1;
4973 + depctl.b.usbactep = 1;
4975 + dwc_write_reg32(addr, depctl.d32);
4976 + DWC_DEBUGPL(DBG_PCDV, "DEPCTL=%08x\n", dwc_read_reg32(addr));
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));
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.
4991 + * @core_if: Programming view of DWC_otg controller.
4992 + * @ep: The EP to deactivate.
4994 +void dwc_otg_ep_deactivate(struct dwc_otg_core_if *core_if, struct dwc_ep *ep)
4996 + union depctl_data depctl = {.d32 = 0 };
4998 + union daint_data daintmsk = {.d32 = 0 };
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;
5005 + addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl;
5006 + daintmsk.ep.out = 1 << ep->num;
5009 + depctl.b.usbactep = 0;
5010 + dwc_write_reg32(addr, depctl.d32);
5012 + /* Disable the Interrupt for this EP */
5013 + dwc_modify_reg32(&core_if->dev_if->dev_global_regs->daintmsk,
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.
5025 + * @core_if: Programming view of DWC_otg controller.
5026 + * @ep: The EP to start the transfer on.
5028 +void dwc_otg_ep_start_transfer(struct dwc_otg_core_if *core_if,
5029 + struct dwc_ep *ep)
5032 + * @todo Refactor this funciton to check the transfer size
5033 + * count value does not execed the number bits in the Transfer
5036 + union depctl_data depctl;
5037 + union deptsiz_data deptsiz;
5038 + union gintmsk_data intr_mask = {.d32 = 0 };
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;
5051 + int lvl = SET_DEBUG_LEVEL(DBG_PCD);
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);
5058 + transfer_len = ep->xfer_len - ep->xfer_count;
5059 + if (transfer_len > MAX_XFER_SIZE)
5060 + transfer_len = MAX_XFER_SIZE;
5062 + if (transfer_len == 0) {
5064 + /* OUT EP to recieve Zero-length packet set transfer
5065 + * size to maxpacket size. */
5067 + transfer_len = ep->maxpacket;
5070 + (transfer_len + ep->maxpacket - 1) / ep->maxpacket;
5071 + if (num_packets > MAX_PKT_COUNT)
5072 + num_packets = MAX_PKT_COUNT;
5074 + DWC_DEBUGPL(DBG_PCD, "transfer_len=%d #pckt=%d\n", transfer_len,
5077 + deptsiz.b.xfersize = transfer_len;
5078 + deptsiz.b.pktcnt = num_packets;
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);
5087 + /* EP enable, IN data in FIFO */
5088 + depctl.b.cnak = 1;
5089 + depctl.b.epena = 1;
5091 + if (ep->is_in == 1) {
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",
5099 + dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
5100 + dwc_write_reg32(&in_regs->diepctl, depctl.d32);
5102 + * Enable the Non-Periodic Tx FIFO empty interrupt, the
5103 + * data will be written into the fifo by the ISR.
5105 + if (core_if->dma_enable) {
5106 + dwc_write_reg32(&in_regs->diepdma,
5107 + (uint32_t) ep->xfer_buff);
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);
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);
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->
5129 + dwc_read_reg32(&core_if->core_global_regs->gintmsk));
5131 + SET_DEBUG_LEVEL(lvl);
5133 + DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s()\n", __func__);
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);
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;
5147 + dwc_read_reg32(&core_if->core_global_regs->gnptxsts);
5148 + if (txstatus.b.nptxqspcavail == 0) {
5150 + DWC_PRINT("TX Queue Full (0x%0x)\n", txstatus.d32);
5155 + depctl.d32 = dwc_read_reg32(&(in_regs->diepctl));
5156 + deptsiz.d32 = dwc_read_reg32(&(in_regs->dieptsiz));
5158 + /* Zero Length Packet? */
5159 + if (ep->xfer_len == 0) {
5160 + deptsiz.b.xfersize = 0;
5161 + deptsiz.b.pktcnt = 1;
5164 + /* Program the transfer size and packet count
5165 + * as follows: xfersize = N * maxpacket +
5166 + * short_packet pktcnt = N + (short_packet
5169 + deptsiz.b.xfersize = ep->xfer_len;
5170 + deptsiz.b.pktcnt =
5171 + (ep->xfer_len - 1 + ep->maxpacket) /
5175 + dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
5177 + /* Write the DMA register */
5178 + if (core_if->dma_enable) {
5179 + dwc_write_reg32(&(in_regs->diepdma),
5180 + (uint32_t) ep->dma_addr);
5183 + * Enable the Non-Periodic Tx FIFO empty interrupt,
5184 + * the data will be written into the fifo by the ISR.
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);
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);
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,
5205 + /* OUT endpoint */
5206 + struct dwc_otg_dev_out_ep_regs *out_regs =
5207 + core_if->dev_if->out_ep_regs[ep->num];
5209 + depctl.d32 = dwc_read_reg32(&(out_regs->doepctl));
5210 + deptsiz.d32 = dwc_read_reg32(&(out_regs->doeptsiz));
5212 + /* Program the transfer size and packet count as follows:
5215 + * xfersize = N * maxpacket
5217 + if (ep->xfer_len == 0) {
5218 + /* Zero Length Packet */
5219 + deptsiz.b.xfersize = ep->maxpacket;
5220 + deptsiz.b.pktcnt = 1;
5222 + deptsiz.b.pktcnt =
5223 + (ep->xfer_len + (ep->maxpacket - 1)) /
5225 + deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket;
5227 + dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32);
5229 + DWC_DEBUGPL(DBG_PCDV, "ep%d xfersize=%d pktcnt=%d\n",
5230 + ep->num, deptsiz.b.xfersize, deptsiz.b.pktcnt);
5232 + if (core_if->dma_enable) {
5233 + dwc_write_reg32(&(out_regs->doepdma),
5234 + (uint32_t) ep->dma_addr);
5237 + if (ep->type == DWC_OTG_EP_TYPE_ISOC) {
5239 + * @todo NGS: dpid is read-only. Use setd0pid
5242 + depctl.b.dpid = ep->even_odd_frame;
5246 + depctl.b.cnak = 1;
5247 + depctl.b.epena = 1;
5249 + dwc_write_reg32(&out_regs->doepctl, depctl.d32);
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->
5257 + dwc_read_reg32(&core_if->core_global_regs->
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.
5268 + * @core_if: Programming view of DWC_otg controller.
5269 + * @ep: The EP0 data.
5271 +void dwc_otg_ep0_start_transfer(struct dwc_otg_core_if *core_if,
5272 + struct dwc_ep *ep)
5274 + union depctl_data depctl;
5275 + union deptsiz0_data deptsiz;
5276 + union gintmsk_data intr_mask = {.d32 = 0 };
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,
5283 + ep->total_len = ep->xfer_len;
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 };
5292 + dwc_read_reg32(&core_if->core_global_regs->gnptxsts);
5293 + if (tx_status.b.nptxqspcavail == 0) {
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",
5300 + deptsiz.b.xfersize, deptsiz.b.pktcnt);
5301 + DWC_PRINT("TX Queue or FIFO Full (0x%0x)\n",
5308 + depctl.d32 = dwc_read_reg32(&in_regs->diepctl);
5309 + deptsiz.d32 = dwc_read_reg32(&in_regs->dieptsiz);
5311 + /* Zero Length Packet? */
5312 + if (ep->xfer_len == 0) {
5313 + deptsiz.b.xfersize = 0;
5314 + deptsiz.b.pktcnt = 1;
5316 + /* Program the transfer size and packet count
5317 + * as follows: xfersize = N * maxpacket +
5318 + * short_packet pktcnt = N + (short_packet
5321 + if (ep->xfer_len > ep->maxpacket) {
5322 + ep->xfer_len = ep->maxpacket;
5323 + deptsiz.b.xfersize = ep->maxpacket;
5325 + deptsiz.b.xfersize = ep->xfer_len;
5327 + deptsiz.b.pktcnt = 1;
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,
5336 + /* Write the DMA register */
5337 + if (core_if->dma_enable) {
5338 + dwc_write_reg32(&(in_regs->diepdma),
5339 + (uint32_t) ep->dma_addr);
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);
5348 + * Enable the Non-Periodic Tx FIFO empty interrupt, the
5349 + * data will be written into the fifo by the ISR.
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);
5357 + dwc_modify_reg32(&core_if->core_global_regs->gintmsk,
5358 + intr_mask.d32, intr_mask.d32);
5361 + } else { /* OUT endpoint */
5362 + struct dwc_otg_dev_out_ep_regs *out_regs =
5363 + core_if->dev_if->out_ep_regs[ep->num];
5365 + depctl.d32 = dwc_read_reg32(&out_regs->doepctl);
5366 + deptsiz.d32 = dwc_read_reg32(&out_regs->doeptsiz);
5368 + /* Program the transfer size and packet count as follows:
5369 + * xfersize = N * (maxpacket + 4 - (maxpacket % 4))
5371 + if (ep->xfer_len == 0) {
5372 + /* Zero Length Packet */
5373 + deptsiz.b.xfersize = ep->maxpacket;
5374 + deptsiz.b.pktcnt = 1;
5376 + deptsiz.b.pktcnt =
5377 + (ep->xfer_len + (ep->maxpacket - 1)) /
5379 + deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket;
5382 + dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32);
5383 + DWC_DEBUGPL(DBG_PCDV, "len=%d xfersize=%d pktcnt=%d\n",
5385 + deptsiz.b.xfersize, deptsiz.b.pktcnt);
5387 + if (core_if->dma_enable) {
5388 + dwc_write_reg32(&(out_regs->doepdma),
5389 + (uint32_t) ep->dma_addr);
5393 + depctl.b.cnak = 1;
5394 + depctl.b.epena = 1;
5395 + dwc_write_reg32(&(out_regs->doepctl), depctl.d32);
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.
5405 + * @core_if: Programming view of DWC_otg controller.
5406 + * @ep: The EP0 data.
5408 +void dwc_otg_ep0_continue_transfer(struct dwc_otg_core_if *core_if,
5409 + struct dwc_ep *ep)
5411 + union depctl_data depctl;
5412 + union deptsiz0_data deptsiz;
5413 + union gintmsk_data intr_mask = {.d32 = 0 };
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 };
5421 + dwc_read_reg32(&core_if->core_global_regs->gnptxsts);
5423 + * @todo Should there be check for room in the Tx
5424 + * Status Queue. If not remove the code above this comment.
5427 + depctl.d32 = dwc_read_reg32(&in_regs->diepctl);
5428 + deptsiz.d32 = dwc_read_reg32(&in_regs->dieptsiz);
5431 + * Program the transfer size and packet count
5432 + * as follows: xfersize = N * maxpacket +
5433 + * short_packet pktcnt = N + (short_packet
5436 + deptsiz.b.xfersize =
5437 + (ep->total_len - ep->xfer_count) >
5438 + ep->maxpacket ? ep->maxpacket : (ep->total_len -
5440 + deptsiz.b.pktcnt = 1;
5441 + ep->xfer_len += deptsiz.b.xfersize;
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,
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);
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);
5461 + * Enable the Non-Periodic Tx FIFO empty interrupt, the
5462 + * data will be written into the fifo by the ISR.
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,
5470 + dwc_modify_reg32(&core_if->core_global_regs->gintmsk,
5471 + intr_mask.d32, intr_mask.d32);
5479 +void dump_msg(const u8 *buf, unsigned int length)
5481 + unsigned int start, num, i;
5482 + char line[52], *p;
5484 + if (length >= 512)
5487 + while (length > 0) {
5488 + num = min(length, 16u);
5490 + for (i = 0; i < num; ++i) {
5493 + sprintf(p, " %02x", buf[i]);
5497 + DWC_PRINT("%6x: %s\n", start, line);
5504 +static inline void dump_msg(const u8 *buf, unsigned int length)
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.
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.
5519 +void dwc_otg_ep_write_packet(struct dwc_otg_core_if *core_if,
5520 + struct dwc_ep *ep,
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.
5528 + * ep->xfer_buff always starts DWORD aligned in memory and is a
5529 + * multiple of DWORD in length
5531 + * ep->xfer_len can be any number of bytes
5533 + * ep->xfer_count is a multiple of ep->maxpacket until the last
5536 + * FIFO access is DWORD */
5539 + uint32_t byte_count;
5540 + uint32_t dword_count;
5542 + uint32_t *data_buff = (uint32_t *) ep->xfer_buff;
5544 + if (ep->xfer_count >= ep->xfer_len) {
5545 + DWC_WARN("%s() No data for EP%d!!!\n", __func__, ep->num);
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;
5553 + byte_count = ep->maxpacket;
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;
5560 + dump_msg(ep->xfer_buff, byte_count);
5562 + if (ep->type == DWC_OTG_EP_TYPE_ISOC)
5564 + *@todo NGS Where are the Periodic Tx FIFO addresses
5565 + * intialized? What should this be?
5567 + fifo = core_if->data_fifo[ep->tx_fifo_num];
5569 + fifo = core_if->data_fifo[ep->num];
5571 + DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "fifo=%p buff=%p *p=%08x bc=%d\n",
5572 + fifo, data_buff, *data_buff, byte_count);
5575 + for (i = 0; i < dword_count; i++, data_buff++)
5576 + dwc_write_reg32(fifo, *data_buff);
5579 + ep->xfer_count += byte_count;
5580 + ep->xfer_buff += byte_count;
5584 + * Set the EP STALL.
5586 + * @core_if: Programming view of DWC_otg controller.
5587 + * @ep: The EP to set the stall on.
5589 +void dwc_otg_ep_set_stall(struct dwc_otg_core_if *core_if, struct dwc_ep *ep)
5591 + union depctl_data depctl;
5592 + uint32_t *depctl_addr;
5594 + DWC_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, ep->num,
5595 + (ep->is_in ? "IN" : "OUT"));
5597 + if (ep->is_in == 1) {
5599 + &(core_if->dev_if->in_ep_regs[ep->num]->diepctl);
5600 + depctl.d32 = dwc_read_reg32(depctl_addr);
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);
5610 + &(core_if->dev_if->out_ep_regs[ep->num]->doepctl);
5611 + depctl.d32 = dwc_read_reg32(depctl_addr);
5613 + /* set the stall bit */
5614 + depctl.b.stall = 1;
5615 + dwc_write_reg32(depctl_addr, depctl.d32);
5617 + DWC_DEBUGPL(DBG_PCD, "DEPCTL=%0x\n", dwc_read_reg32(depctl_addr));
5622 + * Clear the EP STALL.
5624 + * @core_if: Programming view of DWC_otg controller.
5625 + * @ep: The EP to clear stall from.
5627 +void dwc_otg_ep_clear_stall(struct dwc_otg_core_if *core_if, struct dwc_ep *ep)
5629 + union depctl_data depctl;
5630 + uint32_t *depctl_addr;
5632 + DWC_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, ep->num,
5633 + (ep->is_in ? "IN" : "OUT"));
5635 + if (ep->is_in == 1) {
5637 + &(core_if->dev_if->in_ep_regs[ep->num]->diepctl);
5640 + &(core_if->dev_if->out_ep_regs[ep->num]->doepctl);
5643 + depctl.d32 = dwc_read_reg32(depctl_addr);
5645 + /* clear the stall bits */
5646 + depctl.b.stall = 0;
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.
5654 + if (ep->type == DWC_OTG_EP_TYPE_INTR ||
5655 + ep->type == DWC_OTG_EP_TYPE_BULK) {
5656 + depctl.b.setd0pid = 1; /* DATA0 */
5659 + dwc_write_reg32(depctl_addr, depctl.d32);
5660 + DWC_DEBUGPL(DBG_PCD, "DEPCTL=%0x\n", dwc_read_reg32(depctl_addr));
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.
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.
5672 +void dwc_otg_read_packet(struct dwc_otg_core_if *core_if,
5673 + uint8_t *dest, uint16_t bytes)
5676 + int word_count = (bytes + 3) / 4;
5678 + uint32_t *fifo = core_if->data_fifo[0];
5679 + uint32_t *data_buff = (uint32_t *) dest;
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.
5687 + DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s(%p,%p,%d)\n", __func__,
5688 + core_if, dest, bytes);
5690 + for (i = 0; i < word_count; i++, data_buff++)
5691 + *data_buff = dwc_read_reg32(fifo);
5696 + * This functions reads the device registers and prints them
5698 + * @core_if: Programming view of DWC_otg controller.
5700 +void dwc_otg_dump_dev_registers(struct dwc_otg_core_if *core_if)
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));
5726 + addr = &core_if->dev_if->dev_global_regs->dvbusdis;
5727 + DWC_PRINT("DVBUSID @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
5729 + addr = &core_if->dev_if->dev_global_regs->dvbuspulse;
5730 + DWC_PRINT("DVBUSPULSE @%p : 0x%08X\n", addr, dwc_read_reg32(addr));
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));
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));
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));
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));
5780 + * This function reads the host registers and prints them
5782 + * @core_if: Programming view of DWC_otg controller.
5784 +void dwc_otg_dump_host_registers(struct dwc_otg_core_if *core_if)
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));
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));
5831 + * This function reads the core global registers and prints them
5833 + * @core_if: Programming view of DWC_otg controller.
5835 +void dwc_otg_dump_global_registers(struct dwc_otg_core_if *core_if)
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));
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));
5893 + * Flush a Tx FIFO.
5895 + * @core_if: Programming view of DWC_otg controller.
5896 + * @_num: Tx FIFO to flush.
5898 +extern void dwc_otg_flush_tx_fifo(struct dwc_otg_core_if *core_if, const int _num)
5900 + struct dwc_otg_core_global_regs *global_regs = core_if->core_global_regs;
5901 + union grstctl_data greset = {.d32 = 0 };
5904 + DWC_DEBUGPL((DBG_CIL | DBG_PCDV), "Flush Tx FIFO %d\n", _num);
5906 + greset.b.txfflsh = 1;
5907 + greset.b.txfnum = _num;
5908 + dwc_write_reg32(&global_regs->grstctl, greset.d32);
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));
5919 + } while (greset.b.txfflsh == 1);
5920 + /* Wait for 3 PHY Clocks */
5927 + * @core_if: Programming view of DWC_otg controller.
5929 +extern void dwc_otg_flush_rx_fifo(struct dwc_otg_core_if *core_if)
5931 + struct dwc_otg_core_global_regs *global_regs = core_if->core_global_regs;
5932 + union grstctl_data greset = {.d32 = 0 };
5935 + DWC_DEBUGPL((DBG_CIL | DBG_PCDV), "%s\n", __func__);
5939 + greset.b.rxfflsh = 1;
5940 + dwc_write_reg32(&global_regs->grstctl, greset.d32);
5943 + greset.d32 = dwc_read_reg32(&global_regs->grstctl);
5944 + if (++count > 10000) {
5945 + DWC_WARN("%s() HANG! GRSTCTL=%0x\n", __func__,
5949 + } while (greset.b.rxfflsh == 1);
5950 + /* Wait for 3 PHY Clocks */
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.
5958 +void dwc_otg_core_reset(struct dwc_otg_core_if *core_if)
5960 + struct dwc_otg_core_global_regs *global_regs = core_if->core_global_regs;
5961 + union grstctl_data greset = {.d32 = 0 };
5964 + DWC_DEBUGPL(DBG_CILV, "%s\n", __func__);
5965 + /* Wait for AHB master IDLE state. */
5968 + greset.d32 = dwc_read_reg32(&global_regs->grstctl);
5969 + if (++count > 100000) {
5970 + DWC_WARN("%s() HANG! AHB Idle GRSTCTL=%0x\n", __func__,
5974 + } while (greset.b.ahbidle == 0);
5976 + /* Core Soft Reset */
5978 + greset.b.csftrst = 1;
5979 + dwc_write_reg32(&global_regs->grstctl, greset.d32);
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);
5987 + } while (greset.b.csftrst == 1);
5988 + /* Wait for 3 PHY Clocks */
5993 + * Register HCD callbacks. The callbacks are used to start and stop
5994 + * the HCD for interrupt processing.
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*).
6000 +extern void dwc_otg_cil_register_hcd_callbacks(struct dwc_otg_core_if *core_if,
6001 + struct dwc_otg_cil_callbacks *_cb,
6004 + core_if->hcd_cb = _cb;
6009 + * Register PCD callbacks. The callbacks are used to start and stop
6010 + * the PCD for interrupt processing.
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*).
6016 +extern void dwc_otg_cil_register_pcd_callbacks(struct dwc_otg_core_if *core_if,
6017 + struct dwc_otg_cil_callbacks *_cb,
6020 + core_if->pcd_cb = _cb;
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
6027 +++ b/drivers/usb/host/dwc_otg/dwc_otg_cil.h
6029 +/* ==========================================================================
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.
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.
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
6056 + * ========================================================================== */
6058 +#if !defined(__DWC_CIL_H__)
6059 +#define __DWC_CIL_H__
6061 +#include "dwc_otg_plat.h"
6062 +#include "dwc_otg_regs.h"
6064 +#include "linux/timer.h"
6068 + * This file contains the interface to the Core Interface Layer.
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.
6077 + /** EP number used for register address lookup */
6079 + /** EP direction 0 = OUT */
6082 + unsigned active:1;
6085 + * Periodic Tx FIFO # for IN EPs For INTR EP set to 0 to use
6086 + * non-periodic Tx FIFO
6088 + unsigned tx_fifo_num:4;
6089 + /** EP type: 0 - Control, 1 - ISOC, 2 - BULK, 3 - INTR */
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
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;
6103 + /** @name Transfer state */
6107 + * Pointer to the beginning of the transfer buffer -- do not modify
6108 + * during transfer.
6111 + uint32_t dma_addr;
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;
6121 + unsigned sent_zlp:1;
6122 + /** Total len for control transfer */
6123 + unsigned total_len:19;
6129 + * Reasons for halting a host channel.
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
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.
6154 + /** Host channel number used for register address lookup */
6157 + /** Device to access */
6158 + unsigned dev_addr:7;
6160 + /** EP to access */
6161 + unsigned ep_num:4;
6163 + /** EP direction. 0: OUT, 1: IN */
6164 + unsigned ep_is_in:1;
6168 + * One of the following values:
6169 + * - DWC_OTG_EP_SPEED_LOW
6170 + * - DWC_OTG_EP_SPEED_FULL
6171 + * - DWC_OTG_EP_SPEED_HIGH
6174 +#define DWC_OTG_EP_SPEED_LOW 0
6175 +#define DWC_OTG_EP_SPEED_FULL 1
6176 +#define DWC_OTG_EP_SPEED_HIGH 2
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
6186 + unsigned ep_type:2;
6188 + /** Max packet size in bytes */
6189 + unsigned max_packet:11;
6192 + * PID for initial transaction.
6196 + * 3: MDATA (non-Control EP),
6197 + * SETUP (Control EP)
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
6206 + /** Number of periodic transactions per (micro)frame */
6207 + unsigned multi_count:2;
6209 + /** @name Transfer State */
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;
6222 + * Flag to indicate whether the transfer has been started. Set to 1 if
6223 + * it has been started, 0 otherwise.
6225 + uint8_t xfer_started;
6228 + * Set to 1 to indicate that a PING request should be issued on this
6229 + * channel. If 0, process normally.
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.
6237 + uint8_t error_state;
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.
6245 + uint8_t halt_on_queue;
6248 + * Set to 1 if the host channel has been halted, but the core is not
6249 + * finished flushing queued requests. Otherwise 0.
6251 + uint8_t halt_pending;
6254 + * Reason for halting the host channel.
6256 + enum dwc_otg_halt_status halt_status;
6259 + * Split settings for the host channel
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 */
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 */
6274 + /** Set when the host channel does a short read. */
6275 + uint8_t short_read;
6278 + * Number of requests issued for this channel since it was assigned to
6279 + * the current transfer (not counting PINGs).
6284 + * Queue Head for the transfer being processed by this channel.
6286 + struct dwc_otg_qh *qh;
6290 + /** Entry in list of host channels. */
6291 + struct list_head hc_list_entry;
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.
6300 +struct dwc_otg_core_params {
6302 +#define dwc_param_opt_default 1
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
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
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.
6322 + * 1 - DMA (default, if available)
6324 + int32_t dma_enable;
6325 +#define dwc_param_dma_enable_default 1
6328 + * The DMA Burst size (applicable only for External DMA
6329 + * Mode). 1, 4, 8 16, 32, 64, 128, 256 (default 32)
6331 + int32_t dma_burst_size; /* Translate this to GAHBCFG values */
6332 +#define dwc_param_dma_burst_size_default 32
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)
6343 +#define dwc_param_speed_default 0
6344 +#define DWC_SPEED_PARAM_HIGH 0
6345 +#define DWC_SPEED_PARAM_FULL 1
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
6352 + int32_t host_support_fs_ls_low_power;
6353 +#define dwc_param_host_support_fs_ls_low_power_default 0
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.
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
6369 + * 0 - Use cC FIFO size parameters
6370 + * 1 - Allow dynamic FIFO sizing (default)
6372 + int32_t enable_dynamic_fifo;
6373 +#define dwc_param_enable_dynamic_fifo_default 1
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
6378 + * 32 to 32768 (default 8192)
6379 + * Note: The total FIFO memory depth in the FPGA configuration is 8192.
6381 + int32_t data_fifo_size;
6382 +#define dwc_param_data_fifo_size_default 8192
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)
6388 + int32_t dev_rx_fifo_size;
6389 +#define dwc_param_dev_rx_fifo_size_default 1064
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)
6395 + int32_t dev_nperio_tx_fifo_size;
6396 +#define dwc_param_dev_nperio_tx_fifo_size_default 1024
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)
6402 + uint32_t dev_perio_tx_fifo_size[MAX_PERIO_FIFOS];
6403 +#define dwc_param_dev_perio_tx_fifo_size_default 256
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)
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
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)
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
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)
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
6431 + * The maximum transfer size supported in bytes.
6432 + * 2047 to 65,535 (default 65,535)
6434 + int32_t max_transfer_size;
6435 +#define dwc_param_max_transfer_size_default 65535
6438 + * The maximum number of packets in a transfer.
6439 + * 15 to 511 (default 511)
6441 + int32_t max_packet_count;
6442 +#define dwc_param_max_packet_count_default 511
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.
6449 + int32_t host_channels;
6450 +#define dwc_param_host_channels_default 12
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.
6459 + int32_t dev_endpoints;
6460 +#define dwc_param_dev_endpoints_default 6
6463 + * Specifies the type of PHY interface to use. By default, the driver
6464 + * will automatically detect the phy_type.
6466 + * 0 - Full Speed PHY
6467 + * 1 - UTMI+ (default)
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
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.
6485 + * 8 or 16 bits (default 16)
6487 + int32_t phy_utmi_width;
6488 +#define dwc_param_phy_utmi_width_default 16
6491 + * Specifies whether the ULPI operates at double or single
6492 + * data rate. This parameter is only applicable if PHY_TYPE is
6495 + * 0 - single data rate ULPI interface with 8 bit wide data
6497 + * 1 - double data rate ULPI interface with 4 bit wide data
6500 + int32_t phy_ulpi_ddr;
6501 +#define dwc_param_phy_ulpi_ddr_default 0
6504 + * Specifies whether to use the internal or external supply to
6505 + * drive the vbus with a ULPI phy.
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
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)
6518 + int32_t i2c_enable;
6519 +#define dwc_param_i2c_enable_default 0
6521 + int32_t ulpi_fs_ls;
6522 +#define dwc_param_ulpi_fs_ls_default 0
6525 +#define dwc_param_ts_dline_default 0
6530 + * The FIFOs are established based on a default percentage of the total
6531 + * FIFO depth. This check insures that the defaults are reasonable.
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
6540 +struct dwc_otg_core_if;
6541 +struct hc_xfer_info {
6542 + struct dwc_otg_core_if *core_if;
6543 + struct dwc_hc *hc;
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
6553 +struct dwc_otg_core_if {
6554 + /** USB block index number for Octeon's that support multiple */
6557 + /** Parameters that define how the core should be configured.*/
6558 + struct dwc_otg_core_params *core_params;
6560 + /** Core Global registers starting at offset 000h. */
6561 + struct dwc_otg_core_global_regs *core_global_regs;
6563 + /** Device-specific information */
6564 + struct dwc_otg_dev_if *dev_if;
6565 + /** Host-specific information */
6566 + struct dwc_otg_host_if *host_if;
6569 + * Set to 1 if the core PHY interface bits in USBCFG have been
6572 + uint8_t phy_init_done;
6575 + * SRP Success flag, set by srp success interrupt in FS I2C mode
6577 + uint8_t srp_success;
6578 + uint8_t srp_timer_started;
6580 + /* Common configuration information */
6581 + /** Power and Clock Gating Control Register */
6582 + uint32_t *pcgcctl;
6583 +#define DWC_OTG_PCGCCTL_OFFSET 0xE00
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
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;
6597 + /** 1 if DMA is enabled, 0 otherwise. */
6598 + uint8_t dma_enable;
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;
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;
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
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.
6623 + uint8_t restart_hcd_on_session_req;
6625 + /** HCD callbacks */
6626 + /** A-Device is a_host */
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. */
6637 + /** HCD callbacks */
6638 + struct dwc_otg_cil_callbacks *hcd_cb;
6639 + /** PCD callbacks */
6640 + struct dwc_otg_cil_callbacks *pcd_cb;
6643 + uint32_t start_hcchar_val[MAX_EPS_CHANNELS];
6645 + struct hc_xfer_info hc_xfer_info[MAX_EPS_CHANNELS];
6646 + struct timer_list hc_xfer_timer[MAX_EPS_CHANNELS];
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;
6659 + * The following functions support initialization of the CIL driver component
6660 + * and the DWC_otg controller.
6662 +extern struct dwc_otg_core_if *dwc_otg_cil_init(const uint32_t *reg_base_addr,
6663 + struct dwc_otg_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);
6672 +/* Device CIL Functions
6673 + * The following functions support managing the DWC_otg controller in device
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,
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);
6702 +/* Host CIL Functions
6703 + * The following functions support managing the DWC_otg controller in host
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);
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
6729 +static inline uint32_t dwc_otg_read_hprt0(struct dwc_otg_core_if *core_if)
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;
6740 +extern void dwc_otg_dump_host_registers(struct dwc_otg_core_if *core_if);
6742 +/* Common CIL Functions
6743 + * The following functions support managing the DWC_otg controller in either
6744 + * device or host mode.
6748 +extern void dwc_otg_read_packet(struct dwc_otg_core_if *core_if,
6749 + uint8_t *dest, uint16_t bytes);
6751 +extern void dwc_otg_dump_global_registers(struct dwc_otg_core_if *core_if);
6753 +extern void dwc_otg_flush_tx_fifo(struct dwc_otg_core_if *core_if,
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);
6759 + * This function returns the Core Interrupt register.
6761 +static inline uint32_t dwc_otg_read_core_intr(struct dwc_otg_core_if *core_if)
6763 + return dwc_read_reg32(&core_if->core_global_regs->gintsts) &
6764 + dwc_read_reg32(&core_if->core_global_regs->gintmsk);
6768 + * This function returns the OTG Interrupt register.
6770 +static inline uint32_t dwc_otg_read_otg_intr(struct dwc_otg_core_if *core_if)
6772 + return dwc_read_reg32(&core_if->core_global_regs->gotgint);
6776 + * This function reads the Device All Endpoints Interrupt register and
6777 + * returns the IN endpoint interrupt bits.
6779 +static inline uint32_t dwc_otg_read_dev_all_in_ep_intr(struct dwc_otg_core_if *
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;
6790 + * This function reads the Device All Endpoints Interrupt register and
6791 + * returns the OUT endpoint interrupt bits.
6793 +static inline uint32_t
6794 +dwc_otg_read_dev_all_out_ep_intr(struct dwc_otg_core_if *core_if)
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;
6803 + * This function returns the Device IN EP Interrupt register
6805 +static inline uint32_t
6806 +dwc_otg_read_dev_in_ep_intr(struct dwc_otg_core_if *core_if, struct dwc_ep *ep)
6808 + struct dwc_otg_dev_if *dev_if = core_if->dev_if;
6810 + v = dwc_read_reg32(&dev_if->in_ep_regs[ep->num]->diepint) &
6811 + dwc_read_reg32(&dev_if->dev_global_regs->diepmsk);
6816 + * This function returns the Device OUT EP Interrupt register
6818 +static inline uint32_t dwc_otg_read_dev_out_ep_intr(struct dwc_otg_core_if *
6819 + core_if, struct dwc_ep *ep)
6821 + struct dwc_otg_dev_if *dev_if = core_if->dev_if;
6823 + v = dwc_read_reg32(&dev_if->out_ep_regs[ep->num]->doepint) &
6824 + dwc_read_reg32(&dev_if->dev_global_regs->diepmsk);
6829 + * This function returns the Host All Channel Interrupt register
6831 +static inline uint32_t
6832 +dwc_otg_read_host_all_channels_intr(struct dwc_otg_core_if *core_if)
6834 + return dwc_read_reg32(&core_if->host_if->host_global_regs->haint);
6837 +static inline uint32_t
6838 +dwc_otg_read_host_channel_intr(struct dwc_otg_core_if *core_if,
6839 + struct dwc_hc *hc)
6841 + return dwc_read_reg32(&core_if->host_if->hc_regs[hc->hc_num]->hcint);
6845 + * This function returns the mode of the operation, host or device.
6847 + * Returns 0 - Device Mode, 1 - Host Mode
6849 +static inline uint32_t dwc_otg_mode(struct dwc_otg_core_if *core_if)
6851 + return dwc_read_reg32(&core_if->core_global_regs->gintsts) & 0x1;
6854 +static inline uint8_t dwc_otg_is_device_mode(struct dwc_otg_core_if *core_if)
6856 + return dwc_otg_mode(core_if) != DWC_HOST_MODE;
6859 +static inline uint8_t dwc_otg_is_host_mode(struct dwc_otg_core_if *core_if)
6861 + return dwc_otg_mode(core_if) == DWC_HOST_MODE;
6864 +extern int32_t dwc_otg_handle_common_intr(struct dwc_otg_core_if *core_if);
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.
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() */
6888 +extern void dwc_otg_cil_register_pcd_callbacks(struct dwc_otg_core_if *core_if,
6889 + struct dwc_otg_cil_callbacks *cb,
6891 +extern void dwc_otg_cil_register_hcd_callbacks(struct dwc_otg_core_if *core_if,
6892 + struct dwc_otg_cil_callbacks *cb,
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
6899 +++ b/drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c
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.
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.
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
6927 + * ========================================================================== */
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.
6935 + * This file contains the Common Interrupt handlers.
6937 +#include "dwc_otg_plat.h"
6938 +#include "dwc_otg_regs.h"
6939 +#include "dwc_otg_cil.h"
6942 +inline const char *op_state_str(struct dwc_otg_core_if *core_if)
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")))));
6952 +/** This function will log a debug message
6954 + * @core_if: Programming view of DWC_otg controller.
6956 +int32_t dwc_otg_handle_mode_mismatch_intr(struct dwc_otg_core_if *core_if)
6958 + union gintsts_data gintsts;
6959 + DWC_WARN("Mode Mismatch Interrupt: currently in %s mode\n",
6960 + dwc_otg_mode(core_if) ? "Host" : "Device");
6962 + /* Clear interrupt */
6964 + gintsts.b.modemismatch = 1;
6965 + dwc_write_reg32(&core_if->core_global_regs->gintsts, gintsts.d32);
6969 +/** Start the HCD. Helper function for using the HCD callbacks.
6971 + * @core_if: Programming view of DWC_otg controller.
6973 +static inline void hcd_start(struct dwc_otg_core_if *core_if)
6975 + if (core_if->hcd_cb && core_if->hcd_cb->start)
6976 + core_if->hcd_cb->start(core_if->hcd_cb->p);
6979 +/** Stop the HCD. Helper function for using the HCD callbacks.
6981 + * @core_if: Programming view of DWC_otg controller.
6983 +static inline void hcd_stop(struct dwc_otg_core_if *core_if)
6985 + if (core_if->hcd_cb && core_if->hcd_cb->stop)
6986 + core_if->hcd_cb->stop(core_if->hcd_cb->p);
6989 +/** Disconnect the HCD. Helper function for using the HCD callbacks.
6991 + * @core_if: Programming view of DWC_otg controller.
6993 +static inline void hcd_disconnect(struct dwc_otg_core_if *core_if)
6995 + if (core_if->hcd_cb && core_if->hcd_cb->disconnect)
6996 + core_if->hcd_cb->disconnect(core_if->hcd_cb->p);
6999 +/** Inform the HCD the a New Session has begun. Helper function for
7000 + * using the HCD callbacks.
7002 + * @core_if: Programming view of DWC_otg controller.
7004 +static inline void hcd_session_start(struct dwc_otg_core_if *core_if)
7006 + if (core_if->hcd_cb && core_if->hcd_cb->session_start)
7007 + core_if->hcd_cb->session_start(core_if->hcd_cb->p);
7010 +/** Start the PCD. Helper function for using the PCD callbacks.
7012 + * @core_if: Programming view of DWC_otg controller.
7014 +static inline void pcd_start(struct dwc_otg_core_if *core_if)
7016 + if (core_if->pcd_cb && core_if->pcd_cb->start)
7017 + core_if->pcd_cb->start(core_if->pcd_cb->p);
7020 +/** Stop the PCD. Helper function for using the PCD callbacks.
7022 + * @core_if: Programming view of DWC_otg controller.
7024 +static inline void pcd_stop(struct dwc_otg_core_if *core_if)
7026 + if (core_if->pcd_cb && core_if->pcd_cb->stop)
7027 + core_if->pcd_cb->stop(core_if->pcd_cb->p);
7030 +/** Suspend the PCD. Helper function for using the PCD callbacks.
7032 + * @core_if: Programming view of DWC_otg controller.
7034 +static inline void pcd_suspend(struct dwc_otg_core_if *core_if)
7036 + if (core_if->pcd_cb && core_if->pcd_cb->suspend)
7037 + core_if->pcd_cb->suspend(core_if->pcd_cb->p);
7040 +/** Resume the PCD. Helper function for using the PCD callbacks.
7042 + * @core_if: Programming view of DWC_otg controller.
7044 +static inline void pcd_resume(struct dwc_otg_core_if *core_if)
7046 + if (core_if->pcd_cb && core_if->pcd_cb->resume_wakeup)
7047 + core_if->pcd_cb->resume_wakeup(core_if->pcd_cb->p);
7051 + * This function handles the OTG Interrupts. It reads the OTG
7052 + * Interrupt Register (GOTGINT) to determine what interrupt has
7055 + * @core_if: Programming view of DWC_otg controller.
7057 +int32_t dwc_otg_handle_otg_intr(struct dwc_otg_core_if *core_if)
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;
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));
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);
7075 + if (core_if->op_state == B_HOST) {
7076 + pcd_start(core_if);
7077 + core_if->op_state = B_PERIPHERAL;
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");
7086 + /* If Session End Detected the B-Cable has
7087 + * been disconnected. */
7088 + /* Reset PCD and Gadget driver to a
7090 + pcd_stop(core_if);
7093 + gotgctl.b.devhnpen = 1;
7094 + dwc_modify_reg32(&global_regs->gotgctl, gotgctl.d32, 0);
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;
7106 + pcd_resume(core_if);
7107 + /* Clear Session Request */
7109 + gotgctl.b.sesreq = 1;
7110 + dwc_modify_reg32(&global_regs->gotgctl,
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;
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.
7133 + gintmsk.b.sofintr = 1;
7134 + dwc_modify_reg32(&global_regs->gintmsk,
7136 + pcd_stop(core_if);
7138 + * Initialize the Core for Host mode.
7140 + hcd_start(core_if);
7141 + core_if->op_state = B_HOST;
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");
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.
7158 + DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: "
7159 + "Host Negotiation Detected++ (%s)\n",
7160 + (dwc_otg_is_host_mode(core_if) ? "Host" :
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;
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.
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;
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");
7192 + /* Clear GOTGINT */
7193 + dwc_write_reg32(&core_if->core_global_regs->gotgint, gotgint.d32);
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
7204 + * This only occurs when the cable is connected/removed from the PHY
7207 + * @core_if: Programming view of DWC_otg controller.
7209 +int32_t dwc_otg_handle_conn_id_status_change_intr(struct dwc_otg_core_if *core_if)
7211 + uint32_t count = 0;
7213 + union gintsts_data gintsts = {.d32 = 0 };
7214 + union gintmsk_data gintmsk = {.d32 = 0 };
7215 + union gotgctl_data gotgctl = {.d32 = 0 };
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.
7224 + gintmsk.b.sofintr = 1;
7225 + dwc_modify_reg32(&core_if->core_global_regs->gintmsk, gintmsk.d32, 0);
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);
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" :
7242 + if (++count > 10000)
7243 + *(uint32_t *) NULL = 0;
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);
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" :
7256 + if (++count > 10000)
7257 + *(uint32_t *) NULL = 0;
7259 + core_if->op_state = A_HOST;
7261 + * Initialize the Core for Host mode.
7263 + dwc_otg_core_init(core_if);
7264 + dwc_otg_enable_global_interrupts(core_if);
7265 + hcd_start(core_if);
7268 + /* Set flag and clear interrupt */
7269 + gintsts.b.conidstschng = 1;
7270 + dwc_write_reg32(&core_if->core_global_regs->gintsts, gintsts.d32);
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.
7282 + * @core_if: Programming view of DWC_otg controller.
7284 +int32_t dwc_otg_handle_session_req_intr(struct dwc_otg_core_if *core_if)
7286 + union gintsts_data gintsts;
7287 +#ifndef DWC_HOST_ONLY
7288 + union hprt0_data hprt0;
7290 + DWC_DEBUGPL(DBG_ANY, "++Session Request Interrupt++\n");
7292 + if (dwc_otg_is_device_mode(core_if)) {
7293 + DWC_PRINT("SRP: Device mode\n");
7295 + DWC_PRINT("SRP: Host mode\n");
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);
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);
7308 + /* Clear interrupt */
7310 + gintsts.b.sessreqintr = 1;
7311 + dwc_write_reg32(&core_if->core_global_regs->gintsts, gintsts.d32);
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.
7323 +int32_t dwc_otg_handle_wakeup_detected_intr(struct dwc_otg_core_if *core_if)
7325 + union gintsts_data gintsts;
7327 + DWC_DEBUGPL(DBG_ANY,
7328 + "++Resume and Remote Wakeup Detected Interrupt++\n");
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->
7335 +#ifdef PARTIAL_POWER_DOWN
7336 + if (core_if->hwcfg4.b.power_optimiz) {
7337 + union pcgcctl_data power = {.d32 = 0 };
7339 + power.d32 = dwc_read_reg32(core_if->pcgcctl);
7340 + DWC_DEBUGPL(DBG_CIL, "PCGCCTL=%0x\n", power.d32);
7342 + power.b.stoppclk = 0;
7343 + dwc_write_reg32(core_if->pcgcctl, power.d32);
7345 + power.b.pwrclmp = 0;
7346 + dwc_write_reg32(core_if->pcgcctl, power.d32);
7348 + power.b.rstpdwnmodule = 0;
7349 + dwc_write_reg32(core_if->pcgcctl, power.d32);
7352 + /* Clear the Remote Wakeup Signalling */
7353 + dctl.b.rmtwkupsig = 1;
7354 + dwc_modify_reg32(&core_if->dev_if->dev_global_regs->dctl,
7357 + if (core_if->pcd_cb && core_if->pcd_cb->resume_wakeup)
7358 + core_if->pcd_cb->resume_wakeup(core_if->pcd_cb->p);
7361 + * Clear the Resume after 70ms. (Need 20 ms minimum. Use 70 ms
7362 + * so that OPT tests pass with all PHYs).
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);
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);
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));
7381 + /* Clear interrupt */
7383 + gintsts.b.wkupintr = 1;
7384 + dwc_write_reg32(&core_if->core_global_regs->gintsts, gintsts.d32);
7390 + * This interrupt indicates that a device has been disconnected from
7393 +int32_t dwc_otg_handle_disconnect_intr(struct dwc_otg_core_if *core_if)
7395 + union gintsts_data gintsts;
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));
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 };
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.
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;
7425 + DWC_DEBUGPL(DBG_ANY, "!a_peripheral && !devhnpen\n");
7428 + if (core_if->op_state == A_HOST) {
7429 + /* A-Cable still connected but device disconnected. */
7430 + hcd_disconnect(core_if);
7436 + gintsts.b.disconnect = 1;
7437 + dwc_write_reg32(&core_if->core_global_regs->gintsts, gintsts.d32);
7442 + * This interrupt indicates that SUSPEND state has been detected on
7445 + * For HNP the USB Suspend interrupt signals the change from
7446 + * "a_peripheral" to "a_host".
7448 + * When power management is enabled the core will be put in low power
7451 +int32_t dwc_otg_handle_usb_suspend_intr(struct dwc_otg_core_if *core_if)
7453 + union dsts_data dsts;
7454 + union gintsts_data gintsts;
7456 + DWC_DEBUGPL(DBG_ANY, "USB SUSPEND\n");
7458 + if (dwc_otg_is_device_mode(core_if)) {
7459 + /* Check the Device status register to determine if the Suspend
7460 + * state is active. */
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);
7468 +#ifdef PARTIAL_POWER_DOWN
7469 +/** @todo Add a module parameter for power management. */
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");
7475 + power.b.pwrclmp = 1;
7476 + dwc_write_reg32(core_if->pcgcctl, power.d32);
7478 + power.b.rstpdwnmodule = 1;
7479 + dwc_modify_reg32(core_if->pcgcctl, 0, power.d32);
7481 + power.b.stoppclk = 1;
7482 + dwc_modify_reg32(core_if->pcgcctl, 0, power.d32);
7485 + DWC_DEBUGPL(DBG_ANY, "disconnect?\n");
7488 + /* PCD callback for suspend. */
7489 + pcd_suspend(core_if);
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;
7500 + /* Clear interrupt */
7502 + gintsts.b.usbsuspend = 1;
7503 + dwc_write_reg32(&core_if->core_global_regs->gintsts, gintsts.d32);
7509 + * This function returns the Core Interrupt register.
7511 +static inline uint32_t dwc_otg_read_common_intr(struct dwc_otg_core_if *core_if)
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;
7524 + * @todo: The port interrupt occurs while in device
7525 + * mode. Added code to CIL to clear the interrupt for now!
7527 + gintmsk_common.b.portintr = 1;
7529 + gintsts.d32 = dwc_read_reg32(&core_if->core_global_regs->gintsts);
7530 + gintmsk.d32 = dwc_read_reg32(&core_if->core_global_regs->gintmsk);
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);
7539 + return (gintsts.d32 & gintmsk.d32) & gintmsk_common.d32;
7544 + * Common interrupt handler.
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
7551 + * - Connector ID Status Change Interrupt
7552 + * - Session Request Interrupt.
7553 + * - Resume / Remote Wakeup Detected Interrupt.
7556 +extern int32_t dwc_otg_handle_common_intr(struct dwc_otg_core_if *core_if)
7559 + union gintsts_data gintsts;
7561 + gintsts.d32 = dwc_otg_read_common_intr(core_if);
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.
7582 + gintsts.b.portintr = 1;
7583 + dwc_write_reg32(&core_if->core_global_regs->gintsts,
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
7594 +++ b/drivers/usb/host/dwc_otg/dwc_otg_driver.h
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.
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.
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
7622 + * ========================================================================== */
7624 +#ifndef __DWC_OTG_DRIVER_H__
7625 +#define __DWC_OTG_DRIVER_H__
7627 +#include "dwc_otg_cil.h"
7629 +/* Type declarations */
7630 +struct dwc_otg_pcd;
7631 +struct dwc_otg_hcd;
7634 + * This structure is a wrapper that encapsulates the driver components used to
7635 + * manage a single DWC_otg controller.
7637 +struct dwc_otg_device {
7638 + /** Base address returned from ioremap() */
7641 + /** Pointer to the core interface structure. */
7642 + struct dwc_otg_core_if *core_if;
7644 + /** Register offset for Diagnostic API.*/
7645 + uint32_t reg_offset;
7647 + /** Pointer to the PCD structure. */
7648 + struct dwc_otg_pcd *pcd;
7650 + /** Pointer to the HCD structure. */
7651 + struct dwc_otg_hcd *hcd;
7653 + /** Flag to indicate whether the common IRQ handler is installed. */
7654 + uint8_t common_irq_installed;
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
7663 +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
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.
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.
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
7691 + * ========================================================================== */
7692 +#ifndef DWC_DEVICE_ONLY
7696 + * This file contains the implementation of the HCD. In Linux, the HCD
7697 + * implements the hc_driver API.
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>
7712 +#include "dwc_otg_driver.h"
7713 +#include "dwc_otg_hcd.h"
7714 +#include "dwc_otg_regs.h"
7716 +static const char dwc_otg_hcd_name[] = "dwc_otg_hcd";
7718 +static const struct hc_driver dwc_otg_hc_driver = {
7720 + .description = dwc_otg_hcd_name,
7721 + .product_desc = "DWC OTG Controller",
7722 + .hcd_priv_size = sizeof(struct dwc_otg_hcd),
7724 + .irq = dwc_otg_hcd_irq,
7726 + .flags = HCD_MEMORY | HCD_USB2,
7728 + .start = dwc_otg_hcd_start,
7729 + .stop = dwc_otg_hcd_stop,
7731 + .urb_enqueue = dwc_otg_hcd_urb_enqueue,
7732 + .urb_dequeue = dwc_otg_hcd_urb_dequeue,
7733 + .endpoint_disable = dwc_otg_hcd_endpoint_disable,
7735 + .get_frame_number = dwc_otg_hcd_get_frame_number,
7737 + .hub_status_data = dwc_otg_hcd_hub_status_data,
7738 + .hub_control = dwc_otg_hcd_hub_control,
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.
7745 +static void hcd_start_func(struct work_struct *work)
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);
7752 + dwc_otg_hcd_start(usb_hcd);
7756 + * HCD Callback function for starting the HCD when A-Cable is
7759 + * @_p: void pointer to the <code>struct usb_hcd</code>
7761 +static int32_t dwc_otg_hcd_start_cb(void *_p)
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;
7767 + if (core_if->op_state == B_HOST) {
7769 + * Reset the port. During a HNP mode switch the reset
7770 + * needs to occur within 1ms and have a duration of at
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;
7778 + ((struct usb_hcd *)_p)->self.is_b_host = 0;
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);
7790 + * HCD Callback function for stopping the HCD.
7792 + * @_p: void pointer to the <code>struct usb_hcd</code>
7794 +static int32_t dwc_otg_hcd_stop_cb(void *_p)
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);
7802 +static void del_xfer_timers(struct dwc_otg_hcd *hcd)
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]);
7812 +static void del_timers(struct dwc_otg_hcd *hcd)
7814 + del_xfer_timers(hcd);
7815 + del_timer(&hcd->conn_timer);
7819 + * Processes all the URBs in a single list of QHs. Completes them with
7820 + * -ETIMEDOUT and frees the QTD.
7822 +static void kill_urbs_in_qh_list(struct dwc_otg_hcd *hcd,
7823 + struct list_head *_qh_list)
7825 + struct dwc_otg_qh *qh;
7826 + struct dwc_otg_qtd *qtd;
7827 + struct dwc_otg_qtd *qtd_next;
7829 + list_for_each_entry(qh, _qh_list, qh_list_entry) {
7830 + list_for_each_entry_safe(qtd, qtd_next, &qh->qtd_list,
7832 + if (qtd->urb != NULL) {
7833 + dwc_otg_hcd_complete_urb(hcd, qtd->urb,
7837 + dwc_otg_hcd_qtd_remove_and_free(qtd);
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.
7848 +static void kill_all_urbs(struct dwc_otg_hcd *hcd)
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);
7859 + * HCD Callback function for disconnect of the HCD.
7861 + * @_p: void pointer to the <code>struct usb_hcd</code>
7863 +static int32_t dwc_otg_hcd_disconnect_cb(void *_p)
7865 + union gintsts_data intr;
7866 + struct dwc_otg_hcd *dwc_otg_hcd = hcd_to_dwc_otg_hcd(_p);
7869 + * Set status flags for the hub driver.
7871 + dwc_otg_hcd->flags.b.port_connect_status_change = 1;
7872 + dwc_otg_hcd->flags.b.port_connect_status = 0;
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.
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,
7885 + dwc_modify_reg32(&dwc_otg_hcd->core_if->core_global_regs->gintsts,
7888 + del_timers(dwc_otg_hcd);
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
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,
7904 + dwc_otg_disable_host_interrupts(dwc_otg_hcd->core_if);
7907 + /* Respond with an error status to all URBs in the schedule. */
7908 + kill_all_urbs(dwc_otg_hcd);
7910 + if (dwc_otg_is_host_mode(dwc_otg_hcd->core_if)) {
7911 + /* Clean up any host channels that were in use. */
7914 + struct dwc_hc *channel;
7915 + struct dwc_otg_hc_regs *hc_regs;
7916 + union hcchar_data hcchar;
7918 + num_channels = dwc_otg_hcd->core_if->core_params->host_channels;
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)) {
7926 + dwc_otg_hcd->core_if->host_if->
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->
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)) {
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,
7955 + dwc_otg_hc_cleanup(dwc_otg_hcd->core_if,
7957 + list_add_tail(&channel->hc_list_entry,
7958 + &dwc_otg_hcd->free_hc_list);
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;
7970 + * Connection timeout function. An OTG host is required to display a
7971 + * message if the device does not connect within 10 seconds.
7973 +void dwc_otg_hcd_connect_timeout(unsigned long _ptr)
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");
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
7986 +static void dwc_otg_hcd_start_connect_timer(struct dwc_otg_hcd *hcd)
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);
7996 + * HCD Callback function for disconnect of the HCD.
7998 + * @_p: void pointer to the <code>struct usb_hcd</code>
8000 +static int32_t dwc_otg_hcd_session_start_cb(void *_p)
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);
8009 + * HCD Callback structure for handling mode switching.
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,
8020 + * Reset tasklet function
8022 +static void reset_tasklet_func(unsigned long data)
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;
8028 + DWC_DEBUGPL(DBG_HCDV, "USB RESET tasklet called\n");
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);
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;
8042 +static struct tasklet_struct reset_tasklet = {
8045 + .count = ATOMIC_INIT(0),
8046 + .func = reset_tasklet_func,
8050 +static enum hrtimer_restart delayed_enable(struct hrtimer *t)
8052 + struct dwc_otg_hcd *hcd = container_of(t, struct dwc_otg_hcd,
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);
8060 + return HRTIMER_NORESTART;
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.
8069 +int __devinit dwc_otg_hcd_init(struct device *dev)
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;
8077 + struct dwc_hc *channel;
8081 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT\n");
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;
8089 + DWC_PRINT("Using Slave mode\n");
8090 + dev->coherent_dma_mask = 0;
8091 + dev->dma_mask = NULL;
8095 + * Allocate memory for the base HCD plus the DWC OTG HCD.
8096 + * Initialize the base HCD.
8098 + hcd = usb_create_hcd(&dwc_otg_hc_driver, dev, dev_name(dev));
8099 + if (hcd == NULL) {
8103 + hcd->regs = otg_dev->base;
8104 + hcd->self.otg_port = 1;
8106 + /* Integrate TT in root hub, by default this is disbled. */
8109 + /* Initialize the DWC OTG HCD. */
8110 + dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
8112 + spin_lock_init(&dwc_otg_hcd->global_lock);
8114 + dwc_otg_hcd->core_if = otg_dev->core_if;
8115 + otg_dev->hcd = dwc_otg_hcd;
8117 + /* Register the HCD CIL Callbacks */
8118 + dwc_otg_cil_register_hcd_callbacks(otg_dev->core_if,
8119 + &hcd_cil_callbacks, hcd);
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);
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);
8132 + * Create a host channel descriptor for each host channel implemented
8133 + * in the controller. Initialize the channel descriptor array.
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) {
8141 + DWC_ERROR("%s: host channel allocation failed\n",
8145 + memset(channel, 0, sizeof(struct dwc_hc));
8146 + channel->hc_num = i;
8147 + dwc_otg_hcd->hc_ptr_array[i] = channel;
8149 + init_timer(&dwc_otg_hcd->core_if->hc_xfer_timer[i]);
8152 + DWC_DEBUGPL(DBG_HCDV, "HCD Added channel #%d, hc=%p\n", i,
8156 + /* Initialize the Connection timeout timer. */
8157 + init_timer(&dwc_otg_hcd->conn_timer);
8159 + /* Initialize reset tasklet. */
8160 + reset_tasklet.data = (unsigned long)dwc_otg_hcd;
8161 + dwc_otg_hcd->reset_tasklet = &reset_tasklet;
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;
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.
8173 + usb_add_hcd(hcd, platform_get_irq(to_platform_device(dev), 0),
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
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);
8191 + dwc_otg_hcd->status_buf = kmalloc(DWC_OTG_HCD_STATUS_BUF_SIZE,
8194 + if (dwc_otg_hcd->status_buf == NULL) {
8196 + DWC_ERROR("%s: status_buf allocation failed\n", __func__);
8200 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Initialized HCD, usbbus=%d\n",
8201 + hcd->self.busnum);
8205 + /* Error conditions */
8207 + usb_remove_hcd(hcd);
8209 + dwc_otg_hcd_free(hcd);
8216 + * Removes the HCD.
8217 + * Frees memory and resources associated with the HCD and deregisters the bus.
8219 +void dwc_otg_hcd_remove(struct device *dev)
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);
8225 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD REMOVE\n");
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,
8232 + usb_remove_hcd(hcd);
8233 + dwc_otg_hcd_free(hcd);
8239 +/* =========================================================================
8240 + * Linux HC Driver Functions
8241 + * ========================================================================= */
8244 + * Initializes dynamic portions of the DWC_otg HCD state.
8246 +static void hcd_reinit(struct dwc_otg_hcd *hcd)
8248 + struct list_head *item;
8251 + struct dwc_hc *channel;
8253 + hcd->flags.d32 = 0;
8255 + hcd->non_periodic_qh_ptr = &hcd->non_periodic_sched_active;
8256 + hcd->non_periodic_channels = 0;
8257 + hcd->periodic_channels = 0;
8260 + * Put all channels in the free channel list and clean up channel
8263 + item = hcd->free_hc_list.next;
8264 + while (item != &hcd->free_hc_list) {
8266 + item = hcd->free_hc_list.next;
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);
8275 + /* Initialize the DWC core for host mode operation. */
8276 + dwc_otg_core_host_init(hcd->core_if);
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)
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;
8288 + struct usb_bus *bus;
8290 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD START\n");
8292 + spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags);
8294 + bus = hcd_to_bus(hcd);
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;
8302 + hcd->state = HC_STATE_RUNNING;
8304 + hcd_reinit(dwc_otg_hcd);
8306 + spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags);
8311 +static void qh_list_free(struct dwc_otg_hcd *hcd, struct list_head *_qh_list)
8313 + struct list_head *item;
8314 + struct dwc_otg_qh *qh;
8316 + if (_qh_list->next == NULL) {
8317 + /* The list hasn't been initialized yet. */
8321 + /* Ensure there are no QTDs or URBs left. */
8322 + kill_urbs_in_qh_list(hcd, _qh_list);
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);
8331 + * Halts the DWC_otg host mode operations in a clean manner. USB transfers are
8334 +void dwc_otg_hcd_stop(struct usb_hcd *hcd)
8336 + struct dwc_otg_hcd *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
8337 + union hprt0_data hprt0 = {.d32 = 0 };
8339 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD STOP\n");
8341 + /* Turn off all host-specific interrupts. */
8342 + dwc_otg_disable_host_interrupts(dwc_otg_hcd->core_if);
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).
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);
8358 +/** Returns the current frame number. */
8359 +int dwc_otg_hcd_get_frame_number(struct usb_hcd *hcd)
8361 + struct dwc_otg_hcd *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
8362 + union hfnum_data hfnum;
8365 + dwc_read_reg32(&dwc_otg_hcd->core_if->host_if->host_global_regs->
8369 + DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD GET FRAME NUMBER %d\n",
8372 + return hfnum.b.frnum;
8376 + * Frees secondary storage associated with the dwc_otg_hcd structure contained
8377 + * in the struct usb_hcd field.
8379 +void dwc_otg_hcd_free(struct usb_hcd *hcd)
8381 + struct dwc_otg_hcd *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
8384 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD FREE\n");
8386 + del_timers(dwc_otg_hcd);
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);
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];
8400 + DWC_DEBUGPL(DBG_HCDV, "HCD Free channel #%i, hc=%p\n",
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);
8413 + } else if (dwc_otg_hcd->status_buf != NULL) {
8414 + kfree(dwc_otg_hcd->status_buf);
8421 +static void dump_urb_info(struct urb *urb, char *_fn_name)
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",
8430 + switch (usb_pipetype(urb->pipe)) {
8431 + case PIPE_CONTROL:
8432 + pipetype = "CONTROL";
8435 + pipetype = "BULK";
8437 + case PIPE_INTERRUPT:
8438 + pipetype = "INTERRUPT";
8440 + case PIPE_ISOCHRONOUS:
8441 + pipetype = "ISOCHRONOUS";
8444 + pipetype = "UNKNOWN";
8449 + DWC_PRINT(" Speed: %s\n",
8452 + switch (urb->dev->speed) {
8453 + case USB_SPEED_HIGH:
8456 + case USB_SPEED_FULL:
8459 + case USB_SPEED_LOW:
8463 + speed = "UNKNOWN";
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) {
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);
8488 +static void dump_channel_info(struct dwc_otg_hcd *hcd, struct dwc_otg_qh * qh)
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;
8497 + struct dwc_otg_hc_regs *hc_regs;
8498 + union hcchar_data hcchar;
8499 + union hcsplt_data hcsplt;
8500 + union hctsiz_data hctsiz;
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);
8509 + DWC_PRINT(" Assigned to channel %p:\n", hc);
8510 + DWC_PRINT(" hcchar 0x%08x, hcsplt 0x%08x\n", hcchar.d32,
8512 + DWC_PRINT(" hctsiz 0x%08x, hcdma 0x%08x\n", hctsiz.d32,
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,
8528 + DWC_PRINT(" %p\n", qh_item);
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,
8534 + DWC_PRINT(" %p\n", qh_item);
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);
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)
8551 + unsigned long flags;
8553 + struct dwc_otg_hcd *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
8554 + struct dwc_otg_qtd *qtd;
8556 + spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags);
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()
8565 + dwc_modify_reg32(&dwc_otg_hcd->core_if->core_global_regs->gintmsk, 0,
8566 + DWC_SOF_INTR_MASK);
8569 + if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB))
8570 + dump_urb_info(urb, "dwc_otg_hcd_urb_enqueue");
8572 + if (!dwc_otg_hcd->flags.b.port_connect_status) {
8573 + /* No longer connected. */
8578 + qtd = dwc_otg_hcd_qtd_create(urb);
8579 + if (qtd == NULL) {
8580 + DWC_ERROR("DWC OTG HCD URB Enqueue failed creating QTD\n");
8585 + retval = dwc_otg_hcd_qtd_add(qtd, dwc_otg_hcd);
8587 + DWC_ERROR("DWC OTG HCD URB Enqueue failed adding QTD. "
8588 + "Error status %d\n", retval);
8589 + dwc_otg_hcd_qtd_free(qtd);
8592 + spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags);
8597 +/** Aborts/cancels a USB transfer request. Always returns 0 to indicate
8599 +int dwc_otg_hcd_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
8601 + unsigned long flags;
8602 + struct dwc_otg_hcd *dwc_otg_hcd;
8603 + struct dwc_otg_qtd *urb_qtd;
8605 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD URB Dequeue\n");
8607 + dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
8609 + spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags);
8611 + urb_qtd = urb->hcpriv;
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);
8621 + if (urb_qtd == urb_qtd->qh->qtd_in_process) {
8622 + /* The QTD is in process (it has been assigned to a channel). */
8624 + if (dwc_otg_hcd->flags.b.port_connect_status) {
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
8632 + dwc_otg_hc_halt(dwc_otg_hcd->core_if,
8633 + urb_qtd->qh->channel,
8634 + DWC_OTG_HC_XFER_URB_DEQUEUE);
8639 + * Free the QTD and clean up the associated QH. Leave the QH in the
8640 + * schedule if it has any remaining QTDs.
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);
8651 + spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags);
8653 + urb->hcpriv = NULL;
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);
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)
8671 + unsigned long flags;
8672 + struct dwc_otg_qh *qh;
8673 + struct dwc_otg_hcd *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
8675 + spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags);
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));
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
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");
8700 + dwc_otg_hcd_qh_remove_and_free(dwc_otg_hcd, qh);
8701 + _ep->hcpriv = NULL;
8705 + spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags);
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
8714 + * This function is called by the USB core when an interrupt occurs */
8715 +irqreturn_t dwc_otg_hcd_irq(struct usb_hcd *hcd)
8717 + irqreturn_t result;
8718 + unsigned long flags;
8719 + struct dwc_otg_hcd *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
8721 + spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags);
8723 + result = IRQ_RETVAL(dwc_otg_hcd_handle_intr(dwc_otg_hcd));
8725 + spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags);
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)
8736 + struct dwc_otg_hcd *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
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;
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);
8761 + return (_buf[0] != 0);
8764 +#ifdef DWC_HS_ELECT_TST
8766 + * Quick and dirty hack to implement the HS Electrical Test
8767 + * SINGLE_STEP_GET_DEVICE_DESCRIPTOR feature.
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
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;
8783 +static void do_setup(void)
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;
8791 + /* Enable HAINTs */
8792 + dwc_write_reg32(&hc_global_regs->haintmsk, 0x0001);
8794 + /* Enable HCINTs */
8795 + dwc_write_reg32(&hc_regs->hcintmsk, 0x04a3);
8797 + /* Read GINTSTS */
8798 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8801 + haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
8804 + hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
8807 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8810 + dwc_write_reg32(&hc_regs->hcint, hcint.d32);
8813 + dwc_write_reg32(&hc_global_regs->haint, haint.d32);
8815 + /* Clear GINTSTS */
8816 + dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
8818 + /* Read GINTSTS */
8819 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8822 + * Send Setup packet (Get Device Descriptor)
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);
8833 + /* Read GINTSTS */
8834 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8837 + haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
8840 + hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
8843 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8846 + dwc_write_reg32(&hc_regs->hcint, hcint.d32);
8849 + dwc_write_reg32(&hc_global_regs->haint, haint.d32);
8851 + /* Clear GINTSTS */
8852 + dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
8854 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
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);
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;
8870 + hcchar.b.chen = 1;
8871 + dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
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);
8878 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8880 + /* Wait for host channel interrupt */
8882 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8883 + } while (gintsts.b.hcintr == 0);
8886 + /* Disable HCINTs */
8887 + dwc_write_reg32(&hc_regs->hcintmsk, 0x0000);
8889 + /* Disable HAINTs */
8890 + dwc_write_reg32(&hc_global_regs->haintmsk, 0x0000);
8893 + haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
8896 + hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
8899 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8902 + dwc_write_reg32(&hc_regs->hcint, hcint.d32);
8905 + dwc_write_reg32(&hc_global_regs->haint, haint.d32);
8907 + /* Clear GINTSTS */
8908 + dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
8910 + /* Read GINTSTS */
8911 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8914 +static void do_in_ack(void)
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;
8923 + /* Enable HAINTs */
8924 + dwc_write_reg32(&hc_global_regs->haintmsk, 0x0001);
8926 + /* Enable HCINTs */
8927 + dwc_write_reg32(&hc_regs->hcintmsk, 0x04a3);
8929 + /* Read GINTSTS */
8930 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8933 + haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
8936 + hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
8939 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8942 + dwc_write_reg32(&hc_regs->hcint, hcint.d32);
8945 + dwc_write_reg32(&hc_global_regs->haint, haint.d32);
8947 + /* Clear GINTSTS */
8948 + dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
8950 + /* Read GINTSTS */
8951 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8954 + * Receive Control In packet
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);
8966 + /* Read GINTSTS */
8967 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8970 + haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
8973 + hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
8976 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8979 + dwc_write_reg32(&hc_regs->hcint, hcint.d32);
8982 + dwc_write_reg32(&hc_global_regs->haint, haint.d32);
8984 + /* Clear GINTSTS */
8985 + dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
8987 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
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);
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;
9003 + hcchar.b.chen = 1;
9004 + dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
9006 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9008 + /* Wait for receive status queue interrupt */
9010 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9011 + } while (gintsts.b.rxstsqlvl == 0);
9014 + grxsts.d32 = dwc_read_reg32(&global_regs->grxstsp);
9016 + /* Clear RXSTSQLVL in GINTSTS */
9018 + gintsts.b.rxstsqlvl = 1;
9019 + dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
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) {
9026 + int word_count = (grxsts.b.bcnt + 3) / 4;
9028 + data_fifo = (uint32_t *) ((char *)global_regs + 0x1000);
9030 + for (i = 0; i < word_count; i++)
9031 + (void)dwc_read_reg32(data_fifo++);
9039 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9041 + /* Wait for receive status queue interrupt */
9043 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9044 + } while (gintsts.b.rxstsqlvl == 0);
9048 + grxsts.d32 = dwc_read_reg32(&global_regs->grxstsp);
9050 + /* Clear RXSTSQLVL in GINTSTS */
9052 + gintsts.b.rxstsqlvl = 1;
9053 + dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
9055 + switch (grxsts.b.pktsts) {
9056 + case DWC_GRXSTS_PKTSTS_IN_XFER_COMP:
9063 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9065 + /* Wait for host channel interrupt */
9067 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9068 + } while (gintsts.b.hcintr == 0);
9072 + haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
9075 + hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
9078 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
9081 + dwc_write_reg32(&hc_regs->hcint, hcint.d32);
9084 + dwc_write_reg32(&hc_global_regs->haint, haint.d32);
9086 + /* Clear GINTSTS */
9087 + dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
9089 + /* Read GINTSTS */
9090 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9095 + * Send handshake packet
9099 + haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
9102 + hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
9105 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
9108 + dwc_write_reg32(&hc_regs->hcint, hcint.d32);
9111 + dwc_write_reg32(&hc_global_regs->haint, haint.d32);
9113 + /* Clear GINTSTS */
9114 + dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
9116 + /* Read GINTSTS */
9117 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
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);
9128 + /* Read GINTSTS */
9129 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9132 + haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
9135 + hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
9138 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
9141 + dwc_write_reg32(&hc_regs->hcint, hcint.d32);
9144 + dwc_write_reg32(&hc_global_regs->haint, haint.d32);
9146 + /* Clear GINTSTS */
9147 + dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
9149 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
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);
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;
9165 + hcchar.b.chen = 1;
9166 + dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
9168 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9170 + /* Wait for host channel interrupt */
9172 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9173 + } while (gintsts.b.hcintr == 0);
9176 + /* Disable HCINTs */
9177 + dwc_write_reg32(&hc_regs->hcintmsk, 0x0000);
9179 + /* Disable HAINTs */
9180 + dwc_write_reg32(&hc_global_regs->haintmsk, 0x0000);
9183 + haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
9186 + hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
9189 + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
9192 + dwc_write_reg32(&hc_regs->hcint, hcint.d32);
9195 + dwc_write_reg32(&hc_global_regs->haint, haint.d32);
9197 + /* Clear GINTSTS */
9198 + dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
9200 + /* Read GINTSTS */
9201 + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9203 +#endif /* DWC_HS_ELECT_TST */
9205 +/* Handles hub class-specific requests.*/
9206 +int dwc_otg_hcd_hub_control(struct usb_hcd *hcd,
9208 + u16 _wValue, u16 _wIndex, char *_buf, u16 _wLength)
9211 + unsigned long flags;
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 };
9218 + uint32_t port_status;
9219 +#ifdef DWC_HS_ELECT_TST
9221 + union gintmsk_data gintmsk;
9223 + spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags);
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 */
9236 + DWC_ERROR("DWC OTG HCD - "
9237 + "ClearHubFeature request %xh unknown\n",
9241 + case ClearPortFeature:
9242 + if (!_wIndex || _wIndex > 1)
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);
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 */
9261 + hprt0.b.prtres = 0;
9262 + dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
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);
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 */
9276 + case USB_PORT_FEAT_C_CONNECTION:
9277 + /* Clears drivers internal connect status change
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;
9283 + case USB_PORT_FEAT_C_RESET:
9284 + /* Clears the driver's internal Port Reset Change
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;
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;
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;
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;
9312 + DWC_ERROR("DWC OTG HCD - "
9313 + "ClearPortFeature request %xh "
9314 + "unknown or unsupported\n", _wValue);
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;
9330 + case GetHubStatus:
9331 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9332 + "GetHubStatus\n");
9333 + memset(_buf, 0, 4);
9335 + case GetPortStatus:
9336 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9337 + "GetPortStatus\n");
9339 + if (!_wIndex || _wIndex > 1)
9344 + if (dwc_otg_hcd->flags.b.port_connect_status_change)
9345 + port_status |= (1 << USB_PORT_FEAT_C_CONNECTION);
9347 + if (dwc_otg_hcd->flags.b.port_enable_change)
9348 + port_status |= (1 << USB_PORT_FEAT_C_ENABLE);
9350 + if (dwc_otg_hcd->flags.b.port_suspend_change)
9351 + port_status |= (1 << USB_PORT_FEAT_C_SUSPEND);
9353 + if (dwc_otg_hcd->flags.b.port_reset_change)
9354 + port_status |= (1 << USB_PORT_FEAT_C_RESET);
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);
9361 + if (!dwc_otg_hcd->flags.b.port_connect_status) {
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.
9369 + *((__le32 *) _buf) = cpu_to_le32(port_status);
9373 + hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
9374 + DWC_DEBUGPL(DBG_HCDV, " HPRT0: 0x%08x\n", hprt0.d32);
9376 + if (hprt0.b.prtconnsts)
9377 + port_status |= (1 << USB_PORT_FEAT_CONNECTION);
9379 + if (hprt0.b.prtena)
9380 + port_status |= (1 << USB_PORT_FEAT_ENABLE);
9382 + if (hprt0.b.prtsusp)
9383 + port_status |= (1 << USB_PORT_FEAT_SUSPEND);
9385 + if (hprt0.b.prtovrcurract)
9386 + port_status |= (1 << USB_PORT_FEAT_OVER_CURRENT);
9388 + if (hprt0.b.prtrst)
9389 + port_status |= (1 << USB_PORT_FEAT_RESET);
9391 + if (hprt0.b.prtpwr)
9392 + port_status |= (1 << USB_PORT_FEAT_POWER);
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);
9399 + if (hprt0.b.prttstctl)
9400 + port_status |= (1 << USB_PORT_FEAT_TEST);
9402 + /* USB_PORT_FEAT_INDICATOR unsupported always 0 */
9404 + *((__le32 *) _buf) = cpu_to_le32(port_status);
9407 + case SetHubFeature:
9408 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9409 + "SetHubFeature\n");
9410 + /* No HUB features supported */
9412 + case SetPortFeature:
9413 + if (_wValue != USB_PORT_FEAT_TEST && (!_wIndex || _wIndex > 1))
9416 + if (!dwc_otg_hcd->flags.b.port_connect_status) {
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
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;
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 */
9444 + union pcgcctl_data pcgcctl = {.d32 = 0 };
9445 + pcgcctl.b.stoppclk = 1;
9446 + dwc_write_reg32(core_if->pcgcctl, pcgcctl.d32);
9450 + * For HNP the bus must be suspended for at
9453 + if (hcd->self.b_hnp_enable)
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);
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,
9476 + /* Clear reset bit in 10ms (FS/LS) or 50ms (HS) */
9478 + hprt0.b.prtrst = 0;
9479 + dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
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);
9490 + hprt0.d32 = dwc_otg_read_hprt0(core_if);
9491 + hprt0.b.prttstctl = t;
9492 + dwc_write_reg32(core_if->host_if->hprt0,
9495 + /* Setup global vars with reg
9496 + * addresses (quick and dirty hack,
9497 + * should be cleaned up)
9499 + global_regs = core_if->core_global_regs;
9501 + core_if->host_if->host_global_regs;
9503 + (struct dwc_otg_hc_regs *) ((char *)
9507 + (uint32_t *) ((char *)global_regs +
9510 + if (t == 6) { /* HS_HOST_PORT_SUSPEND_RESUME */
9511 + /* Save current interrupt mask */
9513 + dwc_read_reg32(&global_regs->gintmsk);
9515 + /* Disable all interrupts
9516 + * while we muck with the
9517 + * hardware directly
9519 + dwc_write_reg32(&global_regs->gintmsk,
9522 + /* 15 second delay per the test spec */
9525 + /* Drive suspend on the root port */
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,
9533 + /* 15 second delay per the test spec */
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,
9544 + /* Clear the resume bit */
9545 + hprt0.b.prtres = 0;
9546 + dwc_write_reg32(core_if->host_if->hprt0,
9549 + /* Restore interrupts */
9550 + dwc_write_reg32(&global_regs->gintmsk,
9552 + } else if (t == 7) {
9553 + /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR setup */
9554 + /* Save current interrupt mask */
9556 + dwc_read_reg32(&global_regs->gintmsk);
9559 + * Disable all interrupts
9560 + * while we muck with the
9561 + * hardware directly
9563 + dwc_write_reg32(&global_regs->gintmsk,
9566 + /* 15 second delay per the test spec */
9569 + /* Send the Setup packet */
9573 + * 15 second delay so nothing
9574 + * else happens for awhile.
9578 + /* Restore interrupts */
9579 + dwc_write_reg32(&global_regs->gintmsk,
9581 + } else if (t == 8) {
9582 + /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR execute */
9583 + /* Save current interrupt mask */
9585 + dwc_read_reg32(&global_regs->gintmsk);
9588 + * Disable all interrupts
9589 + * while we muck with the
9590 + * hardware directly
9592 + dwc_write_reg32(&global_regs->gintmsk,
9595 + /* Send the Setup packet */
9598 + /* 15 second delay so nothing else happens for awhile */
9601 + /* Send the In and Ack packets */
9604 + /* 15 second delay so nothing else happens for awhile */
9607 + /* Restore interrupts */
9608 + dwc_write_reg32(&global_regs->gintmsk,
9613 +#endif /* DWC_HS_ELECT_TST */
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 */
9622 + DWC_ERROR("DWC OTG HCD - "
9623 + "SetPortFeature request %xh "
9624 + "unknown or unsupported\n", _wValue);
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);
9637 + spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags);
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
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.
9651 +static void assign_and_init_hc(struct dwc_otg_hcd *hcd, struct dwc_otg_qh *_qh)
9653 + struct dwc_hc *hc;
9654 + struct dwc_otg_qtd *qtd;
9657 + DWC_DEBUGPL(DBG_HCDV, "%s(%p,%p)\n", __func__, hcd, _qh);
9659 + hc = list_entry(hcd->free_hc_list.next, struct dwc_hc, hc_list_entry);
9661 + /* Remove the host channel from the free list. */
9662 + list_del_init(&hc->hc_list_entry);
9664 + qtd = list_entry(_qh->qtd_list.next, struct dwc_otg_qtd,
9667 + _qh->channel = hc;
9668 + _qh->qtd_in_process = qtd;
9671 + * Use usb_pipedevice to determine device address. This address is
9672 + * 0 before the SET_ADDRESS command and the correct address afterward.
9674 + hc->dev_addr = usb_pipedevice(urb->pipe);
9675 + hc->ep_num = usb_pipeendpoint(urb->pipe);
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;
9682 + hc->speed = DWC_OTG_EP_SPEED_HIGH;
9684 + hc->max_packet = dwc_max_packet(_qh->maxp);
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;
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.
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;
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 */
9710 + (uint8_t *) (unsigned long)urb->transfer_dma +
9711 + urb->actual_length;
9712 +#ifdef CONFIG_CPU_CAVIUM_OCTEON
9713 + /* Octeon uses external DMA */
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 */
9724 + (uint8_t *) urb->transfer_buffer + urb->actual_length;
9726 + hc->xfer_len = urb->transfer_buffer_length - urb->actual_length;
9727 + hc->xfer_count = 0;
9730 + * Set the split attributes
9733 + if (_qh->do_split) {
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;
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");
9749 + hc->data_pid_start = DWC_OTG_HC_PID_SETUP;
9750 + if (hcd->core_if->dma_enable) {
9752 + (uint8_t *) (unsigned long)urb->setup_dma;
9754 + hc->xfer_buff = (uint8_t *) urb->setup_packet;
9758 + case DWC_OTG_CONTROL_DATA:
9759 + DWC_DEBUGPL(DBG_HCDV, " Control data transaction\n");
9760 + hc->data_pid_start = qtd->data_toggle;
9762 + case DWC_OTG_CONTROL_STATUS:
9764 + * Direction is opposite of data direction or IN if no
9767 + DWC_DEBUGPL(DBG_HCDV, " Control status transaction\n");
9768 + if (urb->transfer_buffer_length == 0) {
9772 + (usb_pipein(urb->pipe) != USB_DIR_IN);
9776 + hc->data_pid_start = DWC_OTG_HC_PID_DATA1;
9778 + if (hcd->core_if->dma_enable) {
9780 + (uint8_t *) (unsigned long)hcd->
9783 + hc->xfer_buff = (uint8_t *) hcd->status_buf;
9789 + hc->ep_type = DWC_OTG_EP_TYPE_BULK;
9791 + case PIPE_INTERRUPT:
9792 + hc->ep_type = DWC_OTG_EP_TYPE_INTR;
9794 + case PIPE_ISOCHRONOUS:
9796 + struct usb_iso_packet_descriptor *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) {
9802 + (uint8_t *) (unsigned long)urb->
9806 + (uint8_t *) urb->transfer_buffer;
9809 + frame_desc->offset + qtd->isoc_split_offset;
9811 + frame_desc->length - qtd->isoc_split_offset;
9813 + if (hc->xact_pos == DWC_HCSPLIT_XACTPOS_ALL) {
9814 + if (hc->xfer_len <= 188) {
9815 + hc->xact_pos = DWC_HCSPLIT_XACTPOS_ALL;
9818 + DWC_HCSPLIT_XACTPOS_BEGIN;
9825 + if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
9826 + hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
9828 + * This value may be modified when the transfer is started to
9829 + * reflect the actual transfer length.
9831 + hc->multi_count = dwc_hb_mult(_qh->maxp);
9834 + dwc_otg_hc_init(hcd->core_if, hc);
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.
9843 + * @hcd: The HCD state structure.
9845 + * Returns The types of new transactions that were assigned to host channels.
9847 +enum dwc_otg_transaction_type dwc_otg_hcd_select_transactions(struct dwc_otg_hcd
9850 + struct list_head *qh_ptr;
9851 + struct dwc_otg_qh *qh;
9853 + enum dwc_otg_transaction_type ret_val = DWC_OTG_TRANSACTION_NONE;
9856 + DWC_DEBUGPL(DBG_HCD, " Select Transactions\n");
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)) {
9864 + qh = list_entry(qh_ptr, struct dwc_otg_qh, qh_list_entry);
9865 + assign_and_init_hc(hcd, qh);
9868 + * Move the QH from the periodic ready schedule to the
9869 + * periodic assigned schedule.
9871 + qh_ptr = qh_ptr->next;
9872 + list_move(&qh->qh_list_entry, &hcd->periodic_sched_assigned);
9874 + ret_val = DWC_OTG_TRANSACTION_PERIODIC;
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.
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)) {
9889 + qh = list_entry(qh_ptr, struct dwc_otg_qh, qh_list_entry);
9890 + assign_and_init_hc(hcd, qh);
9893 + * Move the QH from the non-periodic inactive schedule to the
9894 + * non-periodic active schedule.
9896 + qh_ptr = qh_ptr->next;
9897 + list_move(&qh->qh_list_entry, &hcd->non_periodic_sched_active);
9899 + if (ret_val == DWC_OTG_TRANSACTION_NONE)
9900 + ret_val = DWC_OTG_TRANSACTION_NON_PERIODIC;
9902 + ret_val = DWC_OTG_TRANSACTION_ALL;
9904 + hcd->non_periodic_channels++;
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.
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
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.
9928 +static int queue_transaction(struct dwc_otg_hcd *hcd,
9929 + struct dwc_hc *_hc, uint16_t _fifo_dwords_avail)
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;
9939 + } else if (_hc->halt_pending) {
9940 + /* Don't queue a request if the channel has been halted. */
9942 + } else if (_hc->halt_on_queue) {
9943 + dwc_otg_hc_halt(hcd->core_if, _hc, _hc->halt_status);
9945 + } else if (_hc->do_ping) {
9946 + if (!_hc->xfer_started)
9947 + dwc_otg_hc_start_transfer(hcd->core_if, _hc);
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);
9957 + dwc_otg_hc_continue_transfer(hcd->core_if,
9964 + if (!_hc->xfer_started) {
9965 + dwc_otg_hc_start_transfer(hcd->core_if, _hc);
9969 + dwc_otg_hc_continue_transfer(hcd->core_if, _hc);
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.
9983 +static void process_non_periodic_channels(struct dwc_otg_hcd *hcd)
9985 + union gnptxsts_data tx_status;
9986 + struct list_head *orig_qh_ptr;
9987 + struct dwc_otg_qh *qh;
9989 + int no_queue_space = 0;
9990 + int no_fifo_space = 0;
9991 + int more_to_do = 0;
9993 + struct dwc_otg_core_global_regs *global_regs =
9994 + hcd->core_if->core_global_regs;
9996 + DWC_DEBUGPL(DBG_HCDV, "Queue non-periodic transactions\n");
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);
10006 + * Keep track of the starting point. Skip over the start-of-list
10009 + if (hcd->non_periodic_qh_ptr == &hcd->non_periodic_sched_active)
10010 + hcd->non_periodic_qh_ptr = hcd->non_periodic_qh_ptr->next;
10012 + orig_qh_ptr = hcd->non_periodic_qh_ptr;
10015 + * Process once through the active list or until no more space is
10016 + * available in the request queue or the Tx FIFO.
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;
10026 + qh = list_entry(hcd->non_periodic_qh_ptr, struct dwc_otg_qh,
10029 + queue_transaction(hcd, qh->channel,
10030 + tx_status.b.nptxfspcavail);
10032 + if (status > 0) {
10034 + } else if (status < 0) {
10035 + no_fifo_space = 1;
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;
10047 + } while (hcd->non_periodic_qh_ptr != orig_qh_ptr);
10049 + if (!hcd->core_if->dma_enable) {
10050 + union gintmsk_data intr_mask = {.d32 = 0 };
10051 + intr_mask.b.nptxfempty = 1;
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);
10062 + if (no_queue_space || no_fifo_space) {
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.)
10070 + dwc_modify_reg32(&global_regs->gintmsk, 0,
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
10080 + dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32,
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 */
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);
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.
10112 +static void process_periodic_channels(struct dwc_otg_hcd *hcd)
10114 + union hptxsts_data tx_status;
10115 + struct list_head *qh_ptr;
10116 + struct dwc_otg_qh *qh;
10118 + int no_queue_space = 0;
10119 + int no_fifo_space = 0;
10121 + struct dwc_otg_host_global_regs *host_regs;
10122 + host_regs = hcd->core_if->host_if->host_global_regs;
10124 + DWC_DEBUGPL(DBG_HCDV, "Queue periodic transactions\n");
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);
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;
10142 + qh = list_entry(qh_ptr, struct dwc_otg_qh, qh_list_entry);
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.
10149 + if ((!hcd->core_if->dma_enable) &&
10150 + (qh->channel->multi_count > 1)) {
10151 + hcd->core_if->queuing_high_bandwidth = 1;
10155 + queue_transaction(hcd, qh->channel,
10156 + tx_status.b.ptxfspcavail);
10157 + if (status < 0) {
10158 + no_fifo_space = 1;
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.
10169 + if (hcd->core_if->dma_enable ||
10171 + qh->channel->requests == qh->channel->multi_count)) {
10172 + qh_ptr = qh_ptr->next;
10174 + * Move the QH from the periodic assigned schedule to
10175 + * the periodic queued schedule.
10177 + list_move(&qh->qh_list_entry,
10178 + &hcd->periodic_sched_queued);
10180 + /* done queuing high bandwidth */
10181 + hcd->core_if->queuing_high_bandwidth = 0;
10185 + if (!hcd->core_if->dma_enable) {
10186 + struct dwc_otg_core_global_regs *global_regs;
10187 + union gintmsk_data intr_mask = {.d32 = 0 };
10189 + global_regs = hcd->core_if->core_global_regs;
10190 + intr_mask.b.ptxfempty = 1;
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);
10200 + if (!(list_empty(&hcd->periodic_sched_assigned)) ||
10201 + no_queue_space || no_fifo_space) {
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.)
10209 + dwc_modify_reg32(&global_regs->gintmsk, 0,
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
10219 + dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32,
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.
10230 + * @hcd: The HCD state structure.
10231 + * @_tr_type: The type(s) of transactions to queue (non-periodic,
10232 + * periodic, or both).
10234 +void dwc_otg_hcd_queue_transactions(struct dwc_otg_hcd *hcd,
10235 + enum dwc_otg_transaction_type _tr_type)
10238 + DWC_DEBUGPL(DBG_HCD, "Queue Transactions\n");
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)) {
10245 + process_periodic_channels(hcd);
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);
10255 + * Ensure NP Tx FIFO empty interrupt is disabled when
10256 + * there are no non-periodic transfers to process.
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);
10267 + * Sets the final status of an URB and returns it to the device driver. Any
10268 + * required cleanup of the URB is performed.
10270 +void dwc_otg_hcd_complete_urb(struct dwc_otg_hcd *hcd, struct urb *urb,
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) {
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);
10289 + urb->status = status;
10290 + urb->hcpriv = NULL;
10292 + usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(hcd), urb, status);
10296 + * Returns the Queue Head for an URB.
10298 +struct dwc_otg_qh *dwc_urb_to_qh(struct urb *urb)
10300 + struct usb_host_endpoint *ep = dwc_urb_to_endpoint(urb);
10301 + return ep->hcpriv;
10305 +void dwc_print_setup_data(uint8_t *setup)
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]);
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) {
10319 + DWC_PRINT("Standard\n");
10322 + DWC_PRINT("Class\n");
10325 + DWC_PRINT("Vendor\n");
10328 + DWC_PRINT("Reserved\n");
10331 + DWC_PRINT(" bmRequestType Recipient = ");
10332 + switch (setup[0] & 0x1f) {
10334 + DWC_PRINT("Device\n");
10337 + DWC_PRINT("Interface\n");
10340 + DWC_PRINT("Endpoint\n");
10343 + DWC_PRINT("Other\n");
10346 + DWC_PRINT("Reserved\n");
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]));
10357 +void dwc_otg_hcd_dump_frrem(struct dwc_otg_hcd *hcd)
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);
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);
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);
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);
10427 +void dwc_otg_hcd_dump_state(struct dwc_otg_hcd *hcd)
10430 + int num_channels;
10432 + union gnptxsts_data np_tx_status;
10433 + union hptxsts_data p_tx_status;
10435 + num_channels = hcd->core_if->core_params->host_channels;
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;
10472 + dwc_read_reg32(&hcd->core_if->host_if->
10473 + host_global_regs->hfnum);
10475 + dwc_read_reg32(&hcd->core_if->host_if->hc_regs[i]->
10478 + dwc_read_reg32(&hcd->core_if->host_if->hc_regs[i]->
10481 + dwc_read_reg32(&hcd->core_if->host_if->hc_regs[i]->
10484 + dwc_read_reg32(&hcd->core_if->host_if->hc_regs[i]->
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);
10492 + if (hc->xfer_started && (hc->qh != NULL)
10493 + && (hc->qh->qtd_in_process != NULL)) {
10494 + struct dwc_otg_qtd *qtd;
10496 + qtd = hc->qh->qtd_in_process;
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->
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);
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);
10538 + ("************************************************************\n");
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
10547 +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.h
10549 +/* ==========================================================================
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.
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.
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
10576 + * ========================================================================== */
10577 +#ifndef DWC_DEVICE_ONLY
10578 +#if !defined(__DWC_HCD_H__)
10579 +#define __DWC_HCD_H__
10581 +#include <linux/list.h>
10582 +#include <linux/usb.h>
10583 +#include <linux/hrtimer.h>
10585 +#include <../drivers/usb/core/hcd.h>
10587 +struct dwc_otg_device;
10589 +#include "dwc_otg_cil.h"
10593 + * This file contains the structures, constants, and interfaces for
10594 + * the Host Contoller Driver (HCD).
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.
10603 + * Phases for control transfers.
10605 +enum dwc_otg_control_phase {
10606 + DWC_OTG_CONTROL_SETUP,
10607 + DWC_OTG_CONTROL_DATA,
10608 + DWC_OTG_CONTROL_STATUS
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
10619 +struct dwc_otg_qh;
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.
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.
10634 +struct dwc_otg_qtd {
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
10642 + uint8_t data_toggle;
10644 + /** Current phase for control transfers (Setup, Data, or Status). */
10645 + enum dwc_otg_control_phase control_phase;
10647 + /** Keep track of the current split type
10648 + * for FS/LS endpoints on a HS Hub */
10649 + uint8_t complete_split;
10651 + /** How many bytes transferred during SSPLIT OUT */
10652 + uint32_t ssplit_out_xfer_count;
10655 + * Holds the number of bus errors that have occurred for a transaction
10656 + * within this transfer.
10658 + uint8_t error_count;
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.
10667 + int isoc_frame_index;
10669 + /** Position of the ISOC split on full/low speed */
10670 + uint8_t isoc_split_pos;
10672 + /** Position of the ISOC split in the buffer for the current frame */
10673 + uint16_t isoc_split_offset;
10675 + /** URB for this transfer */
10678 + /* The queue head for this transfer. */
10679 + struct dwc_otg_qh *qh;
10681 + /** This list of QTDs */
10682 + struct list_head qtd_list_entry;
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.
10691 +struct dwc_otg_qh {
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
10701 + uint8_t ep_is_in;
10703 + /** wMaxPacketSize Field of Endpoint Descriptor. */
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
10713 + uint8_t data_toggle;
10715 + /** Ping state if 1. */
10716 + uint8_t ping_state;
10719 + * List of QTDs for this QH.
10721 + struct list_head qtd_list;
10723 + /** Host channel currently processing transfers for this QH. */
10724 + struct dwc_hc *channel;
10726 + /** QTD currently assigned to a host channel for this QH. */
10727 + struct dwc_otg_qtd *qtd_in_process;
10729 + /** Full/low speed endpoint on high-speed hub requires split. */
10730 + uint8_t do_split;
10732 + /** @name Periodic schedule information */
10735 + /** Bandwidth in microseconds per (micro)frame. */
10738 + /** Interval between transfers in (micro)frames. */
10739 + uint16_t interval;
10742 + * (micro)frame to initialize a periodic transfer. The transfer
10743 + * executes in the following (micro)frame.
10745 + uint16_t sched_frame;
10747 + /** (micro)frame at which last start split was initialized. */
10748 + uint16_t start_split_frame;
10752 + /** Entry for QH in either the periodic or non-periodic schedule. */
10753 + struct list_head qh_list_entry;
10757 + * This structure holds the state of the HCD, including the non-periodic and
10758 + * periodic schedules.
10760 +struct dwc_otg_hcd {
10762 + /** DWC OTG Core Interface Layer */
10763 + struct dwc_otg_core_if *core_if;
10765 + /** Internal DWC HCD Flags */
10766 + union dwc_otg_hcd_internal_flags {
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;
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;
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.
10794 + struct list_head non_periodic_sched_inactive;
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.
10801 + struct list_head non_periodic_sched_active;
10804 + * Pointer to the next Queue Head to process in the active
10805 + * non-periodic schedule.
10807 + struct list_head *non_periodic_qh_ptr;
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.
10820 + * Items move from this list to periodic_sched_ready when the QH
10821 + * interval counter is 0 at SOF.
10823 + struct list_head periodic_sched_inactive;
10826 + * List of periodic QHs that are ready for execution in the next
10827 + * frame, but have not yet been assigned to host channels.
10829 + * Items move from this list to periodic_sched_assigned as host
10830 + * channels become available during the current frame.
10832 + struct list_head periodic_sched_ready;
10835 + * List of periodic QHs to be executed in the next frame that are
10836 + * assigned to host channels.
10838 + * Items move from this list to periodic_sched_queued as the
10839 + * transactions for the QH are queued to the DWC_otg controller.
10841 + struct list_head periodic_sched_assigned;
10844 + * List of periodic QHs that have been queued for execution.
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.
10852 + struct list_head periodic_sched_queued;
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.
10859 + uint16_t periodic_usecs;
10862 + * Frame number read from the core at SOF. The value ranges from 0 to
10863 + * DWC_HFNUM_MAX_FRNUM.
10865 + uint16_t frame_number;
10868 + * Free host channels in the controller. This is a list of
10869 + * struct dwc_hc items.
10871 + struct list_head free_hc_list;
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.
10879 + int periodic_channels;
10882 + * Number of host channels assigned to non-periodic transfers.
10884 + int non_periodic_channels;
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.
10891 + struct dwc_hc *hc_ptr_array[MAX_EPS_CHANNELS];
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.
10898 + uint8_t *status_buf;
10901 + * DMA address for status_buf.
10903 + dma_addr_t status_buf_dma;
10904 +#define DWC_OTG_HCD_STATUS_BUF_SIZE 64
10907 + * Structure to allow starting the HCD in a non-interrupt context
10908 + * during an OTG role change.
10910 + struct work_struct start_work;
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".
10917 + struct timer_list conn_timer;
10919 + /* Tasket to do a reset */
10920 + struct tasklet_struct *reset_tasklet;
10922 + struct hrtimer poll_rate_limit;
10924 + spinlock_t global_lock;
10927 + uint32_t frrem_samples;
10928 + uint64_t frrem_accum;
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;
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;
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)
10950 + return (struct dwc_otg_hcd *)(hcd->hcd_priv);
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
10957 + return container_of((void *)dwc_otg_hcd, struct usb_hcd, hcd_priv);
10960 +/** @name HCD Create/Destroy Functions */
10962 +extern int __init dwc_otg_hcd_init(struct device *_dev);
10963 +extern void dwc_otg_hcd_remove(struct device *_dev);
10966 +/** @name Linux HC Driver API Functions */
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,
10983 + u16 wIndex, char *buf, u16 wLength);
10986 +/** @name Transaction Execution Functions */
10987 +extern enum dwc_otg_transaction_type dwc_otg_hcd_select_transactions(struct
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,
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
11000 +extern int32_t dwc_otg_hcd_handle_np_tx_fifo_empty_intr(struct dwc_otg_hcd
11002 +extern int32_t dwc_otg_hcd_handle_perio_tx_fifo_empty_intr(struct dwc_otg_hcd
11004 +extern int32_t dwc_otg_hcd_handle_incomplete_periodic_intr(struct 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
11009 +extern int32_t dwc_otg_hcd_handle_disconnect_intr(struct 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,
11014 +extern int32_t dwc_otg_hcd_handle_session_req_intr(struct dwc_otg_hcd
11016 +extern int32_t dwc_otg_hcd_handle_wakeup_detected_intr(struct dwc_otg_hcd
11019 +/** @name Schedule Queue Functions */
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);
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)
11036 + dwc_otg_hcd_qh_remove(hcd, qh);
11037 + dwc_otg_hcd_qh_free(qh);
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)
11044 + return kmalloc(sizeof(struct dwc_otg_qh), GFP_ATOMIC);
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);
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)
11056 + return kmalloc(sizeof(struct dwc_otg_qtd), GFP_ATOMIC);
11060 + * Frees the memory for a QTD structure. QTD should already be removed from
11062 + * @qtd: QTD to free.
11064 +static inline void dwc_otg_hcd_qtd_free(struct dwc_otg_qtd *qtd)
11070 + * Removes a QTD from list.
11071 + * @qtd: QTD to remove from list.
11073 +static inline void dwc_otg_hcd_qtd_remove(struct dwc_otg_qtd *qtd)
11075 + list_del(&qtd->qtd_list_entry);
11078 +/** Remove and free a QTD */
11079 +static inline void dwc_otg_hcd_qtd_remove_and_free(struct dwc_otg_qtd *qtd)
11081 + dwc_otg_hcd_qtd_remove(qtd);
11082 + dwc_otg_hcd_qtd_free(qtd);
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);
11090 +/** Gets the usb_host_endpoint associated with an URB. */
11091 +static inline struct usb_host_endpoint *dwc_urb_to_endpoint(struct urb *urb)
11093 + struct usb_device *dev = urb->dev;
11094 + int ep_num = usb_pipeendpoint(urb->pipe);
11096 + if (usb_pipein(urb->pipe))
11097 + return dev->ep_in[ep_num];
11099 + return dev->ep_out[ep_num];
11103 + * Gets the endpoint number from a bEndpointAddress argument. The endpoint is
11104 + * qualified with its direction (possible 32 endpoints per device).
11106 +#define dwc_ep_addr_to_endpoint(_bEndpointAddress_) \
11107 + ((_bEndpointAddress_ & USB_ENDPOINT_NUMBER_MASK) | \
11108 + ((_bEndpointAddress_ & USB_DIR_IN) != 0) << 4)
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))
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))
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))
11123 +/** High bandwidth multiplier as encoded in highspeed endpoint descriptors */
11124 +#define dwc_hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
11126 +/** Packet size for any kind of endpoint descriptor */
11127 +#define dwc_max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff)
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.
11134 +static inline int dwc_frame_num_le(uint16_t frame1, uint16_t frame2)
11136 + return ((frame2 - frame1) & DWC_HFNUM_MAX_FRNUM) <=
11137 + (DWC_HFNUM_MAX_FRNUM >> 1);
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.
11145 +static inline int dwc_frame_num_gt(uint16_t frame1, uint16_t frame2)
11147 + return (frame1 != frame2) &&
11148 + (((frame1 - frame2) & DWC_HFNUM_MAX_FRNUM) <
11149 + (DWC_HFNUM_MAX_FRNUM >> 1));
11153 + * Increments frame by the amount specified by inc. The addition is done
11154 + * modulo DWC_HFNUM_MAX_FRNUM. Returns the incremented value.
11156 +static inline uint16_t dwc_frame_num_inc(uint16_t frame, uint16_t inc)
11158 + return (frame + inc) & DWC_HFNUM_MAX_FRNUM;
11161 +static inline uint16_t dwc_full_frame_num(uint16_t frame)
11163 + return (frame & DWC_HFNUM_MAX_FRNUM) >> 3;
11166 +static inline uint16_t dwc_micro_frame_num(uint16_t frame)
11168 + return frame & 0x7;
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.
11178 + * To dump the average sample times, read the "hcd_frrem" sysfs attribute. For
11179 + * example, "cat /sys/devices/lm0/hcd_frrem".
11181 +#define dwc_sample_frrem(_hcd, _qh, _letter) \
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) { \
11190 + _hcd->hfnum_7_samples_##_letter++; \
11191 + _hcd->hfnum_7_frrem_accum_##_letter += hfnum.b.frrem; \
11194 + _hcd->hfnum_0_samples_##_letter++; \
11195 + _hcd->hfnum_0_frrem_accum_##_letter += hfnum.b.frrem; \
11198 + _hcd->hfnum_other_samples_##_letter++; \
11199 + _hcd->hfnum_other_frrem_accum_##_letter += \
11206 +#define dwc_sample_frrem(hcd, qh, letter)
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
11214 +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
11216 +/* ==========================================================================
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.
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.
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
11243 + * ========================================================================== */
11244 +#ifndef DWC_DEVICE_ONLY
11246 +#include "dwc_otg_driver.h"
11247 +#include "dwc_otg_hcd.h"
11248 +#include "dwc_otg_regs.h"
11251 + * This file contains the implementation of the HCD Interrupt handlers.
11254 +/* This function handles interrupts for the HCD. */
11255 +int32_t dwc_otg_hcd_handle_intr(struct dwc_otg_hcd *dwc_otg_hcd)
11259 + struct dwc_otg_core_if *core_if = dwc_otg_hcd->core_if;
11260 + union gintsts_data gintsts;
11262 + struct dwc_otg_core_global_regs *global_regs =
11263 + core_if->core_global_regs;
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)
11272 + /* Don't print debug message in the interrupt handler on SOF */
11273 +# ifndef DEBUG_SOF
11274 + if (gintsts.d32 != DWC_SOF_INTR_MASK)
11276 + DWC_DEBUGPL(DBG_HCD, "\n");
11280 +# ifndef DEBUG_SOF
11281 + if (gintsts.d32 != DWC_SOF_INTR_MASK)
11283 + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Interrupt Detected "
11284 + "gintsts&gintmsk=0x%08x\n",
11288 + if (gintsts.b.sofintr)
11289 + retval |= dwc_otg_hcd_handle_sof_intr(dwc_otg_hcd);
11291 + if (gintsts.b.rxstsqlvl)
11293 + dwc_otg_hcd_handle_rx_status_q_level_intr(dwc_otg_hcd);
11295 + if (gintsts.b.nptxfempty)
11297 + dwc_otg_hcd_handle_np_tx_fifo_empty_intr(dwc_otg_hcd);
11299 + if (gintsts.b.i2cintr)
11300 + ;/** @todo Implement i2cintr handler. */
11302 + if (gintsts.b.portintr)
11303 + retval |= dwc_otg_hcd_handle_port_intr(dwc_otg_hcd);
11305 + if (gintsts.b.hcintr)
11306 + retval |= dwc_otg_hcd_handle_hc_intr(dwc_otg_hcd);
11308 + if (gintsts.b.ptxfempty) {
11310 + dwc_otg_hcd_handle_perio_tx_fifo_empty_intr
11314 +# ifndef DEBUG_SOF
11315 + if (gintsts.d32 != DWC_SOF_INTR_MASK)
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));
11328 +# ifndef DEBUG_SOF
11329 + if (gintsts.d32 != DWC_SOF_INTR_MASK)
11331 + DWC_DEBUGPL(DBG_HCD, "\n");
11339 +#ifdef DWC_TRACK_MISSED_SOFS
11340 +#warning Compiling code to track missed SOFs
11341 +#define FRAME_NUM_ARRAY_SIZE 1000
11343 + * This function is for debug only.
11345 +static inline void track_missed_sofs(uint16_t _curr_frame_number)
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;
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;
11359 + } else if (!dumped_frame_num_array) {
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]);
11367 + dumped_frame_num_array = 1;
11369 + last_frame_num = _curr_frame_number;
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.
11379 +int32_t dwc_otg_hcd_handle_sof_intr(struct dwc_otg_hcd *hcd)
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 };
11388 + dwc_read_reg32(&hcd->core_if->host_if->host_global_regs->hfnum);
11391 + DWC_DEBUGPL(DBG_HCD, "--Start of Frame Interrupt--\n");
11394 + hcd->frame_number = hfnum.b.frnum;
11397 + hcd->frrem_accum += hfnum.b.frrem;
11398 + hcd->frrem_samples++;
11401 +#ifdef DWC_TRACK_MISSED_SOFS
11402 + track_missed_sofs(hcd->frame_number);
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)) {
11412 + * Move QH to the ready list to be executed next
11415 + list_move(&qh->qh_list_entry,
11416 + &hcd->periodic_sched_ready);
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)) {
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()
11435 + dwc_modify_reg32(&hcd->core_if->core_global_regs->gintmsk,
11436 + DWC_SOF_INTR_MASK, 0);
11439 + /* Clear interrupt */
11440 + gintsts.b.sofintr = 1;
11441 + dwc_write_reg32(&hcd->core_if->core_global_regs->gintsts, gintsts.d32);
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
11451 +dwc_otg_hcd_handle_rx_status_q_level_intr(struct dwc_otg_hcd *dwc_otg_hcd)
11453 + union host_grxsts_data grxsts;
11454 + struct dwc_hc *hc = NULL;
11456 + DWC_DEBUGPL(DBG_HCD, "--RxStsQ Level Interrupt--\n");
11459 + dwc_read_reg32(&dwc_otg_hcd->core_if->core_global_regs->grxstsp);
11461 + hc = dwc_otg_hcd->hc_ptr_array[grxsts.b.chnum];
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);
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);
11477 + /* Update the HC fields for the next packet received. */
11478 + hc->xfer_count += grxsts.b.bcnt;
11479 + hc->xfer_buff += grxsts.b.bcnt;
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 */
11488 + DWC_ERROR("RX_STS_Q Interrupt: Unknown status %d\n",
11489 + grxsts.b.pktsts);
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
11501 +int32_t dwc_otg_hcd_handle_np_tx_fifo_empty_intr(struct dwc_otg_hcd *
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);
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 *
11517 + DWC_DEBUGPL(DBG_HCD, "--Periodic TxFIFO Empty Interrupt--\n");
11518 + dwc_otg_hcd_queue_transactions(dwc_otg_hcd,
11519 + DWC_OTG_TRANSACTION_PERIODIC);
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)
11529 + union hprt0_data hprt0;
11530 + union hprt0_data hprt0_modify;
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);
11536 + /* Clear appropriate bits in HPRT0 to clear the interrupt bit in
11539 + hprt0_modify.b.prtena = 0;
11540 + hprt0_modify.b.prtconndet = 0;
11541 + hprt0_modify.b.prtenchng = 0;
11542 + hprt0_modify.b.prtovrcurrchng = 0;
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;
11553 + /* B-Device has connected, Delete the connection timer. */
11554 + del_timer(&dwc_otg_hcd->conn_timer);
11556 + /* The Hub driver asserts a reset when it sees port connect
11557 + * status change flag */
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;
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;
11582 + dwc_read_reg32(&global_regs->gusbcfg);
11584 + if ((hprt0.b.prtspd == DWC_HPRT0_PRTSPD_LOW_SPEED)
11585 + || (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_FULL_SPEED)) {
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,
11599 + dwc_read_reg32(&host_if->host_global_regs->hcfg);
11601 + if ((hprt0.b.prtspd ==
11602 + DWC_HPRT0_PRTSPD_LOW_SPEED)
11604 + host_ls_low_power_phy_clk ==
11605 + DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ)) {
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 =
11613 + dwc_write_reg32(&host_if->host_global_regs->hcfg,
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,
11633 + if (usbcfg.b.phylpwrclksel == 1) {
11634 + usbcfg.b.phylpwrclksel = 0;
11635 + dwc_write_reg32(&global_regs->gusbcfg,
11641 + tasklet_schedule(dwc_otg_hcd->reset_tasklet);
11645 + * Port has been enabled set the reset
11648 + dwc_otg_hcd->flags.b.port_reset_change = 1;
11650 + dwc_otg_hcd->flags.b.port_enable_change = 1;
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;
11664 + /* Clear Port Interrupts */
11665 + dwc_write_reg32(dwc_otg_hcd->core_if->host_if->hprt0,
11666 + hprt0_modify.d32);
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)
11679 + union haint_data haint;
11681 + /* Clear appropriate bits in HCINTn to clear the interrupt bit in
11684 + haint.d32 = dwc_otg_read_host_all_channels_intr(dwc_otg_hcd->core_if);
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);
11694 +/* Macro used to clear one channel interrupt */
11695 +#define clear_hc_int(_hc_regs_, _intr_) \
11697 + union hcint_data hcint_clear = {.d32 = 0}; \
11698 + hcint_clear.b._intr_ = 1; \
11699 + dwc_write_reg32(&((_hc_regs_)->hcint), hcint_clear.d32); \
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.
11709 +#define disable_hc_int(_hc_regs_, _intr_) \
11711 + union hcintmsk_data hcintmsk = {.d32 = 0}; \
11712 + hcintmsk.b._intr_ = 1; \
11713 + dwc_modify_reg32(&((_hc_regs_)->hcintmsk), hcintmsk.d32, 0); \
11717 + * Gets the actual length of a transfer after the transfer halts. _halt_status
11718 + * holds the reason for the halt.
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
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)
11732 + union hctsiz_data hctsiz;
11735 + if (_short_read != NULL)
11736 + *_short_read = 0;
11738 + hctsiz.d32 = dwc_read_reg32(&hc_regs->hctsiz);
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;
11748 + length = hc->xfer_len;
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).
11761 + (hc->start_pkt_count - hctsiz.b.pktcnt) * hc->max_packet;
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.
11773 + * Returns 1 if the data transfer specified by the URB is completely finished,
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)
11780 + int xfer_done = 0;
11781 + int short_read = 0;
11783 + urb->actual_length += get_actual_xfer_length(hc, hc_regs, qtd,
11784 + DWC_OTG_HC_XFER_COMPLETE,
11787 + if (short_read || (urb->actual_length == urb->transfer_buffer_length)) {
11789 + if (short_read && (urb->transfer_flags & URB_SHORT_NOT_OK))
11790 + urb->status = -EREMOTEIO;
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"),
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);
11813 + return xfer_done;
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.
11821 +static void save_data_toggle(struct dwc_hc *hc,
11822 + struct dwc_otg_hc_regs *hc_regs,
11823 + struct dwc_otg_qtd *qtd)
11825 + union hctsiz_data hctsiz;
11826 + hctsiz.d32 = dwc_read_reg32(&hc_regs->hctsiz);
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;
11833 + qh->data_toggle = DWC_OTG_HC_PID_DATA1;
11835 + if (hctsiz.b.pid == DWC_HCTSIZ_DATA0)
11836 + qtd->data_toggle = DWC_OTG_HC_PID_DATA0;
11838 + qtd->data_toggle = DWC_OTG_HC_PID_DATA1;
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.
11849 +static void deactivate_qh(struct dwc_otg_hcd *hcd,
11850 + struct dwc_otg_qh *qh, int free_qtd)
11852 + int continue_split = 0;
11853 + struct dwc_otg_qtd *qtd;
11855 + DWC_DEBUGPL(DBG_HCDV, " %s(%p,%p,%d)\n", __func__, hcd, qh, free_qtd);
11857 + qtd = list_entry(qh->qtd_list.next, struct dwc_otg_qtd, qtd_list_entry);
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;
11867 + dwc_otg_hcd_qtd_remove_and_free(qtd);
11868 + continue_split = 0;
11871 + qh->channel = NULL;
11872 + qh->qtd_in_process = NULL;
11873 + dwc_otg_hcd_qh_deactivate(hcd, qh, continue_split);
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.
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.
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)
11892 + struct urb *urb = qtd->urb;
11893 + enum dwc_otg_halt_status ret_val = halt_status;
11894 + struct usb_iso_packet_descriptor *frame_desc;
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);
11904 + case DWC_OTG_HC_XFER_FRAME_OVERRUN:
11905 + urb->error_count++;
11906 + if (hc->ep_is_in)
11907 + frame_desc->status = -ENOSR;
11909 + frame_desc->status = -ECOMM;
11910 + frame_desc->actual_length = 0;
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. */
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);
11925 + DWC_ERROR("%s: Unhandled halt_status (%d)\n", __func__,
11931 + if (++qtd->isoc_frame_index == urb->number_of_packets) {
11933 + * urb->status is not used for isoc transfers.
11934 + * The individual frame_desc statuses are used instead.
11936 + dwc_otg_hcd_complete_urb(hcd, urb, 0);
11938 + ret_val = DWC_OTG_HC_XFER_URB_COMPLETE;
11940 + ret_val = DWC_OTG_HC_XFER_COMPLETE;
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.
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.
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)
11962 + enum dwc_otg_transaction_type tr_type;
11965 + DWC_DEBUGPL(DBG_HCDV, " %s: channel %d, halt_status %d\n",
11966 + __func__, hc->hc_num, halt_status);
11968 + switch (halt_status) {
11969 + case DWC_OTG_HC_XFER_URB_COMPLETE:
11972 + case DWC_OTG_HC_XFER_AHB_ERR:
11973 + case DWC_OTG_HC_XFER_STALL:
11974 + case DWC_OTG_HC_XFER_BABBLE_ERR:
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");
11982 + qtd->urb->status = -EPROTO;
11983 + dwc_otg_hcd_complete_urb(hcd, qtd->urb, -EPROTO);
11989 + case DWC_OTG_HC_XFER_URB_DEQUEUE:
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.
11996 + case DWC_OTG_HC_XFER_NO_HALT_STATUS:
11997 + DWC_ERROR("%s: No halt_status, channel %d\n", __func__,
12006 + deactivate_qh(hcd, hc->qh, free_qtd);
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.
12014 + dwc_otg_hc_cleanup(hcd->core_if, hc);
12015 + list_add_tail(&hc->hc_list_entry, &hcd->free_hc_list);
12017 + switch (hc->ep_type) {
12018 + case DWC_OTG_EP_TYPE_CONTROL:
12019 + case DWC_OTG_EP_TYPE_BULK:
12020 + hcd->non_periodic_channels--;
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).
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);
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.
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
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)
12053 + if (hcd->core_if->dma_enable) {
12054 + release_channel(hcd, hc, qtd, halt_status);
12058 + /* Slave mode processing... */
12059 + dwc_otg_hc_halt(hcd->core_if, hc, halt_status);
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;
12066 + if (hc->ep_type == DWC_OTG_EP_TYPE_CONTROL ||
12067 + hc->ep_type == DWC_OTG_EP_TYPE_BULK) {
12069 + * Make sure the Non-periodic Tx FIFO empty interrupt
12070 + * is enabled so that the non-periodic schedule will
12073 + gintmsk.b.nptxfempty = 1;
12074 + dwc_modify_reg32(&global_regs->gintmsk, 0, gintmsk.d32);
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
12082 + list_move(&hc->qh->qh_list_entry,
12083 + &hcd->periodic_sched_assigned);
12086 + * Make sure the Periodic Tx FIFO Empty interrupt is
12087 + * enabled so that the periodic schedule will be
12090 + gintmsk.b.ptxfempty = 1;
12091 + dwc_modify_reg32(&global_regs->gintmsk, 0, gintmsk.d32);
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.
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)
12107 + union hcint_data hcint;
12109 + qtd->error_count = 0;
12111 + hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
12112 + if (hcint.b.nyet) {
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.
12118 + hc->qh->ping_state = 1;
12119 + clear_hc_int(hc_regs, nyet);
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.
12132 + if (hc->ep_is_in) {
12134 + * IN transfers in Slave mode require an explicit disable to
12135 + * halt the channel. (In DMA mode, this call simply releases
12138 + halt_channel(hcd, hc, qtd, halt_status);
12141 + * The channel is automatically disabled by the core for OUT
12142 + * transfers in Slave mode.
12144 + release_channel(hcd, hc, qtd, halt_status);
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.
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)
12159 + union hctsiz_data hctsiz;
12160 + qtd->error_count = 0;
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);
12167 + /* Flush any outstanding requests from the Tx queue. */
12168 + halt_channel(hcd, hc, qtd, halt_status);
12173 + * Handles a host channel Transfer Complete interrupt. This handler may be
12174 + * called in either DMA mode or Slave mode.
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)
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);
12186 + DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
12187 + "Transfer Complete--\n", hc->hc_num);
12190 + * Handle xfer complete on CSPLIT.
12192 + if (hc->qh->do_split)
12193 + qtd->complete_split = 0;
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;
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;
12208 + case DWC_OTG_CONTROL_DATA:{
12210 + update_urb_state_xfer_comp(hc, hc_regs,
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");
12218 + save_data_toggle(hc, hc_regs, qtd);
12220 + halt_status = DWC_OTG_HC_XFER_COMPLETE;
12223 + case DWC_OTG_CONTROL_STATUS:
12224 + DWC_DEBUGPL(DBG_HCDV, " Control transfer complete\n");
12225 + if (urb->status == -EINPROGRESS)
12227 + dwc_otg_hcd_complete_urb(hcd, urb, urb->status);
12229 + halt_status = DWC_OTG_HC_XFER_URB_COMPLETE;
12233 + complete_non_periodic_xfer(hcd, hc, hc_regs, qtd,
12237 + DWC_DEBUGPL(DBG_HCDV, " Bulk transfer complete\n");
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);
12243 + halt_status = DWC_OTG_HC_XFER_URB_COMPLETE;
12245 + halt_status = DWC_OTG_HC_XFER_COMPLETE;
12248 + save_data_toggle(hc, hc_regs, qtd);
12249 + complete_non_periodic_xfer(hcd, hc, hc_regs, qtd,
12252 + case PIPE_INTERRUPT:
12253 + DWC_DEBUGPL(DBG_HCDV, " Interrupt transfer complete\n");
12254 + update_urb_state_xfer_comp(hc, hc_regs, urb, qtd);
12257 + * Interrupt URB is done on the first transfer complete
12260 + dwc_otg_hcd_complete_urb(hcd, urb, urb->status);
12262 + save_data_toggle(hc, hc_regs, qtd);
12263 + complete_periodic_xfer(hcd, hc, hc_regs, qtd,
12264 + DWC_OTG_HC_XFER_URB_COMPLETE);
12266 + case PIPE_ISOCHRONOUS:
12267 + DWC_DEBUGPL(DBG_HCDV, " Isochronous transfer complete\n");
12268 + if (qtd->isoc_split_pos == DWC_HCSPLIT_XACTPOS_ALL) {
12270 + update_isoc_urb_state(hcd, hc, hc_regs, qtd,
12271 + DWC_OTG_HC_XFER_COMPLETE);
12273 + complete_periodic_xfer(hcd, hc, hc_regs, qtd, halt_status);
12277 + disable_hc_int(hc_regs, xfercompl);
12283 + * Handles a host channel STALL interrupt. This handler may be called in
12284 + * either DMA mode or Slave mode.
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)
12291 + struct urb *urb = qtd->urb;
12292 + int pipe_type = usb_pipetype(urb->pipe);
12294 + DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
12295 + "STALL Received--\n", hc->hc_num);
12297 + if (pipe_type == PIPE_CONTROL) {
12298 + dwc_otg_hcd_complete_urb(hcd, qtd->urb, -EPIPE);
12302 + if (pipe_type == PIPE_BULK || pipe_type == PIPE_INTERRUPT) {
12303 + dwc_otg_hcd_complete_urb(hcd, qtd->urb, -EPIPE);
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.
12312 + hc->qh->data_toggle = 0;
12315 + halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_STALL);
12317 + disable_hc_int(hc_regs, stall);
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.
12328 +static void update_urb_state_xfer_intr(struct dwc_hc *hc,
12329 + struct dwc_otg_hc_regs *hc_regs,
12331 + struct dwc_otg_qtd *qtd,
12332 + enum dwc_otg_halt_status halt_status)
12334 + uint32_t bytes_transferred = get_actual_xfer_length(hc, hc_regs, qtd,
12335 + halt_status, NULL);
12336 + urb->actual_length += bytes_transferred;
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"),
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",
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);
12361 + * Handles a host channel NAK interrupt. This handler may be called in either
12362 + * DMA mode or Slave mode.
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)
12369 + DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
12370 + "NAK Received--\n", hc->hc_num);
12373 + * Handle NAK for IN/OUT SSPLIT/CSPLIT transfers, bulk, control, and
12374 + * interrupt. Re-start the SSPLIT transfer.
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;
12384 + switch (usb_pipetype(qtd->urb->pipe)) {
12385 + case PIPE_CONTROL:
12387 + if (hcd->core_if->dma_enable && hc->ep_is_in) {
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.
12394 + qtd->error_count = 0;
12395 + goto handle_nak_done;
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.
12403 + qtd->error_count = 0;
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;
12414 + * Halt the channel so the transfer can be re-started from
12415 + * the appropriate point or the PING protocol will
12416 + * start/continue.
12418 + halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NAK);
12420 + case PIPE_INTERRUPT:
12421 + qtd->error_count = 0;
12422 + halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NAK);
12424 + case PIPE_ISOCHRONOUS:
12425 + /* Should never get called for isochronous transfers. */
12431 + disable_hc_int(hc_regs, nak);
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.
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)
12446 + DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
12447 + "ACK Received--\n", hc->hc_num);
12449 + if (hc->do_split) {
12451 + * Handle ACK on SSPLIT.
12452 + * ACK should not occur in CSPLIT.
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;
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;
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:
12468 + case DWC_HCSPLIT_XACTPOS_END:
12469 + qtd->isoc_split_pos = DWC_HCSPLIT_XACTPOS_ALL;
12470 + qtd->isoc_split_offset = 0;
12472 + case DWC_HCSPLIT_XACTPOS_BEGIN:
12473 + case DWC_HCSPLIT_XACTPOS_MID:
12475 + * For BEGIN or MID, calculate the length for
12476 + * the next microframe to determine the correct
12477 + * SSPLIT token, either MID or END.
12480 + struct usb_iso_packet_descriptor
12484 + &qtd->urb->iso_frame_desc[qtd->isoc_frame_index];
12485 + qtd->isoc_split_offset += 188;
12487 + if ((frame_desc->length -
12488 + qtd->isoc_split_offset) <= 188) {
12489 + qtd->isoc_split_pos =
12490 + DWC_HCSPLIT_XACTPOS_END;
12492 + qtd->isoc_split_pos =
12493 + DWC_HCSPLIT_XACTPOS_MID;
12500 + halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_ACK);
12503 + qtd->error_count = 0;
12505 + if (hc->qh->ping_state) {
12506 + hc->qh->ping_state = 0;
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.
12514 + halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_ACK);
12519 + * If the ACK occurred when _not_ in the PING state, let the channel
12520 + * continue transferring data after clearing the error count.
12523 + disable_hc_int(hc_regs, ack);
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.
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)
12540 + DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
12541 + "NYET Received--\n", hc->hc_num);
12545 + * re-do the CSPLIT immediately on non-periodic
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)) {
12551 + dwc_otg_hcd_get_frame_number(dwc_otg_hcd_to_hcd
12554 + if (dwc_full_frame_num(frnum) !=
12555 + dwc_full_frame_num(hc->qh->sched_frame)) {
12557 + * No longer in the same full speed frame.
12558 + * Treat this as a transaction error.
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.
12567 + qtd->error_count++;
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;
12577 + halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NYET);
12578 + goto handle_nyet_done;
12581 + hc->qh->ping_state = 1;
12582 + qtd->error_count = 0;
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);
12589 + * Halt the channel and re-start the transfer so the PING
12590 + * protocol will start.
12592 + halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NYET);
12595 + disable_hc_int(hc_regs, nyet);
12600 + * Handles a host channel babble interrupt. This handler may be called in
12601 + * either DMA mode or Slave mode.
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)
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);
12613 + halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_BABBLE_ERR);
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);
12620 + disable_hc_int(hc_regs, bblerr);
12625 + * Handles a host channel AHB error interrupt. This handler is only called in
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)
12633 + union hcchar_data hcchar;
12634 + union hcsplt_data hcsplt;
12635 + union hctsiz_data hctsiz;
12637 + struct urb *urb = qtd->urb;
12639 + DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
12640 + "AHB Error--\n", hc->hc_num);
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);
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",
12657 + switch (usb_pipetype(urb->pipe)) {
12658 + case PIPE_CONTROL:
12659 + pipetype = "CONTROL";
12662 + pipetype = "BULK";
12664 + case PIPE_INTERRUPT:
12665 + pipetype = "INTERRUPT";
12667 + case PIPE_ISOCHRONOUS:
12668 + pipetype = "ISOCHRONOUS";
12671 + pipetype = "UNKNOWN";
12676 + DWC_ERROR(" Speed: %s\n",
12679 + switch (urb->dev->speed) {
12680 + case USB_SPEED_HIGH:
12683 + case USB_SPEED_FULL:
12686 + case USB_SPEED_LOW:
12690 + speed = "UNKNOWN";
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);
12704 + dwc_otg_hcd_complete_urb(hcd, urb, -EIO);
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.
12711 + dwc_otg_hc_halt(hcd->core_if, hc, DWC_OTG_HC_XFER_AHB_ERR);
12713 + disable_hc_int(hc_regs, ahberr);
12718 + * Handles a host channel transaction error interrupt. This handler may be
12719 + * called in either DMA mode or Slave mode.
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)
12726 + DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
12727 + "Transaction Error--\n", hc->hc_num);
12729 + switch (usb_pipetype(qtd->urb->pipe)) {
12730 + case PIPE_CONTROL:
12732 + qtd->error_count++;
12733 + if (!hc->qh->ping_state) {
12734 + update_urb_state_xfer_intr(hc, hc_regs, qtd->urb,
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;
12745 + * Halt the channel so the transfer can be re-started from
12746 + * the appropriate point or the PING protocol will start.
12748 + halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_XACT_ERR);
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);
12756 + case PIPE_ISOCHRONOUS:
12758 + enum dwc_otg_halt_status halt_status;
12760 + update_isoc_urb_state(hcd, hc, hc_regs, qtd,
12761 + DWC_OTG_HC_XFER_XACT_ERR);
12763 + halt_channel(hcd, hc, qtd, halt_status);
12768 + disable_hc_int(hc_regs, xacterr);
12774 + * Handles a host channel frame overrun interrupt. This handler may be called
12775 + * in either DMA mode or Slave mode.
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)
12782 + enum dwc_otg_halt_status halt_status;
12783 + DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
12784 + "Frame Overrun--\n", hc->hc_num);
12786 + switch (usb_pipetype(qtd->urb->pipe)) {
12787 + case PIPE_CONTROL:
12790 + case PIPE_INTERRUPT:
12791 + halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_FRAME_OVERRUN);
12793 + case PIPE_ISOCHRONOUS:
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);
12801 + disable_hc_int(hc_regs, frmovrun);
12807 + * Handles a host channel data toggle error interrupt. This handler may be
12808 + * called in either DMA mode or Slave mode.
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)
12815 + DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
12816 + "Data Toggle Error--\n", hc->hc_num);
12818 + if (hc->ep_is_in) {
12819 + qtd->error_count = 0;
12821 + DWC_ERROR("Data Toggle Error on OUT transfer,"
12822 + "channel %d\n", hc->hc_num);
12825 + disable_hc_int(hc_regs, datatglerr);
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.
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)
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;
12848 + if (hc->halt_status == DWC_OTG_HC_XFER_NO_HALT_STATUS) {
12850 + * This code is here only as a check. This condition should
12851 + * never happen. Ignore the halt if it does occur.
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);
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);
12866 + DWC_WARN("%s: no halt status, channel %d, ignoring interrupt\n",
12867 + __func__, hc->hc_num);
12869 + clear_hc_int(hc_regs, chhltd);
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.
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);
12894 + * Handles a host Channel Halted interrupt in DMA mode. This handler
12895 + * determines the reason the channel halted and proceeds accordingly.
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)
12902 + union hcint_data hcint;
12903 + union hcintmsk_data hcintmsk;
12905 + if (hc->halt_status == DWC_OTG_HC_XFER_URB_DEQUEUE ||
12906 + hc->halt_status == DWC_OTG_HC_XFER_AHB_ERR) {
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
12913 + release_channel(hcd, hc, qtd, hc->halt_status);
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);
12921 + if (hcint.b.xfercomp) {
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.
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) {
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.
12941 + handle_hc_xacterr_intr(hcd, hc, hc_regs, qtd);
12942 + } else if (hcint.b.nyet) {
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.
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) {
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.
12961 + handle_hc_nak_intr(hcd, hc, hc_regs, qtd);
12962 + } else if (hcint.b.ack && !hcintmsk.b.ack) {
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.
12969 + handle_hc_ack_intr(hcd, hc, hc_regs, qtd);
12971 + if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
12972 + hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
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
12980 + DWC_PRINT("%s: Halt channel %d (assume incomplete "
12981 + "periodic transfer)\n",
12982 + __func__, hc->hc_num);
12984 + halt_channel(hcd, hc, qtd,
12985 + DWC_OTG_HC_XFER_PERIODIC_INCOMPLETE);
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->
12998 + * Handles a host channel Channel Halted interrupt.
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.).
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.
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)
13013 + DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
13014 + "Channel Halted--\n", hc->hc_num);
13016 + if (hcd->core_if->dma_enable) {
13017 + handle_hc_chhltd_intr_dma(hcd, hc, hc_regs, qtd);
13020 + if (!halt_status_ok(hcd, hc, hc_regs, qtd))
13023 + release_channel(hcd, hc, qtd, hc->halt_status);
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,
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;
13040 + DWC_DEBUGPL(DBG_HCDV, "--Host Channel Interrupt--, Channel %d\n", _num);
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,
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;
13054 + if (!dwc_otg_hcd->core_if->dma_enable) {
13055 + if ((hcint.b.chhltd) && (hcint.d32 != 0x2))
13056 + hcint.b.chhltd = 0;
13059 + if (hcint.b.xfercomp) {
13061 + handle_hc_xfercomp_intr(dwc_otg_hcd, hc, hc_regs, qtd);
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.
13067 + hcint.b.nyet = 0;
13069 + if (hcint.b.chhltd)
13070 + retval |= handle_hc_chhltd_intr(dwc_otg_hcd, hc, hc_regs, qtd);
13072 + if (hcint.b.ahberr)
13073 + retval |= handle_hc_ahberr_intr(dwc_otg_hcd, hc, hc_regs, qtd);
13075 + if (hcint.b.stall)
13076 + retval |= handle_hc_stall_intr(dwc_otg_hcd, hc, hc_regs, qtd);
13079 + retval |= handle_hc_nak_intr(dwc_otg_hcd, hc, hc_regs, qtd);
13082 + retval |= handle_hc_ack_intr(dwc_otg_hcd, hc, hc_regs, qtd);
13084 + if (hcint.b.nyet)
13085 + retval |= handle_hc_nyet_intr(dwc_otg_hcd, hc, hc_regs, qtd);
13087 + if (hcint.b.xacterr)
13089 + handle_hc_xacterr_intr(dwc_otg_hcd, hc, hc_regs, qtd);
13091 + if (hcint.b.bblerr)
13092 + retval |= handle_hc_babble_intr(dwc_otg_hcd, hc, hc_regs, qtd);
13094 + if (hcint.b.frmovrun)
13096 + handle_hc_frmovrun_intr(dwc_otg_hcd, hc, hc_regs, qtd);
13098 + if (hcint.b.datatglerr)
13100 + handle_hc_datatglerr_intr(dwc_otg_hcd, hc, hc_regs, qtd);
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
13110 +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c
13112 +/* ==========================================================================
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.
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.
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
13139 + * ========================================================================== */
13140 +#ifndef DWC_DEVICE_ONLY
13144 + * This file contains the functions to manage Queue Heads and Queue
13145 + * Transfer Descriptors.
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>
13157 +#include "dwc_otg_driver.h"
13158 +#include "dwc_otg_hcd.h"
13159 +#include "dwc_otg_regs.h"
13162 + * This function allocates and initializes a QH.
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.
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,
13172 + struct dwc_otg_qh *qh;
13174 + /* Allocate memory */
13175 + /** @todo add memflags argument */
13176 + qh = dwc_otg_hcd_qh_alloc();
13180 + dwc_otg_hcd_qh_init(hcd, qh, urb);
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
13188 + * @qh: The QH to free.
13190 +void dwc_otg_hcd_qh_free(struct dwc_otg_qh *qh)
13192 + struct dwc_otg_qtd *qtd;
13193 + struct list_head *pos;
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) {
13199 + qtd = dwc_list_to_qtd(pos);
13200 + dwc_otg_hcd_qtd_free(qtd);
13207 +/** Initializes a QH structure.
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,
13217 + memset(qh, 0, sizeof(struct dwc_otg_qh));
13219 + /* Initialize QH */
13220 + switch (usb_pipetype(urb->pipe)) {
13221 + case PIPE_CONTROL:
13222 + qh->ep_type = USB_ENDPOINT_XFER_CONTROL;
13225 + qh->ep_type = USB_ENDPOINT_XFER_BULK;
13227 + case PIPE_ISOCHRONOUS:
13228 + qh->ep_type = USB_ENDPOINT_XFER_ISOC;
13230 + case PIPE_INTERRUPT:
13231 + qh->ep_type = USB_ENDPOINT_XFER_INT;
13235 + qh->ep_is_in = usb_pipein(urb->pipe) ? 1 : 0;
13237 + qh->data_toggle = DWC_OTG_HC_PID_DATA0;
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;
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 "
13253 + usb_pipeendpoint(urb->pipe),
13254 + urb->dev->tt->hub->devnum, urb->dev->ttport);
13255 + qh->do_split = 1;
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;
13263 + /* todo Account for split transfers in the bus time. */
13265 + dwc_hb_mult(qh->maxp) * dwc_max_packet(qh->maxp);
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
13271 + qh->usecs = usb_calc_bus_time(urb->dev->speed,
13272 + usb_pipein(urb->pipe),
13274 + USB_ENDPOINT_XFER_ISOC),
13275 + bytecount) / 1000;
13277 + /* Start in a slightly future (micro)frame. */
13278 + qh->sched_frame = dwc_frame_num_inc(hcd->frame_number,
13280 + qh->interval = urb->interval;
13282 + /* Increase interrupt polling rate for debugging. */
13283 + if (qh->ep_type == USB_ENDPOINT_XFER_INT)
13284 + qh->interval = 8;
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;
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",
13307 + switch (urb->dev->speed) {
13308 + case USB_SPEED_LOW:
13311 + case USB_SPEED_FULL:
13314 + case USB_SPEED_HIGH:
13323 + DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - Type = %s\n",
13326 + switch (qh->ep_type) {
13327 + case USB_ENDPOINT_XFER_ISOC:
13328 + type = "isochronous";
13330 + case USB_ENDPOINT_XFER_INT:
13331 + type = "interrupt";
13333 + case USB_ENDPOINT_XFER_CONTROL:
13334 + type = "control";
13336 + case USB_ENDPOINT_XFER_BULK:
13346 + if (qh->ep_type == USB_ENDPOINT_XFER_INT) {
13347 + DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - usecs = %d\n",
13349 + DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - interval = %d\n",
13358 + * Checks that a channel is available for a periodic transfer.
13360 + * Returns 0 if successful, negative error code otherise.
13362 +static int periodic_channel_available(struct dwc_otg_hcd *hcd)
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.
13370 + int num_channels;
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)) {
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;
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.
13392 + * @hcd: The HCD state structure for the DWC OTG controller.
13393 + * @qh: QH containing periodic bandwidth required.
13395 + * Returns 0 if successful, negative error code otherwise.
13397 +static int check_periodic_bandwidth(struct dwc_otg_hcd *hcd,
13398 + struct dwc_otg_qh *qh)
13401 + uint16_t max_claimed_usecs;
13405 + if (hcd->core_if->core_params->speed == DWC_SPEED_PARAM_HIGH) {
13407 + * High speed mode.
13408 + * Max periodic usecs is 80% x 125 usec = 100 usec.
13410 + max_claimed_usecs = 100 - qh->usecs;
13413 + * Full speed mode.
13414 + * Max periodic usecs is 90% x 1000 usec = 900 usec.
13416 + max_claimed_usecs = 900 - qh->usecs;
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;
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
13433 + * @hcd: The HCD state structure for the DWC OTG controller.
13434 + * @qh: QH for a periodic endpoint.
13436 + * Returns 0 if successful, negative error code otherwise.
13438 +static int check_max_xfer_size(struct dwc_otg_hcd *hcd, struct dwc_otg_qh *qh)
13441 + uint32_t max_xfer_size;
13442 + uint32_t max_channel_xfer_size;
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;
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;
13460 + * Schedules an interrupt or isochronous transfer in the periodic schedule.
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.
13466 + * Returns 0 if successful, negative error code otherwise.
13468 +static int schedule_periodic(struct dwc_otg_hcd *hcd, struct dwc_otg_qh *qh)
13472 + status = periodic_channel_available(hcd);
13474 + DWC_NOTICE("%s: No host channel available for periodic "
13475 + "transfer.\n", __func__);
13479 + status = check_periodic_bandwidth(hcd, qh);
13481 + DWC_NOTICE("%s: Insufficient periodic bandwidth for "
13482 + "periodic transfer.\n", __func__);
13486 + status = check_max_xfer_size(hcd, qh);
13488 + DWC_NOTICE("%s: Channel max transfer size too small "
13489 + "for periodic transfer.\n", __func__);
13493 + /* Always start in the inactive schedule. */
13494 + list_add_tail(&qh->qh_list_entry, &hcd->periodic_sched_inactive);
13496 + /* Reserve the periodic channel. */
13497 + hcd->periodic_channels++;
13499 + /* Update claimed usecs per (micro)frame. */
13500 + hcd->periodic_usecs += qh->usecs;
13503 + * Update average periodic bandwidth claimed and # periodic
13504 + * reqs for usbfs.
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);
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);
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.
13528 + * Returns 0 if successful, negative error code otherwise.
13530 +int dwc_otg_hcd_qh_add(struct dwc_otg_hcd *hcd, struct dwc_otg_qh *qh)
13534 + if (!spin_is_locked(&hcd->global_lock)) {
13535 + pr_err("%s don't have hcd->global_lock", __func__);
13539 + if (!list_empty(&qh->qh_list_entry)) {
13540 + /* QH already in a schedule. */
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);
13550 + status = schedule_periodic(hcd, qh);
13558 + * Removes an interrupt or isochronous transfer from the periodic schedule.
13560 + * @hcd: The HCD state structure for the DWC OTG controller.
13561 + * @qh: QH for the periodic transfer.
13563 +static void deschedule_periodic(struct dwc_otg_hcd *hcd, struct dwc_otg_qh *qh)
13565 + list_del_init(&qh->qh_list_entry);
13567 + /* Release the periodic channel reservation. */
13568 + hcd->periodic_channels--;
13570 + /* Update claimed usecs per (micro)frame. */
13571 + hcd->periodic_usecs -= qh->usecs;
13574 + * Update average periodic bandwidth claimed and # periodic
13575 + * reqs for usbfs.
13577 + hcd_to_bus(dwc_otg_hcd_to_hcd(hcd))->bandwidth_allocated -=
13578 + qh->usecs / qh->interval;
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);
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);
13594 + * Removes a QH from either the non-periodic or periodic schedule. Memory is
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)
13601 + if (!spin_is_locked(&hcd->global_lock)) {
13602 + pr_err("%s don't have hcd->global_lock", __func__);
13606 + if (list_empty(&qh->qh_list_entry)) {
13607 + /* QH is not in a schedule. */
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;
13616 + list_del_init(&qh->qh_list_entry);
13618 + deschedule_periodic(hcd, qh);
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.
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.
13638 +void dwc_otg_hcd_qh_deactivate(struct dwc_otg_hcd *hcd, struct dwc_otg_qh *qh,
13639 + int sched_next_periodic_split)
13641 + uint16_t frame_number;
13643 + if (!spin_is_locked(&hcd->global_lock)) {
13644 + pr_err("%s don't have hcd->global_lock", __func__);
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);
13656 + frame_number = dwc_otg_hcd_get_frame_number(dwc_otg_hcd_to_hcd(hcd));
13658 + if (qh->do_split) {
13659 + /* Schedule the next continuing periodic split transfer */
13660 + if (sched_next_periodic_split) {
13662 + qh->sched_frame = frame_number;
13663 + if (dwc_frame_num_le(frame_number,
13664 + dwc_frame_num_inc(qh->start_split_frame,
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
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,
13682 + qh->sched_frame =
13683 + dwc_frame_num_inc(qh->start_split_frame,
13685 + if (dwc_frame_num_le(qh->sched_frame, frame_number))
13686 + qh->sched_frame = frame_number;
13688 + qh->sched_frame |= 0x7;
13689 + qh->start_split_frame = qh->sched_frame;
13692 + qh->sched_frame = dwc_frame_num_inc(qh->sched_frame,
13694 + if (dwc_frame_num_le(qh->sched_frame, frame_number))
13695 + qh->sched_frame = frame_number;
13698 + if (list_empty(&qh->qtd_list)) {
13699 + dwc_otg_hcd_qh_remove(hcd, qh);
13702 + * Remove from periodic_sched_queued and move to
13703 + * appropriate queue.
13705 + if (qh->sched_frame == frame_number) {
13706 + list_move(&qh->qh_list_entry,
13707 + &hcd->periodic_sched_ready);
13709 + list_move(&qh->qh_list_entry,
13710 + &hcd->periodic_sched_inactive);
13716 + * This function allocates and initializes a QTD.
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.
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)
13724 + struct dwc_otg_qtd *qtd;
13726 + qtd = dwc_otg_hcd_qtd_alloc();
13730 + dwc_otg_hcd_qtd_init(qtd, urb);
13735 + * Initializes a QTD structure.
13737 + * @qtd: The QTD to initialize.
13738 + * @urb: The URB to use for initialization.
13740 +void dwc_otg_hcd_qtd_init(struct dwc_otg_qtd *qtd, struct urb *urb)
13742 + memset(qtd, 0, sizeof(struct dwc_otg_qtd));
13744 + if (usb_pipecontrol(urb->pipe)) {
13746 + * The only time the QTD data toggle is used is on the data
13747 + * phase of control transfers. This phase always starts with
13750 + qtd->data_toggle = DWC_OTG_HC_PID_DATA1;
13751 + qtd->control_phase = DWC_OTG_CONTROL_SETUP;
13754 + /* start split */
13755 + qtd->complete_split = 0;
13756 + qtd->isoc_split_pos = DWC_HCSPLIT_XACTPOS_ALL;
13757 + qtd->isoc_split_offset = 0;
13759 + /* Store the qtd ptr in the urb to reference what QTD. */
13760 + urb->hcpriv = qtd;
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.
13770 + * @qtd: The QTD to add
13771 + * @dwc_otg_hcd: The DWC HCD structure
13773 + * Returns 0 if successful, negative error code otherwise.
13775 +int dwc_otg_hcd_qtd_add(struct dwc_otg_qtd *qtd,
13776 + struct dwc_otg_hcd *dwc_otg_hcd)
13778 + struct usb_host_endpoint *ep;
13779 + struct dwc_otg_qh *qh;
13782 + struct urb *urb = qtd->urb;
13785 + * Get the QH which holds the QTD-list to insert to. Create QH if it
13788 + ep = dwc_urb_to_endpoint(urb);
13790 + if (qh == NULL) {
13791 + qh = dwc_otg_hcd_qh_create(dwc_otg_hcd, urb);
13792 + if (qh == NULL) {
13793 + retval = -ENOMEM;
13799 + retval = dwc_otg_hcd_qh_add(dwc_otg_hcd, qh);
13801 + list_add_tail(&qtd->qtd_list_entry, &qh->qtd_list);
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
13811 +++ b/drivers/usb/host/dwc_otg/dwc_otg_octeon.c
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.
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.
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
13839 + * ========================================================================== */
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>
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"
13859 +#include "dwc_otg_hcd.h"
13861 +#define DWC_DRIVER_VERSION "2.40a 10-APR-2006"
13862 +#define DWC_DRIVER_DESC "HS OTG USB Controller driver"
13864 +static const char dwc_driver_name[] = "dwc_otg";
13865 +int dwc_errata_write_count; /* See dwc_otg_plat.h, dwc_write_reg32 */
13867 +/*-------------------------------------------------------------------------*/
13868 +/* Encapsulate the module parameter settings */
13870 +static struct dwc_otg_core_params dwc_otg_module_params = {
13873 + .dma_enable = -1,
13874 + .dma_burst_size = -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 */
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,
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,
13914 + * Global Debug Level Mask.
13916 +uint32_t g_dbg_lvl; /* 0 -> OFF */
13919 + * This function shows the Driver Version.
13921 +static ssize_t version_show(struct device_driver *dev, char *buf)
13923 + return snprintf(buf, sizeof(DWC_DRIVER_VERSION) + 2, "%s\n",
13924 + DWC_DRIVER_VERSION);
13927 +static DRIVER_ATTR(version, S_IRUGO, version_show, NULL);
13930 + * This function is called during module intialization to verify that
13931 + * the module parameters are in a valid state.
13933 +static int check_parameters(struct dwc_otg_core_if *core_if)
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_)))
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_) \
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; \
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");
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)) {
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;
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)) {
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;
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] !=
14018 + if (DWC_OTG_PARAM_TEST
14019 + (dev_perio_tx_fifo_size[i], 4, 768)) {
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;
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. */
14038 +/* This sets the parameter to the default value if it has not been set by the
14040 +#define PARAM_SET_DEFAULT(_param_) \
14042 + int changed = 1; \
14043 + if (dwc_otg_module_params._param_ == -1) { \
14045 + dwc_otg_module_params._param_ = dwc_param_##_param_##_default; \
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_) \
14056 + int changed = PARAM_SET_DEFAULT(_param_); \
14058 + if (!(_is_valid_)) { \
14060 + DWC_ERROR("`%d' invalid for parameter `%s'. Check HW configuration.\n", dwc_otg_module_params._param_, _str_); \
14063 + dwc_otg_module_params._param_ = (_set_valid_); \
14069 + retval += PARAM_CHECK_VALID(otg_cap, "otg_cap",
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)
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))
14085 + case DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE:
14086 + /* always valid */
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))
14096 + DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE : DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE));
14098 + retval += PARAM_CHECK_VALID(dma_enable, "dma_enable",
14099 + ((dwc_otg_module_params.
14101 + && (core_if->hwcfg2.b.
14102 + architecture == 0)) ? 0 : 1,
14105 + retval += PARAM_CHECK_VALID(opt, "opt", 1, 0);
14107 + PARAM_SET_DEFAULT(dma_burst_size);
14109 + retval += PARAM_CHECK_VALID(host_support_fs_ls_low_power,
14110 + "host_support_fs_ls_low_power",
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);
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);
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));
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);
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));
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);
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));
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);
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);
14165 + retval += PARAM_CHECK_VALID(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);
14170 + retval += PARAM_CHECK_VALID(dev_endpoints,
14172 + dwc_otg_module_params.dev_endpoints <= core_if->hwcfg2.b.num_dev_ep,
14173 + core_if->hwcfg2.b.num_dev_ep);
14176 + * Define the following to disable the FS PHY Hardware checking. This is for
14177 + * internal testing only.
14179 + * #define NO_FS_PHY_HW_CHECKS
14182 +#ifdef NO_FS_PHY_HW_CHECKS
14183 + retval += PARAM_CHECK_VALID(phy_type, "phy_type", 1, 0);
14185 + retval += PARAM_CHECK_VALID(phy_type, "phy_type",
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)))
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)))
14192 + else if ((dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_FS) && (core_if->hwcfg2.b.fs_phy_type == 1))
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;
14203 + set = DWC_PHY_TYPE_PARAM_ULPI;
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);
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);
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);
14227 +#ifdef NO_FS_PHY_HW_CHECKS
14228 + retval += PARAM_CHECK_VALID(i2c_enable, "i2c_enable", 1, 0);
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);
14235 + for (i = 0; i < 15; i++) {
14240 + if (dwc_otg_module_params.dev_perio_tx_fifo_size[i] == -1) {
14242 + dwc_otg_module_params.dev_perio_tx_fifo_size[i] =
14243 + dwc_param_dev_perio_tx_fifo_size_default;
14246 + (dwc_otg_module_params.dev_perio_tx_fifo_size[i] <=
14247 + (dwc_read_reg32(&core_if->core_global_regs->dptxfsiz[i])))) {
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);
14256 + dwc_otg_module_params.dev_perio_tx_fifo_size[i] =
14257 + dwc_read_reg32(&core_if->core_global_regs->
14267 + * This function is the top level interrupt handler for the Common
14268 + * (Device and host modes) interrupts.
14270 +static irqreturn_t dwc_otg_common_irq(int _irq, void *_dev)
14272 + struct dwc_otg_device *otg_dev = _dev;
14273 + int32_t retval = IRQ_NONE;
14274 + unsigned long flags;
14276 + spin_lock_irqsave(&otg_dev->hcd->global_lock, flags);
14278 + retval = dwc_otg_handle_common_intr(otg_dev->core_if);
14280 + spin_unlock_irqrestore(&otg_dev->hcd->global_lock, flags);
14282 + return IRQ_RETVAL(retval);
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.
14294 +static int dwc_otg_driver_remove(struct platform_device *pdev)
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);
14300 + if (otg_dev == NULL)
14301 + /* Memory allocation for the dwc_otg_device failed. */
14307 + if (otg_dev->common_irq_installed)
14308 + free_irq(platform_get_irq(to_platform_device(dev), 0), otg_dev);
14310 +#ifndef DWC_DEVICE_ONLY
14311 + if (otg_dev->hcd != NULL)
14312 + dwc_otg_hcd_remove(dev);
14315 +#ifndef DWC_HOST_ONLY
14316 + if (otg_dev->pcd != NULL)
14317 + dwc_otg_pcd_remove(dev);
14319 + if (otg_dev->core_if != NULL)
14320 + dwc_otg_cil_remove(otg_dev->core_if);
14323 + * Remove the device attributes
14325 + dwc_otg_attr_remove(dev);
14328 + * Clear the platform_data pointer.
14330 + dev->platform_data = 0;
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.
14343 + * @dev: device definition
14345 +static __devinit int dwc_otg_driver_probe(struct platform_device *pdev)
14347 + struct resource *res_base;
14348 + struct device *dev = &pdev->dev;
14349 + struct dwc_otg_device *dwc_otg_device;
14351 + unsigned long flags;
14355 + dev_dbg(dev, "dwc_otg_driver_probe(%p)\n", dev);
14357 + dwc_otg_device = devm_kzalloc(&pdev->dev,
14358 + sizeof(struct dwc_otg_device),
14360 + if (!dwc_otg_device) {
14361 + dev_err(dev, "kmalloc of dwc_otg_device failed\n");
14364 + dwc_otg_device->reg_offset = 0xFFFFFFFF;
14367 + * Map the DWC_otg Core memory into virtual address space.
14369 + res_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
14373 + dwc_otg_device->base =
14374 + devm_ioremap_nocache(&pdev->dev,
14376 + res_base->end - res_base->start);
14378 + if (!dwc_otg_device->base)
14381 + dev_dbg(dev, "base=%p\n", dwc_otg_device->base);
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".
14389 + dwc_read_reg32((uint32_t *) ((uint8_t *) dwc_otg_device->base +
14391 + if ((snpsid & 0xFFFFF000) != 0x4F542000) {
14392 + dev_err(dev, "Bad value for SNPSID: 0x%08x\n", snpsid);
14397 + * Initialize driver data to point to the global DWC_otg
14398 + * Device structure.
14400 + dev->platform_data = dwc_otg_device;
14401 + dev_dbg(dev, "dwc_otg_device=0x%p\n", dwc_otg_device);
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");
14409 + dwc_otg_device->core_if->usb_num = to_platform_device(dev)->id;
14412 + * Validate parameter values.
14414 + if (check_parameters(dwc_otg_device->core_if) != 0)
14418 + * Create Device Attributes in sysfs
14420 + dwc_otg_attr_create(dev);
14423 + * Disable the global interrupt until all the interrupt
14424 + * handlers are installed.
14426 + dwc_otg_disable_global_interrupts(dwc_otg_device->core_if);
14428 + * Install the interrupt handler for the common interrupts before
14429 + * enabling common interrupts in core_init below.
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);
14439 + dwc_otg_device->common_irq_installed = 1;
14443 + * Initialize the DWC_otg core.
14445 + dwc_otg_core_init(dwc_otg_device->core_if);
14447 +#ifndef DWC_HOST_ONLY
14449 + * Initialize the PCD
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;
14458 +#ifndef DWC_DEVICE_ONLY
14460 + * Initialize the HCD
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;
14471 + * Enable the global interrupt after all the interrupt
14472 + * handlers are installed.
14474 + local_irq_save(flags);
14475 + dwc_otg_enable_global_interrupts(dwc_otg_device->core_if);
14476 + local_irq_restore(flags);
14481 + devm_kfree(&pdev->dev, dwc_otg_device);
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
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.
14496 +static struct platform_driver dwc_otg_driver = {
14497 + .probe = dwc_otg_driver_probe,
14498 + .remove = dwc_otg_driver_remove,
14500 + .name = dwc_driver_name,
14501 + .owner = THIS_MODULE},
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
14514 +static int __init dwc_otg_driver_init(void)
14518 + pr_info("%s: version %s\n", dwc_driver_name, DWC_DRIVER_VERSION);
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;
14525 + retval = platform_driver_register(&dwc_otg_driver);
14527 + if (retval < 0) {
14528 + pr_err("%s retval=%d\n", __func__, retval);
14531 + if (driver_create_file(&dwc_otg_driver.driver, &driver_attr_version))
14532 + pr_warning("DWC_OTG: Failed to create driver version file\n");
14536 +module_init(dwc_otg_driver_init);
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
14544 +static void __exit dwc_otg_driver_cleanup(void)
14546 + printk(KERN_DEBUG "dwc_otg_driver_cleanup()\n");
14548 + driver_remove_file(&dwc_otg_driver.driver, &driver_attr_version);
14550 + platform_driver_unregister(&dwc_otg_driver);
14552 + printk(KERN_INFO "%s module removed\n", dwc_driver_name);
14554 +module_exit(dwc_otg_driver_cleanup);
14556 +MODULE_DESCRIPTION(DWC_DRIVER_DESC);
14557 +MODULE_AUTHOR("Synopsys Inc.");
14558 +MODULE_LICENSE("GPL");
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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, "");
14705 +/** @page "Module Parameters"
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
14712 + * Example: <code>modprobe dwc_otg speed=1 otg_cap=1</code>
14716 + <tr><td>Parameter Name</td><td>Meaning</td></tr>
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
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
14733 + - 1: DMA (default, if available)
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)
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
14747 + - 0: High Speed (default)
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
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)
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)
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)
14781 + Note: The total FIFO memory depth in the FPGA configuration is 8192.
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)
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)
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)
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)
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)
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)
14827 + <td>max_transfer_size</td>
14828 + <td>The maximum transfer size supported in bytes.
14829 + - Values: 2047 to 65,535 (default 65,535)
14833 + <td>max_packet_count</td>
14834 + <td>The maximum number of packets in a transfer.
14835 + - Values: 15 to 511 (default 511)
14839 + <td>host_channels</td>
14840 + <td>The number of host channel registers to use.
14841 + - Values: 1 to 16 (default 12)
14843 + Note: The FPGA configuration supports a maximum of 12 host channels.
14847 + <td>dev_endpoints</td>
14848 + <td>The number of endpoints in addition to EP0 available for device mode
14850 + - Values: 1 to 15 (default 6 IN and OUT)
14852 + Note: The FPGA configuration supports a maximum of 6 IN and OUT endpoints in
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.
14861 + - 1: UTMI+ (default, if available)
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)
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
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)
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
14895 +++ b/drivers/usb/host/dwc_otg/dwc_otg_plat.h
14897 +/* ==========================================================================
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.
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.
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
14924 + * ========================================================================== */
14926 +#if !defined(__DWC_OTG_PLAT_H__)
14927 +#define __DWC_OTG_PLAT_H__
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>
14936 +#include <asm/octeon/octeon.h>
14937 +#include <asm/octeon/cvmx-usbnx-defs.h>
14939 +#define SZ_256K 0x00040000
14940 +#ifndef CONFIG_64BIT
14941 +#define OCTEON_USB_BASE_ADDRESS 0x80016F0010000000ull
14947 + * This file contains the Platform Specific constants, interfaces
14948 + * (functions and macros) for Linux.
14953 + * Reads the content of a register.
14955 + * @_reg: address of register to read.
14956 + * Returns contents of the register.
14960 + * <code>uint32_t dev_ctl = dwc_read_reg32(&dev_regs->dctl);</code>
14962 +static inline uint32_t dwc_read_reg32(uint32_t *_reg)
14965 + /* USB device registers on Octeon are 32bit address swapped */
14966 +#ifdef CONFIG_64BIT
14967 + uint64_t address = (unsigned long)_reg ^ 4;
14969 + uint64_t address = OCTEON_USB_BASE_ADDRESS | ((unsigned long)_reg ^ 4);
14971 + result = cvmx_read64_uint32(address);
14976 + * Writes a register with a 32 bit value.
14978 + * @_reg: address of register to read.
14979 + * @_value: to write to _reg.
14982 + * <code>dwc_write_reg32(&dev_regs->dctl, 0); </code>
14984 +static inline void dwc_write_reg32(uint32_t *_reg,
14985 + const uint32_t _value)
14987 + /* USB device registers on Octeon are 32bit address swapped */
14988 +#ifdef CONFIG_64BIT
14989 + uint64_t address = (unsigned long)_reg ^ 4;
14991 + uint64_t address = OCTEON_USB_BASE_ADDRESS | ((unsigned long)_reg ^ 4);
14994 + cvmx_write64_uint32(address, _value);
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
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;
15011 + * This function modifies bit values in a register. Using the
15012 + * algorithm: (reg_contents & ~clear_mask) | set_mask.
15014 + * @_reg: address of register to read.
15015 + * @_clear_mask: bit mask to be cleared.
15016 + * @_set_mask: bit mask to be set.
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>
15023 +static inline void dwc_modify_reg32(uint32_t *_reg,
15024 + const uint32_t _clear_mask,
15025 + const uint32_t _set_mask)
15027 + uint32_t value = dwc_read_reg32(_reg);
15028 + value &= ~_clear_mask;
15029 + value |= _set_mask;
15030 + dwc_write_reg32(_reg, value);
15034 + * Debugging support vanishes in non-debug builds.
15038 + * The Debug Level bit-mask variable.
15040 +extern uint32_t g_dbg_lvl;
15042 + * Set the Debug Level variable.
15044 +static inline uint32_t SET_DEBUG_LEVEL(const uint32_t _new)
15046 + uint32_t old = g_dbg_lvl;
15047 + g_dbg_lvl = _new;
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
15055 +#define DBG_CILV (0x20)
15056 +/** When debug level has the DBG_PCD bit set, display PCD (Device) debug
15058 +#define DBG_PCD (0x4)
15059 +/** When debug level has the DBG_PCDV set, display PCD (Device) Verbose debug
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
15066 +#define DBG_HCDV (0x80)
15067 +/** When debug level has the DBG_HCD_URB bit set, display enqueued URBs in host
15069 +#define DBG_HCD_URB (0x800)
15071 +/** When debug level has any bit set, display debug messages */
15072 +#define DBG_ANY (0xFF)
15074 +/** All debug messages off */
15077 +/** Prefix string for DWC_DEBUG print macros. */
15078 +#define USB_DWC "DWC_otg: "
15081 + * Print a debug message when the Global debug level variable contains
15082 + * the bit defined in <code>lvl</code>.
15084 + * @lvl: - Debug level, use one of the DBG_ constants above.
15085 + * @x: - like printf
15089 + * DWC_DEBUGPL( DBG_ANY, "%s(%p)\n", __func__, _reg_base_addr);
15092 + * results in:<br>
15094 + * usb-DWC_otg: dwc_otg_cil_init(ca867000)
15099 +# define DWC_DEBUGPL(lvl, x...) \
15101 + if ((lvl)&g_dbg_lvl) \
15102 + printk(KERN_DEBUG USB_DWC x); \
15104 +# define DWC_DEBUGP(x...) DWC_DEBUGPL(DBG_ANY, x)
15106 +# define CHK_DEBUG_LEVEL(level) ((level) & g_dbg_lvl)
15110 +# define DWC_DEBUGPL(lvl, x...) do { } while (0)
15111 +# define DWC_DEBUGP(x...)
15113 +# define CHK_DEBUG_LEVEL(level) (0)
15117 + * Print an Error message.
15119 +#define DWC_ERROR(x...) printk(KERN_ERR USB_DWC x)
15121 + * Print a Warning message.
15123 +#define DWC_WARN(x...) printk(KERN_WARNING USB_DWC x)
15125 + * Print a notice (normal but significant message).
15127 +#define DWC_NOTICE(x...) printk(KERN_NOTICE USB_DWC x)
15129 + * Basic message printing.
15131 +#define DWC_PRINT(x...) printk(KERN_INFO USB_DWC x)
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
15137 +++ b/drivers/usb/host/dwc_otg/dwc_otg_regs.h
15139 +/* ==========================================================================
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.
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.
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
15166 + * ========================================================================== */
15168 +#ifndef __DWC_OTG_REGS_H__
15169 +#define __DWC_OTG_REGS_H__
15173 + * This file contains the data structures for accessing the DWC_otg
15174 + * core registers.
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
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.
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.
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
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;
15234 + *Non Periodic Transmit FIFO/Queue Status Register (Read
15235 + * Only). Offset: 02Ch
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 */
15244 + /* User ID Register. Offset: 03Ch */
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
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
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;
15273 + * Device Periodic Transmit FIFO#n Register.
15274 + * Offset: 104h + (FIFO_Number-1)*04h,
15275 + * 1 <= FIFO Number <= 15 (1<=n<=15).
15277 + uint32_t dptxfsiz[15];
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.
15285 +union gotgctl_data {
15286 + /* raw register data */
15288 + /* register bits */
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;
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;
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.
15329 +union gotgint_data {
15330 + /* raw register data */
15332 + /* register bits */
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;
15347 + /* Current Mode */
15348 + unsigned reserved0_1:2;
15350 + /* Session End Detected */
15351 + unsigned sesenddet:1;
15353 + unsigned reserved3_7:5;
15355 + /* Session Request Success Status Change */
15356 + unsigned sesreqsucstschng:1;
15357 + /* Host Negotiation Success Status Change */
15358 + unsigned hstnegsucstschng:1;
15360 + unsigned reserver10_16:7;
15362 + /* Host Negotiation Detected */
15363 + unsigned hstnegdet:1;
15364 + /* A-Device Timeout Change */
15365 + unsigned adevtoutchng:1;
15366 + /* Debounce Done */
15367 + unsigned debdone:1;
15369 + unsigned reserved31_20:12;
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.
15379 +union gahbcfg_data {
15380 + /* raw register data */
15382 + /* register bits */
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
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;
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;
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.
15419 +union gusbcfg_data {
15420 + /* raw register data */
15422 + /* register bits */
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;
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;
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.
15473 +union grstctl_data {
15474 + /* raw register data */
15476 + /* register bits */
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;
15492 + * Core Soft Reset (CSftRst) (Device and Host)
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.
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.
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
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.
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).
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
15527 + unsigned csftrst:1;
15529 + * Hclk Soft Reset
15531 + * The application uses this bit to reset the control logic in
15532 + * the AHB clock domain. Only AHB clock domain pipelines are
15535 + unsigned hsftrst:1;
15537 + * Host Frame Counter Reset (Host Only)<br>
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
15545 + unsigned hstfrm:1;
15547 + * In Token Sequence Learning Queue Flush
15548 + * (INTknQFlsh) (Device Only)
15550 + unsigned intknqflsh:1;
15552 + * RxFIFO Flush (RxFFlsh) (Device and Host)
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)
15566 + unsigned rxfflsh:1;
15568 + * TxFIFO Flush (TxFFlsh) (Device and Host).
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)
15582 + unsigned txfflsh:1;
15585 + * TxFIFO Number (TxFNum) (Device and Host).
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
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.
15596 + * - 0xF:Periodic TxFIFO #15 Flush in device mode
15597 + * - 0x10: Flush all the Transmit NonPeriodic and
15598 + * Transmit Periodic FIFOs in the core
15600 + unsigned txfnum:5;
15602 + unsigned reserved11_29:19;
15604 + * DMA Request Signal. Indicated DMA request is in
15605 + * probress. Used for debug purpose.
15607 + unsigned dmareq:1;
15609 + * AHB Master Idle. Indicates the AHB Master State
15610 + * Machine is in IDLE condition.
15612 + unsigned ahbidle:1;
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.
15622 +union gintmsk_data {
15623 + /* raw register data */
15625 + /* register bits */
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;
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;
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.
15700 +union gintsts_data {
15701 + /* raw register data */
15703 +#define DWC_SOF_INTR_MASK 0x0008
15705 + /* register bits */
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;
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;
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.
15781 +union device_grxsts_data {
15782 + /* raw register data */
15784 + /* register bits */
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 */
15792 +#ifdef __BIG_ENDIAN_BITFIELD
15793 + unsigned reserved:7;
15795 + unsigned pktsts:4;
15797 + unsigned bcnt:11;
15798 + unsigned epnum:4;
15800 + unsigned epnum:4;
15801 + unsigned bcnt:11;
15803 + unsigned pktsts:4;
15805 + unsigned reserved:7;
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.
15815 +union host_grxsts_data {
15816 + /* raw register data */
15818 + /* register bits */
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
15825 +#ifdef __BIG_ENDIAN_BITFIELD
15826 + unsigned reserved:11;
15827 + unsigned pktsts:4;
15829 + unsigned bcnt:11;
15830 + unsigned chnum:4;
15832 + unsigned chnum:4;
15833 + unsigned bcnt:11;
15835 + unsigned pktsts:4;
15836 + unsigned reserved:11;
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.
15846 +union fifosize_data {
15847 + /* raw register data */
15849 + /* register bits */
15851 +#ifdef __BIG_ENDIAN_BITFIELD
15852 + unsigned depth:16;
15853 + unsigned startaddr:16;
15855 + unsigned startaddr:16;
15856 + unsigned depth:16;
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
15867 +union gnptxsts_data {
15868 + /* raw register data */
15870 + /* register bits */
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;
15880 + unsigned nptxfspcavail:16;
15881 + unsigned nptxqspcavail:8;
15883 + * Top of the Non-Periodic Transmit Request Queue
15884 + * - bit 24 - Terminate (Last entry for the selected
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
15893 + unsigned nptxqtop_terminate:1;
15894 + unsigned nptxqtop_token:2;
15895 + unsigned nptxqtop_chnep:4;
15896 + unsigned reserved:1;
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.
15906 +union gi2cctl_data {
15907 + /* raw register data */
15909 + /* register bits */
15911 +#ifdef __BIG_ENDIAN_BITFIELD
15912 + unsigned bsydne:1;
15914 + unsigned reserved:2;
15915 + unsigned i2cdevaddr:2;
15916 + unsigned i2csuspctl:1;
15918 + unsigned i2cen:1;
15920 + unsigned regaddr:8;
15921 + unsigned rwdata:8;
15923 + unsigned rwdata:8;
15924 + unsigned regaddr:8;
15926 + unsigned i2cen:1;
15928 + unsigned i2csuspctl:1;
15929 + unsigned i2cdevaddr:2;
15930 + unsigned reserved:2;
15932 + unsigned bsydne:1;
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.
15942 +union hwcfg1_data {
15943 + /* raw register data */
15945 + /* register bits */
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;
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;
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.
15990 +union hwcfg2_data {
15991 + /* raw register data */
15993 + /* register bits */
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
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;
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;
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.
16046 +union hwcfg3_data {
16047 + /* raw register data */
16049 + /* register bits */
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;
16060 + unsigned otg_func:1;
16061 + unsigned packet_size_cntr_width:3;
16062 + unsigned xfer_size_cntr_width:4;
16064 + unsigned xfer_size_cntr_width:4;
16065 + unsigned packet_size_cntr_width:3;
16066 + unsigned otg_func: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;
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.
16083 +union hwcfg4_data {
16084 + /* raw register data */
16086 + /* register bits */
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;
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;
16118 + * Device Global Registers. Offsets 800h-BFFh
16120 + * The following structures define the size and relative field offsets
16121 + * for the Device Mode Registers.
16123 + * These registers are visible only in Device mode and must not be
16124 + * accessed in Host mode, as the results are unknown.
16126 +struct dwc_otg_dev_global_regs {
16127 + /* Device Configuration Register. Offset 800h */
16129 + /* Device Control Register. Offset: 804h */
16131 + /* Device Status Register (Read Only). Offset: 808h */
16133 + /* Reserved. Offset: 80Ch */
16136 + * Device IN Endpoint Common Interrupt Mask Register. Offset: 810h
16138 + uint32_t diepmsk;
16140 + * Device OUT Endpoint Common Interrupt Mask
16141 + * Register. Offset: 814h
16143 + uint32_t doepmsk;
16145 + * Device All Endpoints Interrupt Register. Offset: 818h
16149 + * Device All Endpoints Interrupt Mask Register. Offset:
16152 + uint32_t daintmsk;
16154 + * Device IN Token Queue Read Register-1 (Read Only).
16157 + uint32_t dtknqr1;
16159 + * Device IN Token Queue Read Register-2 (Read Only).
16162 + uint32_t dtknqr2;
16164 + * Device VBUS discharge Register. Offset: 828h
16166 + uint32_t dvbusdis;
16168 + * Device VBUS Pulse Register. Offset: 82Ch
16170 + uint32_t dvbuspulse;
16172 + * Device IN Token Queue Read Register-3 (Read Only).
16175 + uint32_t dtknqr3;
16177 + * Device IN Token Queue Read Register-4 (Read Only).
16180 + uint32_t dtknqr4;
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.
16190 + /* raw register data */
16192 + /* register bits */
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
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;
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;
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.
16234 + /* raw register data */
16236 + /* register bits */
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;
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;
16270 + unsigned reserved:21;
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.
16281 + /* raw register data */
16283 + /* register bits */
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
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;
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;
16314 + * This union represents the bit fields in the Device IN EP Interrupt
16315 + * Register and the Device IN EP Common Mask Register.
16317 + * It also represents the bit fields in the Device IN EP Common
16318 + * Interrupt Mask Register.
16320 + * - Read the register into the d32 member then set/clear the
16321 + * bits using the bit elements.
16323 +union diepint_data {
16324 + /* raw register data */
16326 + /* register bits */
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;
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;
16359 + * This union represents the bit fields in the Device OUT EP Interrupt
16360 + * Registerand Device OUT EP Common Interrupt Mask Register.
16362 + * It also represents the bit fields in the Device OUT EP Common
16363 + * Interrupt Mask Register.
16365 + * - Read the register into the d32 member then set/clear the
16366 + * bits using the bit elements.
16368 +union doepint_data {
16369 + /* raw register data */
16371 + /* register bits */
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;
16381 + /* Transfer complete */
16382 + unsigned xfercompl:1;
16383 + /* Endpoint disable */
16384 + unsigned epdisabled:1;
16386 + unsigned ahberr:1;
16387 + /* Setup Phase Done (contorl EPs) */
16388 + unsigned setup:1;
16389 + unsigned reserved04_31:28;
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.
16400 +union daint_data {
16401 + /* raw register data */
16403 + /* register bits */
16405 +#ifdef __BIG_ENDIAN_BITFIELD
16410 + /* IN Endpoint bits */
16412 + /* OUT Endpoint bits */
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;
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;
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
16496 +union dtknq1_data {
16497 + /* raw register data */
16499 + /* register bits */
16501 +#ifdef __BIG_ENDIAN_BITFIELD
16502 + unsigned epnums0_5:24;
16503 + unsigned wrap_bit:1;
16504 + unsigned reserved05_06:2;
16505 + unsigned intknwptr:5;
16508 + /* In Token Queue Write Pointer */
16509 + unsigned intknwptr:5;
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;
16521 + * Device Logical IN Endpoint-Specific Registers. Offsets
16524 + * There will be one set of endpoint registers per logical endpoint
16527 + * These registers are visible only in Device mode and must not be
16528 + * accessed in Host mode, as the results are unknown.
16530 +struct dwc_otg_dev_in_ep_regs {
16532 + * Device IN Endpoint Control Register. Offset:900h +
16533 + * (ep_num * 20h) + 00h
16535 + uint32_t diepctl;
16536 + /* Reserved. Offset:900h + (ep_num * 20h) + 04h */
16537 + uint32_t reserved04;
16539 + * Device IN Endpoint Interrupt Register. Offset:900h +
16540 + * (ep_num * 20h) + 08h
16542 + uint32_t diepint;
16543 + /* Reserved. Offset:900h + (ep_num * 20h) + 0Ch */
16544 + uint32_t reserved0C;
16546 + * Device IN Endpoint Transfer Size
16547 + * Register. Offset:900h + (ep_num * 20h) + 10h
16549 + uint32_t dieptsiz;
16551 + * Device IN Endpoint DMA Address Register. Offset:900h +
16552 + * (ep_num * 20h) + 14h
16554 + uint32_t diepdma;
16556 + * Reserved. Offset:900h + (ep_num * 20h) + 18h - 900h +
16557 + * (ep_num * 20h) + 1Ch
16559 + uint32_t reserved18[2];
16563 + * Device Logical OUT Endpoint-Specific Registers. Offsets:
16566 + * There will be one set of endpoint registers per logical endpoint
16569 + * These registers are visible only in Device mode and must not be
16570 + * accessed in Host mode, as the results are unknown.
16572 +struct dwc_otg_dev_out_ep_regs {
16574 + * Device OUT Endpoint Control Register. Offset:B00h +
16575 + * (ep_num * 20h) + 00h
16577 + uint32_t doepctl;
16579 + * Device OUT Endpoint Frame number Register. Offset:
16580 + * B00h + (ep_num * 20h) + 04h
16584 + * Device OUT Endpoint Interrupt Register. Offset:B00h +
16585 + * (ep_num * 20h) + 08h
16587 + uint32_t doepint;
16589 + * Reserved. Offset:B00h + (ep_num * 20h) + 0Ch */
16590 + uint32_t reserved0C;
16592 + * Device OUT Endpoint Transfer Size Register. Offset:
16593 + * B00h + (ep_num * 20h) + 10h
16595 + uint32_t doeptsiz;
16597 + * Device OUT Endpoint DMA Address Register. Offset:B00h
16598 + * + (ep_num * 20h) + 14h
16600 + uint32_t doepdma;
16602 + * Reserved. Offset:B00h + (ep_num * 20h) + 18h - B00h +
16603 + * (ep_num * 20h) + 1Ch
16605 + uint32_t unused[2];
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.
16613 +union depctl_data {
16614 + /* raw register data */
16616 + /* register bits */
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
16623 +#ifdef __BIG_ENDIAN_BITFIELD
16625 + unsigned epena:1;
16626 + unsigned epdis:1;
16627 + unsigned setd1pid:1;
16628 + unsigned setd0pid:1;
16631 + unsigned txfnum:4;
16632 + unsigned stall:1;
16634 + unsigned eptype:2;
16635 + unsigned naksts:1;
16637 + unsigned usbactep:1;
16638 + unsigned nextep:4;
16642 + * Maximum Packet Size
16644 + * IN/OUT EP0 - 2 bits
16645 + * 2'b00: 64 Bytes
16654 + * OUT EPn/OUT EP0 - reserved
16656 + unsigned nextep:4;
16658 + /* USB Active Endpoint */
16659 + unsigned usbactep:1;
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
16672 + * The encoding for this field is
16679 + unsigned naksts:1;
16684 + * 2'b01: Isochronous
16686 + * 2'b11: Interrupt
16688 + unsigned eptype:2;
16692 + * OUT EPn/OUT EP0
16693 + * IN EPn/IN EP0 - reserved
16697 + /* Stall Handshake */
16698 + unsigned stall:1;
16703 + * OUT EPn/OUT EP0 - reserved
16705 + unsigned txfnum:4;
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)
16720 + unsigned setd0pid:1;
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.
16729 + unsigned setd1pid:1;
16731 + /* Endpoint Disable */
16732 + unsigned epdis:1;
16733 + /* Endpoint Enable */
16734 + unsigned epena:1;
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.
16744 +union deptsiz_data {
16745 + /* raw register data */
16747 + /* register bits */
16749 +#ifdef __BIG_ENDIAN_BITFIELD
16750 + unsigned reserved:1;
16752 + unsigned pktcnt:10;
16753 + unsigned xfersize:19;
16756 + /* Transfer size */
16757 + unsigned xfersize:19;
16758 + /* Packet Count */
16759 + unsigned pktcnt:10;
16760 + /* Multi Count - Periodic IN endpoints */
16762 + unsigned reserved:1;
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.
16772 +union deptsiz0_data {
16773 + /* raw register data */
16775 + /* register bits */
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;
16786 + /* Transfer size */
16787 + unsigned xfersize:7;
16789 + unsigned reserved7_18:12;
16790 + /* Packet Count */
16791 + unsigned pktcnt:1;
16793 + unsigned reserved20_28:9;
16794 + /* Setup Packet Count (DOEPTSIZ0 Only) */
16795 + unsigned supcnt:2;
16796 + unsigned reserved31:1;
16801 +/** Maximum number of Periodic FIFOs */
16802 +#define MAX_PERIO_FIFOS 15
16804 +/** Maximum number of Endpoints/HostChannels */
16805 +#define MAX_EPS_CHANNELS 16
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.
16812 +struct dwc_otg_dev_if {
16814 + * Pointer to device Global registers.
16815 + * Device Global Registers starting at offset 800h
16817 + struct dwc_otg_dev_global_regs *dev_global_regs;
16818 +#define DWC_DEV_GLOBAL_REG_OFFSET 0x800
16821 + * Device Logical IN Endpoint-Specific Registers 900h-AFCh
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
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
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 */
16836 + /* Size of periodic FIFOs (Bytes) */
16837 + uint16_t perio_tx_fifo_size[MAX_PERIO_FIFOS];
16842 +/* Host Mode Register Structures */
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.
16849 +struct dwc_otg_host_global_regs {
16850 + /* Host Configuration Register. Offset: 400h */
16852 + /* Host Frame Interval Register. Offset: 404h */
16854 + /* Host Frame Number / Frame Remaining Register. Offset: 408h */
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 */
16862 + /* Host All Channels Interrupt Mask Register. Offset: 418h */
16863 + uint32_t haintmsk;
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.
16872 + /** raw register data */
16875 + /** register bits */
16877 +#define DWC_HCFG_6_MHZ 2
16878 +#define DWC_HCFG_48_MHZ 1
16879 +#define DWC_HCFG_30_60_MHZ 0
16881 +#ifdef __BIG_ENDIAN_BITFIELD
16882 + unsigned reserved:29;
16883 + unsigned fslssupp:1;
16884 + unsigned fslspclksel:2;
16887 + /* FS/LS Phy Clock Select */
16888 + unsigned fslspclksel:2;
16889 + /* FS/LS Only Support */
16890 + unsigned fslssupp:1;
16891 + unsigned reserved:29;
16897 + * This union represents the bit fields in the Host Frame Remaing/Number
16901 + /* raw register data */
16904 + /* register bits */
16906 +#ifdef __BIG_ENDIAN_BITFIELD
16907 + unsigned reserved:16;
16908 + unsigned frint:16;
16910 + unsigned frint:16;
16911 + unsigned reserved:16;
16917 + * This union represents the bit fields in the Host Frame Remaing/Number
16920 +union hfnum_data {
16921 + /* raw register data */
16924 + /* register bits */
16926 +#define DWC_HFNUM_MAX_FRNUM 0x3FFF
16928 +#ifdef __BIG_ENDIAN_BITFIELD
16929 + unsigned frrem:16;
16930 + unsigned frnum:16;
16932 + unsigned frnum:16;
16933 + unsigned frrem:16;
16938 +union hptxsts_data {
16939 + /* raw register data */
16942 + /* register bits */
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;
16952 + unsigned ptxfspcavail:16;
16953 + unsigned ptxqspcavail:8;
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
16960 + * - 2'b10 - Disable
16961 + * - bits 30:27 - Channel Number
16962 + * - bit 31 - Odd/even microframe
16964 + unsigned ptxqtop_terminate:1;
16965 + unsigned ptxqtop_token:2;
16966 + unsigned ptxqtop_chnum:4;
16967 + unsigned ptxqtop_odd:1;
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.
16978 +union hprt0_data {
16979 + /** raw register data */
16981 + /** register bits */
16983 +#define DWC_HPRT0_PRTSPD_LOW_SPEED 2
16984 +#define DWC_HPRT0_PRTSPD_FULL_SPEED 1
16985 +#define DWC_HPRT0_PRTSPD_HIGH_SPEED 0
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;
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;
17024 + * This union represents the bit fields in the Host All Interrupt
17027 +union haint_data {
17028 + /** raw register data */
17030 + /** register bits */
17032 +#ifdef __BIG_ENDIAN_BITFIELD
17033 + unsigned reserved:16;
17067 + unsigned reserved:16;
17071 +#ifdef __BIG_ENDIAN_BITFIELD
17072 + unsigned reserved:16;
17073 + unsigned chint:16;
17075 + unsigned chint:16;
17076 + unsigned reserved:16;
17082 + * This union represents the bit fields in the Host All Interrupt
17085 +union haintmsk_data {
17086 + /** raw register data */
17088 + /** register bits */
17090 +#ifdef __BIG_ENDIAN_BITFIELD
17091 + unsigned reserved:16;
17125 + unsigned reserved:16;
17129 +#ifdef __BIG_ENDIAN_BITFIELD
17130 + unsigned reserved:16;
17131 + unsigned chint:16;
17133 + unsigned chint:16;
17134 + unsigned reserved:16;
17140 + * Host Channel Specific Registers. 500h-5FCh
17142 +struct dwc_otg_hc_regs {
17144 + * Host Channel 0 Characteristic Register.
17145 + * Offset: 500h + (chan_num * 20h) + 00h
17149 + * Host Channel 0 Split Control Register.
17150 + * Offset: 500h + (chan_num * 20h) + 04h
17154 + * Host Channel 0 Interrupt Register.
17155 + * Offset: 500h + (chan_num * 20h) + 08h
17159 + * Host Channel 0 Interrupt Mask Register.
17160 + * Offset: 500h + (chan_num * 20h) + 0Ch
17162 + uint32_t hcintmsk;
17164 + * Host Channel 0 Transfer Size Register.
17165 + * Offset: 500h + (chan_num * 20h) + 10h
17169 + * Host Channel 0 DMA Address Register.
17170 + * Offset: 500h + (chan_num * 20h) + 14h
17175 + * Offset: 500h + (chan_num * 20h) + 18h -
17176 + * 500h + (chan_num * 20h) + 1Ch
17178 + uint32_t reserved[2];
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.
17187 +union hcchar_data {
17188 + /** raw register data */
17191 + /** register bits */
17193 +#ifdef __BIG_ENDIAN_BITFIELD
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;
17207 + /* Maximum packet size in bytes */
17210 + /* Endpoint number */
17211 + unsigned epnum:4;
17213 + /* 0: OUT, 1: IN */
17214 + unsigned epdir:1;
17216 + unsigned reserved:1;
17218 + /* 0: Full/high speed device, 1: Low speed device */
17219 + unsigned lspddev:1;
17221 + /* 0: Control, 1: Isoc, 2: Bulk, 3: Intr */
17222 + unsigned eptype:2;
17224 + /* Packets per frame for periodic transfers. 0 is reserved. */
17225 + unsigned multicnt:2;
17227 + /* Device address */
17228 + unsigned devaddr:7;
17231 + * Frame to transmit periodic transaction.
17232 + * 0: even, 1: odd
17234 + unsigned oddfrm:1;
17236 + /* Channel disable */
17237 + unsigned chdis:1;
17239 + /* Channel enable */
17245 +union hcsplt_data {
17246 + /* raw register data */
17249 + /* register bits */
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
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;
17265 + /* Port Address */
17266 + unsigned prtaddr:7;
17268 + /* Hub Address */
17269 + unsigned hubaddr:7;
17271 + /* Transaction Position */
17272 + unsigned xactpos:2;
17274 + /* Do Complete Split */
17275 + unsigned compsplt:1;
17278 + unsigned reserved:14;
17280 + /* Split Enble */
17281 + unsigned spltena:1;
17287 + * This union represents the bit fields in the Host All Interrupt
17290 +union hcint_data {
17291 + /* raw register data */
17293 + /* register bits */
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;
17304 + unsigned stall:1;
17305 + unsigned ahberr:1;
17306 + unsigned chhltd:1;
17307 + unsigned xfercomp:1;
17310 + /* Transfer Complete */
17311 + unsigned xfercomp:1;
17312 + /* Channel Halted */
17313 + unsigned chhltd:1;
17315 + unsigned ahberr:1;
17316 + /* STALL Response Received */
17317 + unsigned stall:1;
17318 + /* NAK Response Received */
17320 + /* ACK Response Received */
17322 + /* NYET Response Received */
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;
17333 + unsigned reserved:21;
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.
17344 +union hctsiz_data {
17345 + /* raw register data */
17348 + /* register bits */
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
17356 +#ifdef __BIG_ENDIAN_BITFIELD
17357 + unsigned dopng:1;
17359 + unsigned pktcnt:10;
17360 + unsigned xfersize:19;
17363 + /* Total transfer size in bytes */
17364 + unsigned xfersize:19;
17366 + /* Data packets to transfer */
17367 + unsigned pktcnt:10;
17370 + * Packet ID for next data packet
17374 + * 3: MDATA (non-Control), SETUP (Control)
17378 + /* Do PING protocol when 1 */
17379 + unsigned dopng:1;
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.
17390 +union hcintmsk_data {
17391 + /** raw register data */
17394 + /** register bits */
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;
17405 + unsigned stall:1;
17406 + unsigned ahberr:1;
17407 + unsigned chhltd:1;
17408 + unsigned xfercompl:1;
17410 + unsigned xfercompl:1;
17411 + unsigned chhltd:1;
17412 + unsigned ahberr:1;
17413 + unsigned stall:1;
17417 + unsigned xacterr:1;
17418 + unsigned bblerr:1;
17419 + unsigned frmovrun:1;
17420 + unsigned datatglerr:1;
17421 + unsigned reserved:21;
17426 +/** OTG Host Interface Structure.
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
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
17438 + /* Host Port 0 Control and Status Register */
17440 +#define DWC_OTG_HOST_PORT_REGS_OFFSET 0x440
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
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;
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.
17462 +union pcgcctl_data {
17463 + /* raw register data */
17466 + /* register bits */
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;
17478 + unsigned stoppclk:1;
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;
17488 + unsigned reserved:27;