Root/target/linux/lantiq/patches-3.0/0018-MIPS-lantiq-adds-dwc_otg.patch

1From ffd7924fcc69ff146d62f131d72ef18575bf0227 Mon Sep 17 00:00:00 2001
2From: John Crispin <blogic@openwrt.org>
3Date: Fri, 30 Sep 2011 14:37:36 +0200
4Subject: [PATCH 18/24] MIPS: lantiq: adds dwc_otg
5
6---
7 drivers/usb/Kconfig | 2 +
8 drivers/usb/Makefile | 2 +
9 drivers/usb/core/hub.c | 4 +-
10 drivers/usb/dwc_otg/Kconfig | 37 +
11 drivers/usb/dwc_otg/Makefile | 39 +
12 drivers/usb/dwc_otg/dwc_otg_attr.c | 802 ++++++++
13 drivers/usb/dwc_otg/dwc_otg_attr.h | 67 +
14 drivers/usb/dwc_otg/dwc_otg_cil.c | 3025 +++++++++++++++++++++++++++++++
15 drivers/usb/dwc_otg/dwc_otg_cil.h | 911 ++++++++++
16 drivers/usb/dwc_otg/dwc_otg_cil_ifx.h | 58 +
17 drivers/usb/dwc_otg/dwc_otg_cil_intr.c | 708 ++++++++
18 drivers/usb/dwc_otg/dwc_otg_driver.c | 1274 +++++++++++++
19 drivers/usb/dwc_otg/dwc_otg_driver.h | 84 +
20 drivers/usb/dwc_otg/dwc_otg_hcd.c | 2870 +++++++++++++++++++++++++++++
21 drivers/usb/dwc_otg/dwc_otg_hcd.h | 676 +++++++
22 drivers/usb/dwc_otg/dwc_otg_hcd_intr.c | 1841 +++++++++++++++++++
23 drivers/usb/dwc_otg/dwc_otg_hcd_queue.c | 794 ++++++++
24 drivers/usb/dwc_otg/dwc_otg_ifx.c | 100 +
25 drivers/usb/dwc_otg/dwc_otg_ifx.h | 85 +
26 drivers/usb/dwc_otg/dwc_otg_plat.h | 269 +++
27 drivers/usb/dwc_otg/dwc_otg_regs.h | 1797 ++++++++++++++++++
28 21 files changed, 15443 insertions(+), 2 deletions(-)
29 create mode 100644 drivers/usb/dwc_otg/Kconfig
30 create mode 100644 drivers/usb/dwc_otg/Makefile
31 create mode 100644 drivers/usb/dwc_otg/dwc_otg_attr.c
32 create mode 100644 drivers/usb/dwc_otg/dwc_otg_attr.h
33 create mode 100644 drivers/usb/dwc_otg/dwc_otg_cil.c
34 create mode 100644 drivers/usb/dwc_otg/dwc_otg_cil.h
35 create mode 100644 drivers/usb/dwc_otg/dwc_otg_cil_ifx.h
36 create mode 100644 drivers/usb/dwc_otg/dwc_otg_cil_intr.c
37 create mode 100644 drivers/usb/dwc_otg/dwc_otg_driver.c
38 create mode 100644 drivers/usb/dwc_otg/dwc_otg_driver.h
39 create mode 100644 drivers/usb/dwc_otg/dwc_otg_hcd.c
40 create mode 100644 drivers/usb/dwc_otg/dwc_otg_hcd.h
41 create mode 100644 drivers/usb/dwc_otg/dwc_otg_hcd_intr.c
42 create mode 100644 drivers/usb/dwc_otg/dwc_otg_hcd_queue.c
43 create mode 100644 drivers/usb/dwc_otg/dwc_otg_ifx.c
44 create mode 100644 drivers/usb/dwc_otg/dwc_otg_ifx.h
45 create mode 100644 drivers/usb/dwc_otg/dwc_otg_plat.h
46 create mode 100644 drivers/usb/dwc_otg/dwc_otg_regs.h
47
48diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
49index 48f1781..b48c1bd 100644
50--- a/drivers/usb/Kconfig
51+++ b/drivers/usb/Kconfig
52@@ -116,6 +116,8 @@ source "drivers/usb/wusbcore/Kconfig"
53 
54 source "drivers/usb/host/Kconfig"
55 
56+source "drivers/usb/dwc_otg/Kconfig"
57+
58 source "drivers/usb/musb/Kconfig"
59 
60 source "drivers/usb/renesas_usbhs/Kconfig"
61diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
62index 30ddf8d..ba3b993 100644
63--- a/drivers/usb/Makefile
64+++ b/drivers/usb/Makefile
65@@ -28,6 +28,8 @@ obj-$(CONFIG_USB_C67X00_HCD) += c67x00/
66 
67 obj-$(CONFIG_USB_WUSB) += wusbcore/
68 
69+obj-$(CONFIG_DWC_OTG) += dwc_otg/
70+
71 obj-$(CONFIG_USB_ACM) += class/
72 obj-$(CONFIG_USB_PRINTER) += class/
73 obj-$(CONFIG_USB_WDM) += class/
74diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
75index a428aa0..115ae9a 100644
76--- a/drivers/usb/core/hub.c
77+++ b/drivers/usb/core/hub.c
78@@ -2885,11 +2885,11 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
79         udev->ttport = hdev->ttport;
80     } else if (udev->speed != USB_SPEED_HIGH
81             && hdev->speed == USB_SPEED_HIGH) {
82- if (!hub->tt.hub) {
83+/* if (!hub->tt.hub) {
84             dev_err(&udev->dev, "parent hub has no TT\n");
85             retval = -EINVAL;
86             goto fail;
87- }
88+ }*/
89         udev->tt = &hub->tt;
90         udev->ttport = port1;
91     }
92diff --git a/drivers/usb/dwc_otg/Kconfig b/drivers/usb/dwc_otg/Kconfig
93new file mode 100644
94index 0000000..e018490
95--- /dev/null
96+++ b/drivers/usb/dwc_otg/Kconfig
97@@ -0,0 +1,37 @@
98+config DWC_OTG
99+ tristate "Synopsis DWC_OTG support"
100+ depends on USB
101+ help
102+ This driver supports Synopsis DWC_OTG IP core
103+ embebbed on many SOCs (ralink, infineon, etc)
104+
105+choice
106+ prompt "USB Operation Mode"
107+ depends on DWC_OTG
108+ default DWC_OTG_HOST_ONLY
109+
110+config DWC_OTG_HOST_ONLY
111+ bool "HOST ONLY MODE"
112+ depends on DWC_OTG
113+
114+#config DWC_OTG_DEVICE_ONLY
115+# bool "DEVICE ONLY MODE"
116+# depends on DWC_OTG
117+endchoice
118+
119+choice
120+ prompt "Platform"
121+ depends on DWC_OTG
122+ default DWC_OTG_LANTIQ
123+
124+config DWC_OTG_LANTIQ
125+ bool "Lantiq"
126+ depends on LANTIQ
127+ help
128+ Danube USB Host Controller
129+ platform support
130+endchoice
131+
132+config DWC_OTG_DEBUG
133+ bool "Enable debug mode"
134+ depends on DWC_OTG
135diff --git a/drivers/usb/dwc_otg/Makefile b/drivers/usb/dwc_otg/Makefile
136new file mode 100644
137index 0000000..d4d2355
138--- /dev/null
139+++ b/drivers/usb/dwc_otg/Makefile
140@@ -0,0 +1,39 @@
141+#
142+# Makefile for DWC_otg Highspeed USB controller driver
143+#
144+
145+ifeq ($(CONFIG_DWC_OTG_DEBUG),y)
146+EXTRA_CFLAGS += -DDEBUG
147+endif
148+
149+# Use one of the following flags to compile the software in host-only or
150+# device-only mode based on the configuration selected by the user
151+ifeq ($(CONFIG_DWC_OTG_HOST_ONLY),y)
152+ EXTRA_CFLAGS += -DDWC_OTG_HOST_ONLY -DDWC_HOST_ONLY
153+ EXTRA_CFLAGS += -DDWC_OTG_EN_ISOC -DDWC_EN_ISOC
154+else ifeq ($(CONFIG_DWC_OTG_DEVICE_ONLY),y)
155+ EXTRA_CFLAGS += -DDWC_OTG_DEVICE_ONLY
156+else
157+ EXTRA_CFLAGS += -DDWC_OTG_MODE
158+endif
159+
160+# EXTRA_CFLAGS += -DDWC_HS_ELECT_TST
161+# EXTRA_CFLAGS += -DDWC_OTG_EXT_CHG_PUMP
162+
163+ifeq ($(CONFIG_DWC_OTG_LANTIQ),y)
164+ EXTRA_CFLAGS += -Dlinux -D__LINUX__ -DDWC_OTG_IFX -DDWC_OTG_HOST_ONLY -DDWC_HOST_ONLY -D__KERNEL__
165+endif
166+ifeq ($(CONFIG_DWC_OTG_LANTIQ),m)
167+ EXTRA_CFLAGS += -Dlinux -D__LINUX__ -DDWC_OTG_IFX -DDWC_HOST_ONLY -DMODULE -D__KERNEL__ -DDEBUG
168+endif
169+
170+obj-$(CONFIG_DWC_OTG) := dwc_otg.o
171+dwc_otg-objs := dwc_otg_hcd.o dwc_otg_hcd_intr.o dwc_otg_hcd_queue.o
172+#dwc_otg-objs += dwc_otg_pcd.o dwc_otg_pcd_intr.o
173+dwc_otg-objs += dwc_otg_attr.o
174+dwc_otg-objs += dwc_otg_cil.o dwc_otg_cil_intr.o
175+dwc_otg-objs += dwc_otg_ifx.o
176+dwc_otg-objs += dwc_otg_driver.o
177+
178+#obj-$(CONFIG_DWC_OTG_IFX) := dwc_otg_ifx.o
179+#dwc_otg_ifx-objs := dwc_otg_ifx.o
180diff --git a/drivers/usb/dwc_otg/dwc_otg_attr.c b/drivers/usb/dwc_otg/dwc_otg_attr.c
181new file mode 100644
182index 0000000..4675a5c
183--- /dev/null
184+++ b/drivers/usb/dwc_otg/dwc_otg_attr.c
185@@ -0,0 +1,802 @@
186+/* ==========================================================================
187+ * $File: //dwh/usb_iip/dev/software/otg_ipmate/linux/drivers/dwc_otg_attr.c $
188+ * $Revision: 1.1.1.1 $
189+ * $Date: 2009-04-17 06:15:34 $
190+ * $Change: 537387 $
191+ *
192+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
193+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
194+ * otherwise expressly agreed to in writing between Synopsys and you.
195+ *
196+ * The Software IS NOT an item of Licensed Software or Licensed Product under
197+ * any End User Software License Agreement or Agreement for Licensed Product
198+ * with Synopsys or any supplement thereto. You are permitted to use and
199+ * redistribute this Software in source and binary forms, with or without
200+ * modification, provided that redistributions of source code must retain this
201+ * notice. You may not view, use, disclose, copy or distribute this file or
202+ * any information contained herein except pursuant to this license grant from
203+ * Synopsys. If you do not agree with this notice, including the disclaimer
204+ * below, then you are not authorized to use the Software.
205+ *
206+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
207+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
208+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
209+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
210+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
211+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
212+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
213+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
214+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
215+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
216+ * DAMAGE.
217+ * ========================================================================== */
218+
219+/** @file
220+ *
221+ * The diagnostic interface will provide access to the controller for
222+ * bringing up the hardware and testing. The Linux driver attributes
223+ * feature will be used to provide the Linux Diagnostic
224+ * Interface. These attributes are accessed through sysfs.
225+ */
226+
227+/** @page "Linux Module Attributes"
228+ *
229+ * The Linux module attributes feature is used to provide the Linux
230+ * Diagnostic Interface. These attributes are accessed through sysfs.
231+ * The diagnostic interface will provide access to the controller for
232+ * bringing up the hardware and testing.
233+
234+
235+ The following table shows the attributes.
236+ <table>
237+ <tr>
238+ <td><b> Name</b></td>
239+ <td><b> Description</b></td>
240+ <td><b> Access</b></td>
241+ </tr>
242+
243+ <tr>
244+ <td> mode </td>
245+ <td> Returns the current mode: 0 for device mode, 1 for host mode</td>
246+ <td> Read</td>
247+ </tr>
248+
249+ <tr>
250+ <td> hnpcapable </td>
251+ <td> Gets or sets the "HNP-capable" bit in the Core USB Configuraton Register.
252+ Read returns the current value.</td>
253+ <td> Read/Write</td>
254+ </tr>
255+
256+ <tr>
257+ <td> srpcapable </td>
258+ <td> Gets or sets the "SRP-capable" bit in the Core USB Configuraton Register.
259+ Read returns the current value.</td>
260+ <td> Read/Write</td>
261+ </tr>
262+
263+ <tr>
264+ <td> hnp </td>
265+ <td> Initiates the Host Negotiation Protocol. Read returns the status.</td>
266+ <td> Read/Write</td>
267+ </tr>
268+
269+ <tr>
270+ <td> srp </td>
271+ <td> Initiates the Session Request Protocol. Read returns the status.</td>
272+ <td> Read/Write</td>
273+ </tr>
274+
275+ <tr>
276+ <td> buspower </td>
277+ <td> Gets or sets the Power State of the bus (0 - Off or 1 - On)</td>
278+ <td> Read/Write</td>
279+ </tr>
280+
281+ <tr>
282+ <td> bussuspend </td>
283+ <td> Suspends the USB bus.</td>
284+ <td> Read/Write</td>
285+ </tr>
286+
287+ <tr>
288+ <td> busconnected </td>
289+ <td> Gets the connection status of the bus</td>
290+ <td> Read</td>
291+ </tr>
292+
293+ <tr>
294+ <td> gotgctl </td>
295+ <td> Gets or sets the Core Control Status Register.</td>
296+ <td> Read/Write</td>
297+ </tr>
298+
299+ <tr>
300+ <td> gusbcfg </td>
301+ <td> Gets or sets the Core USB Configuration Register</td>
302+ <td> Read/Write</td>
303+ </tr>
304+
305+ <tr>
306+ <td> grxfsiz </td>
307+ <td> Gets or sets the Receive FIFO Size Register</td>
308+ <td> Read/Write</td>
309+ </tr>
310+
311+ <tr>
312+ <td> gnptxfsiz </td>
313+ <td> Gets or sets the non-periodic Transmit Size Register</td>
314+ <td> Read/Write</td>
315+ </tr>
316+
317+ <tr>
318+ <td> gpvndctl </td>
319+ <td> Gets or sets the PHY Vendor Control Register</td>
320+ <td> Read/Write</td>
321+ </tr>
322+
323+ <tr>
324+ <td> ggpio </td>
325+ <td> Gets the value in the lower 16-bits of the General Purpose IO Register
326+ or sets the upper 16 bits.</td>
327+ <td> Read/Write</td>
328+ </tr>
329+
330+ <tr>
331+ <td> guid </td>
332+ <td> Gets or sets the value of the User ID Register</td>
333+ <td> Read/Write</td>
334+ </tr>
335+
336+ <tr>
337+ <td> gsnpsid </td>
338+ <td> Gets the value of the Synopsys ID Regester</td>
339+ <td> Read</td>
340+ </tr>
341+
342+ <tr>
343+ <td> devspeed </td>
344+ <td> Gets or sets the device speed setting in the DCFG register</td>
345+ <td> Read/Write</td>
346+ </tr>
347+
348+ <tr>
349+ <td> enumspeed </td>
350+ <td> Gets the device enumeration Speed.</td>
351+ <td> Read</td>
352+ </tr>
353+
354+ <tr>
355+ <td> hptxfsiz </td>
356+ <td> Gets the value of the Host Periodic Transmit FIFO</td>
357+ <td> Read</td>
358+ </tr>
359+
360+ <tr>
361+ <td> hprt0 </td>
362+ <td> Gets or sets the value in the Host Port Control and Status Register</td>
363+ <td> Read/Write</td>
364+ </tr>
365+
366+ <tr>
367+ <td> regoffset </td>
368+ <td> Sets the register offset for the next Register Access</td>
369+ <td> Read/Write</td>
370+ </tr>
371+
372+ <tr>
373+ <td> regvalue </td>
374+ <td> Gets or sets the value of the register at the offset in the regoffset attribute.</td>
375+ <td> Read/Write</td>
376+ </tr>
377+
378+ <tr>
379+ <td> remote_wakeup </td>
380+ <td> On read, shows the status of Remote Wakeup. On write, initiates a remote
381+ wakeup of the host. When bit 0 is 1 and Remote Wakeup is enabled, the Remote
382+ Wakeup signalling bit in the Device Control Register is set for 1
383+ milli-second.</td>
384+ <td> Read/Write</td>
385+ </tr>
386+
387+ <tr>
388+ <td> regdump </td>
389+ <td> Dumps the contents of core registers.</td>
390+ <td> Read</td>
391+ </tr>
392+
393+ <tr>
394+ <td> hcddump </td>
395+ <td> Dumps the current HCD state.</td>
396+ <td> Read</td>
397+ </tr>
398+
399+ <tr>
400+ <td> hcd_frrem </td>
401+ <td> Shows the average value of the Frame Remaining
402+ field in the Host Frame Number/Frame Remaining register when an SOF interrupt
403+ occurs. This can be used to determine the average interrupt latency. Also
404+ shows the average Frame Remaining value for start_transfer and the "a" and
405+ "b" sample points. The "a" and "b" sample points may be used during debugging
406+ bto determine how long it takes to execute a section of the HCD code.</td>
407+ <td> Read</td>
408+ </tr>
409+
410+ <tr>
411+ <td> rd_reg_test </td>
412+ <td> Displays the time required to read the GNPTXFSIZ register many times
413+ (the output shows the number of times the register is read).
414+ <td> Read</td>
415+ </tr>
416+
417+ <tr>
418+ <td> wr_reg_test </td>
419+ <td> Displays the time required to write the GNPTXFSIZ register many times
420+ (the output shows the number of times the register is written).
421+ <td> Read</td>
422+ </tr>
423+
424+ </table>
425+
426+ Example usage:
427+ To get the current mode:
428+ cat /sys/devices/lm0/mode
429+
430+ To power down the USB:
431+ echo 0 > /sys/devices/lm0/buspower
432+ */
433+#include <linux/kernel.h>
434+#include <linux/module.h>
435+#include <linux/moduleparam.h>
436+#include <linux/init.h>
437+#include <linux/device.h>
438+#include <linux/errno.h>
439+#include <linux/types.h>
440+#include <linux/stat.h> /* permission constants */
441+
442+#include <asm/io.h>
443+
444+#include "dwc_otg_plat.h"
445+#include "dwc_otg_attr.h"
446+#include "dwc_otg_driver.h"
447+// #include "dwc_otg_pcd.h"
448+#include "dwc_otg_hcd.h"
449+
450+// 20070316, winder added.
451+#ifndef SZ_256K
452+#define SZ_256K 0x00040000
453+#endif
454+
455+/*
456+ * MACROs for defining sysfs attribute
457+ */
458+#define DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
459+static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
460+{ \
461+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);\
462+ uint32_t val; \
463+ val = dwc_read_reg32 (_addr_); \
464+ val = (val & (_mask_)) >> _shift_; \
465+ return sprintf (buf, "%s = 0x%x\n", _string_, val); \
466+}
467+#define DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
468+static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, const char *buf, size_t count) \
469+{ \
470+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);\
471+ uint32_t set = simple_strtoul(buf, NULL, 16); \
472+ uint32_t clear = set; \
473+ clear = ((~clear) << _shift_) & _mask_; \
474+ set = (set << _shift_) & _mask_; \
475+ dev_dbg(_dev, "Storing Address=0x%08x Set=0x%08x Clear=0x%08x\n", (uint32_t)_addr_, set, clear); \
476+ dwc_modify_reg32(_addr_, clear, set); \
477+ return count; \
478+}
479+
480+#define DWC_OTG_DEVICE_ATTR_BITFIELD_RW(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
481+DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
482+DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
483+DEVICE_ATTR(_otg_attr_name_,0644,_otg_attr_name_##_show,_otg_attr_name_##_store);
484+
485+#define DWC_OTG_DEVICE_ATTR_BITFIELD_RO(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
486+DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
487+DEVICE_ATTR(_otg_attr_name_,0444,_otg_attr_name_##_show,NULL);
488+
489+/*
490+ * MACROs for defining sysfs attribute for 32-bit registers
491+ */
492+#define DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_addr_,_string_) \
493+static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
494+{ \
495+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);\
496+ uint32_t val; \
497+ val = dwc_read_reg32 (_addr_); \
498+ return sprintf (buf, "%s = 0x%08x\n", _string_, val); \
499+}
500+#define DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_addr_,_string_) \
501+static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, const char *buf, size_t count) \
502+{ \
503+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);\
504+ uint32_t val = simple_strtoul(buf, NULL, 16); \
505+ dev_dbg(_dev, "Storing Address=0x%08x Val=0x%08x\n", (uint32_t)_addr_, val); \
506+ dwc_write_reg32(_addr_, val); \
507+ return count; \
508+}
509+
510+#define DWC_OTG_DEVICE_ATTR_REG32_RW(_otg_attr_name_,_addr_,_string_) \
511+DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_addr_,_string_) \
512+DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_addr_,_string_) \
513+DEVICE_ATTR(_otg_attr_name_,0644,_otg_attr_name_##_show,_otg_attr_name_##_store);
514+
515+#define DWC_OTG_DEVICE_ATTR_REG32_RO(_otg_attr_name_,_addr_,_string_) \
516+DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_addr_,_string_) \
517+DEVICE_ATTR(_otg_attr_name_,0444,_otg_attr_name_##_show,NULL);
518+
519+
520+/** @name Functions for Show/Store of Attributes */
521+/**@{*/
522+
523+/**
524+ * Show the register offset of the Register Access.
525+ */
526+static ssize_t regoffset_show( struct device *_dev, struct device_attribute *attr, char *buf)
527+{
528+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
529+ return snprintf(buf, sizeof("0xFFFFFFFF\n")+1,"0x%08x\n", otg_dev->reg_offset);
530+}
531+
532+/**
533+ * Set the register offset for the next Register Access Read/Write
534+ */
535+static ssize_t regoffset_store( struct device *_dev, struct device_attribute *attr, const char *buf,
536+ size_t count )
537+{
538+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
539+ uint32_t offset = simple_strtoul(buf, NULL, 16);
540+ //dev_dbg(_dev, "Offset=0x%08x\n", offset);
541+ if (offset < SZ_256K ) {
542+ otg_dev->reg_offset = offset;
543+ }
544+ else {
545+ dev_err( _dev, "invalid offset\n" );
546+ }
547+
548+ return count;
549+}
550+DEVICE_ATTR(regoffset, S_IRUGO|S_IWUSR, regoffset_show, regoffset_store);
551+
552+/**
553+ * Show the value of the register at the offset in the reg_offset
554+ * attribute.
555+ */
556+static ssize_t regvalue_show( struct device *_dev, struct device_attribute *attr, char *buf)
557+{
558+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
559+ uint32_t val;
560+ volatile uint32_t *addr;
561+
562+ if (otg_dev->reg_offset != 0xFFFFFFFF && 0 != otg_dev->base) {
563+ /* Calculate the address */
564+ addr = (uint32_t*)(otg_dev->reg_offset +
565+ (uint8_t*)otg_dev->base);
566+ //dev_dbg(_dev, "@0x%08x\n", (unsigned)addr);
567+ val = dwc_read_reg32( addr );
568+ return snprintf(buf, sizeof("Reg@0xFFFFFFFF = 0xFFFFFFFF\n")+1,
569+ "Reg@0x%06x = 0x%08x\n",
570+ otg_dev->reg_offset, val);
571+ }
572+ else {
573+ dev_err(_dev, "Invalid offset (0x%0x)\n",
574+ otg_dev->reg_offset);
575+ return sprintf(buf, "invalid offset\n" );
576+ }
577+}
578+
579+/**
580+ * Store the value in the register at the offset in the reg_offset
581+ * attribute.
582+ *
583+ */
584+static ssize_t regvalue_store( struct device *_dev, struct device_attribute *attr, const char *buf,
585+ size_t count )
586+{
587+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
588+ volatile uint32_t * addr;
589+ uint32_t val = simple_strtoul(buf, NULL, 16);
590+ //dev_dbg(_dev, "Offset=0x%08x Val=0x%08x\n", otg_dev->reg_offset, val);
591+ if (otg_dev->reg_offset != 0xFFFFFFFF && 0 != otg_dev->base) {
592+ /* Calculate the address */
593+ addr = (uint32_t*)(otg_dev->reg_offset +
594+ (uint8_t*)otg_dev->base);
595+ //dev_dbg(_dev, "@0x%08x\n", (unsigned)addr);
596+ dwc_write_reg32( addr, val );
597+ }
598+ else {
599+ dev_err(_dev, "Invalid Register Offset (0x%08x)\n",
600+ otg_dev->reg_offset);
601+ }
602+ return count;
603+}
604+DEVICE_ATTR(regvalue, S_IRUGO|S_IWUSR, regvalue_show, regvalue_store);
605+
606+/*
607+ * Attributes
608+ */
609+DWC_OTG_DEVICE_ATTR_BITFIELD_RO(mode,&(otg_dev->core_if->core_global_regs->gotgctl),(1<<20),20,"Mode");
610+DWC_OTG_DEVICE_ATTR_BITFIELD_RW(hnpcapable,&(otg_dev->core_if->core_global_regs->gusbcfg),(1<<9),9,"Mode");
611+DWC_OTG_DEVICE_ATTR_BITFIELD_RW(srpcapable,&(otg_dev->core_if->core_global_regs->gusbcfg),(1<<8),8,"Mode");
612+
613+//DWC_OTG_DEVICE_ATTR_BITFIELD_RW(buspower,&(otg_dev->core_if->core_global_regs->gotgctl),(1<<8),8,"Mode");
614+//DWC_OTG_DEVICE_ATTR_BITFIELD_RW(bussuspend,&(otg_dev->core_if->core_global_regs->gotgctl),(1<<8),8,"Mode");
615+DWC_OTG_DEVICE_ATTR_BITFIELD_RO(busconnected,otg_dev->core_if->host_if->hprt0,0x01,0,"Bus Connected");
616+
617+DWC_OTG_DEVICE_ATTR_REG32_RW(gotgctl,&(otg_dev->core_if->core_global_regs->gotgctl),"GOTGCTL");
618+DWC_OTG_DEVICE_ATTR_REG32_RW(gusbcfg,&(otg_dev->core_if->core_global_regs->gusbcfg),"GUSBCFG");
619+DWC_OTG_DEVICE_ATTR_REG32_RW(grxfsiz,&(otg_dev->core_if->core_global_regs->grxfsiz),"GRXFSIZ");
620+DWC_OTG_DEVICE_ATTR_REG32_RW(gnptxfsiz,&(otg_dev->core_if->core_global_regs->gnptxfsiz),"GNPTXFSIZ");
621+DWC_OTG_DEVICE_ATTR_REG32_RW(gpvndctl,&(otg_dev->core_if->core_global_regs->gpvndctl),"GPVNDCTL");
622+DWC_OTG_DEVICE_ATTR_REG32_RW(ggpio,&(otg_dev->core_if->core_global_regs->ggpio),"GGPIO");
623+DWC_OTG_DEVICE_ATTR_REG32_RW(guid,&(otg_dev->core_if->core_global_regs->guid),"GUID");
624+DWC_OTG_DEVICE_ATTR_REG32_RO(gsnpsid,&(otg_dev->core_if->core_global_regs->gsnpsid),"GSNPSID");
625+DWC_OTG_DEVICE_ATTR_BITFIELD_RW(devspeed,&(otg_dev->core_if->dev_if->dev_global_regs->dcfg),0x3,0,"Device Speed");
626+DWC_OTG_DEVICE_ATTR_BITFIELD_RO(enumspeed,&(otg_dev->core_if->dev_if->dev_global_regs->dsts),0x6,1,"Device Enumeration Speed");
627+
628+DWC_OTG_DEVICE_ATTR_REG32_RO(hptxfsiz,&(otg_dev->core_if->core_global_regs->hptxfsiz),"HPTXFSIZ");
629+DWC_OTG_DEVICE_ATTR_REG32_RW(hprt0,otg_dev->core_if->host_if->hprt0,"HPRT0");
630+
631+
632+/**
633+ * @todo Add code to initiate the HNP.
634+ */
635+/**
636+ * Show the HNP status bit
637+ */
638+static ssize_t hnp_show( struct device *_dev, struct device_attribute *attr, char *buf)
639+{
640+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
641+ gotgctl_data_t val;
642+ val.d32 = dwc_read_reg32 (&(otg_dev->core_if->core_global_regs->gotgctl));
643+ return sprintf (buf, "HstNegScs = 0x%x\n", val.b.hstnegscs);
644+}
645+
646+/**
647+ * Set the HNP Request bit
648+ */
649+static ssize_t hnp_store( struct device *_dev, struct device_attribute *attr, const char *buf,
650+ size_t count )
651+{
652+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
653+ uint32_t in = simple_strtoul(buf, NULL, 16);
654+ uint32_t *addr = (uint32_t *)&(otg_dev->core_if->core_global_regs->gotgctl);
655+ gotgctl_data_t mem;
656+ mem.d32 = dwc_read_reg32(addr);
657+ mem.b.hnpreq = in;
658+ dev_dbg(_dev, "Storing Address=0x%08x Data=0x%08x\n", (uint32_t)addr, mem.d32);
659+ dwc_write_reg32(addr, mem.d32);
660+ return count;
661+}
662+DEVICE_ATTR(hnp, 0644, hnp_show, hnp_store);
663+
664+/**
665+ * @todo Add code to initiate the SRP.
666+ */
667+/**
668+ * Show the SRP status bit
669+ */
670+static ssize_t srp_show( struct device *_dev, struct device_attribute *attr, char *buf)
671+{
672+#ifndef DWC_HOST_ONLY
673+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
674+ gotgctl_data_t val;
675+ val.d32 = dwc_read_reg32 (&(otg_dev->core_if->core_global_regs->gotgctl));
676+ return sprintf (buf, "SesReqScs = 0x%x\n", val.b.sesreqscs);
677+#else
678+ return sprintf(buf, "Host Only Mode!\n");
679+#endif
680+}
681+
682+/**
683+ * Set the SRP Request bit
684+ */
685+static ssize_t srp_store( struct device *_dev, struct device_attribute *attr, const char *buf,
686+ size_t count )
687+{
688+#ifndef DWC_HOST_ONLY
689+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
690+ dwc_otg_pcd_initiate_srp(otg_dev->pcd);
691+#endif
692+ return count;
693+}
694+DEVICE_ATTR(srp, 0644, srp_show, srp_store);
695+
696+/**
697+ * @todo Need to do more for power on/off?
698+ */
699+/**
700+ * Show the Bus Power status
701+ */
702+static ssize_t buspower_show( struct device *_dev, struct device_attribute *attr, char *buf)
703+{
704+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
705+ hprt0_data_t val;
706+ val.d32 = dwc_read_reg32 (otg_dev->core_if->host_if->hprt0);
707+ return sprintf (buf, "Bus Power = 0x%x\n", val.b.prtpwr);
708+}
709+
710+
711+/**
712+ * Set the Bus Power status
713+ */
714+static ssize_t buspower_store( struct device *_dev, struct device_attribute *attr, const char *buf,
715+ size_t count )
716+{
717+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
718+ uint32_t on = simple_strtoul(buf, NULL, 16);
719+ uint32_t *addr = (uint32_t *)otg_dev->core_if->host_if->hprt0;
720+ hprt0_data_t mem;
721+
722+ mem.d32 = dwc_read_reg32(addr);
723+ mem.b.prtpwr = on;
724+
725+ //dev_dbg(_dev, "Storing Address=0x%08x Data=0x%08x\n", (uint32_t)addr, mem.d32);
726+ dwc_write_reg32(addr, mem.d32);
727+
728+ return count;
729+}
730+DEVICE_ATTR(buspower, 0644, buspower_show, buspower_store);
731+
732+/**
733+ * @todo Need to do more for suspend?
734+ */
735+/**
736+ * Show the Bus Suspend status
737+ */
738+static ssize_t bussuspend_show( struct device *_dev, struct device_attribute *attr, char *buf)
739+{
740+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
741+ hprt0_data_t val;
742+ val.d32 = dwc_read_reg32 (otg_dev->core_if->host_if->hprt0);
743+ return sprintf (buf, "Bus Suspend = 0x%x\n", val.b.prtsusp);
744+}
745+
746+/**
747+ * Set the Bus Suspend status
748+ */
749+static ssize_t bussuspend_store( struct device *_dev, struct device_attribute *attr, const char *buf,
750+ size_t count )
751+{
752+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
753+ uint32_t in = simple_strtoul(buf, NULL, 16);
754+ uint32_t *addr = (uint32_t *)otg_dev->core_if->host_if->hprt0;
755+ hprt0_data_t mem;
756+ mem.d32 = dwc_read_reg32(addr);
757+ mem.b.prtsusp = in;
758+ dev_dbg(_dev, "Storing Address=0x%08x Data=0x%08x\n", (uint32_t)addr, mem.d32);
759+ dwc_write_reg32(addr, mem.d32);
760+ return count;
761+}
762+DEVICE_ATTR(bussuspend, 0644, bussuspend_show, bussuspend_store);
763+
764+/**
765+ * Show the status of Remote Wakeup.
766+ */
767+static ssize_t remote_wakeup_show( struct device *_dev, struct device_attribute *attr, char *buf)
768+{
769+#ifndef DWC_HOST_ONLY
770+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
771+ dctl_data_t val;
772+ val.d32 = dwc_read_reg32( &otg_dev->core_if->dev_if->dev_global_regs->dctl);
773+ return sprintf( buf, "Remote Wakeup = %d Enabled = %d\n",
774+ val.b.rmtwkupsig, otg_dev->pcd->remote_wakeup_enable);
775+#else
776+ return sprintf(buf, "Host Only Mode!\n");
777+#endif
778+}
779+
780+/**
781+ * Initiate a remote wakeup of the host. The Device control register
782+ * Remote Wakeup Signal bit is written if the PCD Remote wakeup enable
783+ * flag is set.
784+ *
785+ */
786+static ssize_t remote_wakeup_store( struct device *_dev, struct device_attribute *attr, const char *buf,
787+ size_t count )
788+{
789+#ifndef DWC_HOST_ONLY
790+ uint32_t val = simple_strtoul(buf, NULL, 16);
791+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
792+ if (val&1) {
793+ dwc_otg_pcd_remote_wakeup(otg_dev->pcd, 1);
794+ }
795+ else {
796+ dwc_otg_pcd_remote_wakeup(otg_dev->pcd, 0);
797+ }
798+#endif
799+ return count;
800+}
801+DEVICE_ATTR(remote_wakeup, S_IRUGO|S_IWUSR, remote_wakeup_show,
802+ remote_wakeup_store);
803+
804+/**
805+ * Dump global registers and either host or device registers (depending on the
806+ * current mode of the core).
807+ */
808+static ssize_t regdump_show( struct device *_dev, struct device_attribute *attr, char *buf)
809+{
810+#ifdef DEBUG
811+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
812+ printk("%s otg_dev=0x%p\n", __FUNCTION__, otg_dev);
813+
814+ dwc_otg_dump_global_registers( otg_dev->core_if);
815+ if (dwc_otg_is_host_mode(otg_dev->core_if)) {
816+ dwc_otg_dump_host_registers( otg_dev->core_if);
817+ } else {
818+ dwc_otg_dump_dev_registers( otg_dev->core_if);
819+ }
820+#endif
821+
822+ return sprintf( buf, "Register Dump\n" );
823+}
824+
825+DEVICE_ATTR(regdump, S_IRUGO|S_IWUSR, regdump_show, 0);
826+
827+/**
828+ * Dump the current hcd state.
829+ */
830+static ssize_t hcddump_show( struct device *_dev, struct device_attribute *attr, char *buf)
831+{
832+#ifndef DWC_DEVICE_ONLY
833+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
834+ dwc_otg_hcd_dump_state(otg_dev->hcd);
835+#endif
836+ return sprintf( buf, "HCD Dump\n" );
837+}
838+
839+DEVICE_ATTR(hcddump, S_IRUGO|S_IWUSR, hcddump_show, 0);
840+
841+/**
842+ * Dump the average frame remaining at SOF. This can be used to
843+ * determine average interrupt latency. Frame remaining is also shown for
844+ * start transfer and two additional sample points.
845+ */
846+static ssize_t hcd_frrem_show( struct device *_dev, struct device_attribute *attr, char *buf)
847+{
848+#ifndef DWC_DEVICE_ONLY
849+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
850+ dwc_otg_hcd_dump_frrem(otg_dev->hcd);
851+#endif
852+ return sprintf( buf, "HCD Dump Frame Remaining\n" );
853+}
854+
855+DEVICE_ATTR(hcd_frrem, S_IRUGO|S_IWUSR, hcd_frrem_show, 0);
856+
857+/**
858+ * Displays the time required to read the GNPTXFSIZ register many times (the
859+ * output shows the number of times the register is read).
860+ */
861+#define RW_REG_COUNT 10000000
862+#define MSEC_PER_JIFFIE 1000/HZ
863+static ssize_t rd_reg_test_show( struct device *_dev, struct device_attribute *attr, char *buf)
864+{
865+ int i;
866+ int time;
867+ int start_jiffies;
868+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
869+
870+ printk("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n",
871+ HZ, MSEC_PER_JIFFIE, loops_per_jiffy);
872+ start_jiffies = jiffies;
873+ for (i = 0; i < RW_REG_COUNT; i++) {
874+ dwc_read_reg32(&otg_dev->core_if->core_global_regs->gnptxfsiz);
875+ }
876+ time = jiffies - start_jiffies;
877+ return sprintf( buf, "Time to read GNPTXFSIZ reg %d times: %d msecs (%d jiffies)\n",
878+ RW_REG_COUNT, time * MSEC_PER_JIFFIE, time );
879+}
880+
881+DEVICE_ATTR(rd_reg_test, S_IRUGO|S_IWUSR, rd_reg_test_show, 0);
882+
883+/**
884+ * Displays the time required to write the GNPTXFSIZ register many times (the
885+ * output shows the number of times the register is written).
886+ */
887+static ssize_t wr_reg_test_show( struct device *_dev, struct device_attribute *attr, char *buf)
888+{
889+ int i;
890+ int time;
891+ int start_jiffies;
892+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
893+ uint32_t reg_val;
894+
895+ printk("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n",
896+ HZ, MSEC_PER_JIFFIE, loops_per_jiffy);
897+ reg_val = dwc_read_reg32(&otg_dev->core_if->core_global_regs->gnptxfsiz);
898+ start_jiffies = jiffies;
899+ for (i = 0; i < RW_REG_COUNT; i++) {
900+ dwc_write_reg32(&otg_dev->core_if->core_global_regs->gnptxfsiz, reg_val);
901+ }
902+ time = jiffies - start_jiffies;
903+ return sprintf( buf, "Time to write GNPTXFSIZ reg %d times: %d msecs (%d jiffies)\n",
904+ RW_REG_COUNT, time * MSEC_PER_JIFFIE, time);
905+}
906+
907+DEVICE_ATTR(wr_reg_test, S_IRUGO|S_IWUSR, wr_reg_test_show, 0);
908+/**@}*/
909+
910+/**
911+ * Create the device files
912+ */
913+void dwc_otg_attr_create (struct device *_dev)
914+{
915+ int retval;
916+
917+ retval = device_create_file(_dev, &dev_attr_regoffset);
918+ retval += device_create_file(_dev, &dev_attr_regvalue);
919+ retval += device_create_file(_dev, &dev_attr_mode);
920+ retval += device_create_file(_dev, &dev_attr_hnpcapable);
921+ retval += device_create_file(_dev, &dev_attr_srpcapable);
922+ retval += device_create_file(_dev, &dev_attr_hnp);
923+ retval += device_create_file(_dev, &dev_attr_srp);
924+ retval += device_create_file(_dev, &dev_attr_buspower);
925+ retval += device_create_file(_dev, &dev_attr_bussuspend);
926+ retval += device_create_file(_dev, &dev_attr_busconnected);
927+ retval += device_create_file(_dev, &dev_attr_gotgctl);
928+ retval += device_create_file(_dev, &dev_attr_gusbcfg);
929+ retval += device_create_file(_dev, &dev_attr_grxfsiz);
930+ retval += device_create_file(_dev, &dev_attr_gnptxfsiz);
931+ retval += device_create_file(_dev, &dev_attr_gpvndctl);
932+ retval += device_create_file(_dev, &dev_attr_ggpio);
933+ retval += device_create_file(_dev, &dev_attr_guid);
934+ retval += device_create_file(_dev, &dev_attr_gsnpsid);
935+ retval += device_create_file(_dev, &dev_attr_devspeed);
936+ retval += device_create_file(_dev, &dev_attr_enumspeed);
937+ retval += device_create_file(_dev, &dev_attr_hptxfsiz);
938+ retval += device_create_file(_dev, &dev_attr_hprt0);
939+ retval += device_create_file(_dev, &dev_attr_remote_wakeup);
940+ retval += device_create_file(_dev, &dev_attr_regdump);
941+ retval += device_create_file(_dev, &dev_attr_hcddump);
942+ retval += device_create_file(_dev, &dev_attr_hcd_frrem);
943+ retval += device_create_file(_dev, &dev_attr_rd_reg_test);
944+ retval += device_create_file(_dev, &dev_attr_wr_reg_test);
945+
946+ if(retval != 0)
947+ {
948+ DWC_PRINT("cannot create sysfs device files.\n");
949+ // DWC_PRINT("killing own sysfs device files!\n");
950+ dwc_otg_attr_remove(_dev);
951+ }
952+}
953+
954+/**
955+ * Remove the device files
956+ */
957+void dwc_otg_attr_remove (struct device *_dev)
958+{
959+ device_remove_file(_dev, &dev_attr_regoffset);
960+ device_remove_file(_dev, &dev_attr_regvalue);
961+ device_remove_file(_dev, &dev_attr_mode);
962+ device_remove_file(_dev, &dev_attr_hnpcapable);
963+ device_remove_file(_dev, &dev_attr_srpcapable);
964+ device_remove_file(_dev, &dev_attr_hnp);
965+ device_remove_file(_dev, &dev_attr_srp);
966+ device_remove_file(_dev, &dev_attr_buspower);
967+ device_remove_file(_dev, &dev_attr_bussuspend);
968+ device_remove_file(_dev, &dev_attr_busconnected);
969+ device_remove_file(_dev, &dev_attr_gotgctl);
970+ device_remove_file(_dev, &dev_attr_gusbcfg);
971+ device_remove_file(_dev, &dev_attr_grxfsiz);
972+ device_remove_file(_dev, &dev_attr_gnptxfsiz);
973+ device_remove_file(_dev, &dev_attr_gpvndctl);
974+ device_remove_file(_dev, &dev_attr_ggpio);
975+ device_remove_file(_dev, &dev_attr_guid);
976+ device_remove_file(_dev, &dev_attr_gsnpsid);
977+ device_remove_file(_dev, &dev_attr_devspeed);
978+ device_remove_file(_dev, &dev_attr_enumspeed);
979+ device_remove_file(_dev, &dev_attr_hptxfsiz);
980+ device_remove_file(_dev, &dev_attr_hprt0);
981+ device_remove_file(_dev, &dev_attr_remote_wakeup);
982+ device_remove_file(_dev, &dev_attr_regdump);
983+ device_remove_file(_dev, &dev_attr_hcddump);
984+ device_remove_file(_dev, &dev_attr_hcd_frrem);
985+ device_remove_file(_dev, &dev_attr_rd_reg_test);
986+ device_remove_file(_dev, &dev_attr_wr_reg_test);
987+}
988diff --git a/drivers/usb/dwc_otg/dwc_otg_attr.h b/drivers/usb/dwc_otg/dwc_otg_attr.h
989new file mode 100644
990index 0000000..4bbf7df
991--- /dev/null
992+++ b/drivers/usb/dwc_otg/dwc_otg_attr.h
993@@ -0,0 +1,67 @@
994+/* ==========================================================================
995+ * $File: //dwh/usb_iip/dev/software/otg_ipmate/linux/drivers/dwc_otg_attr.h $
996+ * $Revision: 1.1.1.1 $
997+ * $Date: 2009-04-17 06:15:34 $
998+ * $Change: 510275 $
999+ *
1000+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
1001+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
1002+ * otherwise expressly agreed to in writing between Synopsys and you.
1003+ *
1004+ * The Software IS NOT an item of Licensed Software or Licensed Product under
1005+ * any End User Software License Agreement or Agreement for Licensed Product
1006+ * with Synopsys or any supplement thereto. You are permitted to use and
1007+ * redistribute this Software in source and binary forms, with or without
1008+ * modification, provided that redistributions of source code must retain this
1009+ * notice. You may not view, use, disclose, copy or distribute this file or
1010+ * any information contained herein except pursuant to this license grant from
1011+ * Synopsys. If you do not agree with this notice, including the disclaimer
1012+ * below, then you are not authorized to use the Software.
1013+ *
1014+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
1015+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1016+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1017+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
1018+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1019+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
1020+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
1021+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1022+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1023+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
1024+ * DAMAGE.
1025+ * ========================================================================== */
1026+
1027+#if !defined(__DWC_OTG_ATTR_H__)
1028+#define __DWC_OTG_ATTR_H__
1029+
1030+/** @file
1031+ * This file contains the interface to the Linux device attributes.
1032+ */
1033+extern struct device_attribute dev_attr_regoffset;
1034+extern struct device_attribute dev_attr_regvalue;
1035+
1036+extern struct device_attribute dev_attr_mode;
1037+extern struct device_attribute dev_attr_hnpcapable;
1038+extern struct device_attribute dev_attr_srpcapable;
1039+extern struct device_attribute dev_attr_hnp;
1040+extern struct device_attribute dev_attr_srp;
1041+extern struct device_attribute dev_attr_buspower;
1042+extern struct device_attribute dev_attr_bussuspend;
1043+extern struct device_attribute dev_attr_busconnected;
1044+extern struct device_attribute dev_attr_gotgctl;
1045+extern struct device_attribute dev_attr_gusbcfg;
1046+extern struct device_attribute dev_attr_grxfsiz;
1047+extern struct device_attribute dev_attr_gnptxfsiz;
1048+extern struct device_attribute dev_attr_gpvndctl;
1049+extern struct device_attribute dev_attr_ggpio;
1050+extern struct device_attribute dev_attr_guid;
1051+extern struct device_attribute dev_attr_gsnpsid;
1052+extern struct device_attribute dev_attr_devspeed;
1053+extern struct device_attribute dev_attr_enumspeed;
1054+extern struct device_attribute dev_attr_hptxfsiz;
1055+extern struct device_attribute dev_attr_hprt0;
1056+
1057+void dwc_otg_attr_create (struct device *_dev);
1058+void dwc_otg_attr_remove (struct device *_dev);
1059+
1060+#endif
1061diff --git a/drivers/usb/dwc_otg/dwc_otg_cil.c b/drivers/usb/dwc_otg/dwc_otg_cil.c
1062new file mode 100644
1063index 0000000..42c69eb
1064--- /dev/null
1065+++ b/drivers/usb/dwc_otg/dwc_otg_cil.c
1066@@ -0,0 +1,3025 @@
1067+/* ==========================================================================
1068+ * $File: //dwh/usb_iip/dev/software/otg_ipmate/linux/drivers/dwc_otg_cil.c $
1069+ * $Revision: 1.1.1.1 $
1070+ * $Date: 2009-04-17 06:15:34 $
1071+ * $Change: 631780 $
1072+ *
1073+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
1074+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
1075+ * otherwise expressly agreed to in writing between Synopsys and you.
1076+ *
1077+ * The Software IS NOT an item of Licensed Software or Licensed Product under
1078+ * any End User Software License Agreement or Agreement for Licensed Product
1079+ * with Synopsys or any supplement thereto. You are permitted to use and
1080+ * redistribute this Software in source and binary forms, with or without
1081+ * modification, provided that redistributions of source code must retain this
1082+ * notice. You may not view, use, disclose, copy or distribute this file or
1083+ * any information contained herein except pursuant to this license grant from
1084+ * Synopsys. If you do not agree with this notice, including the disclaimer
1085+ * below, then you are not authorized to use the Software.
1086+ *
1087+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
1088+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1089+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1090+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
1091+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1092+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
1093+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
1094+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1095+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1096+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
1097+ * DAMAGE.
1098+ * ========================================================================== */
1099+
1100+/** @file
1101+ *
1102+ * The Core Interface Layer provides basic services for accessing and
1103+ * managing the DWC_otg hardware. These services are used by both the
1104+ * Host Controller Driver and the Peripheral Controller Driver.
1105+ *
1106+ * The CIL manages the memory map for the core so that the HCD and PCD
1107+ * don't have to do this separately. It also handles basic tasks like
1108+ * reading/writing the registers and data FIFOs in the controller.
1109+ * Some of the data access functions provide encapsulation of several
1110+ * operations required to perform a task, such as writing multiple
1111+ * registers to start a transfer. Finally, the CIL performs basic
1112+ * services that are not specific to either the host or device modes
1113+ * of operation. These services include management of the OTG Host
1114+ * Negotiation Protocol (HNP) and Session Request Protocol (SRP). A
1115+ * Diagnostic API is also provided to allow testing of the controller
1116+ * hardware.
1117+ *
1118+ * The Core Interface Layer has the following requirements:
1119+ * - Provides basic controller operations.
1120+ * - Minimal use of OS services.
1121+ * - The OS services used will be abstracted by using inline functions
1122+ * or macros.
1123+ *
1124+ */
1125+#include <asm/unaligned.h>
1126+
1127+#ifdef DEBUG
1128+#include <linux/jiffies.h>
1129+#endif
1130+
1131+#include "dwc_otg_plat.h"
1132+
1133+#include "dwc_otg_regs.h"
1134+#include "dwc_otg_cil.h"
1135+
1136+/**
1137+ * This function is called to initialize the DWC_otg CSR data
1138+ * structures. The register addresses in the device and host
1139+ * structures are initialized from the base address supplied by the
1140+ * caller. The calling function must make the OS calls to get the
1141+ * base address of the DWC_otg controller registers. The core_params
1142+ * argument holds the parameters that specify how the core should be
1143+ * configured.
1144+ *
1145+ * @param[in] _reg_base_addr Base address of DWC_otg core registers
1146+ * @param[in] _core_params Pointer to the core configuration parameters
1147+ *
1148+ */
1149+dwc_otg_core_if_t *dwc_otg_cil_init(const uint32_t *_reg_base_addr,
1150+ dwc_otg_core_params_t *_core_params)
1151+{
1152+ dwc_otg_core_if_t *core_if = 0;
1153+ dwc_otg_dev_if_t *dev_if = 0;
1154+ dwc_otg_host_if_t *host_if = 0;
1155+ uint8_t *reg_base = (uint8_t *)_reg_base_addr;
1156+ int i = 0;
1157+
1158+ DWC_DEBUGPL(DBG_CILV, "%s(%p,%p)\n", __func__, _reg_base_addr, _core_params);
1159+
1160+ core_if = kmalloc( sizeof(dwc_otg_core_if_t), GFP_KERNEL);
1161+ if (core_if == 0) {
1162+ DWC_DEBUGPL(DBG_CIL, "Allocation of dwc_otg_core_if_t failed\n");
1163+ return 0;
1164+ }
1165+ memset(core_if, 0, sizeof(dwc_otg_core_if_t));
1166+
1167+ core_if->core_params = _core_params;
1168+ core_if->core_global_regs = (dwc_otg_core_global_regs_t *)reg_base;
1169+ /*
1170+ * Allocate the Device Mode structures.
1171+ */
1172+ dev_if = kmalloc( sizeof(dwc_otg_dev_if_t), GFP_KERNEL);
1173+ if (dev_if == 0) {
1174+ DWC_DEBUGPL(DBG_CIL, "Allocation of dwc_otg_dev_if_t failed\n");
1175+ kfree( core_if );
1176+ return 0;
1177+ }
1178+
1179+ dev_if->dev_global_regs =
1180+ (dwc_otg_device_global_regs_t *)(reg_base + DWC_DEV_GLOBAL_REG_OFFSET);
1181+
1182+ for (i=0; i<MAX_EPS_CHANNELS; i++) {
1183+ dev_if->in_ep_regs[i] = (dwc_otg_dev_in_ep_regs_t *)
1184+ (reg_base + DWC_DEV_IN_EP_REG_OFFSET +
1185+ (i * DWC_EP_REG_OFFSET));
1186+
1187+ dev_if->out_ep_regs[i] = (dwc_otg_dev_out_ep_regs_t *)
1188+ (reg_base + DWC_DEV_OUT_EP_REG_OFFSET +
1189+ (i * DWC_EP_REG_OFFSET));
1190+ DWC_DEBUGPL(DBG_CILV, "in_ep_regs[%d]->diepctl=%p\n",
1191+ i, &dev_if->in_ep_regs[i]->diepctl);
1192+ DWC_DEBUGPL(DBG_CILV, "out_ep_regs[%d]->doepctl=%p\n",
1193+ i, &dev_if->out_ep_regs[i]->doepctl);
1194+ }
1195+ dev_if->speed = 0; // unknown
1196+ //dev_if->num_eps = MAX_EPS_CHANNELS;
1197+ //dev_if->num_perio_eps = 0;
1198+
1199+ core_if->dev_if = dev_if;
1200+ /*
1201+ * Allocate the Host Mode structures.
1202+ */
1203+ host_if = kmalloc( sizeof(dwc_otg_host_if_t), GFP_KERNEL);
1204+ if (host_if == 0) {
1205+ DWC_DEBUGPL(DBG_CIL, "Allocation of dwc_otg_host_if_t failed\n");
1206+ kfree( dev_if );
1207+ kfree( core_if );
1208+ return 0;
1209+ }
1210+
1211+ host_if->host_global_regs = (dwc_otg_host_global_regs_t *)
1212+ (reg_base + DWC_OTG_HOST_GLOBAL_REG_OFFSET);
1213+ host_if->hprt0 = (uint32_t*)(reg_base + DWC_OTG_HOST_PORT_REGS_OFFSET);
1214+ for (i=0; i<MAX_EPS_CHANNELS; i++) {
1215+ host_if->hc_regs[i] = (dwc_otg_hc_regs_t *)
1216+ (reg_base + DWC_OTG_HOST_CHAN_REGS_OFFSET +
1217+ (i * DWC_OTG_CHAN_REGS_OFFSET));
1218+ DWC_DEBUGPL(DBG_CILV, "hc_reg[%d]->hcchar=%p\n",
1219+ i, &host_if->hc_regs[i]->hcchar);
1220+ }
1221+ host_if->num_host_channels = MAX_EPS_CHANNELS;
1222+ core_if->host_if = host_if;
1223+
1224+ for (i=0; i<MAX_EPS_CHANNELS; i++) {
1225+ core_if->data_fifo[i] =
1226+ (uint32_t *)(reg_base + DWC_OTG_DATA_FIFO_OFFSET +
1227+ (i * DWC_OTG_DATA_FIFO_SIZE));
1228+ DWC_DEBUGPL(DBG_CILV, "data_fifo[%d]=0x%08x\n",
1229+ i, (unsigned)core_if->data_fifo[i]);
1230+ } // for loop.
1231+
1232+ core_if->pcgcctl = (uint32_t*)(reg_base + DWC_OTG_PCGCCTL_OFFSET);
1233+
1234+ /*
1235+ * Store the contents of the hardware configuration registers here for
1236+ * easy access later.
1237+ */
1238+ core_if->hwcfg1.d32 = dwc_read_reg32(&core_if->core_global_regs->ghwcfg1);
1239+ core_if->hwcfg2.d32 = dwc_read_reg32(&core_if->core_global_regs->ghwcfg2);
1240+ core_if->hwcfg3.d32 = dwc_read_reg32(&core_if->core_global_regs->ghwcfg3);
1241+ core_if->hwcfg4.d32 = dwc_read_reg32(&core_if->core_global_regs->ghwcfg4);
1242+
1243+ DWC_DEBUGPL(DBG_CILV,"hwcfg1=%08x\n",core_if->hwcfg1.d32);
1244+ DWC_DEBUGPL(DBG_CILV,"hwcfg2=%08x\n",core_if->hwcfg2.d32);
1245+ DWC_DEBUGPL(DBG_CILV,"hwcfg3=%08x\n",core_if->hwcfg3.d32);
1246+ DWC_DEBUGPL(DBG_CILV,"hwcfg4=%08x\n",core_if->hwcfg4.d32);
1247+
1248+
1249+ DWC_DEBUGPL(DBG_CILV,"op_mode=%0x\n",core_if->hwcfg2.b.op_mode);
1250+ DWC_DEBUGPL(DBG_CILV,"arch=%0x\n",core_if->hwcfg2.b.architecture);
1251+ DWC_DEBUGPL(DBG_CILV,"num_dev_ep=%d\n",core_if->hwcfg2.b.num_dev_ep);
1252+ DWC_DEBUGPL(DBG_CILV,"num_host_chan=%d\n",core_if->hwcfg2.b.num_host_chan);
1253+ DWC_DEBUGPL(DBG_CILV,"nonperio_tx_q_depth=0x%0x\n",core_if->hwcfg2.b.nonperio_tx_q_depth);
1254+ DWC_DEBUGPL(DBG_CILV,"host_perio_tx_q_depth=0x%0x\n",core_if->hwcfg2.b.host_perio_tx_q_depth);
1255+ DWC_DEBUGPL(DBG_CILV,"dev_token_q_depth=0x%0x\n",core_if->hwcfg2.b.dev_token_q_depth);
1256+
1257+ DWC_DEBUGPL(DBG_CILV,"Total FIFO SZ=%d\n", core_if->hwcfg3.b.dfifo_depth);
1258+ DWC_DEBUGPL(DBG_CILV,"xfer_size_cntr_width=%0x\n", core_if->hwcfg3.b.xfer_size_cntr_width);
1259+
1260+ /*
1261+ * Set the SRP sucess bit for FS-I2c
1262+ */
1263+ core_if->srp_success = 0;
1264+ core_if->srp_timer_started = 0;
1265+
1266+ return core_if;
1267+}
1268+/**
1269+ * This function frees the structures allocated by dwc_otg_cil_init().
1270+ *
1271+ * @param[in] _core_if The core interface pointer returned from
1272+ * dwc_otg_cil_init().
1273+ *
1274+ */
1275+void dwc_otg_cil_remove( dwc_otg_core_if_t *_core_if )
1276+{
1277+ /* Disable all interrupts */
1278+ dwc_modify_reg32( &_core_if->core_global_regs->gahbcfg, 1, 0);
1279+ dwc_write_reg32( &_core_if->core_global_regs->gintmsk, 0);
1280+
1281+ if ( _core_if->dev_if ) {
1282+ kfree( _core_if->dev_if );
1283+ }
1284+ if ( _core_if->host_if ) {
1285+ kfree( _core_if->host_if );
1286+ }
1287+ kfree( _core_if );
1288+}
1289+
1290+/**
1291+ * This function enables the controller's Global Interrupt in the AHB Config
1292+ * register.
1293+ *
1294+ * @param[in] _core_if Programming view of DWC_otg controller.
1295+ */
1296+extern void dwc_otg_enable_global_interrupts( dwc_otg_core_if_t *_core_if )
1297+{
1298+ gahbcfg_data_t ahbcfg = { .d32 = 0};
1299+ ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */
1300+ dwc_modify_reg32(&_core_if->core_global_regs->gahbcfg, 0, ahbcfg.d32);
1301+}
1302+/**
1303+ * This function disables the controller's Global Interrupt in the AHB Config
1304+ * register.
1305+ *
1306+ * @param[in] _core_if Programming view of DWC_otg controller.
1307+ */
1308+extern void dwc_otg_disable_global_interrupts( dwc_otg_core_if_t *_core_if )
1309+{
1310+ gahbcfg_data_t ahbcfg = { .d32 = 0};
1311+ ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */
1312+ dwc_modify_reg32(&_core_if->core_global_regs->gahbcfg, ahbcfg.d32, 0);
1313+}
1314+
1315+/**
1316+ * This function initializes the commmon interrupts, used in both
1317+ * device and host modes.
1318+ *
1319+ * @param[in] _core_if Programming view of the DWC_otg controller
1320+ *
1321+ */
1322+static void dwc_otg_enable_common_interrupts(dwc_otg_core_if_t *_core_if)
1323+{
1324+ dwc_otg_core_global_regs_t *global_regs =
1325+ _core_if->core_global_regs;
1326+ gintmsk_data_t intr_mask = { .d32 = 0};
1327+ /* Clear any pending OTG Interrupts */
1328+ dwc_write_reg32( &global_regs->gotgint, 0xFFFFFFFF);
1329+ /* Clear any pending interrupts */
1330+ dwc_write_reg32( &global_regs->gintsts, 0xFFFFFFFF);
1331+ /*
1332+ * Enable the interrupts in the GINTMSK.
1333+ */
1334+ intr_mask.b.modemismatch = 1;
1335+ intr_mask.b.otgintr = 1;
1336+ if (!_core_if->dma_enable) {
1337+ intr_mask.b.rxstsqlvl = 1;
1338+ }
1339+ intr_mask.b.conidstschng = 1;
1340+ intr_mask.b.wkupintr = 1;
1341+ intr_mask.b.disconnect = 1;
1342+ intr_mask.b.usbsuspend = 1;
1343+ intr_mask.b.sessreqintr = 1;
1344+ dwc_write_reg32( &global_regs->gintmsk, intr_mask.d32);
1345+}
1346+
1347+/**
1348+ * Initializes the FSLSPClkSel field of the HCFG register depending on the PHY
1349+ * type.
1350+ */
1351+static void init_fslspclksel(dwc_otg_core_if_t *_core_if)
1352+{
1353+ uint32_t val;
1354+ hcfg_data_t hcfg;
1355+
1356+ if (((_core_if->hwcfg2.b.hs_phy_type == 2) &&
1357+ (_core_if->hwcfg2.b.fs_phy_type == 1) &&
1358+ (_core_if->core_params->ulpi_fs_ls)) ||
1359+ (_core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS))
1360+ {
1361+ /* Full speed PHY */
1362+ val = DWC_HCFG_48_MHZ;
1363+ } else {
1364+ /* High speed PHY running at full speed or high speed */
1365+ val = DWC_HCFG_30_60_MHZ;
1366+ }
1367+
1368+ DWC_DEBUGPL(DBG_CIL, "Initializing HCFG.FSLSPClkSel to 0x%1x\n", val);
1369+ hcfg.d32 = dwc_read_reg32(&_core_if->host_if->host_global_regs->hcfg);
1370+ hcfg.b.fslspclksel = val;
1371+ dwc_write_reg32(&_core_if->host_if->host_global_regs->hcfg, hcfg.d32);
1372+}
1373+
1374+/**
1375+ * Initializes the DevSpd field of the DCFG register depending on the PHY type
1376+ * and the enumeration speed of the device.
1377+ */
1378+static void init_devspd(dwc_otg_core_if_t *_core_if)
1379+{
1380+ uint32_t val;
1381+ dcfg_data_t dcfg;
1382+
1383+ if (((_core_if->hwcfg2.b.hs_phy_type == 2) &&
1384+ (_core_if->hwcfg2.b.fs_phy_type == 1) &&
1385+ (_core_if->core_params->ulpi_fs_ls)) ||
1386+ (_core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS))
1387+ {
1388+ /* Full speed PHY */
1389+ val = 0x3;
1390+ } else if (_core_if->core_params->speed == DWC_SPEED_PARAM_FULL) {
1391+ /* High speed PHY running at full speed */
1392+ val = 0x1;
1393+ } else {
1394+ /* High speed PHY running at high speed */
1395+ val = 0x0;
1396+ }
1397+
1398+ DWC_DEBUGPL(DBG_CIL, "Initializing DCFG.DevSpd to 0x%1x\n", val);
1399+ dcfg.d32 = dwc_read_reg32(&_core_if->dev_if->dev_global_regs->dcfg);
1400+ dcfg.b.devspd = val;
1401+ dwc_write_reg32(&_core_if->dev_if->dev_global_regs->dcfg, dcfg.d32);
1402+}
1403+
1404+/**
1405+ * This function calculates the number of IN EPS
1406+ * using GHWCFG1 and GHWCFG2 registers values
1407+ *
1408+ * @param _pcd the pcd structure.
1409+ */
1410+static uint32_t calc_num_in_eps(dwc_otg_core_if_t * _core_if)
1411+{
1412+ uint32_t num_in_eps = 0;
1413+ uint32_t num_eps = _core_if->hwcfg2.b.num_dev_ep;
1414+ uint32_t hwcfg1 = _core_if->hwcfg1.d32 >> 2;
1415+ uint32_t num_tx_fifos = _core_if->hwcfg4.b.num_in_eps;
1416+ int i;
1417+ for (i = 0; i < num_eps; ++i) {
1418+ if (!(hwcfg1 & 0x1))
1419+ num_in_eps++;
1420+ hwcfg1 >>= 2;
1421+ }
1422+ if (_core_if->hwcfg4.b.ded_fifo_en) {
1423+ num_in_eps = (num_in_eps > num_tx_fifos) ? num_tx_fifos : num_in_eps;
1424+ }
1425+ return num_in_eps;
1426+}
1427+
1428+
1429+/**
1430+ * This function calculates the number of OUT EPS
1431+ * using GHWCFG1 and GHWCFG2 registers values
1432+ *
1433+ * @param _pcd the pcd structure.
1434+ */
1435+static uint32_t calc_num_out_eps(dwc_otg_core_if_t * _core_if)
1436+{
1437+ uint32_t num_out_eps = 0;
1438+ uint32_t num_eps = _core_if->hwcfg2.b.num_dev_ep;
1439+ uint32_t hwcfg1 = _core_if->hwcfg1.d32 >> 2;
1440+ int i;
1441+ for (i = 0; i < num_eps; ++i) {
1442+ if (!(hwcfg1 & 0x2))
1443+ num_out_eps++;
1444+ hwcfg1 >>= 2;
1445+ }
1446+ return num_out_eps;
1447+}
1448+/**
1449+ * This function initializes the DWC_otg controller registers and
1450+ * prepares the core for device mode or host mode operation.
1451+ *
1452+ * @param _core_if Programming view of the DWC_otg controller
1453+ *
1454+ */
1455+void dwc_otg_core_init(dwc_otg_core_if_t *_core_if)
1456+{
1457+ dwc_otg_core_global_regs_t * global_regs = _core_if->core_global_regs;
1458+ dwc_otg_dev_if_t *dev_if = _core_if->dev_if;
1459+ int i = 0;
1460+ gahbcfg_data_t ahbcfg = { .d32 = 0};
1461+ gusbcfg_data_t usbcfg = { .d32 = 0 };
1462+ gi2cctl_data_t i2cctl = {.d32 = 0};
1463+
1464+ DWC_DEBUGPL(DBG_CILV, "dwc_otg_core_init(%p)\n",_core_if);
1465+
1466+ /* Common Initialization */
1467+
1468+ usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
1469+ DWC_DEBUGPL(DBG_CIL, "USB config register: 0x%08x\n", usbcfg.d32);
1470+
1471+ /* Program the ULPI External VBUS bit if needed */
1472+ //usbcfg.b.ulpi_ext_vbus_drv = 1;
1473+ //usbcfg.b.ulpi_ext_vbus_drv = 0;
1474+ usbcfg.b.ulpi_ext_vbus_drv =
1475+ (_core_if->core_params->phy_ulpi_ext_vbus == DWC_PHY_ULPI_EXTERNAL_VBUS) ? 1 : 0;
1476+
1477+ /* Set external TS Dline pulsing */
1478+ usbcfg.b.term_sel_dl_pulse = (_core_if->core_params->ts_dline == 1) ? 1 : 0;
1479+ dwc_write_reg32 (&global_regs->gusbcfg, usbcfg.d32);
1480+
1481+ /* Reset the Controller */
1482+ dwc_otg_core_reset( _core_if );
1483+
1484+ /* Initialize parameters from Hardware configuration registers. */
1485+#if 0
1486+ dev_if->num_eps = _core_if->hwcfg2.b.num_dev_ep;
1487+ dev_if->num_perio_eps = _core_if->hwcfg4.b.num_dev_perio_in_ep;
1488+#else
1489+ dev_if->num_in_eps = calc_num_in_eps(_core_if);
1490+ dev_if->num_out_eps = calc_num_out_eps(_core_if);
1491+#endif
1492+ DWC_DEBUGPL(DBG_CIL, "num_dev_perio_in_ep=%d\n",
1493+ _core_if->hwcfg4.b.num_dev_perio_in_ep);
1494+ DWC_DEBUGPL(DBG_CIL, "Is power optimization enabled? %s\n",
1495+ _core_if->hwcfg4.b.power_optimiz ? "Yes" : "No");
1496+ DWC_DEBUGPL(DBG_CIL, "vbus_valid filter enabled? %s\n",
1497+ _core_if->hwcfg4.b.vbus_valid_filt_en ? "Yes" : "No");
1498+ DWC_DEBUGPL(DBG_CIL, "iddig filter enabled? %s\n",
1499+ _core_if->hwcfg4.b.iddig_filt_en ? "Yes" : "No");
1500+
1501+ DWC_DEBUGPL(DBG_CIL, "num_dev_perio_in_ep=%d\n",_core_if->hwcfg4.b.num_dev_perio_in_ep);
1502+ for (i=0; i < _core_if->hwcfg4.b.num_dev_perio_in_ep; i++) {
1503+ dev_if->perio_tx_fifo_size[i] =
1504+ dwc_read_reg32(&global_regs->dptxfsiz_dieptxf[i]) >> 16;
1505+ DWC_DEBUGPL(DBG_CIL, "Periodic Tx FIFO SZ #%d=0x%0x\n", i,
1506+ dev_if->perio_tx_fifo_size[i]);
1507+ }
1508+ for (i = 0; i < _core_if->hwcfg4.b.num_in_eps; i++) {
1509+ dev_if->tx_fifo_size[i] =
1510+ dwc_read_reg32(&global_regs->dptxfsiz_dieptxf[i]) >> 16;
1511+ DWC_DEBUGPL(DBG_CIL, "Tx FIFO SZ #%d=0x%0x\n", i,
1512+ dev_if->perio_tx_fifo_size[i]);
1513+ }
1514+
1515+ _core_if->total_fifo_size = _core_if->hwcfg3.b.dfifo_depth;
1516+ _core_if->rx_fifo_size = dwc_read_reg32(&global_regs->grxfsiz);
1517+ _core_if->nperio_tx_fifo_size = dwc_read_reg32(&global_regs->gnptxfsiz) >> 16;
1518+
1519+ DWC_DEBUGPL(DBG_CIL, "Total FIFO SZ=%d\n", _core_if->total_fifo_size);
1520+ DWC_DEBUGPL(DBG_CIL, "Rx FIFO SZ=%d\n", _core_if->rx_fifo_size);
1521+ DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO SZ=%d\n", _core_if->nperio_tx_fifo_size);
1522+
1523+ /* This programming sequence needs to happen in FS mode before any other
1524+ * programming occurs */
1525+ if ((_core_if->core_params->speed == DWC_SPEED_PARAM_FULL) &&
1526+ (_core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
1527+ /* If FS mode with FS PHY */
1528+
1529+ /* core_init() is now called on every switch so only call the
1530+ * following for the first time through. */
1531+ if (!_core_if->phy_init_done) {
1532+ _core_if->phy_init_done = 1;
1533+ DWC_DEBUGPL(DBG_CIL, "FS_PHY detected\n");
1534+ usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
1535+ usbcfg.b.physel = 1;
1536+ dwc_write_reg32 (&global_regs->gusbcfg, usbcfg.d32);
1537+
1538+ /* Reset after a PHY select */
1539+ dwc_otg_core_reset( _core_if );
1540+ }
1541+
1542+ /* Program DCFG.DevSpd or HCFG.FSLSPclkSel to 48Mhz in FS. Also
1543+ * do this on HNP Dev/Host mode switches (done in dev_init and
1544+ * host_init). */
1545+ if (dwc_otg_is_host_mode(_core_if)) {
1546+ DWC_DEBUGPL(DBG_CIL, "host mode\n");
1547+ init_fslspclksel(_core_if);
1548+ } else {
1549+ DWC_DEBUGPL(DBG_CIL, "device mode\n");
1550+ init_devspd(_core_if);
1551+ }
1552+
1553+ if (_core_if->core_params->i2c_enable) {
1554+ DWC_DEBUGPL(DBG_CIL, "FS_PHY Enabling I2c\n");
1555+ /* Program GUSBCFG.OtgUtmifsSel to I2C */
1556+ usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
1557+ usbcfg.b.otgutmifssel = 1;
1558+ dwc_write_reg32 (&global_regs->gusbcfg, usbcfg.d32);
1559+
1560+ /* Program GI2CCTL.I2CEn */
1561+ i2cctl.d32 = dwc_read_reg32(&global_regs->gi2cctl);
1562+ i2cctl.b.i2cdevaddr = 1;
1563+ i2cctl.b.i2cen = 0;
1564+ dwc_write_reg32 (&global_regs->gi2cctl, i2cctl.d32);
1565+ i2cctl.b.i2cen = 1;
1566+ dwc_write_reg32 (&global_regs->gi2cctl, i2cctl.d32);
1567+ }
1568+
1569+ } /* endif speed == DWC_SPEED_PARAM_FULL */
1570+ else {
1571+ /* High speed PHY. */
1572+ if (!_core_if->phy_init_done) {
1573+ _core_if->phy_init_done = 1;
1574+ DWC_DEBUGPL(DBG_CIL, "High spped PHY\n");
1575+ /* HS PHY parameters. These parameters are preserved
1576+ * during soft reset so only program the first time. Do
1577+ * a soft reset immediately after setting phyif. */
1578+ usbcfg.b.ulpi_utmi_sel = _core_if->core_params->phy_type;
1579+ if (usbcfg.b.ulpi_utmi_sel == 2) { // winder
1580+ DWC_DEBUGPL(DBG_CIL, "ULPI\n");
1581+ /* ULPI interface */
1582+ usbcfg.b.phyif = 0;
1583+ usbcfg.b.ddrsel = _core_if->core_params->phy_ulpi_ddr;
1584+ } else {
1585+ /* UTMI+ interface */
1586+ if (_core_if->core_params->phy_utmi_width == 16) {
1587+ usbcfg.b.phyif = 1;
1588+ DWC_DEBUGPL(DBG_CIL, "UTMI+ 16\n");
1589+ } else {
1590+ DWC_DEBUGPL(DBG_CIL, "UTMI+ 8\n");
1591+ usbcfg.b.phyif = 0;
1592+ }
1593+ }
1594+ dwc_write_reg32( &global_regs->gusbcfg, usbcfg.d32);
1595+
1596+ /* Reset after setting the PHY parameters */
1597+ dwc_otg_core_reset( _core_if );
1598+ }
1599+ }
1600+
1601+ if ((_core_if->hwcfg2.b.hs_phy_type == 2) &&
1602+ (_core_if->hwcfg2.b.fs_phy_type == 1) &&
1603+ (_core_if->core_params->ulpi_fs_ls))
1604+ {
1605+ DWC_DEBUGPL(DBG_CIL, "Setting ULPI FSLS\n");
1606+ usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
1607+ usbcfg.b.ulpi_fsls = 1;
1608+ usbcfg.b.ulpi_clk_sus_m = 1;
1609+ dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
1610+ } else {
1611+ DWC_DEBUGPL(DBG_CIL, "Setting ULPI FSLS=0\n");
1612+ usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
1613+ usbcfg.b.ulpi_fsls = 0;
1614+ usbcfg.b.ulpi_clk_sus_m = 0;
1615+ dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
1616+ }
1617+
1618+ /* Program the GAHBCFG Register.*/
1619+ switch (_core_if->hwcfg2.b.architecture){
1620+
1621+ case DWC_SLAVE_ONLY_ARCH:
1622+ DWC_DEBUGPL(DBG_CIL, "Slave Only Mode\n");
1623+ ahbcfg.b.nptxfemplvl_txfemplvl = DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
1624+ ahbcfg.b.ptxfemplvl = DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
1625+ _core_if->dma_enable = 0;
1626+ break;
1627+
1628+ case DWC_EXT_DMA_ARCH:
1629+ DWC_DEBUGPL(DBG_CIL, "External DMA Mode\n");
1630+ ahbcfg.b.hburstlen = _core_if->core_params->dma_burst_size;
1631+ _core_if->dma_enable = (_core_if->core_params->dma_enable != 0);
1632+ break;
1633+
1634+ case DWC_INT_DMA_ARCH:
1635+ DWC_DEBUGPL(DBG_CIL, "Internal DMA Mode\n");
1636+ //ahbcfg.b.hburstlen = DWC_GAHBCFG_INT_DMA_BURST_INCR;
1637+ ahbcfg.b.hburstlen = DWC_GAHBCFG_INT_DMA_BURST_INCR4;
1638+ _core_if->dma_enable = (_core_if->core_params->dma_enable != 0);
1639+ break;
1640+ }
1641+ ahbcfg.b.dmaenable = _core_if->dma_enable;
1642+ dwc_write_reg32(&global_regs->gahbcfg, ahbcfg.d32);
1643+ _core_if->en_multiple_tx_fifo = _core_if->hwcfg4.b.ded_fifo_en;
1644+
1645+ /*
1646+ * Program the GUSBCFG register.
1647+ */
1648+ usbcfg.d32 = dwc_read_reg32( &global_regs->gusbcfg );
1649+
1650+ switch (_core_if->hwcfg2.b.op_mode) {
1651+ case DWC_MODE_HNP_SRP_CAPABLE:
1652+ usbcfg.b.hnpcap = (_core_if->core_params->otg_cap ==
1653+ DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE);
1654+ usbcfg.b.srpcap = (_core_if->core_params->otg_cap !=
1655+ DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
1656+ break;
1657+
1658+ case DWC_MODE_SRP_ONLY_CAPABLE:
1659+ usbcfg.b.hnpcap = 0;
1660+ usbcfg.b.srpcap = (_core_if->core_params->otg_cap !=
1661+ DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
1662+ break;
1663+
1664+ case DWC_MODE_NO_HNP_SRP_CAPABLE:
1665+ usbcfg.b.hnpcap = 0;
1666+ usbcfg.b.srpcap = 0;
1667+ break;
1668+
1669+ case DWC_MODE_SRP_CAPABLE_DEVICE:
1670+ usbcfg.b.hnpcap = 0;
1671+ usbcfg.b.srpcap = (_core_if->core_params->otg_cap !=
1672+ DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
1673+ break;
1674+
1675+ case DWC_MODE_NO_SRP_CAPABLE_DEVICE:
1676+ usbcfg.b.hnpcap = 0;
1677+ usbcfg.b.srpcap = 0;
1678+ break;
1679+
1680+ case DWC_MODE_SRP_CAPABLE_HOST:
1681+ usbcfg.b.hnpcap = 0;
1682+ usbcfg.b.srpcap = (_core_if->core_params->otg_cap !=
1683+ DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
1684+ break;
1685+
1686+ case DWC_MODE_NO_SRP_CAPABLE_HOST:
1687+ usbcfg.b.hnpcap = 0;
1688+ usbcfg.b.srpcap = 0;
1689+ break;
1690+ }
1691+
1692+ dwc_write_reg32( &global_regs->gusbcfg, usbcfg.d32);
1693+
1694+ /* Enable common interrupts */
1695+ dwc_otg_enable_common_interrupts( _core_if );
1696+
1697+ /* Do device or host intialization based on mode during PCD
1698+ * and HCD initialization */
1699+ if (dwc_otg_is_host_mode( _core_if )) {
1700+ DWC_DEBUGPL(DBG_ANY, "Host Mode\n" );
1701+ _core_if->op_state = A_HOST;
1702+ } else {
1703+ DWC_DEBUGPL(DBG_ANY, "Device Mode\n" );
1704+ _core_if->op_state = B_PERIPHERAL;
1705+#ifdef DWC_DEVICE_ONLY
1706+ dwc_otg_core_dev_init( _core_if );
1707+#endif
1708+ }
1709+}
1710+
1711+
1712+/**
1713+ * This function enables the Device mode interrupts.
1714+ *
1715+ * @param _core_if Programming view of DWC_otg controller
1716+ */
1717+void dwc_otg_enable_device_interrupts(dwc_otg_core_if_t *_core_if)
1718+{
1719+ gintmsk_data_t intr_mask = { .d32 = 0};
1720+ dwc_otg_core_global_regs_t * global_regs = _core_if->core_global_regs;
1721+
1722+ DWC_DEBUGPL(DBG_CIL, "%s()\n", __func__);
1723+
1724+ /* Disable all interrupts. */
1725+ dwc_write_reg32( &global_regs->gintmsk, 0);
1726+
1727+ /* Clear any pending interrupts */
1728+ dwc_write_reg32( &global_regs->gintsts, 0xFFFFFFFF);
1729+
1730+ /* Enable the common interrupts */
1731+ dwc_otg_enable_common_interrupts( _core_if );
1732+
1733+ /* Enable interrupts */
1734+ intr_mask.b.usbreset = 1;
1735+ intr_mask.b.enumdone = 1;
1736+ //intr_mask.b.epmismatch = 1;
1737+ intr_mask.b.inepintr = 1;
1738+ intr_mask.b.outepintr = 1;
1739+ intr_mask.b.erlysuspend = 1;
1740+ if (_core_if->en_multiple_tx_fifo == 0) {
1741+ intr_mask.b.epmismatch = 1;
1742+ }
1743+
1744+ /** @todo NGS: Should this be a module parameter? */
1745+ intr_mask.b.isooutdrop = 1;
1746+ intr_mask.b.eopframe = 1;
1747+ intr_mask.b.incomplisoin = 1;
1748+ intr_mask.b.incomplisoout = 1;
1749+
1750+ dwc_modify_reg32( &global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
1751+
1752+ DWC_DEBUGPL(DBG_CIL, "%s() gintmsk=%0x\n", __func__,
1753+ dwc_read_reg32( &global_regs->gintmsk));
1754+}
1755+
1756+/**
1757+ * This function initializes the DWC_otg controller registers for
1758+ * device mode.
1759+ *
1760+ * @param _core_if Programming view of DWC_otg controller
1761+ *
1762+ */
1763+void dwc_otg_core_dev_init(dwc_otg_core_if_t *_core_if)
1764+{
1765+ dwc_otg_core_global_regs_t *global_regs =
1766+ _core_if->core_global_regs;
1767+ dwc_otg_dev_if_t *dev_if = _core_if->dev_if;
1768+ dwc_otg_core_params_t *params = _core_if->core_params;
1769+ dcfg_data_t dcfg = {.d32 = 0};
1770+ grstctl_t resetctl = { .d32=0 };
1771+ int i;
1772+ uint32_t rx_fifo_size;
1773+ fifosize_data_t nptxfifosize;
1774+ fifosize_data_t txfifosize;
1775+ dthrctl_data_t dthrctl;
1776+
1777+ fifosize_data_t ptxfifosize;
1778+
1779+ /* Restart the Phy Clock */
1780+ dwc_write_reg32(_core_if->pcgcctl, 0);
1781+
1782+ /* Device configuration register */
1783+ init_devspd(_core_if);
1784+ dcfg.d32 = dwc_read_reg32( &dev_if->dev_global_regs->dcfg);
1785+ dcfg.b.perfrint = DWC_DCFG_FRAME_INTERVAL_80;
1786+ dwc_write_reg32( &dev_if->dev_global_regs->dcfg, dcfg.d32 );
1787+
1788+ /* Configure data FIFO sizes */
1789+ if ( _core_if->hwcfg2.b.dynamic_fifo && params->enable_dynamic_fifo ) {
1790+
1791+ DWC_DEBUGPL(DBG_CIL, "Total FIFO Size=%d\n", _core_if->total_fifo_size);
1792+ DWC_DEBUGPL(DBG_CIL, "Rx FIFO Size=%d\n", params->dev_rx_fifo_size);
1793+ DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO Size=%d\n", params->dev_nperio_tx_fifo_size);
1794+
1795+ /* Rx FIFO */
1796+ DWC_DEBUGPL(DBG_CIL, "initial grxfsiz=%08x\n",
1797+ dwc_read_reg32(&global_regs->grxfsiz));
1798+ rx_fifo_size = params->dev_rx_fifo_size;
1799+ dwc_write_reg32( &global_regs->grxfsiz, rx_fifo_size );
1800+ DWC_DEBUGPL(DBG_CIL, "new grxfsiz=%08x\n",
1801+ dwc_read_reg32(&global_regs->grxfsiz));
1802+
1803+ /** Set Periodic Tx FIFO Mask all bits 0 */
1804+ _core_if->p_tx_msk = 0;
1805+
1806+ /** Set Tx FIFO Mask all bits 0 */
1807+ _core_if->tx_msk = 0;
1808+ if (_core_if->en_multiple_tx_fifo == 0) {
1809+ /* Non-periodic Tx FIFO */
1810+ DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n",
1811+ dwc_read_reg32(&global_regs->gnptxfsiz));
1812+ nptxfifosize.b.depth = params->dev_nperio_tx_fifo_size;
1813+ nptxfifosize.b.startaddr = params->dev_rx_fifo_size;
1814+ dwc_write_reg32( &global_regs->gnptxfsiz, nptxfifosize.d32 );
1815+ DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",
1816+ dwc_read_reg32(&global_regs->gnptxfsiz));
1817+
1818+
1819+ /**@todo NGS: Fix Periodic FIFO Sizing! */
1820+ /*
1821+ * Periodic Tx FIFOs These FIFOs are numbered from 1 to 15.
1822+ * Indexes of the FIFO size module parameters in the
1823+ * dev_perio_tx_fifo_size array and the FIFO size registers in
1824+ * the dptxfsiz array run from 0 to 14.
1825+ */
1826+ /** @todo Finish debug of this */
1827+ ptxfifosize.b.startaddr =
1828+ nptxfifosize.b.startaddr + nptxfifosize.b.depth;
1829+ for (i = 0; i < _core_if->hwcfg4.b.num_dev_perio_in_ep;i++) {
1830+ ptxfifosize.b.depth = params->dev_perio_tx_fifo_size[i];
1831+ DWC_DEBUGPL(DBG_CIL,"initial dptxfsiz_dieptxf[%d]=%08x\n",
1832+ i,dwc_read_reg32(&global_regs->dptxfsiz_dieptxf[i]));
1833+ dwc_write_reg32(&global_regs->dptxfsiz_dieptxf[i],ptxfifosize.d32);
1834+ DWC_DEBUGPL(DBG_CIL,"new dptxfsiz_dieptxf[%d]=%08x\n",
1835+ i,dwc_read_reg32(&global_regs->dptxfsiz_dieptxf[i]));
1836+ ptxfifosize.b.startaddr += ptxfifosize.b.depth;
1837+ }
1838+ } else {
1839+
1840+ /*
1841+ * Tx FIFOs These FIFOs are numbered from 1 to 15.
1842+ * Indexes of the FIFO size module parameters in the
1843+ * dev_tx_fifo_size array and the FIFO size registers in
1844+ * the dptxfsiz_dieptxf array run from 0 to 14.
1845+ */
1846+
1847+ /* Non-periodic Tx FIFO */
1848+ DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n",
1849+ dwc_read_reg32(&global_regs->gnptxfsiz));
1850+ nptxfifosize.b.depth = params->dev_nperio_tx_fifo_size;
1851+ nptxfifosize.b.startaddr = params->dev_rx_fifo_size;
1852+ dwc_write_reg32(&global_regs->gnptxfsiz, nptxfifosize.d32);
1853+ DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",
1854+ dwc_read_reg32(&global_regs->gnptxfsiz));
1855+ txfifosize.b.startaddr = nptxfifosize.b.startaddr + nptxfifosize.b.depth;
1856+ for (i = 1;i < _core_if->hwcfg4.b.num_dev_perio_in_ep;i++) {
1857+ txfifosize.b.depth = params->dev_tx_fifo_size[i];
1858+ DWC_DEBUGPL(DBG_CIL,"initial dptxfsiz_dieptxf[%d]=%08x\n",
1859+ i,dwc_read_reg32(&global_regs->dptxfsiz_dieptxf[i]));
1860+ dwc_write_reg32(&global_regs->dptxfsiz_dieptxf[i - 1],txfifosize.d32);
1861+ DWC_DEBUGPL(DBG_CIL,"new dptxfsiz_dieptxf[%d]=%08x\n",
1862+ i,dwc_read_reg32(&global_regs->dptxfsiz_dieptxf[i-1]));
1863+ txfifosize.b.startaddr += txfifosize.b.depth;
1864+ }
1865+ }
1866+ }
1867+ /* Flush the FIFOs */
1868+ dwc_otg_flush_tx_fifo(_core_if, 0x10); /* all Tx FIFOs */
1869+ dwc_otg_flush_rx_fifo(_core_if);
1870+
1871+ /* Flush the Learning Queue. */
1872+ resetctl.b.intknqflsh = 1;
1873+ dwc_write_reg32( &_core_if->core_global_regs->grstctl, resetctl.d32);
1874+
1875+ /* Clear all pending Device Interrupts */
1876+ dwc_write_reg32( &dev_if->dev_global_regs->diepmsk, 0 );
1877+ dwc_write_reg32( &dev_if->dev_global_regs->doepmsk, 0 );
1878+ dwc_write_reg32( &dev_if->dev_global_regs->daint, 0xFFFFFFFF );
1879+ dwc_write_reg32( &dev_if->dev_global_regs->daintmsk, 0 );
1880+
1881+ for (i = 0; i <= dev_if->num_in_eps; i++) {
1882+ depctl_data_t depctl;
1883+ depctl.d32 = dwc_read_reg32(&dev_if->in_ep_regs[i]->diepctl);
1884+ if (depctl.b.epena) {
1885+ depctl.d32 = 0;
1886+ depctl.b.epdis = 1;
1887+ depctl.b.snak = 1;
1888+ } else {
1889+ depctl.d32 = 0;
1890+ }
1891+ dwc_write_reg32( &dev_if->in_ep_regs[i]->diepctl, depctl.d32);
1892+
1893+ dwc_write_reg32(&dev_if->in_ep_regs[i]->dieptsiz, 0);
1894+ dwc_write_reg32(&dev_if->in_ep_regs[i]->diepdma, 0);
1895+ dwc_write_reg32(&dev_if->in_ep_regs[i]->diepint, 0xFF);
1896+ }
1897+ for (i = 0; i <= dev_if->num_out_eps; i++) {
1898+ depctl_data_t depctl;
1899+ depctl.d32 = dwc_read_reg32(&dev_if->out_ep_regs[i]->doepctl);
1900+ if (depctl.b.epena) {
1901+ depctl.d32 = 0;
1902+ depctl.b.epdis = 1;
1903+ depctl.b.snak = 1;
1904+ } else {
1905+ depctl.d32 = 0;
1906+ }
1907+ dwc_write_reg32( &dev_if->out_ep_regs[i]->doepctl, depctl.d32);
1908+
1909+ //dwc_write_reg32( &dev_if->in_ep_regs[i]->dieptsiz, 0);
1910+ dwc_write_reg32( &dev_if->out_ep_regs[i]->doeptsiz, 0);
1911+ //dwc_write_reg32( &dev_if->in_ep_regs[i]->diepdma, 0);
1912+ dwc_write_reg32( &dev_if->out_ep_regs[i]->doepdma, 0);
1913+ //dwc_write_reg32( &dev_if->in_ep_regs[i]->diepint, 0xFF);
1914+ dwc_write_reg32( &dev_if->out_ep_regs[i]->doepint, 0xFF);
1915+ }
1916+
1917+ if (_core_if->en_multiple_tx_fifo && _core_if->dma_enable) {
1918+ dev_if->non_iso_tx_thr_en = _core_if->core_params->thr_ctl & 0x1;
1919+ dev_if->iso_tx_thr_en = (_core_if->core_params->thr_ctl >> 1) & 0x1;
1920+ dev_if->rx_thr_en = (_core_if->core_params->thr_ctl >> 2) & 0x1;
1921+ dev_if->rx_thr_length = _core_if->core_params->rx_thr_length;
1922+ dev_if->tx_thr_length = _core_if->core_params->tx_thr_length;
1923+ dthrctl.d32 = 0;
1924+ dthrctl.b.non_iso_thr_en = dev_if->non_iso_tx_thr_en;
1925+ dthrctl.b.iso_thr_en = dev_if->iso_tx_thr_en;
1926+ dthrctl.b.tx_thr_len = dev_if->tx_thr_length;
1927+ dthrctl.b.rx_thr_en = dev_if->rx_thr_en;
1928+ dthrctl.b.rx_thr_len = dev_if->rx_thr_length;
1929+ dwc_write_reg32(&dev_if->dev_global_regs->dtknqr3_dthrctl,dthrctl.d32);
1930+ DWC_DEBUGPL(DBG_CIL, "Non ISO Tx Thr - %d\nISO Tx Thr - %d\n"
1931+ "Rx Thr - %d\nTx Thr Len - %d\nRx Thr Len - %d\n",
1932+ dthrctl.b.non_iso_thr_en, dthrctl.b.iso_thr_en,
1933+ dthrctl.b.rx_thr_en, dthrctl.b.tx_thr_len,
1934+ dthrctl.b.rx_thr_len);
1935+ }
1936+ dwc_otg_enable_device_interrupts( _core_if );
1937+ {
1938+ diepmsk_data_t msk = {.d32 = 0};
1939+ msk.b.txfifoundrn = 1;
1940+ dwc_modify_reg32(&dev_if->dev_global_regs->diepmsk, msk.d32,msk.d32);
1941+}
1942+}
1943+
1944+/**
1945+ * This function enables the Host mode interrupts.
1946+ *
1947+ * @param _core_if Programming view of DWC_otg controller
1948+ */
1949+void dwc_otg_enable_host_interrupts(dwc_otg_core_if_t *_core_if)
1950+{
1951+ dwc_otg_core_global_regs_t *global_regs = _core_if->core_global_regs;
1952+ gintmsk_data_t intr_mask = {.d32 = 0};
1953+
1954+ DWC_DEBUGPL(DBG_CIL, "%s()\n", __func__);
1955+
1956+ /* Disable all interrupts. */
1957+ dwc_write_reg32(&global_regs->gintmsk, 0);
1958+
1959+ /* Clear any pending interrupts. */
1960+ dwc_write_reg32(&global_regs->gintsts, 0xFFFFFFFF);
1961+
1962+ /* Enable the common interrupts */
1963+ dwc_otg_enable_common_interrupts(_core_if);
1964+
1965+ /*
1966+ * Enable host mode interrupts without disturbing common
1967+ * interrupts.
1968+ */
1969+ intr_mask.b.sofintr = 1;
1970+ intr_mask.b.portintr = 1;
1971+ intr_mask.b.hcintr = 1;
1972+
1973+ //dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
1974+ //dwc_modify_reg32(&global_regs->gintmsk, 0, intr_mask.d32);
1975+ dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
1976+}
1977+
1978+/**
1979+ * This function disables the Host Mode interrupts.
1980+ *
1981+ * @param _core_if Programming view of DWC_otg controller
1982+ */
1983+void dwc_otg_disable_host_interrupts(dwc_otg_core_if_t *_core_if)
1984+{
1985+ dwc_otg_core_global_regs_t *global_regs =
1986+ _core_if->core_global_regs;
1987+ gintmsk_data_t intr_mask = {.d32 = 0};
1988+
1989+ DWC_DEBUGPL(DBG_CILV, "%s()\n", __func__);
1990+
1991+ /*
1992+ * Disable host mode interrupts without disturbing common
1993+ * interrupts.
1994+ */
1995+ intr_mask.b.sofintr = 1;
1996+ intr_mask.b.portintr = 1;
1997+ intr_mask.b.hcintr = 1;
1998+ intr_mask.b.ptxfempty = 1;
1999+ intr_mask.b.nptxfempty = 1;
2000+
2001+ dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, 0);
2002+}
2003+
2004+#if 0
2005+/* currently not used, keep it here as if needed later */
2006+static int phy_read(dwc_otg_core_if_t * _core_if, int addr)
2007+{
2008+ u32 val;
2009+ int timeout = 10;
2010+
2011+ dwc_write_reg32(&_core_if->core_global_regs->gpvndctl,
2012+ 0x02000000 | (addr << 16));
2013+ val = dwc_read_reg32(&_core_if->core_global_regs->gpvndctl);
2014+ while (((val & 0x08000000) == 0) && (timeout--)) {
2015+ udelay(1000);
2016+ val = dwc_read_reg32(&_core_if->core_global_regs->gpvndctl);
2017+ }
2018+ val = dwc_read_reg32(&_core_if->core_global_regs->gpvndctl);
2019+ printk("%s: addr=%02x regval=%02x\n", __func__, addr, val & 0x000000ff);
2020+
2021+ return 0;
2022+}
2023+#endif
2024+
2025+/**
2026+ * This function initializes the DWC_otg controller registers for
2027+ * host mode.
2028+ *
2029+ * This function flushes the Tx and Rx FIFOs and it flushes any entries in the
2030+ * request queues. Host channels are reset to ensure that they are ready for
2031+ * performing transfers.
2032+ *
2033+ * @param _core_if Programming view of DWC_otg controller
2034+ *
2035+ */
2036+void dwc_otg_core_host_init(dwc_otg_core_if_t *_core_if)
2037+{
2038+ dwc_otg_core_global_regs_t *global_regs = _core_if->core_global_regs;
2039+ dwc_otg_host_if_t *host_if = _core_if->host_if;
2040+ dwc_otg_core_params_t *params = _core_if->core_params;
2041+ hprt0_data_t hprt0 = {.d32 = 0};
2042+ fifosize_data_t nptxfifosize;
2043+ fifosize_data_t ptxfifosize;
2044+ int i;
2045+ hcchar_data_t hcchar;
2046+ hcfg_data_t hcfg;
2047+ dwc_otg_hc_regs_t *hc_regs;
2048+ int num_channels;
2049+ gotgctl_data_t gotgctl = {.d32 = 0};
2050+
2051+ DWC_DEBUGPL(DBG_CILV,"%s(%p)\n", __func__, _core_if);
2052+
2053+ /* Restart the Phy Clock */
2054+ dwc_write_reg32(_core_if->pcgcctl, 0);
2055+
2056+ /* Initialize Host Configuration Register */
2057+ init_fslspclksel(_core_if);
2058+ if (_core_if->core_params->speed == DWC_SPEED_PARAM_FULL) {
2059+ hcfg.d32 = dwc_read_reg32(&host_if->host_global_regs->hcfg);
2060+ hcfg.b.fslssupp = 1;
2061+ dwc_write_reg32(&host_if->host_global_regs->hcfg, hcfg.d32);
2062+ }
2063+
2064+ /* Configure data FIFO sizes */
2065+ if (_core_if->hwcfg2.b.dynamic_fifo && params->enable_dynamic_fifo) {
2066+ DWC_DEBUGPL(DBG_CIL,"Total FIFO Size=%d\n", _core_if->total_fifo_size);
2067+ DWC_DEBUGPL(DBG_CIL,"Rx FIFO Size=%d\n", params->host_rx_fifo_size);
2068+ DWC_DEBUGPL(DBG_CIL,"NP Tx FIFO Size=%d\n", params->host_nperio_tx_fifo_size);
2069+ DWC_DEBUGPL(DBG_CIL,"P Tx FIFO Size=%d\n", params->host_perio_tx_fifo_size);
2070+
2071+ /* Rx FIFO */
2072+ DWC_DEBUGPL(DBG_CIL,"initial grxfsiz=%08x\n", dwc_read_reg32(&global_regs->grxfsiz));
2073+ dwc_write_reg32(&global_regs->grxfsiz, params->host_rx_fifo_size);
2074+ DWC_DEBUGPL(DBG_CIL,"new grxfsiz=%08x\n", dwc_read_reg32(&global_regs->grxfsiz));
2075+
2076+ /* Non-periodic Tx FIFO */
2077+ DWC_DEBUGPL(DBG_CIL,"initial gnptxfsiz=%08x\n", dwc_read_reg32(&global_regs->gnptxfsiz));
2078+ nptxfifosize.b.depth = params->host_nperio_tx_fifo_size;
2079+ nptxfifosize.b.startaddr = params->host_rx_fifo_size;
2080+ dwc_write_reg32(&global_regs->gnptxfsiz, nptxfifosize.d32);
2081+ DWC_DEBUGPL(DBG_CIL,"new gnptxfsiz=%08x\n", dwc_read_reg32(&global_regs->gnptxfsiz));
2082+
2083+ /* Periodic Tx FIFO */
2084+ DWC_DEBUGPL(DBG_CIL,"initial hptxfsiz=%08x\n", dwc_read_reg32(&global_regs->hptxfsiz));
2085+ ptxfifosize.b.depth = params->host_perio_tx_fifo_size;
2086+ ptxfifosize.b.startaddr = nptxfifosize.b.startaddr + nptxfifosize.b.depth;
2087+ dwc_write_reg32(&global_regs->hptxfsiz, ptxfifosize.d32);
2088+ DWC_DEBUGPL(DBG_CIL,"new hptxfsiz=%08x\n", dwc_read_reg32(&global_regs->hptxfsiz));
2089+ }
2090+
2091+ /* Clear Host Set HNP Enable in the OTG Control Register */
2092+ gotgctl.b.hstsethnpen = 1;
2093+ dwc_modify_reg32( &global_regs->gotgctl, gotgctl.d32, 0);
2094+
2095+ /* Make sure the FIFOs are flushed. */
2096+ dwc_otg_flush_tx_fifo(_core_if, 0x10 /* all Tx FIFOs */);
2097+ dwc_otg_flush_rx_fifo(_core_if);
2098+
2099+ /* Flush out any leftover queued requests. */
2100+ num_channels = _core_if->core_params->host_channels;
2101+ for (i = 0; i < num_channels; i++) {
2102+ hc_regs = _core_if->host_if->hc_regs[i];
2103+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
2104+ hcchar.b.chen = 0;
2105+ hcchar.b.chdis = 1;
2106+ hcchar.b.epdir = 0;
2107+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
2108+ }
2109+
2110+ /* Halt all channels to put them into a known state. */
2111+ for (i = 0; i < num_channels; i++) {
2112+ int count = 0;
2113+ hc_regs = _core_if->host_if->hc_regs[i];
2114+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
2115+ hcchar.b.chen = 1;
2116+ hcchar.b.chdis = 1;
2117+ hcchar.b.epdir = 0;
2118+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
2119+ DWC_DEBUGPL(DBG_HCDV, "%s: Halt channel %d\n", __func__, i);
2120+ do {
2121+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
2122+ if (++count > 200) {
2123+ DWC_ERROR("%s: Unable to clear halt on channel %d\n",
2124+ __func__, i);
2125+ break;
2126+ }
2127+ udelay(100);
2128+ } while (hcchar.b.chen);
2129+ }
2130+
2131+ /* Turn on the vbus power. */
2132+ DWC_PRINT("Init: Port Power? op_state=%d\n", _core_if->op_state);
2133+ if (_core_if->op_state == A_HOST){
2134+ hprt0.d32 = dwc_otg_read_hprt0(_core_if);
2135+ DWC_PRINT("Init: Power Port (%d)\n", hprt0.b.prtpwr);
2136+ if (hprt0.b.prtpwr == 0 ) {
2137+ hprt0.b.prtpwr = 1;
2138+ dwc_write_reg32(host_if->hprt0, hprt0.d32);
2139+ }
2140+ }
2141+
2142+ dwc_otg_enable_host_interrupts( _core_if );
2143+}
2144+
2145+/**
2146+ * Prepares a host channel for transferring packets to/from a specific
2147+ * endpoint. The HCCHARn register is set up with the characteristics specified
2148+ * in _hc. Host channel interrupts that may need to be serviced while this
2149+ * transfer is in progress are enabled.
2150+ *
2151+ * @param _core_if Programming view of DWC_otg controller
2152+ * @param _hc Information needed to initialize the host channel
2153+ */
2154+void dwc_otg_hc_init(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc)
2155+{
2156+ uint32_t intr_enable;
2157+ hcintmsk_data_t hc_intr_mask;
2158+ gintmsk_data_t gintmsk = {.d32 = 0};
2159+ hcchar_data_t hcchar;
2160+ hcsplt_data_t hcsplt;
2161+
2162+ uint8_t hc_num = _hc->hc_num;
2163+ dwc_otg_host_if_t *host_if = _core_if->host_if;
2164+ dwc_otg_hc_regs_t *hc_regs = host_if->hc_regs[hc_num];
2165+
2166+ /* Clear old interrupt conditions for this host channel. */
2167+ hc_intr_mask.d32 = 0xFFFFFFFF;
2168+ hc_intr_mask.b.reserved = 0;
2169+ dwc_write_reg32(&hc_regs->hcint, hc_intr_mask.d32);
2170+
2171+ /* Enable channel interrupts required for this transfer. */
2172+ hc_intr_mask.d32 = 0;
2173+ hc_intr_mask.b.chhltd = 1;
2174+ if (_core_if->dma_enable) {
2175+ hc_intr_mask.b.ahberr = 1;
2176+ if (_hc->error_state && !_hc->do_split &&
2177+ _hc->ep_type != DWC_OTG_EP_TYPE_ISOC) {
2178+ hc_intr_mask.b.ack = 1;
2179+ if (_hc->ep_is_in) {
2180+ hc_intr_mask.b.datatglerr = 1;
2181+ if (_hc->ep_type != DWC_OTG_EP_TYPE_INTR) {
2182+ hc_intr_mask.b.nak = 1;
2183+ }
2184+ }
2185+ }
2186+ } else {
2187+ switch (_hc->ep_type) {
2188+ case DWC_OTG_EP_TYPE_CONTROL:
2189+ case DWC_OTG_EP_TYPE_BULK:
2190+ hc_intr_mask.b.xfercompl = 1;
2191+ hc_intr_mask.b.stall = 1;
2192+ hc_intr_mask.b.xacterr = 1;
2193+ hc_intr_mask.b.datatglerr = 1;
2194+ if (_hc->ep_is_in) {
2195+ hc_intr_mask.b.bblerr = 1;
2196+ } else {
2197+ hc_intr_mask.b.nak = 1;
2198+ hc_intr_mask.b.nyet = 1;
2199+ if (_hc->do_ping) {
2200+ hc_intr_mask.b.ack = 1;
2201+ }
2202+ }
2203+
2204+ if (_hc->do_split) {
2205+ hc_intr_mask.b.nak = 1;
2206+ if (_hc->complete_split) {
2207+ hc_intr_mask.b.nyet = 1;
2208+ }
2209+ else {
2210+ hc_intr_mask.b.ack = 1;
2211+ }
2212+ }
2213+
2214+ if (_hc->error_state) {
2215+ hc_intr_mask.b.ack = 1;
2216+ }
2217+ break;
2218+ case DWC_OTG_EP_TYPE_INTR:
2219+ hc_intr_mask.b.xfercompl = 1;
2220+ hc_intr_mask.b.nak = 1;
2221+ hc_intr_mask.b.stall = 1;
2222+ hc_intr_mask.b.xacterr = 1;
2223+ hc_intr_mask.b.datatglerr = 1;
2224+ hc_intr_mask.b.frmovrun = 1;
2225+
2226+ if (_hc->ep_is_in) {
2227+ hc_intr_mask.b.bblerr = 1;
2228+ }
2229+ if (_hc->error_state) {
2230+ hc_intr_mask.b.ack = 1;
2231+ }
2232+ if (_hc->do_split) {
2233+ if (_hc->complete_split) {
2234+ hc_intr_mask.b.nyet = 1;
2235+ }
2236+ else {
2237+ hc_intr_mask.b.ack = 1;
2238+ }
2239+ }
2240+ break;
2241+ case DWC_OTG_EP_TYPE_ISOC:
2242+ hc_intr_mask.b.xfercompl = 1;
2243+ hc_intr_mask.b.frmovrun = 1;
2244+ hc_intr_mask.b.ack = 1;
2245+
2246+ if (_hc->ep_is_in) {
2247+ hc_intr_mask.b.xacterr = 1;
2248+ hc_intr_mask.b.bblerr = 1;
2249+ }
2250+ break;
2251+ }
2252+ }
2253+ dwc_write_reg32(&hc_regs->hcintmsk, hc_intr_mask.d32);
2254+
2255+ /* Enable the top level host channel interrupt. */
2256+ intr_enable = (1 << hc_num);
2257+ dwc_modify_reg32(&host_if->host_global_regs->haintmsk, 0, intr_enable);
2258+
2259+ /* Make sure host channel interrupts are enabled. */
2260+ gintmsk.b.hcintr = 1;
2261+ dwc_modify_reg32(&_core_if->core_global_regs->gintmsk, 0, gintmsk.d32);
2262+
2263+ /*
2264+ * Program the HCCHARn register with the endpoint characteristics for
2265+ * the current transfer.
2266+ */
2267+ hcchar.d32 = 0;
2268+ hcchar.b.devaddr = _hc->dev_addr;
2269+ hcchar.b.epnum = _hc->ep_num;
2270+ hcchar.b.epdir = _hc->ep_is_in;
2271+ hcchar.b.lspddev = (_hc->speed == DWC_OTG_EP_SPEED_LOW);
2272+ hcchar.b.eptype = _hc->ep_type;
2273+ hcchar.b.mps = _hc->max_packet;
2274+
2275+ dwc_write_reg32(&host_if->hc_regs[hc_num]->hcchar, hcchar.d32);
2276+
2277+ DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, _hc->hc_num);
2278+ DWC_DEBUGPL(DBG_HCDV, " Dev Addr: %d\n", hcchar.b.devaddr);
2279+ DWC_DEBUGPL(DBG_HCDV, " Ep Num: %d\n", hcchar.b.epnum);
2280+ DWC_DEBUGPL(DBG_HCDV, " Is In: %d\n", hcchar.b.epdir);
2281+ DWC_DEBUGPL(DBG_HCDV, " Is Low Speed: %d\n", hcchar.b.lspddev);
2282+ DWC_DEBUGPL(DBG_HCDV, " Ep Type: %d\n", hcchar.b.eptype);
2283+ DWC_DEBUGPL(DBG_HCDV, " Max Pkt: %d\n", hcchar.b.mps);
2284+ DWC_DEBUGPL(DBG_HCDV, " Multi Cnt: %d\n", hcchar.b.multicnt);
2285+
2286+ /*
2287+ * Program the HCSPLIT register for SPLITs
2288+ */
2289+ hcsplt.d32 = 0;
2290+ if (_hc->do_split) {
2291+ DWC_DEBUGPL(DBG_HCDV, "Programming HC %d with split --> %s\n", _hc->hc_num,
2292+ _hc->complete_split ? "CSPLIT" : "SSPLIT");
2293+ hcsplt.b.compsplt = _hc->complete_split;
2294+ hcsplt.b.xactpos = _hc->xact_pos;
2295+ hcsplt.b.hubaddr = _hc->hub_addr;
2296+ hcsplt.b.prtaddr = _hc->port_addr;
2297+ DWC_DEBUGPL(DBG_HCDV, " comp split %d\n", _hc->complete_split);
2298+ DWC_DEBUGPL(DBG_HCDV, " xact pos %d\n", _hc->xact_pos);
2299+ DWC_DEBUGPL(DBG_HCDV, " hub addr %d\n", _hc->hub_addr);
2300+ DWC_DEBUGPL(DBG_HCDV, " port addr %d\n", _hc->port_addr);
2301+ DWC_DEBUGPL(DBG_HCDV, " is_in %d\n", _hc->ep_is_in);
2302+ DWC_DEBUGPL(DBG_HCDV, " Max Pkt: %d\n", hcchar.b.mps);
2303+ DWC_DEBUGPL(DBG_HCDV, " xferlen: %d\n", _hc->xfer_len);
2304+ }
2305+ dwc_write_reg32(&host_if->hc_regs[hc_num]->hcsplt, hcsplt.d32);
2306+
2307+}
2308+
2309+/**
2310+ * Attempts to halt a host channel. This function should only be called in
2311+ * Slave mode or to abort a transfer in either Slave mode or DMA mode. Under
2312+ * normal circumstances in DMA mode, the controller halts the channel when the
2313+ * transfer is complete or a condition occurs that requires application
2314+ * intervention.
2315+ *
2316+ * In slave mode, checks for a free request queue entry, then sets the Channel
2317+ * Enable and Channel Disable bits of the Host Channel Characteristics
2318+ * register of the specified channel to intiate the halt. If there is no free
2319+ * request queue entry, sets only the Channel Disable bit of the HCCHARn
2320+ * register to flush requests for this channel. In the latter case, sets a
2321+ * flag to indicate that the host channel needs to be halted when a request
2322+ * queue slot is open.
2323+ *
2324+ * In DMA mode, always sets the Channel Enable and Channel Disable bits of the
2325+ * HCCHARn register. The controller ensures there is space in the request
2326+ * queue before submitting the halt request.
2327+ *
2328+ * Some time may elapse before the core flushes any posted requests for this
2329+ * host channel and halts. The Channel Halted interrupt handler completes the
2330+ * deactivation of the host channel.
2331+ *
2332+ * @param _core_if Controller register interface.
2333+ * @param _hc Host channel to halt.
2334+ * @param _halt_status Reason for halting the channel.
2335+ */
2336+void dwc_otg_hc_halt(dwc_otg_core_if_t *_core_if,
2337+ dwc_hc_t *_hc,
2338+ dwc_otg_halt_status_e _halt_status)
2339+{
2340+ gnptxsts_data_t nptxsts;
2341+ hptxsts_data_t hptxsts;
2342+ hcchar_data_t hcchar;
2343+ dwc_otg_hc_regs_t *hc_regs;
2344+ dwc_otg_core_global_regs_t *global_regs;
2345+ dwc_otg_host_global_regs_t *host_global_regs;
2346+
2347+ hc_regs = _core_if->host_if->hc_regs[_hc->hc_num];
2348+ global_regs = _core_if->core_global_regs;
2349+ host_global_regs = _core_if->host_if->host_global_regs;
2350+
2351+ WARN_ON(_halt_status == DWC_OTG_HC_XFER_NO_HALT_STATUS);
2352+
2353+ if (_halt_status == DWC_OTG_HC_XFER_URB_DEQUEUE ||
2354+ _halt_status == DWC_OTG_HC_XFER_AHB_ERR) {
2355+ /*
2356+ * Disable all channel interrupts except Ch Halted. The QTD
2357+ * and QH state associated with this transfer has been cleared
2358+ * (in the case of URB_DEQUEUE), so the channel needs to be
2359+ * shut down carefully to prevent crashes.
2360+ */
2361+ hcintmsk_data_t hcintmsk;
2362+ hcintmsk.d32 = 0;
2363+ hcintmsk.b.chhltd = 1;
2364+ dwc_write_reg32(&hc_regs->hcintmsk, hcintmsk.d32);
2365+
2366+ /*
2367+ * Make sure no other interrupts besides halt are currently
2368+ * pending. Handling another interrupt could cause a crash due
2369+ * to the QTD and QH state.
2370+ */
2371+ dwc_write_reg32(&hc_regs->hcint, ~hcintmsk.d32);
2372+
2373+ /*
2374+ * Make sure the halt status is set to URB_DEQUEUE or AHB_ERR
2375+ * even if the channel was already halted for some other
2376+ * reason.
2377+ */
2378+ _hc->halt_status = _halt_status;
2379+
2380+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
2381+ if (hcchar.b.chen == 0) {
2382+ /*
2383+ * The channel is either already halted or it hasn't
2384+ * started yet. In DMA mode, the transfer may halt if
2385+ * it finishes normally or a condition occurs that
2386+ * requires driver intervention. Don't want to halt
2387+ * the channel again. In either Slave or DMA mode,
2388+ * it's possible that the transfer has been assigned
2389+ * to a channel, but not started yet when an URB is
2390+ * dequeued. Don't want to halt a channel that hasn't
2391+ * started yet.
2392+ */
2393+ return;
2394+ }
2395+ }
2396+
2397+ if (_hc->halt_pending) {
2398+ /*
2399+ * A halt has already been issued for this channel. This might
2400+ * happen when a transfer is aborted by a higher level in
2401+ * the stack.
2402+ */
2403+#ifdef DEBUG
2404+ DWC_PRINT("*** %s: Channel %d, _hc->halt_pending already set ***\n",
2405+ __func__, _hc->hc_num);
2406+
2407+/* dwc_otg_dump_global_registers(_core_if); */
2408+/* dwc_otg_dump_host_registers(_core_if); */
2409+#endif
2410+ return;
2411+ }
2412+
2413+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
2414+ hcchar.b.chen = 1;
2415+ hcchar.b.chdis = 1;
2416+
2417+ if (!_core_if->dma_enable) {
2418+ /* Check for space in the request queue to issue the halt. */
2419+ if (_hc->ep_type == DWC_OTG_EP_TYPE_CONTROL ||
2420+ _hc->ep_type == DWC_OTG_EP_TYPE_BULK) {
2421+ nptxsts.d32 = dwc_read_reg32(&global_regs->gnptxsts);
2422+ if (nptxsts.b.nptxqspcavail == 0) {
2423+ hcchar.b.chen = 0;
2424+ }
2425+ } else {
2426+ hptxsts.d32 = dwc_read_reg32(&host_global_regs->hptxsts);
2427+ if ((hptxsts.b.ptxqspcavail == 0) || (_core_if->queuing_high_bandwidth)) {
2428+ hcchar.b.chen = 0;
2429+ }
2430+ }
2431+ }
2432+
2433+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
2434+
2435+ _hc->halt_status = _halt_status;
2436+
2437+ if (hcchar.b.chen) {
2438+ _hc->halt_pending = 1;
2439+ _hc->halt_on_queue = 0;
2440+ } else {
2441+ _hc->halt_on_queue = 1;
2442+ }
2443+
2444+ DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, _hc->hc_num);
2445+ DWC_DEBUGPL(DBG_HCDV, " hcchar: 0x%08x\n", hcchar.d32);
2446+ DWC_DEBUGPL(DBG_HCDV, " halt_pending: %d\n", _hc->halt_pending);
2447+ DWC_DEBUGPL(DBG_HCDV, " halt_on_queue: %d\n", _hc->halt_on_queue);
2448+ DWC_DEBUGPL(DBG_HCDV, " halt_status: %d\n", _hc->halt_status);
2449+
2450+ return;
2451+}
2452+
2453+/**
2454+ * Clears the transfer state for a host channel. This function is normally
2455+ * called after a transfer is done and the host channel is being released.
2456+ *
2457+ * @param _core_if Programming view of DWC_otg controller.
2458+ * @param _hc Identifies the host channel to clean up.
2459+ */
2460+void dwc_otg_hc_cleanup(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc)
2461+{
2462+ dwc_otg_hc_regs_t *hc_regs;
2463+
2464+ _hc->xfer_started = 0;
2465+
2466+ /*
2467+ * Clear channel interrupt enables and any unhandled channel interrupt
2468+ * conditions.
2469+ */
2470+ hc_regs = _core_if->host_if->hc_regs[_hc->hc_num];
2471+ dwc_write_reg32(&hc_regs->hcintmsk, 0);
2472+ dwc_write_reg32(&hc_regs->hcint, 0xFFFFFFFF);
2473+
2474+#ifdef DEBUG
2475+ del_timer(&_core_if->hc_xfer_timer[_hc->hc_num]);
2476+ {
2477+ hcchar_data_t hcchar;
2478+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
2479+ if (hcchar.b.chdis) {
2480+ DWC_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n",
2481+ __func__, _hc->hc_num, hcchar.d32);
2482+ }
2483+ }
2484+#endif
2485+}
2486+
2487+/**
2488+ * Sets the channel property that indicates in which frame a periodic transfer
2489+ * should occur. This is always set to the _next_ frame. This function has no
2490+ * effect on non-periodic transfers.
2491+ *
2492+ * @param _core_if Programming view of DWC_otg controller.
2493+ * @param _hc Identifies the host channel to set up and its properties.
2494+ * @param _hcchar Current value of the HCCHAR register for the specified host
2495+ * channel.
2496+ */
2497+static inline void hc_set_even_odd_frame(dwc_otg_core_if_t *_core_if,
2498+ dwc_hc_t *_hc,
2499+ hcchar_data_t *_hcchar)
2500+{
2501+ if (_hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
2502+ _hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
2503+ hfnum_data_t hfnum;
2504+ hfnum.d32 = dwc_read_reg32(&_core_if->host_if->host_global_regs->hfnum);
2505+ /* 1 if _next_ frame is odd, 0 if it's even */
2506+ _hcchar->b.oddfrm = (hfnum.b.frnum & 0x1) ? 0 : 1;
2507+#ifdef DEBUG
2508+ if (_hc->ep_type == DWC_OTG_EP_TYPE_INTR && _hc->do_split && !_hc->complete_split) {
2509+ switch (hfnum.b.frnum & 0x7) {
2510+ case 7:
2511+ _core_if->hfnum_7_samples++;
2512+ _core_if->hfnum_7_frrem_accum += hfnum.b.frrem;
2513+ break;
2514+ case 0:
2515+ _core_if->hfnum_0_samples++;
2516+ _core_if->hfnum_0_frrem_accum += hfnum.b.frrem;
2517+ break;
2518+ default:
2519+ _core_if->hfnum_other_samples++;
2520+ _core_if->hfnum_other_frrem_accum += hfnum.b.frrem;
2521+ break;
2522+ }
2523+ }
2524+#endif
2525+ }
2526+}
2527+
2528+#ifdef DEBUG
2529+static void hc_xfer_timeout(unsigned long _ptr)
2530+{
2531+ hc_xfer_info_t *xfer_info = (hc_xfer_info_t *)_ptr;
2532+ int hc_num = xfer_info->hc->hc_num;
2533+ DWC_WARN("%s: timeout on channel %d\n", __func__, hc_num);
2534+ DWC_WARN(" start_hcchar_val 0x%08x\n", xfer_info->core_if->start_hcchar_val[hc_num]);
2535+}
2536+#endif
2537+
2538+/*
2539+ * This function does the setup for a data transfer for a host channel and
2540+ * starts the transfer. May be called in either Slave mode or DMA mode. In
2541+ * Slave mode, the caller must ensure that there is sufficient space in the
2542+ * request queue and Tx Data FIFO.
2543+ *
2544+ * For an OUT transfer in Slave mode, it loads a data packet into the
2545+ * appropriate FIFO. If necessary, additional data packets will be loaded in
2546+ * the Host ISR.
2547+ *
2548+ * For an IN transfer in Slave mode, a data packet is requested. The data
2549+ * packets are unloaded from the Rx FIFO in the Host ISR. If necessary,
2550+ * additional data packets are requested in the Host ISR.
2551+ *
2552+ * For a PING transfer in Slave mode, the Do Ping bit is set in the HCTSIZ
2553+ * register along with a packet count of 1 and the channel is enabled. This
2554+ * causes a single PING transaction to occur. Other fields in HCTSIZ are
2555+ * simply set to 0 since no data transfer occurs in this case.
2556+ *
2557+ * For a PING transfer in DMA mode, the HCTSIZ register is initialized with
2558+ * all the information required to perform the subsequent data transfer. In
2559+ * addition, the Do Ping bit is set in the HCTSIZ register. In this case, the
2560+ * controller performs the entire PING protocol, then starts the data
2561+ * transfer.
2562+ *
2563+ * @param _core_if Programming view of DWC_otg controller.
2564+ * @param _hc Information needed to initialize the host channel. The xfer_len
2565+ * value may be reduced to accommodate the max widths of the XferSize and
2566+ * PktCnt fields in the HCTSIZn register. The multi_count value may be changed
2567+ * to reflect the final xfer_len value.
2568+ */
2569+void dwc_otg_hc_start_transfer(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc)
2570+{
2571+ hcchar_data_t hcchar;
2572+ hctsiz_data_t hctsiz;
2573+ uint16_t num_packets;
2574+ uint32_t max_hc_xfer_size = _core_if->core_params->max_transfer_size;
2575+ uint16_t max_hc_pkt_count = _core_if->core_params->max_packet_count;
2576+ dwc_otg_hc_regs_t *hc_regs = _core_if->host_if->hc_regs[_hc->hc_num];
2577+
2578+ hctsiz.d32 = 0;
2579+
2580+ if (_hc->do_ping) {
2581+ if (!_core_if->dma_enable) {
2582+ dwc_otg_hc_do_ping(_core_if, _hc);
2583+ _hc->xfer_started = 1;
2584+ return;
2585+ } else {
2586+ hctsiz.b.dopng = 1;
2587+ }
2588+ }
2589+
2590+ if (_hc->do_split) {
2591+ num_packets = 1;
2592+
2593+ if (_hc->complete_split && !_hc->ep_is_in) {
2594+ /* For CSPLIT OUT Transfer, set the size to 0 so the
2595+ * core doesn't expect any data written to the FIFO */
2596+ _hc->xfer_len = 0;
2597+ } else if (_hc->ep_is_in || (_hc->xfer_len > _hc->max_packet)) {
2598+ _hc->xfer_len = _hc->max_packet;
2599+ } else if (!_hc->ep_is_in && (_hc->xfer_len > 188)) {
2600+ _hc->xfer_len = 188;
2601+ }
2602+
2603+ hctsiz.b.xfersize = _hc->xfer_len;
2604+ } else {
2605+ /*
2606+ * Ensure that the transfer length and packet count will fit
2607+ * in the widths allocated for them in the HCTSIZn register.
2608+ */
2609+ if (_hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
2610+ _hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
2611+ /*
2612+ * Make sure the transfer size is no larger than one
2613+ * (micro)frame's worth of data. (A check was done
2614+ * when the periodic transfer was accepted to ensure
2615+ * that a (micro)frame's worth of data can be
2616+ * programmed into a channel.)
2617+ */
2618+ uint32_t max_periodic_len = _hc->multi_count * _hc->max_packet;
2619+ if (_hc->xfer_len > max_periodic_len) {
2620+ _hc->xfer_len = max_periodic_len;
2621+ } else {
2622+ }
2623+ } else if (_hc->xfer_len > max_hc_xfer_size) {
2624+ /* Make sure that xfer_len is a multiple of max packet size. */
2625+ _hc->xfer_len = max_hc_xfer_size - _hc->max_packet + 1;
2626+ }
2627+
2628+ if (_hc->xfer_len > 0) {
2629+ num_packets = (_hc->xfer_len + _hc->max_packet - 1) / _hc->max_packet;
2630+ if (num_packets > max_hc_pkt_count) {
2631+ num_packets = max_hc_pkt_count;
2632+ _hc->xfer_len = num_packets * _hc->max_packet;
2633+ }
2634+ } else {
2635+ /* Need 1 packet for transfer length of 0. */
2636+ num_packets = 1;
2637+ }
2638+
2639+ if (_hc->ep_is_in) {
2640+ /* Always program an integral # of max packets for IN transfers. */
2641+ _hc->xfer_len = num_packets * _hc->max_packet;
2642+ }
2643+
2644+ if (_hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
2645+ _hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
2646+ /*
2647+ * Make sure that the multi_count field matches the
2648+ * actual transfer length.
2649+ */
2650+ _hc->multi_count = num_packets;
2651+
2652+ }
2653+
2654+ if (_hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
2655+ /* Set up the initial PID for the transfer. */
2656+ if (_hc->speed == DWC_OTG_EP_SPEED_HIGH) {
2657+ if (_hc->ep_is_in) {
2658+ if (_hc->multi_count == 1) {
2659+ _hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
2660+ } else if (_hc->multi_count == 2) {
2661+ _hc->data_pid_start = DWC_OTG_HC_PID_DATA1;
2662+ } else {
2663+ _hc->data_pid_start = DWC_OTG_HC_PID_DATA2;
2664+ }
2665+ } else {
2666+ if (_hc->multi_count == 1) {
2667+ _hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
2668+ } else {
2669+ _hc->data_pid_start = DWC_OTG_HC_PID_MDATA;
2670+ }
2671+ }
2672+ } else {
2673+ _hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
2674+ }
2675+ }
2676+
2677+ hctsiz.b.xfersize = _hc->xfer_len;
2678+ }
2679+
2680+ _hc->start_pkt_count = num_packets;
2681+ hctsiz.b.pktcnt = num_packets;
2682+ hctsiz.b.pid = _hc->data_pid_start;
2683+ dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
2684+
2685+ DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, _hc->hc_num);
2686+ DWC_DEBUGPL(DBG_HCDV, " Xfer Size: %d\n", hctsiz.b.xfersize);
2687+ DWC_DEBUGPL(DBG_HCDV, " Num Pkts: %d\n", hctsiz.b.pktcnt);
2688+ DWC_DEBUGPL(DBG_HCDV, " Start PID: %d\n", hctsiz.b.pid);
2689+
2690+ if (_core_if->dma_enable) {
2691+#ifdef DEBUG
2692+if(((uint32_t)_hc->xfer_buff)%4)
2693+printk("dwc_otg_hc_start_transfer _hc->xfer_buff not 4 byte alignment\n");
2694+#endif
2695+ dwc_write_reg32(&hc_regs->hcdma, (uint32_t)_hc->xfer_buff);
2696+ }
2697+
2698+ /* Start the split */
2699+ if (_hc->do_split) {
2700+ hcsplt_data_t hcsplt;
2701+ hcsplt.d32 = dwc_read_reg32 (&hc_regs->hcsplt);
2702+ hcsplt.b.spltena = 1;
2703+ dwc_write_reg32(&hc_regs->hcsplt, hcsplt.d32);
2704+ }
2705+
2706+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
2707+ hcchar.b.multicnt = _hc->multi_count;
2708+ hc_set_even_odd_frame(_core_if, _hc, &hcchar);
2709+#ifdef DEBUG
2710+ _core_if->start_hcchar_val[_hc->hc_num] = hcchar.d32;
2711+ if (hcchar.b.chdis) {
2712+ DWC_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n",
2713+ __func__, _hc->hc_num, hcchar.d32);
2714+ }
2715+#endif
2716+
2717+ /* Set host channel enable after all other setup is complete. */
2718+ hcchar.b.chen = 1;
2719+ hcchar.b.chdis = 0;
2720+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
2721+
2722+ _hc->xfer_started = 1;
2723+ _hc->requests++;
2724+
2725+ if (!_core_if->dma_enable && !_hc->ep_is_in && _hc->xfer_len > 0) {
2726+ /* Load OUT packet into the appropriate Tx FIFO. */
2727+ dwc_otg_hc_write_packet(_core_if, _hc);
2728+ }
2729+
2730+#ifdef DEBUG
2731+ /* Start a timer for this transfer. */
2732+ _core_if->hc_xfer_timer[_hc->hc_num].function = hc_xfer_timeout;
2733+ _core_if->hc_xfer_info[_hc->hc_num].core_if = _core_if;
2734+ _core_if->hc_xfer_info[_hc->hc_num].hc = _hc;
2735+ _core_if->hc_xfer_timer[_hc->hc_num].data = (unsigned long)(&_core_if->hc_xfer_info[_hc->hc_num]);
2736+ _core_if->hc_xfer_timer[_hc->hc_num].expires = jiffies + (HZ*10);
2737+ add_timer(&_core_if->hc_xfer_timer[_hc->hc_num]);
2738+#endif
2739+}
2740+
2741+/**
2742+ * This function continues a data transfer that was started by previous call
2743+ * to <code>dwc_otg_hc_start_transfer</code>. The caller must ensure there is
2744+ * sufficient space in the request queue and Tx Data FIFO. This function
2745+ * should only be called in Slave mode. In DMA mode, the controller acts
2746+ * autonomously to complete transfers programmed to a host channel.
2747+ *
2748+ * For an OUT transfer, a new data packet is loaded into the appropriate FIFO
2749+ * if there is any data remaining to be queued. For an IN transfer, another
2750+ * data packet is always requested. For the SETUP phase of a control transfer,
2751+ * this function does nothing.
2752+ *
2753+ * @return 1 if a new request is queued, 0 if no more requests are required
2754+ * for this transfer.
2755+ */
2756+int dwc_otg_hc_continue_transfer(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc)
2757+{
2758+ DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, _hc->hc_num);
2759+
2760+ if (_hc->do_split) {
2761+ /* SPLITs always queue just once per channel */
2762+ return 0;
2763+ } else if (_hc->data_pid_start == DWC_OTG_HC_PID_SETUP) {
2764+ /* SETUPs are queued only once since they can't be NAKed. */
2765+ return 0;
2766+ } else if (_hc->ep_is_in) {
2767+ /*
2768+ * Always queue another request for other IN transfers. If
2769+ * back-to-back INs are issued and NAKs are received for both,
2770+ * the driver may still be processing the first NAK when the
2771+ * second NAK is received. When the interrupt handler clears
2772+ * the NAK interrupt for the first NAK, the second NAK will
2773+ * not be seen. So we can't depend on the NAK interrupt
2774+ * handler to requeue a NAKed request. Instead, IN requests
2775+ * are issued each time this function is called. When the
2776+ * transfer completes, the extra requests for the channel will
2777+ * be flushed.
2778+ */
2779+ hcchar_data_t hcchar;
2780+ dwc_otg_hc_regs_t *hc_regs = _core_if->host_if->hc_regs[_hc->hc_num];
2781+
2782+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
2783+ hc_set_even_odd_frame(_core_if, _hc, &hcchar);
2784+ hcchar.b.chen = 1;
2785+ hcchar.b.chdis = 0;
2786+ DWC_DEBUGPL(DBG_HCDV, " IN xfer: hcchar = 0x%08x\n", hcchar.d32);
2787+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
2788+ _hc->requests++;
2789+ return 1;
2790+ } else {
2791+ /* OUT transfers. */
2792+ if (_hc->xfer_count < _hc->xfer_len) {
2793+ if (_hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
2794+ _hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
2795+ hcchar_data_t hcchar;
2796+ dwc_otg_hc_regs_t *hc_regs;
2797+ hc_regs = _core_if->host_if->hc_regs[_hc->hc_num];
2798+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
2799+ hc_set_even_odd_frame(_core_if, _hc, &hcchar);
2800+ }
2801+
2802+ /* Load OUT packet into the appropriate Tx FIFO. */
2803+ dwc_otg_hc_write_packet(_core_if, _hc);
2804+ _hc->requests++;
2805+ return 1;
2806+ } else {
2807+ return 0;
2808+ }
2809+ }
2810+}
2811+
2812+/**
2813+ * Starts a PING transfer. This function should only be called in Slave mode.
2814+ * The Do Ping bit is set in the HCTSIZ register, then the channel is enabled.
2815+ */
2816+void dwc_otg_hc_do_ping(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc)
2817+{
2818+ hcchar_data_t hcchar;
2819+ hctsiz_data_t hctsiz;
2820+ dwc_otg_hc_regs_t *hc_regs = _core_if->host_if->hc_regs[_hc->hc_num];
2821+
2822+ DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, _hc->hc_num);
2823+
2824+ hctsiz.d32 = 0;
2825+ hctsiz.b.dopng = 1;
2826+ hctsiz.b.pktcnt = 1;
2827+ dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
2828+
2829+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
2830+ hcchar.b.chen = 1;
2831+ hcchar.b.chdis = 0;
2832+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
2833+}
2834+
2835+/*
2836+ * This function writes a packet into the Tx FIFO associated with the Host
2837+ * Channel. For a channel associated with a non-periodic EP, the non-periodic
2838+ * Tx FIFO is written. For a channel associated with a periodic EP, the
2839+ * periodic Tx FIFO is written. This function should only be called in Slave
2840+ * mode.
2841+ *
2842+ * Upon return the xfer_buff and xfer_count fields in _hc are incremented by
2843+ * then number of bytes written to the Tx FIFO.
2844+ */
2845+void dwc_otg_hc_write_packet(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc)
2846+{
2847+ uint32_t i;
2848+ uint32_t remaining_count;
2849+ uint32_t byte_count;
2850+ uint32_t dword_count;
2851+
2852+ uint32_t *data_buff = (uint32_t *)(_hc->xfer_buff);
2853+ uint32_t *data_fifo = _core_if->data_fifo[_hc->hc_num];
2854+
2855+ remaining_count = _hc->xfer_len - _hc->xfer_count;
2856+ if (remaining_count > _hc->max_packet) {
2857+ byte_count = _hc->max_packet;
2858+ } else {
2859+ byte_count = remaining_count;
2860+ }
2861+
2862+ dword_count = (byte_count + 3) / 4;
2863+
2864+ if ((((unsigned long)data_buff) & 0x3) == 0) {
2865+ /* xfer_buff is DWORD aligned. */
2866+ for (i = 0; i < dword_count; i++, data_buff++) {
2867+ dwc_write_reg32(data_fifo, *data_buff);
2868+ }
2869+ } else {
2870+ /* xfer_buff is not DWORD aligned. */
2871+ for (i = 0; i < dword_count; i++, data_buff++) {
2872+ dwc_write_reg32(data_fifo, get_unaligned(data_buff));
2873+ }
2874+ }
2875+
2876+ _hc->xfer_count += byte_count;
2877+ _hc->xfer_buff += byte_count;
2878+}
2879+
2880+/**
2881+ * Gets the current USB frame number. This is the frame number from the last
2882+ * SOF packet.
2883+ */
2884+uint32_t dwc_otg_get_frame_number(dwc_otg_core_if_t *_core_if)
2885+{
2886+ dsts_data_t dsts;
2887+ dsts.d32 = dwc_read_reg32(&_core_if->dev_if->dev_global_regs->dsts);
2888+
2889+ /* read current frame/microfreme number from DSTS register */
2890+ return dsts.b.soffn;
2891+}
2892+
2893+/**
2894+ * This function reads a setup packet from the Rx FIFO into the destination
2895+ * buffer. This function is called from the Rx Status Queue Level (RxStsQLvl)
2896+ * Interrupt routine when a SETUP packet has been received in Slave mode.
2897+ *
2898+ * @param _core_if Programming view of DWC_otg controller.
2899+ * @param _dest Destination buffer for packet data.
2900+ */
2901+void dwc_otg_read_setup_packet(dwc_otg_core_if_t *_core_if, uint32_t *_dest)
2902+{
2903+ /* Get the 8 bytes of a setup transaction data */
2904+
2905+ /* Pop 2 DWORDS off the receive data FIFO into memory */
2906+ _dest[0] = dwc_read_reg32(_core_if->data_fifo[0]);
2907+ _dest[1] = dwc_read_reg32(_core_if->data_fifo[0]);
2908+ //_dest[0] = dwc_read_datafifo32(_core_if->data_fifo[0]);
2909+ //_dest[1] = dwc_read_datafifo32(_core_if->data_fifo[0]);
2910+}
2911+
2912+
2913+/**
2914+ * This function enables EP0 OUT to receive SETUP packets and configures EP0
2915+ * IN for transmitting packets. It is normally called when the
2916+ * "Enumeration Done" interrupt occurs.
2917+ *
2918+ * @param _core_if Programming view of DWC_otg controller.
2919+ * @param _ep The EP0 data.
2920+ */
2921+void dwc_otg_ep0_activate(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep)
2922+{
2923+ dwc_otg_dev_if_t *dev_if = _core_if->dev_if;
2924+ dsts_data_t dsts;
2925+ depctl_data_t diepctl;
2926+ depctl_data_t doepctl;
2927+ dctl_data_t dctl ={.d32=0};
2928+
2929+ /* Read the Device Status and Endpoint 0 Control registers */
2930+ dsts.d32 = dwc_read_reg32(&dev_if->dev_global_regs->dsts);
2931+ diepctl.d32 = dwc_read_reg32(&dev_if->in_ep_regs[0]->diepctl);
2932+ doepctl.d32 = dwc_read_reg32(&dev_if->out_ep_regs[0]->doepctl);
2933+
2934+ /* Set the MPS of the IN EP based on the enumeration speed */
2935+ switch (dsts.b.enumspd) {
2936+ case DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
2937+ case DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
2938+ case DWC_DSTS_ENUMSPD_FS_PHY_48MHZ:
2939+ diepctl.b.mps = DWC_DEP0CTL_MPS_64;
2940+ break;
2941+ case DWC_DSTS_ENUMSPD_LS_PHY_6MHZ:
2942+ diepctl.b.mps = DWC_DEP0CTL_MPS_8;
2943+ break;
2944+ }
2945+
2946+ dwc_write_reg32(&dev_if->in_ep_regs[0]->diepctl, diepctl.d32);
2947+
2948+ /* Enable OUT EP for receive */
2949+ doepctl.b.epena = 1;
2950+ dwc_write_reg32(&dev_if->out_ep_regs[0]->doepctl, doepctl.d32);
2951+
2952+#ifdef VERBOSE
2953+ DWC_DEBUGPL(DBG_PCDV,"doepctl0=%0x\n",
2954+ dwc_read_reg32(&dev_if->out_ep_regs[0]->doepctl));
2955+ DWC_DEBUGPL(DBG_PCDV,"diepctl0=%0x\n",
2956+ dwc_read_reg32(&dev_if->in_ep_regs[0]->diepctl));
2957+#endif
2958+ dctl.b.cgnpinnak = 1;
2959+ dwc_modify_reg32(&dev_if->dev_global_regs->dctl, dctl.d32, dctl.d32);
2960+ DWC_DEBUGPL(DBG_PCDV,"dctl=%0x\n",
2961+ dwc_read_reg32(&dev_if->dev_global_regs->dctl));
2962+}
2963+
2964+/**
2965+ * This function activates an EP. The Device EP control register for
2966+ * the EP is configured as defined in the ep structure. Note: This
2967+ * function is not used for EP0.
2968+ *
2969+ * @param _core_if Programming view of DWC_otg controller.
2970+ * @param _ep The EP to activate.
2971+ */
2972+void dwc_otg_ep_activate(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep)
2973+{
2974+ dwc_otg_dev_if_t *dev_if = _core_if->dev_if;
2975+ depctl_data_t depctl;
2976+ volatile uint32_t *addr;
2977+ daint_data_t daintmsk = {.d32=0};
2978+
2979+ DWC_DEBUGPL(DBG_PCDV, "%s() EP%d-%s\n", __func__, _ep->num,
2980+ (_ep->is_in?"IN":"OUT"));
2981+
2982+ /* Read DEPCTLn register */
2983+ if (_ep->is_in == 1) {
2984+ addr = &dev_if->in_ep_regs[_ep->num]->diepctl;
2985+ daintmsk.ep.in = 1<<_ep->num;
2986+ } else {
2987+ addr = &dev_if->out_ep_regs[_ep->num]->doepctl;
2988+ daintmsk.ep.out = 1<<_ep->num;
2989+ }
2990+
2991+ /* If the EP is already active don't change the EP Control
2992+ * register. */
2993+ depctl.d32 = dwc_read_reg32(addr);
2994+ if (!depctl.b.usbactep) {
2995+ depctl.b.mps = _ep->maxpacket;
2996+ depctl.b.eptype = _ep->type;
2997+ depctl.b.txfnum = _ep->tx_fifo_num;
2998+
2999+ if (_ep->type == DWC_OTG_EP_TYPE_ISOC) {
3000+ depctl.b.setd0pid = 1; // ???
3001+ } else {
3002+ depctl.b.setd0pid = 1;
3003+ }
3004+ depctl.b.usbactep = 1;
3005+
3006+ dwc_write_reg32(addr, depctl.d32);
3007+ DWC_DEBUGPL(DBG_PCDV,"DEPCTL=%08x\n", dwc_read_reg32(addr));
3008+ }
3009+
3010+
3011+ /* Enable the Interrupt for this EP */
3012+ dwc_modify_reg32(&dev_if->dev_global_regs->daintmsk,
3013+ 0, daintmsk.d32);
3014+ DWC_DEBUGPL(DBG_PCDV,"DAINTMSK=%0x\n",
3015+ dwc_read_reg32(&dev_if->dev_global_regs->daintmsk));
3016+ _ep->stall_clear_flag = 0;
3017+ return;
3018+}
3019+
3020+/**
3021+ * This function deactivates an EP. This is done by clearing the USB Active
3022+ * EP bit in the Device EP control register. Note: This function is not used
3023+ * for EP0. EP0 cannot be deactivated.
3024+ *
3025+ * @param _core_if Programming view of DWC_otg controller.
3026+ * @param _ep The EP to deactivate.
3027+ */
3028+void dwc_otg_ep_deactivate(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep)
3029+{
3030+ depctl_data_t depctl ={.d32 = 0};
3031+ volatile uint32_t *addr;
3032+ daint_data_t daintmsk = {.d32=0};
3033+
3034+ /* Read DEPCTLn register */
3035+ if (_ep->is_in == 1) {
3036+ addr = &_core_if->dev_if->in_ep_regs[_ep->num]->diepctl;
3037+ daintmsk.ep.in = 1<<_ep->num;
3038+ } else {
3039+ addr = &_core_if->dev_if->out_ep_regs[_ep->num]->doepctl;
3040+ daintmsk.ep.out = 1<<_ep->num;
3041+ }
3042+
3043+ depctl.b.usbactep = 0;
3044+ dwc_write_reg32(addr, depctl.d32);
3045+
3046+ /* Disable the Interrupt for this EP */
3047+ dwc_modify_reg32(&_core_if->dev_if->dev_global_regs->daintmsk,
3048+ daintmsk.d32, 0);
3049+
3050+ return;
3051+}
3052+
3053+/**
3054+ * This function does the setup for a data transfer for an EP and
3055+ * starts the transfer. For an IN transfer, the packets will be
3056+ * loaded into the appropriate Tx FIFO in the ISR. For OUT transfers,
3057+ * the packets are unloaded from the Rx FIFO in the ISR. the ISR.
3058+ *
3059+ * @param _core_if Programming view of DWC_otg controller.
3060+ * @param _ep The EP to start the transfer on.
3061+ */
3062+void dwc_otg_ep_start_transfer(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep)
3063+{
3064+ /** @todo Refactor this funciton to check the transfer size
3065+ * count value does not execed the number bits in the Transfer
3066+ * count register. */
3067+ depctl_data_t depctl;
3068+ deptsiz_data_t deptsiz;
3069+ gintmsk_data_t intr_mask = { .d32 = 0};
3070+
3071+#ifdef CHECK_PACKET_COUNTER_WIDTH
3072+ const uint32_t MAX_XFER_SIZE =
3073+ _core_if->core_params->max_transfer_size;
3074+ const uint32_t MAX_PKT_COUNT =
3075+ _core_if->core_params->max_packet_count;
3076+ uint32_t num_packets;
3077+ uint32_t transfer_len;
3078+ dwc_otg_dev_out_ep_regs_t *out_regs =
3079+ _core_if->dev_if->out_ep_regs[_ep->num];
3080+ dwc_otg_dev_in_ep_regs_t *in_regs =
3081+ _core_if->dev_if->in_ep_regs[_ep->num];
3082+ gnptxsts_data_t txstatus;
3083+
3084+ int lvl = SET_DEBUG_LEVEL(DBG_PCD);
3085+
3086+
3087+ DWC_DEBUGPL(DBG_PCD, "ep%d-%s xfer_len=%d xfer_cnt=%d "
3088+ "xfer_buff=%p start_xfer_buff=%p\n",
3089+ _ep->num, (_ep->is_in?"IN":"OUT"), _ep->xfer_len,
3090+ _ep->xfer_count, _ep->xfer_buff, _ep->start_xfer_buff);
3091+
3092+ transfer_len = _ep->xfer_len - _ep->xfer_count;
3093+ if (transfer_len > MAX_XFER_SIZE) {
3094+ transfer_len = MAX_XFER_SIZE;
3095+ }
3096+ if (transfer_len == 0) {
3097+ num_packets = 1;
3098+ /* OUT EP to recieve Zero-length packet set transfer
3099+ * size to maxpacket size. */
3100+ if (!_ep->is_in) {
3101+ transfer_len = _ep->maxpacket;
3102+ }
3103+ } else {
3104+ num_packets =
3105+ (transfer_len + _ep->maxpacket - 1) / _ep->maxpacket;
3106+ if (num_packets > MAX_PKT_COUNT) {
3107+ num_packets = MAX_PKT_COUNT;
3108+ }
3109+ }
3110+ DWC_DEBUGPL(DBG_PCD, "transfer_len=%d #pckt=%d\n", transfer_len,
3111+ num_packets);
3112+
3113+ deptsiz.b.xfersize = transfer_len;
3114+ deptsiz.b.pktcnt = num_packets;
3115+
3116+ /* IN endpoint */
3117+ if (_ep->is_in == 1) {
3118+ depctl.d32 = dwc_read_reg32(&in_regs->diepctl);
3119+ } else {/* OUT endpoint */
3120+ depctl.d32 = dwc_read_reg32(&out_regs->doepctl);
3121+ }
3122+
3123+ /* EP enable, IN data in FIFO */
3124+ depctl.b.cnak = 1;
3125+ depctl.b.epena = 1;
3126+ /* IN endpoint */
3127+ if (_ep->is_in == 1) {
3128+ txstatus.d32 =
3129+ dwc_read_reg32(&_core_if->core_global_regs->gnptxsts);
3130+ if (txstatus.b.nptxqspcavail == 0) {
3131+ DWC_DEBUGPL(DBG_ANY, "TX Queue Full (0x%0x)\n",
3132+ txstatus.d32);
3133+ return;
3134+ }
3135+ dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
3136+ dwc_write_reg32(&in_regs->diepctl, depctl.d32);
3137+ /**
3138+ * Enable the Non-Periodic Tx FIFO empty interrupt, the
3139+ * data will be written into the fifo by the ISR.
3140+ */
3141+ if (_core_if->dma_enable) {
3142+ dwc_write_reg32(&in_regs->diepdma, (uint32_t) _ep->xfer_buff);
3143+ } else {
3144+ if (_core_if->en_multiple_tx_fifo == 0) {
3145+ intr_mask.b.nptxfempty = 1;
3146+ dwc_modify_reg32( &_core_if->core_global_regs->gintsts,
3147+ intr_mask.d32, 0);
3148+ dwc_modify_reg32( &_core_if->core_global_regs->gintmsk,
3149+ intr_mask.d32, intr_mask.d32);
3150+ } else {
3151+ /* Enable the Tx FIFO Empty Interrupt for this EP */
3152+ if (_ep->xfer_len > 0 &&
3153+ _ep->type != DWC_OTG_EP_TYPE_ISOC) {
3154+ uint32_t fifoemptymsk = 0;
3155+ fifoemptymsk = (0x1 << _ep->num);
3156+ dwc_modify_reg32(&_core_if->dev_if->dev_global_regs->
3157+ dtknqr4_fifoemptymsk,0, fifoemptymsk);
3158+ }
3159+ }
3160+ }
3161+ } else { /* OUT endpoint */
3162+ dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32);
3163+ dwc_write_reg32(&out_regs->doepctl, depctl.d32);
3164+ if (_core_if->dma_enable) {
3165+ dwc_write_reg32(&out_regs->doepdma,(uint32_t) _ep->xfer_buff);
3166+ }
3167+ }
3168+ DWC_DEBUGPL(DBG_PCD, "DOEPCTL=%08x DOEPTSIZ=%08x\n",
3169+ dwc_read_reg32(&out_regs->doepctl),
3170+ dwc_read_reg32(&out_regs->doeptsiz));
3171+ DWC_DEBUGPL(DBG_PCD, "DAINTMSK=%08x GINTMSK=%08x\n",
3172+ dwc_read_reg32(&_core_if->dev_if->dev_global_regs->daintmsk),
3173+ dwc_read_reg32(&_core_if->core_global_regs->gintmsk));
3174+
3175+ SET_DEBUG_LEVEL(lvl);
3176+#endif
3177+ DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s()\n", __func__);
3178+
3179+ DWC_DEBUGPL(DBG_PCD, "ep%d-%s xfer_len=%d xfer_cnt=%d "
3180+ "xfer_buff=%p start_xfer_buff=%p\n",
3181+ _ep->num, (_ep->is_in?"IN":"OUT"), _ep->xfer_len,
3182+ _ep->xfer_count, _ep->xfer_buff, _ep->start_xfer_buff);
3183+
3184+ /* IN endpoint */
3185+ if (_ep->is_in == 1) {
3186+ dwc_otg_dev_in_ep_regs_t * in_regs = _core_if->dev_if->in_ep_regs[_ep->num];
3187+ gnptxsts_data_t gtxstatus;
3188+ gtxstatus.d32 = dwc_read_reg32(&_core_if->core_global_regs->gnptxsts);
3189+ if (_core_if->en_multiple_tx_fifo == 0 &&
3190+ gtxstatus.b.nptxqspcavail == 0) {
3191+#ifdef DEBUG
3192+ DWC_PRINT("TX Queue Full (0x%0x)\n", gtxstatus.d32);
3193+#endif
3194+ //return;
3195+ MDELAY(100); //james
3196+ }
3197+
3198+ depctl.d32 = dwc_read_reg32(&(in_regs->diepctl));
3199+ deptsiz.d32 = dwc_read_reg32(&(in_regs->dieptsiz));
3200+
3201+ /* Zero Length Packet? */
3202+ if (_ep->xfer_len == 0) {
3203+ deptsiz.b.xfersize = 0;
3204+ deptsiz.b.pktcnt = 1;
3205+ } else {
3206+
3207+ /* Program the transfer size and packet count
3208+ * as follows: xfersize = N * maxpacket +
3209+ * short_packet pktcnt = N + (short_packet
3210+ * exist ? 1 : 0)
3211+ */
3212+ deptsiz.b.xfersize = _ep->xfer_len;
3213+ deptsiz.b.pktcnt = (_ep->xfer_len - 1 + _ep->maxpacket) / _ep->maxpacket;
3214+ }
3215+
3216+ dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
3217+
3218+ /* Write the DMA register */
3219+ if (_core_if->dma_enable) {
3220+#if 1 // winder
3221+ dma_cache_wback_inv((unsigned long) _ep->xfer_buff, _ep->xfer_len); // winder
3222+ dwc_write_reg32 (&(in_regs->diepdma),
3223+ CPHYSADDR((uint32_t)_ep->xfer_buff)); // winder
3224+#else
3225+ dwc_write_reg32 (&(in_regs->diepdma),
3226+ (uint32_t)_ep->dma_addr);
3227+#endif
3228+ } else {
3229+ if (_ep->type != DWC_OTG_EP_TYPE_ISOC) {
3230+ /**
3231+ * Enable the Non-Periodic Tx FIFO empty interrupt,
3232+ * or the Tx FIFO epmty interrupt in dedicated Tx FIFO mode,
3233+ * the data will be written into the fifo by the ISR.
3234+ */
3235+ if (_core_if->en_multiple_tx_fifo == 0) {
3236+ intr_mask.b.nptxfempty = 1;
3237+ dwc_modify_reg32( &_core_if->core_global_regs->gintsts,
3238+ intr_mask.d32, 0);
3239+ dwc_modify_reg32( &_core_if->core_global_regs->gintmsk,
3240+ intr_mask.d32, intr_mask.d32);
3241+ } else {
3242+ /* Enable the Tx FIFO Empty Interrupt for this EP */
3243+ if (_ep->xfer_len > 0) {
3244+ uint32_t fifoemptymsk = 0;
3245+ fifoemptymsk = 1 << _ep->num;
3246+ dwc_modify_reg32(&_core_if->dev_if->dev_global_regs->
3247+ dtknqr4_fifoemptymsk,0,fifoemptymsk);
3248+ }
3249+ }
3250+ }
3251+ }
3252+
3253+ /* EP enable, IN data in FIFO */
3254+ depctl.b.cnak = 1;
3255+ depctl.b.epena = 1;
3256+ dwc_write_reg32(&in_regs->diepctl, depctl.d32);
3257+
3258+ if (_core_if->dma_enable) {
3259+ depctl.d32 = dwc_read_reg32 (&_core_if->dev_if->in_ep_regs[0]->diepctl);
3260+ depctl.b.nextep = _ep->num;
3261+ dwc_write_reg32 (&_core_if->dev_if->in_ep_regs[0]->diepctl, depctl.d32);
3262+
3263+ }
3264+ } else {
3265+ /* OUT endpoint */
3266+ dwc_otg_dev_out_ep_regs_t * out_regs = _core_if->dev_if->out_ep_regs[_ep->num];
3267+
3268+ depctl.d32 = dwc_read_reg32(&(out_regs->doepctl));
3269+ deptsiz.d32 = dwc_read_reg32(&(out_regs->doeptsiz));
3270+
3271+ /* Program the transfer size and packet count as follows:
3272+ *
3273+ * pktcnt = N
3274+ * xfersize = N * maxpacket
3275+ */
3276+ if (_ep->xfer_len == 0) {
3277+ /* Zero Length Packet */
3278+ deptsiz.b.xfersize = _ep->maxpacket;
3279+ deptsiz.b.pktcnt = 1;
3280+ } else {
3281+ deptsiz.b.pktcnt = (_ep->xfer_len + (_ep->maxpacket - 1)) / _ep->maxpacket;
3282+ deptsiz.b.xfersize = deptsiz.b.pktcnt * _ep->maxpacket;
3283+ }
3284+ dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32);
3285+
3286+ DWC_DEBUGPL(DBG_PCDV, "ep%d xfersize=%d pktcnt=%d\n",
3287+ _ep->num, deptsiz.b.xfersize, deptsiz.b.pktcnt);
3288+
3289+ if (_core_if->dma_enable) {
3290+#if 1 // winder
3291+ dwc_write_reg32 (&(out_regs->doepdma),
3292+ CPHYSADDR((uint32_t)_ep->xfer_buff)); // winder
3293+#else
3294+ dwc_write_reg32 (&(out_regs->doepdma),
3295+ (uint32_t)_ep->dma_addr);
3296+#endif
3297+ }
3298+
3299+ if (_ep->type == DWC_OTG_EP_TYPE_ISOC) {
3300+ /** @todo NGS: dpid is read-only. Use setd0pid
3301+ * or setd1pid. */
3302+ if (_ep->even_odd_frame) {
3303+ depctl.b.setd1pid = 1;
3304+ } else {
3305+ depctl.b.setd0pid = 1;
3306+ }
3307+ }
3308+
3309+ /* EP enable */
3310+ depctl.b.cnak = 1;
3311+ depctl.b.epena = 1;
3312+
3313+ dwc_write_reg32(&out_regs->doepctl, depctl.d32);
3314+
3315+ DWC_DEBUGPL(DBG_PCD, "DOEPCTL=%08x DOEPTSIZ=%08x\n",
3316+ dwc_read_reg32(&out_regs->doepctl),
3317+ dwc_read_reg32(&out_regs->doeptsiz));
3318+ DWC_DEBUGPL(DBG_PCD, "DAINTMSK=%08x GINTMSK=%08x\n",
3319+ dwc_read_reg32(&_core_if->dev_if->dev_global_regs->daintmsk),
3320+ dwc_read_reg32(&_core_if->core_global_regs->gintmsk));
3321+ }
3322+}
3323+
3324+
3325+/**
3326+ * This function does the setup for a data transfer for EP0 and starts
3327+ * the transfer. For an IN transfer, the packets will be loaded into
3328+ * the appropriate Tx FIFO in the ISR. For OUT transfers, the packets are
3329+ * unloaded from the Rx FIFO in the ISR.
3330+ *
3331+ * @param _core_if Programming view of DWC_otg controller.
3332+ * @param _ep The EP0 data.
3333+ */
3334+void dwc_otg_ep0_start_transfer(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep)
3335+{
3336+ volatile depctl_data_t depctl;
3337+ volatile deptsiz0_data_t deptsiz;
3338+ gintmsk_data_t intr_mask = { .d32 = 0};
3339+
3340+ DWC_DEBUGPL(DBG_PCD, "ep%d-%s xfer_len=%d xfer_cnt=%d "
3341+ "xfer_buff=%p start_xfer_buff=%p total_len=%d\n",
3342+ _ep->num, (_ep->is_in?"IN":"OUT"), _ep->xfer_len,
3343+ _ep->xfer_count, _ep->xfer_buff, _ep->start_xfer_buff,
3344+ _ep->total_len);
3345+ _ep->total_len = _ep->xfer_len;
3346+
3347+ /* IN endpoint */
3348+ if (_ep->is_in == 1) {
3349+ dwc_otg_dev_in_ep_regs_t * in_regs = _core_if->dev_if->in_ep_regs[0];
3350+ gnptxsts_data_t gtxstatus;
3351+ gtxstatus.d32 = dwc_read_reg32(&_core_if->core_global_regs->gnptxsts);
3352+ if (_core_if->en_multiple_tx_fifo == 0 &&
3353+ gtxstatus.b.nptxqspcavail == 0) {
3354+#ifdef DEBUG
3355+ deptsiz.d32 = dwc_read_reg32(&in_regs->dieptsiz);
3356+ DWC_DEBUGPL(DBG_PCD,"DIEPCTL0=%0x\n",
3357+ dwc_read_reg32(&in_regs->diepctl));
3358+ DWC_DEBUGPL(DBG_PCD, "DIEPTSIZ0=%0x (sz=%d, pcnt=%d)\n",
3359+ deptsiz.d32, deptsiz.b.xfersize,deptsiz.b.pktcnt);
3360+ DWC_PRINT("TX Queue or FIFO Full (0x%0x)\n", gtxstatus.d32);
3361+#endif /* */
3362+ printk("TX Queue or FIFO Full!!!!\n"); // test-only
3363+ //return;
3364+ MDELAY(100); //james
3365+ }
3366+
3367+ depctl.d32 = dwc_read_reg32(&in_regs->diepctl);
3368+ deptsiz.d32 = dwc_read_reg32(&in_regs->dieptsiz);
3369+
3370+ /* Zero Length Packet? */
3371+ if (_ep->xfer_len == 0) {
3372+ deptsiz.b.xfersize = 0;
3373+ deptsiz.b.pktcnt = 1;
3374+ } else {
3375+ /* Program the transfer size and packet count
3376+ * as follows: xfersize = N * maxpacket +
3377+ * short_packet pktcnt = N + (short_packet
3378+ * exist ? 1 : 0)
3379+ */
3380+ if (_ep->xfer_len > _ep->maxpacket) {
3381+ _ep->xfer_len = _ep->maxpacket;
3382+ deptsiz.b.xfersize = _ep->maxpacket;
3383+ }
3384+ else {
3385+ deptsiz.b.xfersize = _ep->xfer_len;
3386+ }
3387+ deptsiz.b.pktcnt = 1;
3388+
3389+ }
3390+ dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
3391+ DWC_DEBUGPL(DBG_PCDV, "IN len=%d xfersize=%d pktcnt=%d [%08x]\n",
3392+ _ep->xfer_len, deptsiz.b.xfersize,deptsiz.b.pktcnt, deptsiz.d32);
3393+
3394+ /* Write the DMA register */
3395+ if (_core_if->dma_enable) {
3396+ dwc_write_reg32(&(in_regs->diepdma), (uint32_t) _ep->dma_addr);
3397+ }
3398+
3399+ /* EP enable, IN data in FIFO */
3400+ depctl.b.cnak = 1;
3401+ depctl.b.epena = 1;
3402+ dwc_write_reg32(&in_regs->diepctl, depctl.d32);
3403+
3404+ /**
3405+ * Enable the Non-Periodic Tx FIFO empty interrupt, the
3406+ * data will be written into the fifo by the ISR.
3407+ */
3408+ if (!_core_if->dma_enable) {
3409+ if (_core_if->en_multiple_tx_fifo == 0) {
3410+ intr_mask.b.nptxfempty = 1;
3411+ dwc_modify_reg32(&_core_if->core_global_regs->gintsts, intr_mask.d32, 0);
3412+ dwc_modify_reg32(&_core_if->core_global_regs->gintmsk, intr_mask.d32,
3413+ intr_mask.d32);
3414+ } else {
3415+ /* Enable the Tx FIFO Empty Interrupt for this EP */
3416+ if (_ep->xfer_len > 0) {
3417+ uint32_t fifoemptymsk = 0;
3418+ fifoemptymsk |= 1 << _ep->num;
3419+ dwc_modify_reg32(&_core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
3420+ 0, fifoemptymsk);
3421+ }
3422+
3423+ }
3424+ }
3425+ } else {
3426+ /* OUT endpoint */
3427+ dwc_otg_dev_out_ep_regs_t * out_regs = _core_if->dev_if->out_ep_regs[_ep->num];
3428+
3429+ depctl.d32 = dwc_read_reg32(&out_regs->doepctl);
3430+ deptsiz.d32 = dwc_read_reg32(&out_regs->doeptsiz);
3431+
3432+ /* Program the transfer size and packet count as follows:
3433+ * xfersize = N * (maxpacket + 4 - (maxpacket % 4))
3434+ * pktcnt = N */
3435+ if (_ep->xfer_len == 0) {
3436+ /* Zero Length Packet */
3437+ deptsiz.b.xfersize = _ep->maxpacket;
3438+ deptsiz.b.pktcnt = 1;
3439+ } else {
3440+ deptsiz.b.pktcnt = (_ep->xfer_len + (_ep->maxpacket - 1)) / _ep->maxpacket;
3441+ deptsiz.b.xfersize = deptsiz.b.pktcnt * _ep->maxpacket;
3442+ }
3443+
3444+ dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32);
3445+ DWC_DEBUGPL(DBG_PCDV, "len=%d xfersize=%d pktcnt=%d\n",
3446+ _ep->xfer_len, deptsiz.b.xfersize,deptsiz.b.pktcnt);
3447+
3448+ if (_core_if->dma_enable) {
3449+ dwc_write_reg32(&(out_regs->doepdma), (uint32_t) _ep->dma_addr);
3450+ }
3451+
3452+ /* EP enable */
3453+ depctl.b.cnak = 1;
3454+ depctl.b.epena = 1;
3455+ dwc_write_reg32 (&(out_regs->doepctl), depctl.d32);
3456+ }
3457+}
3458+
3459+/**
3460+ * This function continues control IN transfers started by
3461+ * dwc_otg_ep0_start_transfer, when the transfer does not fit in a
3462+ * single packet. NOTE: The DIEPCTL0/DOEPCTL0 registers only have one
3463+ * bit for the packet count.
3464+ *
3465+ * @param _core_if Programming view of DWC_otg controller.
3466+ * @param _ep The EP0 data.
3467+ */
3468+void dwc_otg_ep0_continue_transfer(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep)
3469+{
3470+ depctl_data_t depctl;
3471+ deptsiz0_data_t deptsiz;
3472+ gintmsk_data_t intr_mask = { .d32 = 0};
3473+
3474+ if (_ep->is_in == 1) {
3475+ dwc_otg_dev_in_ep_regs_t *in_regs =
3476+ _core_if->dev_if->in_ep_regs[0];
3477+ gnptxsts_data_t tx_status = {.d32 = 0};
3478+
3479+ tx_status.d32 = dwc_read_reg32( &_core_if->core_global_regs->gnptxsts );
3480+ /** @todo Should there be check for room in the Tx
3481+ * Status Queue. If not remove the code above this comment. */
3482+
3483+ depctl.d32 = dwc_read_reg32(&in_regs->diepctl);
3484+ deptsiz.d32 = dwc_read_reg32(&in_regs->dieptsiz);
3485+
3486+ /* Program the transfer size and packet count
3487+ * as follows: xfersize = N * maxpacket +
3488+ * short_packet pktcnt = N + (short_packet
3489+ * exist ? 1 : 0)
3490+ */
3491+ deptsiz.b.xfersize = (_ep->total_len - _ep->xfer_count) > _ep->maxpacket ? _ep->maxpacket :
3492+ (_ep->total_len - _ep->xfer_count);
3493+ deptsiz.b.pktcnt = 1;
3494+ _ep->xfer_len += deptsiz.b.xfersize;
3495+
3496+ dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
3497+ DWC_DEBUGPL(DBG_PCDV, "IN len=%d xfersize=%d pktcnt=%d [%08x]\n",
3498+ _ep->xfer_len,
3499+ deptsiz.b.xfersize, deptsiz.b.pktcnt, deptsiz.d32);
3500+
3501+ /* Write the DMA register */
3502+ if (_core_if->hwcfg2.b.architecture == DWC_INT_DMA_ARCH) {
3503+ dwc_write_reg32 (&(in_regs->diepdma),
3504+ CPHYSADDR((uint32_t)_ep->dma_addr)); // winder
3505+ }
3506+
3507+ /* EP enable, IN data in FIFO */
3508+ depctl.b.cnak = 1;
3509+ depctl.b.epena = 1;
3510+ dwc_write_reg32(&in_regs->diepctl, depctl.d32);
3511+
3512+ /**
3513+ * Enable the Non-Periodic Tx FIFO empty interrupt, the
3514+ * data will be written into the fifo by the ISR.
3515+ */
3516+ if (!_core_if->dma_enable) {
3517+ /* First clear it from GINTSTS */
3518+ intr_mask.b.nptxfempty = 1;
3519+ dwc_write_reg32( &_core_if->core_global_regs->gintsts,
3520+ intr_mask.d32 );
3521+
3522+ dwc_modify_reg32( &_core_if->core_global_regs->gintmsk,
3523+ intr_mask.d32, intr_mask.d32);
3524+ }
3525+
3526+ }
3527+
3528+}
3529+
3530+#ifdef DEBUG
3531+void dump_msg(const u8 *buf, unsigned int length)
3532+{
3533+ unsigned int start, num, i;
3534+ char line[52], *p;
3535+
3536+ if (length >= 512)
3537+ return;
3538+ start = 0;
3539+ while (length > 0) {
3540+ num = min(length, 16u);
3541+ p = line;
3542+ for (i = 0; i < num; ++i) {
3543+ if (i == 8)
3544+ *p++ = ' ';
3545+ sprintf(p, " %02x", buf[i]);
3546+ p += 3;
3547+ }
3548+ *p = 0;
3549+ DWC_PRINT( "%6x: %s\n", start, line);
3550+ buf += num;
3551+ start += num;
3552+ length -= num;
3553+ }
3554+}
3555+#else
3556+static inline void dump_msg(const u8 *buf, unsigned int length)
3557+{
3558+}
3559+#endif
3560+
3561+/**
3562+ * This function writes a packet into the Tx FIFO associated with the
3563+ * EP. For non-periodic EPs the non-periodic Tx FIFO is written. For
3564+ * periodic EPs the periodic Tx FIFO associated with the EP is written
3565+ * with all packets for the next micro-frame.
3566+ *
3567+ * @param _core_if Programming view of DWC_otg controller.
3568+ * @param _ep The EP to write packet for.
3569+ * @param _dma Indicates if DMA is being used.
3570+ */
3571+void dwc_otg_ep_write_packet(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep, int _dma)
3572+{
3573+ /**
3574+ * The buffer is padded to DWORD on a per packet basis in
3575+ * slave/dma mode if the MPS is not DWORD aligned. The last
3576+ * packet, if short, is also padded to a multiple of DWORD.
3577+ *
3578+ * ep->xfer_buff always starts DWORD aligned in memory and is a
3579+ * multiple of DWORD in length
3580+ *
3581+ * ep->xfer_len can be any number of bytes
3582+ *
3583+ * ep->xfer_count is a multiple of ep->maxpacket until the last
3584+ * packet
3585+ *
3586+ * FIFO access is DWORD */
3587+
3588+ uint32_t i;
3589+ uint32_t byte_count;
3590+ uint32_t dword_count;
3591+ uint32_t *fifo;
3592+ uint32_t *data_buff = (uint32_t *)_ep->xfer_buff;
3593+
3594+ //DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s(%p,%p)\n", __func__, _core_if, _ep);
3595+ if (_ep->xfer_count >= _ep->xfer_len) {
3596+ DWC_WARN("%s() No data for EP%d!!!\n", __func__, _ep->num);
3597+ return;
3598+ }
3599+
3600+ /* Find the byte length of the packet either short packet or MPS */
3601+ if ((_ep->xfer_len - _ep->xfer_count) < _ep->maxpacket) {
3602+ byte_count = _ep->xfer_len - _ep->xfer_count;
3603+ }
3604+ else {
3605+ byte_count = _ep->maxpacket;
3606+ }
3607+
3608+ /* Find the DWORD length, padded by extra bytes as neccessary if MPS
3609+ * is not a multiple of DWORD */
3610+ dword_count = (byte_count + 3) / 4;
3611+
3612+#ifdef VERBOSE
3613+ dump_msg(_ep->xfer_buff, byte_count);
3614+#endif
3615+ if (_ep->type == DWC_OTG_EP_TYPE_ISOC) {
3616+ /**@todo NGS Where are the Periodic Tx FIFO addresses
3617+ * intialized? What should this be? */
3618+ fifo = _core_if->data_fifo[_ep->tx_fifo_num];
3619+ } else {
3620+ fifo = _core_if->data_fifo[_ep->num];
3621+ }
3622+
3623+ DWC_DEBUGPL((DBG_PCDV|DBG_CILV), "fifo=%p buff=%p *p=%08x bc=%d\n",
3624+ fifo, data_buff, *data_buff, byte_count);
3625+
3626+
3627+ if (!_dma) {
3628+ for (i=0; i<dword_count; i++, data_buff++) {
3629+ dwc_write_reg32( fifo, *data_buff );
3630+ }
3631+ }
3632+
3633+ _ep->xfer_count += byte_count;
3634+ _ep->xfer_buff += byte_count;
3635+#if 1 // winder, why do we need this??
3636+ _ep->dma_addr += byte_count;
3637+#endif
3638+}
3639+
3640+/**
3641+ * Set the EP STALL.
3642+ *
3643+ * @param _core_if Programming view of DWC_otg controller.
3644+ * @param _ep The EP to set the stall on.
3645+ */
3646+void dwc_otg_ep_set_stall(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep)
3647+{
3648+ depctl_data_t depctl;
3649+ volatile uint32_t *depctl_addr;
3650+
3651+ DWC_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, _ep->num,
3652+ (_ep->is_in?"IN":"OUT"));
3653+
3654+ if (_ep->is_in == 1) {
3655+ depctl_addr = &(_core_if->dev_if->in_ep_regs[_ep->num]->diepctl);
3656+ depctl.d32 = dwc_read_reg32(depctl_addr);
3657+
3658+ /* set the disable and stall bits */
3659+ if (depctl.b.epena) {
3660+ depctl.b.epdis = 1;
3661+ }
3662+ depctl.b.stall = 1;
3663+ dwc_write_reg32(depctl_addr, depctl.d32);
3664+
3665+ } else {
3666+ depctl_addr = &(_core_if->dev_if->out_ep_regs[_ep->num]->doepctl);
3667+ depctl.d32 = dwc_read_reg32(depctl_addr);
3668+
3669+ /* set the stall bit */
3670+ depctl.b.stall = 1;
3671+ dwc_write_reg32(depctl_addr, depctl.d32);
3672+ }
3673+ DWC_DEBUGPL(DBG_PCD,"DEPCTL=%0x\n",dwc_read_reg32(depctl_addr));
3674+ return;
3675+}
3676+
3677+/**
3678+ * Clear the EP STALL.
3679+ *
3680+ * @param _core_if Programming view of DWC_otg controller.
3681+ * @param _ep The EP to clear stall from.
3682+ */
3683+void dwc_otg_ep_clear_stall(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep)
3684+{
3685+ depctl_data_t depctl;
3686+ volatile uint32_t *depctl_addr;
3687+
3688+ DWC_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, _ep->num,
3689+ (_ep->is_in?"IN":"OUT"));
3690+
3691+ if (_ep->is_in == 1) {
3692+ depctl_addr = &(_core_if->dev_if->in_ep_regs[_ep->num]->diepctl);
3693+ } else {
3694+ depctl_addr = &(_core_if->dev_if->out_ep_regs[_ep->num]->doepctl);
3695+ }
3696+
3697+ depctl.d32 = dwc_read_reg32(depctl_addr);
3698+
3699+ /* clear the stall bits */
3700+ depctl.b.stall = 0;
3701+
3702+ /*
3703+ * USB Spec 9.4.5: For endpoints using data toggle, regardless
3704+ * of whether an endpoint has the Halt feature set, a
3705+ * ClearFeature(ENDPOINT_HALT) request always results in the
3706+ * data toggle being reinitialized to DATA0.
3707+ */
3708+ if (_ep->type == DWC_OTG_EP_TYPE_INTR ||
3709+ _ep->type == DWC_OTG_EP_TYPE_BULK) {
3710+ depctl.b.setd0pid = 1; /* DATA0 */
3711+ }
3712+
3713+ dwc_write_reg32(depctl_addr, depctl.d32);
3714+ DWC_DEBUGPL(DBG_PCD,"DEPCTL=%0x\n",dwc_read_reg32(depctl_addr));
3715+ return;
3716+}
3717+
3718+/**
3719+ * This function reads a packet from the Rx FIFO into the destination
3720+ * buffer. To read SETUP data use dwc_otg_read_setup_packet.
3721+ *
3722+ * @param _core_if Programming view of DWC_otg controller.
3723+ * @param _dest Destination buffer for the packet.
3724+ * @param _bytes Number of bytes to copy to the destination.
3725+ */
3726+void dwc_otg_read_packet(dwc_otg_core_if_t *_core_if,
3727+ uint8_t *_dest,
3728+ uint16_t _bytes)
3729+{
3730+ int i;
3731+ int word_count = (_bytes + 3) / 4;
3732+
3733+ volatile uint32_t *fifo = _core_if->data_fifo[0];
3734+ uint32_t *data_buff = (uint32_t *)_dest;
3735+
3736+ /**
3737+ * @todo Account for the case where _dest is not dword aligned. This
3738+ * requires reading data from the FIFO into a uint32_t temp buffer,
3739+ * then moving it into the data buffer.
3740+ */
3741+
3742+ DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s(%p,%p,%d)\n", __func__,
3743+ _core_if, _dest, _bytes);
3744+
3745+ for (i=0; i<word_count; i++, data_buff++) {
3746+ *data_buff = dwc_read_reg32(fifo);
3747+ }
3748+
3749+ return;
3750+}
3751+
3752+
3753+#ifdef DEBUG
3754+/**
3755+ * This functions reads the device registers and prints them
3756+ *
3757+ * @param _core_if Programming view of DWC_otg controller.
3758+ */
3759+void dwc_otg_dump_dev_registers(dwc_otg_core_if_t *_core_if)
3760+{
3761+ int i;
3762+ volatile uint32_t *addr;
3763+
3764+ DWC_PRINT("Device Global Registers\n");
3765+ addr=&_core_if->dev_if->dev_global_regs->dcfg;
3766+ DWC_PRINT("DCFG @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3767+ addr=&_core_if->dev_if->dev_global_regs->dctl;
3768+ DWC_PRINT("DCTL @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3769+ addr=&_core_if->dev_if->dev_global_regs->dsts;
3770+ DWC_PRINT("DSTS @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3771+ addr=&_core_if->dev_if->dev_global_regs->diepmsk;
3772+ DWC_PRINT("DIEPMSK @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3773+ addr=&_core_if->dev_if->dev_global_regs->doepmsk;
3774+ DWC_PRINT("DOEPMSK @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3775+ addr=&_core_if->dev_if->dev_global_regs->daint;
3776+ DWC_PRINT("DAINT @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3777+ addr=&_core_if->dev_if->dev_global_regs->dtknqr1;
3778+ DWC_PRINT("DTKNQR1 @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3779+ if (_core_if->hwcfg2.b.dev_token_q_depth > 6) {
3780+ addr=&_core_if->dev_if->dev_global_regs->dtknqr2;
3781+ DWC_PRINT("DTKNQR2 @0x%08X : 0x%08X\n",
3782+ (uint32_t)addr,dwc_read_reg32(addr));
3783+ }
3784+
3785+ addr=&_core_if->dev_if->dev_global_regs->dvbusdis;
3786+ DWC_PRINT("DVBUSID @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3787+
3788+ addr=&_core_if->dev_if->dev_global_regs->dvbuspulse;
3789+ DWC_PRINT("DVBUSPULSE @0x%08X : 0x%08X\n",
3790+ (uint32_t)addr,dwc_read_reg32(addr));
3791+
3792+ if (_core_if->hwcfg2.b.dev_token_q_depth > 14) {
3793+ addr = &_core_if->dev_if->dev_global_regs->dtknqr3_dthrctl;
3794+ DWC_PRINT("DTKNQR3 @0x%08X : 0x%08X\n",
3795+ (uint32_t)addr, dwc_read_reg32(addr));
3796+ }
3797+
3798+ if (_core_if->hwcfg2.b.dev_token_q_depth > 22) {
3799+ addr = &_core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk;
3800+ DWC_PRINT("DTKNQR4 @0x%08X : 0x%08X\n", (uint32_t) addr,
3801+ dwc_read_reg32(addr));
3802+ }
3803+ for (i = 0; i <= _core_if->dev_if->num_in_eps; i++) {
3804+ DWC_PRINT("Device IN EP %d Registers\n", i);
3805+ addr=&_core_if->dev_if->in_ep_regs[i]->diepctl;
3806+ DWC_PRINT("DIEPCTL @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3807+ addr=&_core_if->dev_if->in_ep_regs[i]->diepint;
3808+ DWC_PRINT("DIEPINT @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3809+ addr=&_core_if->dev_if->in_ep_regs[i]->dieptsiz;
3810+ DWC_PRINT("DIETSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3811+ addr=&_core_if->dev_if->in_ep_regs[i]->diepdma;
3812+ DWC_PRINT("DIEPDMA @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3813+
3814+addr = &_core_if->dev_if->in_ep_regs[i]->dtxfsts;
3815+ DWC_PRINT("DTXFSTS @0x%08X : 0x%08X\n", (uint32_t) addr,
3816+ dwc_read_reg32(addr));
3817+ }
3818+ for (i = 0; i <= _core_if->dev_if->num_out_eps; i++) {
3819+ DWC_PRINT("Device OUT EP %d Registers\n", i);
3820+ addr=&_core_if->dev_if->out_ep_regs[i]->doepctl;
3821+ DWC_PRINT("DOEPCTL @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3822+ addr=&_core_if->dev_if->out_ep_regs[i]->doepfn;
3823+ DWC_PRINT("DOEPFN @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3824+ addr=&_core_if->dev_if->out_ep_regs[i]->doepint;
3825+ DWC_PRINT("DOEPINT @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3826+ addr=&_core_if->dev_if->out_ep_regs[i]->doeptsiz;
3827+ DWC_PRINT("DOETSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3828+ addr=&_core_if->dev_if->out_ep_regs[i]->doepdma;
3829+ DWC_PRINT("DOEPDMA @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3830+ }
3831+ return;
3832+}
3833+
3834+/**
3835+ * This function reads the host registers and prints them
3836+ *
3837+ * @param _core_if Programming view of DWC_otg controller.
3838+ */
3839+void dwc_otg_dump_host_registers(dwc_otg_core_if_t *_core_if)
3840+{
3841+ int i;
3842+ volatile uint32_t *addr;
3843+
3844+ DWC_PRINT("Host Global Registers\n");
3845+ addr=&_core_if->host_if->host_global_regs->hcfg;
3846+ DWC_PRINT("HCFG @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3847+ addr=&_core_if->host_if->host_global_regs->hfir;
3848+ DWC_PRINT("HFIR @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3849+ addr=&_core_if->host_if->host_global_regs->hfnum;
3850+ DWC_PRINT("HFNUM @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3851+ addr=&_core_if->host_if->host_global_regs->hptxsts;
3852+ DWC_PRINT("HPTXSTS @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3853+ addr=&_core_if->host_if->host_global_regs->haint;
3854+ DWC_PRINT("HAINT @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3855+ addr=&_core_if->host_if->host_global_regs->haintmsk;
3856+ DWC_PRINT("HAINTMSK @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3857+ addr=_core_if->host_if->hprt0;
3858+ DWC_PRINT("HPRT0 @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3859+
3860+ for (i=0; i<_core_if->core_params->host_channels; i++) {
3861+ DWC_PRINT("Host Channel %d Specific Registers\n", i);
3862+ addr=&_core_if->host_if->hc_regs[i]->hcchar;
3863+ DWC_PRINT("HCCHAR @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3864+ addr=&_core_if->host_if->hc_regs[i]->hcsplt;
3865+ DWC_PRINT("HCSPLT @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3866+ addr=&_core_if->host_if->hc_regs[i]->hcint;
3867+ DWC_PRINT("HCINT @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3868+ addr=&_core_if->host_if->hc_regs[i]->hcintmsk;
3869+ DWC_PRINT("HCINTMSK @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3870+ addr=&_core_if->host_if->hc_regs[i]->hctsiz;
3871+ DWC_PRINT("HCTSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3872+ addr=&_core_if->host_if->hc_regs[i]->hcdma;
3873+ DWC_PRINT("HCDMA @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3874+
3875+ }
3876+ return;
3877+}
3878+
3879+/**
3880+ * This function reads the core global registers and prints them
3881+ *
3882+ * @param _core_if Programming view of DWC_otg controller.
3883+ */
3884+void dwc_otg_dump_global_registers(dwc_otg_core_if_t *_core_if)
3885+{
3886+ int i;
3887+ volatile uint32_t *addr;
3888+
3889+ DWC_PRINT("Core Global Registers\n");
3890+ addr=&_core_if->core_global_regs->gotgctl;
3891+ DWC_PRINT("GOTGCTL @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3892+ addr=&_core_if->core_global_regs->gotgint;
3893+ DWC_PRINT("GOTGINT @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3894+ addr=&_core_if->core_global_regs->gahbcfg;
3895+ DWC_PRINT("GAHBCFG @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3896+ addr=&_core_if->core_global_regs->gusbcfg;
3897+ DWC_PRINT("GUSBCFG @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3898+ addr=&_core_if->core_global_regs->grstctl;
3899+ DWC_PRINT("GRSTCTL @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3900+ addr=&_core_if->core_global_regs->gintsts;
3901+ DWC_PRINT("GINTSTS @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3902+ addr=&_core_if->core_global_regs->gintmsk;
3903+ DWC_PRINT("GINTMSK @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3904+ addr=&_core_if->core_global_regs->grxstsr;
3905+ DWC_PRINT("GRXSTSR @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3906+ //addr=&_core_if->core_global_regs->grxstsp;
3907+ //DWC_PRINT("GRXSTSP @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3908+ addr=&_core_if->core_global_regs->grxfsiz;
3909+ DWC_PRINT("GRXFSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3910+ addr=&_core_if->core_global_regs->gnptxfsiz;
3911+ DWC_PRINT("GNPTXFSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3912+ addr=&_core_if->core_global_regs->gnptxsts;
3913+ DWC_PRINT("GNPTXSTS @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3914+ addr=&_core_if->core_global_regs->gi2cctl;
3915+ DWC_PRINT("GI2CCTL @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3916+ addr=&_core_if->core_global_regs->gpvndctl;
3917+ DWC_PRINT("GPVNDCTL @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3918+ addr=&_core_if->core_global_regs->ggpio;
3919+ DWC_PRINT("GGPIO @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3920+ addr=&_core_if->core_global_regs->guid;
3921+ DWC_PRINT("GUID @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3922+ addr=&_core_if->core_global_regs->gsnpsid;
3923+ DWC_PRINT("GSNPSID @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3924+ addr=&_core_if->core_global_regs->ghwcfg1;
3925+ DWC_PRINT("GHWCFG1 @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3926+ addr=&_core_if->core_global_regs->ghwcfg2;
3927+ DWC_PRINT("GHWCFG2 @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3928+ addr=&_core_if->core_global_regs->ghwcfg3;
3929+ DWC_PRINT("GHWCFG3 @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3930+ addr=&_core_if->core_global_regs->ghwcfg4;
3931+ DWC_PRINT("GHWCFG4 @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3932+ addr=&_core_if->core_global_regs->hptxfsiz;
3933+ DWC_PRINT("HPTXFSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3934+
3935+ for (i=0; i<_core_if->hwcfg4.b.num_dev_perio_in_ep; i++) {
3936+ addr=&_core_if->core_global_regs->dptxfsiz_dieptxf[i];
3937+ DWC_PRINT("DPTXFSIZ[%d] @0x%08X : 0x%08X\n",i,(uint32_t)addr,dwc_read_reg32(addr));
3938+ }
3939+
3940+}
3941+#endif
3942+
3943+/**
3944+ * Flush a Tx FIFO.
3945+ *
3946+ * @param _core_if Programming view of DWC_otg controller.
3947+ * @param _num Tx FIFO to flush.
3948+ */
3949+extern void dwc_otg_flush_tx_fifo( dwc_otg_core_if_t *_core_if,
3950+ const int _num )
3951+{
3952+ dwc_otg_core_global_regs_t *global_regs = _core_if->core_global_regs;
3953+ volatile grstctl_t greset = { .d32 = 0};
3954+ int count = 0;
3955+
3956+ DWC_DEBUGPL((DBG_CIL|DBG_PCDV), "Flush Tx FIFO %d\n", _num);
3957+
3958+ greset.b.txfflsh = 1;
3959+ greset.b.txfnum = _num;
3960+ dwc_write_reg32( &global_regs->grstctl, greset.d32 );
3961+
3962+ do {
3963+ greset.d32 = dwc_read_reg32( &global_regs->grstctl);
3964+ if (++count > 10000){
3965+ DWC_WARN("%s() HANG! GRSTCTL=%0x GNPTXSTS=0x%08x\n",
3966+ __func__, greset.d32,
3967+ dwc_read_reg32( &global_regs->gnptxsts));
3968+ break;
3969+ }
3970+
3971+ udelay(1);
3972+ } while (greset.b.txfflsh == 1);
3973+ /* Wait for 3 PHY Clocks*/
3974+ UDELAY(1);
3975+}
3976+
3977+/**
3978+ * Flush Rx FIFO.
3979+ *
3980+ * @param _core_if Programming view of DWC_otg controller.
3981+ */
3982+extern void dwc_otg_flush_rx_fifo( dwc_otg_core_if_t *_core_if )
3983+{
3984+ dwc_otg_core_global_regs_t *global_regs = _core_if->core_global_regs;
3985+ volatile grstctl_t greset = { .d32 = 0};
3986+ int count = 0;
3987+
3988+ DWC_DEBUGPL((DBG_CIL|DBG_PCDV), "%s\n", __func__);
3989+ /*
3990+ *
3991+ */
3992+ greset.b.rxfflsh = 1;
3993+ dwc_write_reg32( &global_regs->grstctl, greset.d32 );
3994+
3995+ do {
3996+ greset.d32 = dwc_read_reg32( &global_regs->grstctl);
3997+ if (++count > 10000){
3998+ DWC_WARN("%s() HANG! GRSTCTL=%0x\n", __func__,
3999+ greset.d32);
4000+ break;
4001+ }
4002+ } while (greset.b.rxfflsh == 1);
4003+ /* Wait for 3 PHY Clocks*/
4004+ UDELAY(1);
4005+}
4006+
4007+/**
4008+ * Do core a soft reset of the core. Be careful with this because it
4009+ * resets all the internal state machines of the core.
4010+ */
4011+
4012+void dwc_otg_core_reset(dwc_otg_core_if_t *_core_if)
4013+{
4014+ dwc_otg_core_global_regs_t *global_regs = _core_if->core_global_regs;
4015+ volatile grstctl_t greset = { .d32 = 0};
4016+ int count = 0;
4017+
4018+ DWC_DEBUGPL(DBG_CILV, "%s\n", __func__);
4019+ /* Wait for AHB master IDLE state. */
4020+ do {
4021+ UDELAY(10);
4022+ greset.d32 = dwc_read_reg32( &global_regs->grstctl);
4023+ if (++count > 100000){
4024+ DWC_WARN("%s() HANG! AHB Idle GRSTCTL=%0x %x\n", __func__,
4025+ greset.d32, greset.b.ahbidle);
4026+ return;
4027+ }
4028+ } while (greset.b.ahbidle == 0);
4029+
4030+// winder add.
4031+#if 1
4032+ /* Note: Actually, I don't exactly why we need to put delay here. */
4033+ MDELAY(100);
4034+#endif
4035+ /* Core Soft Reset */
4036+ count = 0;
4037+ greset.b.csftrst = 1;
4038+ dwc_write_reg32( &global_regs->grstctl, greset.d32 );
4039+// winder add.
4040+#if 1
4041+ /* Note: Actually, I don't exactly why we need to put delay here. */
4042+ MDELAY(100);
4043+#endif
4044+ do {
4045+ greset.d32 = dwc_read_reg32( &global_regs->grstctl);
4046+ if (++count > 10000){
4047+ DWC_WARN("%s() HANG! Soft Reset GRSTCTL=%0x\n", __func__,
4048+ greset.d32);
4049+ break;
4050+ }
4051+ udelay(1);
4052+ } while (greset.b.csftrst == 1);
4053+ /* Wait for 3 PHY Clocks*/
4054+ //DWC_PRINT("100ms\n");
4055+ MDELAY(100);
4056+}
4057+
4058+
4059+
4060+/**
4061+ * Register HCD callbacks. The callbacks are used to start and stop
4062+ * the HCD for interrupt processing.
4063+ *
4064+ * @param _core_if Programming view of DWC_otg controller.
4065+ * @param _cb the HCD callback structure.
4066+ * @param _p pointer to be passed to callback function (usb_hcd*).
4067+ */
4068+extern void dwc_otg_cil_register_hcd_callbacks( dwc_otg_core_if_t *_core_if,
4069+ dwc_otg_cil_callbacks_t *_cb,
4070+ void *_p)
4071+{
4072+ _core_if->hcd_cb = _cb;
4073+ _cb->p = _p;
4074+}
4075+
4076+/**
4077+ * Register PCD callbacks. The callbacks are used to start and stop
4078+ * the PCD for interrupt processing.
4079+ *
4080+ * @param _core_if Programming view of DWC_otg controller.
4081+ * @param _cb the PCD callback structure.
4082+ * @param _p pointer to be passed to callback function (pcd*).
4083+ */
4084+extern void dwc_otg_cil_register_pcd_callbacks( dwc_otg_core_if_t *_core_if,
4085+ dwc_otg_cil_callbacks_t *_cb,
4086+ void *_p)
4087+{
4088+ _core_if->pcd_cb = _cb;
4089+ _cb->p = _p;
4090+}
4091+
4092diff --git a/drivers/usb/dwc_otg/dwc_otg_cil.h b/drivers/usb/dwc_otg/dwc_otg_cil.h
4093new file mode 100644
4094index 0000000..bbb9516
4095--- /dev/null
4096+++ b/drivers/usb/dwc_otg/dwc_otg_cil.h
4097@@ -0,0 +1,911 @@
4098+/* ==========================================================================
4099+ * $File: //dwh/usb_iip/dev/software/otg_ipmate/linux/drivers/dwc_otg_cil.h $
4100+ * $Revision: 1.1.1.1 $
4101+ * $Date: 2009-04-17 06:15:34 $
4102+ * $Change: 631780 $
4103+ *
4104+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
4105+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
4106+ * otherwise expressly agreed to in writing between Synopsys and you.
4107+ *
4108+ * The Software IS NOT an item of Licensed Software or Licensed Product under
4109+ * any End User Software License Agreement or Agreement for Licensed Product
4110+ * with Synopsys or any supplement thereto. You are permitted to use and
4111+ * redistribute this Software in source and binary forms, with or without
4112+ * modification, provided that redistributions of source code must retain this
4113+ * notice. You may not view, use, disclose, copy or distribute this file or
4114+ * any information contained herein except pursuant to this license grant from
4115+ * Synopsys. If you do not agree with this notice, including the disclaimer
4116+ * below, then you are not authorized to use the Software.
4117+ *
4118+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
4119+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4120+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4121+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
4122+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
4123+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
4124+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
4125+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4126+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
4127+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
4128+ * DAMAGE.
4129+ * ========================================================================== */
4130+
4131+#if !defined(__DWC_CIL_H__)
4132+#define __DWC_CIL_H__
4133+
4134+#include "dwc_otg_plat.h"
4135+
4136+#include "dwc_otg_regs.h"
4137+#ifdef DEBUG
4138+#include "linux/timer.h"
4139+#endif
4140+
4141+/* the OTG capabilities. */
4142+#define DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE 0
4143+#define DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE 1
4144+#define DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE 2
4145+/* the maximum speed of operation in host and device mode. */
4146+#define DWC_SPEED_PARAM_HIGH 0
4147+#define DWC_SPEED_PARAM_FULL 1
4148+/* the PHY clock rate in low power mode when connected to a
4149+ * Low Speed device in host mode. */
4150+#define DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ 0
4151+#define DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ 1
4152+/* the type of PHY interface to use. */
4153+#define DWC_PHY_TYPE_PARAM_FS 0
4154+#define DWC_PHY_TYPE_PARAM_UTMI 1
4155+#define DWC_PHY_TYPE_PARAM_ULPI 2
4156+/* whether to use the internal or external supply to
4157+ * drive the vbus with a ULPI phy. */
4158+#define DWC_PHY_ULPI_INTERNAL_VBUS 0
4159+#define DWC_PHY_ULPI_EXTERNAL_VBUS 1
4160+/* EP type. */
4161+
4162+/**
4163+ * @file
4164+ * This file contains the interface to the Core Interface Layer.
4165+ */
4166+
4167+/**
4168+ * The <code>dwc_ep</code> structure represents the state of a single
4169+ * endpoint when acting in device mode. It contains the data items
4170+ * needed for an endpoint to be activated and transfer packets.
4171+ */
4172+typedef struct dwc_ep {
4173+ /** EP number used for register address lookup */
4174+ uint8_t num;
4175+ /** EP direction 0 = OUT */
4176+ unsigned is_in : 1;
4177+ /** EP active. */
4178+ unsigned active : 1;
4179+
4180+ /** Periodic Tx FIFO # for IN EPs For INTR EP set to 0 to use non-periodic Tx FIFO
4181+ If dedicated Tx FIFOs are enabled for all IN Eps - Tx FIFO # FOR IN EPs*/
4182+ unsigned tx_fifo_num : 4;
4183+ /** EP type: 0 - Control, 1 - ISOC, 2 - BULK, 3 - INTR */
4184+ unsigned type : 2;
4185+#define DWC_OTG_EP_TYPE_CONTROL 0
4186+#define DWC_OTG_EP_TYPE_ISOC 1
4187+#define DWC_OTG_EP_TYPE_BULK 2
4188+#define DWC_OTG_EP_TYPE_INTR 3
4189+
4190+ /** DATA start PID for INTR and BULK EP */
4191+ unsigned data_pid_start : 1;
4192+ /** Frame (even/odd) for ISOC EP */
4193+ unsigned even_odd_frame : 1;
4194+ /** Max Packet bytes */
4195+ unsigned maxpacket : 11;
4196+
4197+ /** @name Transfer state */
4198+ /** @{ */
4199+
4200+ /**
4201+ * Pointer to the beginning of the transfer buffer -- do not modify
4202+ * during transfer.
4203+ */
4204+
4205+ uint32_t dma_addr;
4206+
4207+ uint8_t *start_xfer_buff;
4208+ /** pointer to the transfer buffer */
4209+ uint8_t *xfer_buff;
4210+ /** Number of bytes to transfer */
4211+ unsigned xfer_len : 19;
4212+ /** Number of bytes transferred. */
4213+ unsigned xfer_count : 19;
4214+ /** Sent ZLP */
4215+ unsigned sent_zlp : 1;
4216+ /** Total len for control transfer */
4217+ unsigned total_len : 19;
4218+
4219+ /** stall clear flag */
4220+ unsigned stall_clear_flag : 1;
4221+
4222+ /** @} */
4223+} dwc_ep_t;
4224+
4225+/*
4226+ * Reasons for halting a host channel.
4227+ */
4228+typedef enum dwc_otg_halt_status {
4229+ DWC_OTG_HC_XFER_NO_HALT_STATUS,
4230+ DWC_OTG_HC_XFER_COMPLETE,
4231+ DWC_OTG_HC_XFER_URB_COMPLETE,
4232+ DWC_OTG_HC_XFER_ACK,
4233+ DWC_OTG_HC_XFER_NAK,
4234+ DWC_OTG_HC_XFER_NYET,
4235+ DWC_OTG_HC_XFER_STALL,
4236+ DWC_OTG_HC_XFER_XACT_ERR,
4237+ DWC_OTG_HC_XFER_FRAME_OVERRUN,
4238+ DWC_OTG_HC_XFER_BABBLE_ERR,
4239+ DWC_OTG_HC_XFER_DATA_TOGGLE_ERR,
4240+ DWC_OTG_HC_XFER_AHB_ERR,
4241+ DWC_OTG_HC_XFER_PERIODIC_INCOMPLETE,
4242+ DWC_OTG_HC_XFER_URB_DEQUEUE
4243+} dwc_otg_halt_status_e;
4244+
4245+/**
4246+ * Host channel descriptor. This structure represents the state of a single
4247+ * host channel when acting in host mode. It contains the data items needed to
4248+ * transfer packets to an endpoint via a host channel.
4249+ */
4250+typedef struct dwc_hc {
4251+ /** Host channel number used for register address lookup */
4252+ uint8_t hc_num;
4253+
4254+ /** Device to access */
4255+ unsigned dev_addr : 7;
4256+
4257+ /** EP to access */
4258+ unsigned ep_num : 4;
4259+
4260+ /** EP direction. 0: OUT, 1: IN */
4261+ unsigned ep_is_in : 1;
4262+
4263+ /**
4264+ * EP speed.
4265+ * One of the following values:
4266+ * - DWC_OTG_EP_SPEED_LOW
4267+ * - DWC_OTG_EP_SPEED_FULL
4268+ * - DWC_OTG_EP_SPEED_HIGH
4269+ */
4270+ unsigned speed : 2;
4271+#define DWC_OTG_EP_SPEED_LOW 0
4272+#define DWC_OTG_EP_SPEED_FULL 1
4273+#define DWC_OTG_EP_SPEED_HIGH 2
4274+
4275+ /**
4276+ * Endpoint type.
4277+ * One of the following values:
4278+ * - DWC_OTG_EP_TYPE_CONTROL: 0
4279+ * - DWC_OTG_EP_TYPE_ISOC: 1
4280+ * - DWC_OTG_EP_TYPE_BULK: 2
4281+ * - DWC_OTG_EP_TYPE_INTR: 3
4282+ */
4283+ unsigned ep_type : 2;
4284+
4285+ /** Max packet size in bytes */
4286+ unsigned max_packet : 11;
4287+
4288+ /**
4289+ * PID for initial transaction.
4290+ * 0: DATA0,<br>
4291+ * 1: DATA2,<br>
4292+ * 2: DATA1,<br>
4293+ * 3: MDATA (non-Control EP),
4294+ * SETUP (Control EP)
4295+ */
4296+ unsigned data_pid_start : 2;
4297+#define DWC_OTG_HC_PID_DATA0 0
4298+#define DWC_OTG_HC_PID_DATA2 1
4299+#define DWC_OTG_HC_PID_DATA1 2
4300+#define DWC_OTG_HC_PID_MDATA 3
4301+#define DWC_OTG_HC_PID_SETUP 3
4302+
4303+ /** Number of periodic transactions per (micro)frame */
4304+ unsigned multi_count: 2;
4305+
4306+ /** @name Transfer State */
4307+ /** @{ */
4308+
4309+ /** Pointer to the current transfer buffer position. */
4310+ uint8_t *xfer_buff;
4311+ /** Total number of bytes to transfer. */
4312+ uint32_t xfer_len;
4313+ /** Number of bytes transferred so far. */
4314+ uint32_t xfer_count;
4315+ /** Packet count at start of transfer.*/
4316+ uint16_t start_pkt_count;
4317+
4318+ /**
4319+ * Flag to indicate whether the transfer has been started. Set to 1 if
4320+ * it has been started, 0 otherwise.
4321+ */
4322+ uint8_t xfer_started;
4323+
4324+ /**
4325+ * Set to 1 to indicate that a PING request should be issued on this
4326+ * channel. If 0, process normally.
4327+ */
4328+ uint8_t do_ping;
4329+
4330+ /**
4331+ * Set to 1 to indicate that the error count for this transaction is
4332+ * non-zero. Set to 0 if the error count is 0.
4333+ */
4334+ uint8_t error_state;
4335+
4336+ /**
4337+ * Set to 1 to indicate that this channel should be halted the next
4338+ * time a request is queued for the channel. This is necessary in
4339+ * slave mode if no request queue space is available when an attempt
4340+ * is made to halt the channel.
4341+ */
4342+ uint8_t halt_on_queue;
4343+
4344+ /**
4345+ * Set to 1 if the host channel has been halted, but the core is not
4346+ * finished flushing queued requests. Otherwise 0.
4347+ */
4348+ uint8_t halt_pending;
4349+
4350+ /**
4351+ * Reason for halting the host channel.
4352+ */
4353+ dwc_otg_halt_status_e halt_status;
4354+
4355+ /*
4356+ * Split settings for the host channel
4357+ */
4358+ uint8_t do_split; /**< Enable split for the channel */
4359+ uint8_t complete_split; /**< Enable complete split */
4360+ uint8_t hub_addr; /**< Address of high speed hub */
4361+
4362+ uint8_t port_addr; /**< Port of the low/full speed device */
4363+ /** Split transaction position
4364+ * One of the following values:
4365+ * - DWC_HCSPLIT_XACTPOS_MID
4366+ * - DWC_HCSPLIT_XACTPOS_BEGIN
4367+ * - DWC_HCSPLIT_XACTPOS_END
4368+ * - DWC_HCSPLIT_XACTPOS_ALL */
4369+ uint8_t xact_pos;
4370+
4371+ /** Set when the host channel does a short read. */
4372+ uint8_t short_read;
4373+
4374+ /**
4375+ * Number of requests issued for this channel since it was assigned to
4376+ * the current transfer (not counting PINGs).
4377+ */
4378+ uint8_t requests;
4379+
4380+ /**
4381+ * Queue Head for the transfer being processed by this channel.
4382+ */
4383+ struct dwc_otg_qh *qh;
4384+
4385+ /** @} */
4386+
4387+ /** Entry in list of host channels. */
4388+ struct list_head hc_list_entry;
4389+} dwc_hc_t;
4390+
4391+/**
4392+ * The following parameters may be specified when starting the module. These
4393+ * parameters define how the DWC_otg controller should be configured.
4394+ * Parameter values are passed to the CIL initialization function
4395+ * dwc_otg_cil_init.
4396+ */
4397+
4398+typedef struct dwc_otg_core_params
4399+{
4400+ int32_t opt;
4401+//#define dwc_param_opt_default 1
4402+ /**
4403+ * Specifies the OTG capabilities. The driver will automatically
4404+ * detect the value for this parameter if none is specified.
4405+ * 0 - HNP and SRP capable (default)
4406+ * 1 - SRP Only capable
4407+ * 2 - No HNP/SRP capable
4408+ */
4409+ int32_t otg_cap;
4410+#define DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE 0
4411+#define DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE 1
4412+#define DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE 2
4413+//#define dwc_param_otg_cap_default DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE
4414+ /**
4415+ * Specifies whether to use slave or DMA mode for accessing the data
4416+ * FIFOs. The driver will automatically detect the value for this
4417+ * parameter if none is specified.
4418+ * 0 - Slave
4419+ * 1 - DMA (default, if available)
4420+ */
4421+ int32_t dma_enable;
4422+//#define dwc_param_dma_enable_default 1
4423+ /** The DMA Burst size (applicable only for External DMA
4424+ * Mode). 1, 4, 8 16, 32, 64, 128, 256 (default 32)
4425+ */
4426+ int32_t dma_burst_size; /* Translate this to GAHBCFG values */
4427+//#define dwc_param_dma_burst_size_default 32
4428+ /**
4429+ * Specifies the maximum speed of operation in host and device mode.
4430+ * The actual speed depends on the speed of the attached device and
4431+ * the value of phy_type. The actual speed depends on the speed of the
4432+ * attached device.
4433+ * 0 - High Speed (default)
4434+ * 1 - Full Speed
4435+ */
4436+ int32_t speed;
4437+//#define dwc_param_speed_default 0
4438+#define DWC_SPEED_PARAM_HIGH 0
4439+#define DWC_SPEED_PARAM_FULL 1
4440+
4441+ /** Specifies whether low power mode is supported when attached
4442+ * to a Full Speed or Low Speed device in host mode.
4443+ * 0 - Don't support low power mode (default)
4444+ * 1 - Support low power mode
4445+ */
4446+ int32_t host_support_fs_ls_low_power;
4447+//#define dwc_param_host_support_fs_ls_low_power_default 0
4448+ /** Specifies the PHY clock rate in low power mode when connected to a
4449+ * Low Speed device in host mode. This parameter is applicable only if
4450+ * HOST_SUPPORT_FS_LS_LOW_POWER is enabled. If PHY_TYPE is set to FS
4451+ * then defaults to 6 MHZ otherwise 48 MHZ.
4452+ *
4453+ * 0 - 48 MHz
4454+ * 1 - 6 MHz
4455+ */
4456+ int32_t host_ls_low_power_phy_clk;
4457+//#define dwc_param_host_ls_low_power_phy_clk_default 0
4458+#define DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ 0
4459+#define DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ 1
4460+ /**
4461+ * 0 - Use cC FIFO size parameters
4462+ * 1 - Allow dynamic FIFO sizing (default)
4463+ */
4464+ int32_t enable_dynamic_fifo;
4465+//#define dwc_param_enable_dynamic_fifo_default 1
4466+ /** Total number of 4-byte words in the data FIFO memory. This
4467+ * memory includes the Rx FIFO, non-periodic Tx FIFO, and periodic
4468+ * Tx FIFOs.
4469+ * 32 to 32768 (default 8192)
4470+ * Note: The total FIFO memory depth in the FPGA configuration is 8192.
4471+ */
4472+ int32_t data_fifo_size;
4473+//#define dwc_param_data_fifo_size_default 8192
4474+ /** Number of 4-byte words in the Rx FIFO in device mode when dynamic
4475+ * FIFO sizing is enabled.
4476+ * 16 to 32768 (default 1064)
4477+ */
4478+ int32_t dev_rx_fifo_size;
4479+//#define dwc_param_dev_rx_fifo_size_default 1064
4480+ /** Number of 4-byte words in the non-periodic Tx FIFO in device mode
4481+ * when dynamic FIFO sizing is enabled.
4482+ * 16 to 32768 (default 1024)
4483+ */
4484+ int32_t dev_nperio_tx_fifo_size;
4485+//#define dwc_param_dev_nperio_tx_fifo_size_default 1024
4486+ /** Number of 4-byte words in each of the periodic Tx FIFOs in device
4487+ * mode when dynamic FIFO sizing is enabled.
4488+ * 4 to 768 (default 256)
4489+ */
4490+ uint32_t dev_perio_tx_fifo_size[MAX_PERIO_FIFOS];
4491+//#define dwc_param_dev_perio_tx_fifo_size_default 256
4492+ /** Number of 4-byte words in the Rx FIFO in host mode when dynamic
4493+ * FIFO sizing is enabled.
4494+ * 16 to 32768 (default 1024)
4495+ */
4496+ int32_t host_rx_fifo_size;
4497+//#define dwc_param_host_rx_fifo_size_default 1024
4498+ /** Number of 4-byte words in the non-periodic Tx FIFO in host mode
4499+ * when Dynamic FIFO sizing is enabled in the core.
4500+ * 16 to 32768 (default 1024)
4501+ */
4502+ int32_t host_nperio_tx_fifo_size;
4503+//#define dwc_param_host_nperio_tx_fifo_size_default 1024
4504+ /** Number of 4-byte words in the host periodic Tx FIFO when dynamic
4505+ * FIFO sizing is enabled.
4506+ * 16 to 32768 (default 1024)
4507+ */
4508+ int32_t host_perio_tx_fifo_size;
4509+//#define dwc_param_host_perio_tx_fifo_size_default 1024
4510+ /** The maximum transfer size supported in bytes.
4511+ * 2047 to 65,535 (default 65,535)
4512+ */
4513+ int32_t max_transfer_size;
4514+//#define dwc_param_max_transfer_size_default 65535
4515+ /** The maximum number of packets in a transfer.
4516+ * 15 to 511 (default 511)
4517+ */
4518+ int32_t max_packet_count;
4519+//#define dwc_param_max_packet_count_default 511
4520+ /** The number of host channel registers to use.
4521+ * 1 to 16 (default 12)
4522+ * Note: The FPGA configuration supports a maximum of 12 host channels.
4523+ */
4524+ int32_t host_channels;
4525+//#define dwc_param_host_channels_default 12
4526+ /** The number of endpoints in addition to EP0 available for device
4527+ * mode operations.
4528+ * 1 to 15 (default 6 IN and OUT)
4529+ * Note: The FPGA configuration supports a maximum of 6 IN and OUT
4530+ * endpoints in addition to EP0.
4531+ */
4532+ int32_t dev_endpoints;
4533+//#define dwc_param_dev_endpoints_default 6
4534+ /**
4535+ * Specifies the type of PHY interface to use. By default, the driver
4536+ * will automatically detect the phy_type.
4537+ *
4538+ * 0 - Full Speed PHY
4539+ * 1 - UTMI+ (default)
4540+ * 2 - ULPI
4541+ */
4542+ int32_t phy_type;
4543+#define DWC_PHY_TYPE_PARAM_FS 0
4544+#define DWC_PHY_TYPE_PARAM_UTMI 1
4545+#define DWC_PHY_TYPE_PARAM_ULPI 2
4546+//#define dwc_param_phy_type_default DWC_PHY_TYPE_PARAM_UTMI
4547+ /**
4548+ * Specifies the UTMI+ Data Width. This parameter is
4549+ * applicable for a PHY_TYPE of UTMI+ or ULPI. (For a ULPI
4550+ * PHY_TYPE, this parameter indicates the data width between
4551+ * the MAC and the ULPI Wrapper.) Also, this parameter is
4552+ * applicable only if the OTG_HSPHY_WIDTH cC parameter was set
4553+ * to "8 and 16 bits", meaning that the core has been
4554+ * configured to work at either data path width.
4555+ *
4556+ * 8 or 16 bits (default 16)
4557+ */
4558+ int32_t phy_utmi_width;
4559+//#define dwc_param_phy_utmi_width_default 16
4560+ /**
4561+ * Specifies whether the ULPI operates at double or single
4562+ * data rate. This parameter is only applicable if PHY_TYPE is
4563+ * ULPI.
4564+ *
4565+ * 0 - single data rate ULPI interface with 8 bit wide data
4566+ * bus (default)
4567+ * 1 - double data rate ULPI interface with 4 bit wide data
4568+ * bus
4569+ */
4570+ int32_t phy_ulpi_ddr;
4571+//#define dwc_param_phy_ulpi_ddr_default 0
4572+ /**
4573+ * Specifies whether to use the internal or external supply to
4574+ * drive the vbus with a ULPI phy.
4575+ */
4576+ int32_t phy_ulpi_ext_vbus;
4577+#define DWC_PHY_ULPI_INTERNAL_VBUS 0
4578+#define DWC_PHY_ULPI_EXTERNAL_VBUS 1
4579+//#define dwc_param_phy_ulpi_ext_vbus_default DWC_PHY_ULPI_INTERNAL_VBUS
4580+ /**
4581+ * Specifies whether to use the I2Cinterface for full speed PHY. This
4582+ * parameter is only applicable if PHY_TYPE is FS.
4583+ * 0 - No (default)
4584+ * 1 - Yes
4585+ */
4586+ int32_t i2c_enable;
4587+//#define dwc_param_i2c_enable_default 0
4588+
4589+ int32_t ulpi_fs_ls;
4590+//#define dwc_param_ulpi_fs_ls_default 0
4591+
4592+ int32_t ts_dline;
4593+//#define dwc_param_ts_dline_default 0
4594+
4595+ /**
4596+ * Specifies whether dedicated transmit FIFOs are
4597+ * enabled for non periodic IN endpoints in device mode
4598+ * 0 - No
4599+ * 1 - Yes
4600+ */
4601+ int32_t en_multiple_tx_fifo;
4602+#define dwc_param_en_multiple_tx_fifo_default 1
4603+
4604+ /** Number of 4-byte words in each of the Tx FIFOs in device
4605+ * mode when dynamic FIFO sizing is enabled.
4606+ * 4 to 768 (default 256)
4607+ */
4608+ uint32_t dev_tx_fifo_size[MAX_TX_FIFOS];
4609+#define dwc_param_dev_tx_fifo_size_default 256
4610+
4611+ /** Thresholding enable flag-
4612+ * bit 0 - enable non-ISO Tx thresholding
4613+ * bit 1 - enable ISO Tx thresholding
4614+ * bit 2 - enable Rx thresholding
4615+ */
4616+ uint32_t thr_ctl;
4617+#define dwc_param_thr_ctl_default 0
4618+
4619+ /** Thresholding length for Tx
4620+ * FIFOs in 32 bit DWORDs
4621+ */
4622+ uint32_t tx_thr_length;
4623+#define dwc_param_tx_thr_length_default 64
4624+
4625+ /** Thresholding length for Rx
4626+ * FIFOs in 32 bit DWORDs
4627+ */
4628+ uint32_t rx_thr_length;
4629+#define dwc_param_rx_thr_length_default 64
4630+} dwc_otg_core_params_t;
4631+
4632+#ifdef DEBUG
4633+struct dwc_otg_core_if;
4634+typedef struct hc_xfer_info
4635+{
4636+ struct dwc_otg_core_if *core_if;
4637+ dwc_hc_t *hc;
4638+} hc_xfer_info_t;
4639+#endif
4640+
4641+/**
4642+ * The <code>dwc_otg_core_if</code> structure contains information needed to manage
4643+ * the DWC_otg controller acting in either host or device mode. It
4644+ * represents the programming view of the controller as a whole.
4645+ */
4646+typedef struct dwc_otg_core_if
4647+{
4648+ /** Parameters that define how the core should be configured.*/
4649+ dwc_otg_core_params_t *core_params;
4650+
4651+ /** Core Global registers starting at offset 000h. */
4652+ dwc_otg_core_global_regs_t *core_global_regs;
4653+
4654+ /** Device-specific information */
4655+ dwc_otg_dev_if_t *dev_if;
4656+ /** Host-specific information */
4657+ dwc_otg_host_if_t *host_if;
4658+
4659+ /*
4660+ * Set to 1 if the core PHY interface bits in USBCFG have been
4661+ * initialized.
4662+ */
4663+ uint8_t phy_init_done;
4664+
4665+ /*
4666+ * SRP Success flag, set by srp success interrupt in FS I2C mode
4667+ */
4668+ uint8_t srp_success;
4669+ uint8_t srp_timer_started;
4670+
4671+ /* Common configuration information */
4672+ /** Power and Clock Gating Control Register */
4673+ volatile uint32_t *pcgcctl;
4674+#define DWC_OTG_PCGCCTL_OFFSET 0xE00
4675+
4676+ /** Push/pop addresses for endpoints or host channels.*/
4677+ uint32_t *data_fifo[MAX_EPS_CHANNELS];
4678+#define DWC_OTG_DATA_FIFO_OFFSET 0x1000
4679+#define DWC_OTG_DATA_FIFO_SIZE 0x1000
4680+
4681+ /** Total RAM for FIFOs (Bytes) */
4682+ uint16_t total_fifo_size;
4683+ /** Size of Rx FIFO (Bytes) */
4684+ uint16_t rx_fifo_size;
4685+ /** Size of Non-periodic Tx FIFO (Bytes) */
4686+ uint16_t nperio_tx_fifo_size;
4687+
4688+ /** 1 if DMA is enabled, 0 otherwise. */
4689+ uint8_t dma_enable;
4690+
4691+ /** 1 if dedicated Tx FIFOs are enabled, 0 otherwise. */
4692+ uint8_t en_multiple_tx_fifo;
4693+
4694+ /** Set to 1 if multiple packets of a high-bandwidth transfer is in
4695+ * process of being queued */
4696+ uint8_t queuing_high_bandwidth;
4697+
4698+ /** Hardware Configuration -- stored here for convenience.*/
4699+ hwcfg1_data_t hwcfg1;
4700+ hwcfg2_data_t hwcfg2;
4701+ hwcfg3_data_t hwcfg3;
4702+ hwcfg4_data_t hwcfg4;
4703+
4704+ /** The operational State, during transations
4705+ * (a_host>>a_peripherial and b_device=>b_host) this may not
4706+ * match the core but allows the software to determine
4707+ * transitions.
4708+ */
4709+ uint8_t op_state;
4710+
4711+ /**
4712+ * Set to 1 if the HCD needs to be restarted on a session request
4713+ * interrupt. This is required if no connector ID status change has
4714+ * occurred since the HCD was last disconnected.
4715+ */
4716+ uint8_t restart_hcd_on_session_req;
4717+
4718+ /** HCD callbacks */
4719+ /** A-Device is a_host */
4720+#define A_HOST (1)
4721+ /** A-Device is a_suspend */
4722+#define A_SUSPEND (2)
4723+ /** A-Device is a_peripherial */
4724+#define A_PERIPHERAL (3)
4725+ /** B-Device is operating as a Peripheral. */
4726+#define B_PERIPHERAL (4)
4727+ /** B-Device is operating as a Host. */
4728+#define B_HOST (5)
4729+
4730+ /** HCD callbacks */
4731+ struct dwc_otg_cil_callbacks *hcd_cb;
4732+ /** PCD callbacks */
4733+ struct dwc_otg_cil_callbacks *pcd_cb;
4734+
4735+ /** Device mode Periodic Tx FIFO Mask */
4736+ uint32_t p_tx_msk;
4737+ /** Device mode Periodic Tx FIFO Mask */
4738+ uint32_t tx_msk;
4739+
4740+#ifdef DEBUG
4741+ uint32_t start_hcchar_val[MAX_EPS_CHANNELS];
4742+
4743+ hc_xfer_info_t hc_xfer_info[MAX_EPS_CHANNELS];
4744+ struct timer_list hc_xfer_timer[MAX_EPS_CHANNELS];
4745+
4746+#if 1 // winder
4747+ uint32_t hfnum_7_samples;
4748+ uint32_t hfnum_7_frrem_accum;
4749+ uint32_t hfnum_0_samples;
4750+ uint32_t hfnum_0_frrem_accum;
4751+ uint32_t hfnum_other_samples;
4752+ uint32_t hfnum_other_frrem_accum;
4753+#else
4754+ uint32_t hfnum_7_samples;
4755+ uint64_t hfnum_7_frrem_accum;
4756+ uint32_t hfnum_0_samples;
4757+ uint64_t hfnum_0_frrem_accum;
4758+ uint32_t hfnum_other_samples;
4759+ uint64_t hfnum_other_frrem_accum;
4760+#endif
4761+ resource_size_t phys_addr; /* Added to support PLB DMA : phys-virt mapping */
4762+#endif
4763+
4764+} dwc_otg_core_if_t;
4765+
4766+/*
4767+ * The following functions support initialization of the CIL driver component
4768+ * and the DWC_otg controller.
4769+ */
4770+extern dwc_otg_core_if_t *dwc_otg_cil_init(const uint32_t *_reg_base_addr,
4771+ dwc_otg_core_params_t *_core_params);
4772+extern void dwc_otg_cil_remove(dwc_otg_core_if_t *_core_if);
4773+extern void dwc_otg_core_init(dwc_otg_core_if_t *_core_if);
4774+extern void dwc_otg_core_host_init(dwc_otg_core_if_t *_core_if);
4775+extern void dwc_otg_core_dev_init(dwc_otg_core_if_t *_core_if);
4776+extern void dwc_otg_enable_global_interrupts( dwc_otg_core_if_t *_core_if );
4777+extern void dwc_otg_disable_global_interrupts( dwc_otg_core_if_t *_core_if );
4778+
4779+/** @name Device CIL Functions
4780+ * The following functions support managing the DWC_otg controller in device
4781+ * mode.
4782+ */
4783+/**@{*/
4784+extern void dwc_otg_wakeup(dwc_otg_core_if_t *_core_if);
4785+extern void dwc_otg_read_setup_packet (dwc_otg_core_if_t *_core_if, uint32_t *_dest);
4786+extern uint32_t dwc_otg_get_frame_number(dwc_otg_core_if_t *_core_if);
4787+extern void dwc_otg_ep0_activate(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep);
4788+extern void dwc_otg_ep_activate(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep);
4789+extern void dwc_otg_ep_deactivate(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep);
4790+extern void dwc_otg_ep_start_transfer(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep);
4791+extern void dwc_otg_ep0_start_transfer(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep);
4792+extern void dwc_otg_ep0_continue_transfer(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep);
4793+extern void dwc_otg_ep_write_packet(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep, int _dma);
4794+extern void dwc_otg_ep_set_stall(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep);
4795+extern void dwc_otg_ep_clear_stall(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep);
4796+extern void dwc_otg_enable_device_interrupts(dwc_otg_core_if_t *_core_if);
4797+extern void dwc_otg_dump_dev_registers(dwc_otg_core_if_t *_core_if);
4798+/**@}*/
4799+
4800+/** @name Host CIL Functions
4801+ * The following functions support managing the DWC_otg controller in host
4802+ * mode.
4803+ */
4804+/**@{*/
4805+extern void dwc_otg_hc_init(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc);
4806+extern void dwc_otg_hc_halt(dwc_otg_core_if_t *_core_if,
4807+ dwc_hc_t *_hc,
4808+ dwc_otg_halt_status_e _halt_status);
4809+extern void dwc_otg_hc_cleanup(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc);
4810+extern void dwc_otg_hc_start_transfer(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc);
4811+extern int dwc_otg_hc_continue_transfer(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc);
4812+extern void dwc_otg_hc_do_ping(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc);
4813+extern void dwc_otg_hc_write_packet(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc);
4814+extern void dwc_otg_enable_host_interrupts(dwc_otg_core_if_t *_core_if);
4815+extern void dwc_otg_disable_host_interrupts(dwc_otg_core_if_t *_core_if);
4816+
4817+/**
4818+ * This function Reads HPRT0 in preparation to modify. It keeps the
4819+ * WC bits 0 so that if they are read as 1, they won't clear when you
4820+ * write it back
4821+ */
4822+static inline uint32_t dwc_otg_read_hprt0(dwc_otg_core_if_t *_core_if)
4823+{
4824+ hprt0_data_t hprt0;
4825+ hprt0.d32 = dwc_read_reg32(_core_if->host_if->hprt0);
4826+ hprt0.b.prtena = 0;
4827+ hprt0.b.prtconndet = 0;
4828+ hprt0.b.prtenchng = 0;
4829+ hprt0.b.prtovrcurrchng = 0;
4830+ return hprt0.d32;
4831+}
4832+
4833+extern void dwc_otg_dump_host_registers(dwc_otg_core_if_t *_core_if);
4834+/**@}*/
4835+
4836+/** @name Common CIL Functions
4837+ * The following functions support managing the DWC_otg controller in either
4838+ * device or host mode.
4839+ */
4840+/**@{*/
4841+
4842+extern void dwc_otg_read_packet(dwc_otg_core_if_t *core_if,
4843+ uint8_t *dest,
4844+ uint16_t bytes);
4845+
4846+extern void dwc_otg_dump_global_registers(dwc_otg_core_if_t *_core_if);
4847+
4848+extern void dwc_otg_flush_tx_fifo( dwc_otg_core_if_t *_core_if,
4849+ const int _num );
4850+extern void dwc_otg_flush_rx_fifo( dwc_otg_core_if_t *_core_if );
4851+extern void dwc_otg_core_reset( dwc_otg_core_if_t *_core_if );
4852+
4853+#define NP_TXFIFO_EMPTY -1
4854+#define MAX_NP_TXREQUEST_Q_SLOTS 8
4855+/**
4856+ * This function returns the endpoint number of the request at
4857+ * the top of non-periodic TX FIFO, or -1 if the request FIFO is
4858+ * empty.
4859+ */
4860+static inline int dwc_otg_top_nptxfifo_epnum(dwc_otg_core_if_t *_core_if) {
4861+ gnptxsts_data_t txstatus = {.d32 = 0};
4862+
4863+ txstatus.d32 = dwc_read_reg32(&_core_if->core_global_regs->gnptxsts);
4864+ return (txstatus.b.nptxqspcavail == MAX_NP_TXREQUEST_Q_SLOTS ?
4865+ -1 : txstatus.b.nptxqtop_chnep);
4866+}
4867+/**
4868+ * This function returns the Core Interrupt register.
4869+ */
4870+static inline uint32_t dwc_otg_read_core_intr(dwc_otg_core_if_t *_core_if) {
4871+ return (dwc_read_reg32(&_core_if->core_global_regs->gintsts) &
4872+ dwc_read_reg32(&_core_if->core_global_regs->gintmsk));
4873+}
4874+
4875+/**
4876+ * This function returns the OTG Interrupt register.
4877+ */
4878+static inline uint32_t dwc_otg_read_otg_intr (dwc_otg_core_if_t *_core_if) {
4879+ return (dwc_read_reg32 (&_core_if->core_global_regs->gotgint));
4880+}
4881+
4882+/**
4883+ * This function reads the Device All Endpoints Interrupt register and
4884+ * returns the IN endpoint interrupt bits.
4885+ */
4886+static inline uint32_t dwc_otg_read_dev_all_in_ep_intr(dwc_otg_core_if_t *_core_if) {
4887+ uint32_t v;
4888+ v = dwc_read_reg32(&_core_if->dev_if->dev_global_regs->daint) &
4889+ dwc_read_reg32(&_core_if->dev_if->dev_global_regs->daintmsk);
4890+ return (v & 0xffff);
4891+
4892+}
4893+
4894+/**
4895+ * This function reads the Device All Endpoints Interrupt register and
4896+ * returns the OUT endpoint interrupt bits.
4897+ */
4898+static inline uint32_t dwc_otg_read_dev_all_out_ep_intr(dwc_otg_core_if_t *_core_if) {
4899+ uint32_t v;
4900+ v = dwc_read_reg32(&_core_if->dev_if->dev_global_regs->daint) &
4901+ dwc_read_reg32(&_core_if->dev_if->dev_global_regs->daintmsk);
4902+ return ((v & 0xffff0000) >> 16);
4903+}
4904+
4905+/**
4906+ * This function returns the Device IN EP Interrupt register
4907+ */
4908+static inline uint32_t dwc_otg_read_dev_in_ep_intr(dwc_otg_core_if_t *_core_if,
4909+ dwc_ep_t *_ep)
4910+{
4911+ dwc_otg_dev_if_t *dev_if = _core_if->dev_if;
4912+ uint32_t v, msk, emp;
4913+ msk = dwc_read_reg32(&dev_if->dev_global_regs->diepmsk);
4914+ emp = dwc_read_reg32(&dev_if->dev_global_regs->dtknqr4_fifoemptymsk);
4915+ msk |= ((emp >> _ep->num) & 0x1) << 7;
4916+ v = dwc_read_reg32(&dev_if->in_ep_regs[_ep->num]->diepint) & msk;
4917+/*
4918+ dwc_otg_dev_if_t *dev_if = _core_if->dev_if;
4919+ uint32_t v;
4920+ v = dwc_read_reg32(&dev_if->in_ep_regs[_ep->num]->diepint) &
4921+ dwc_read_reg32(&dev_if->dev_global_regs->diepmsk);
4922+*/
4923+ return v;
4924+}
4925+/**
4926+ * This function returns the Device OUT EP Interrupt register
4927+ */
4928+static inline uint32_t dwc_otg_read_dev_out_ep_intr(dwc_otg_core_if_t *_core_if,
4929+ dwc_ep_t *_ep)
4930+{
4931+ dwc_otg_dev_if_t *dev_if = _core_if->dev_if;
4932+ uint32_t v;
4933+ v = dwc_read_reg32( &dev_if->out_ep_regs[_ep->num]->doepint) &
4934+ dwc_read_reg32(&dev_if->dev_global_regs->doepmsk);
4935+ return v;
4936+}
4937+
4938+/**
4939+ * This function returns the Host All Channel Interrupt register
4940+ */
4941+static inline uint32_t dwc_otg_read_host_all_channels_intr (dwc_otg_core_if_t *_core_if)
4942+{
4943+ return (dwc_read_reg32 (&_core_if->host_if->host_global_regs->haint));
4944+}
4945+
4946+static inline uint32_t dwc_otg_read_host_channel_intr (dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc)
4947+{
4948+ return (dwc_read_reg32 (&_core_if->host_if->hc_regs[_hc->hc_num]->hcint));
4949+}
4950+
4951+
4952+/**
4953+ * This function returns the mode of the operation, host or device.
4954+ *
4955+ * @return 0 - Device Mode, 1 - Host Mode
4956+ */
4957+static inline uint32_t dwc_otg_mode(dwc_otg_core_if_t *_core_if) {
4958+ return (dwc_read_reg32( &_core_if->core_global_regs->gintsts ) & 0x1);
4959+}
4960+
4961+static inline uint8_t dwc_otg_is_device_mode(dwc_otg_core_if_t *_core_if)
4962+{
4963+ return (dwc_otg_mode(_core_if) != DWC_HOST_MODE);
4964+}
4965+static inline uint8_t dwc_otg_is_host_mode(dwc_otg_core_if_t *_core_if)
4966+{
4967+ return (dwc_otg_mode(_core_if) == DWC_HOST_MODE);
4968+}
4969+
4970+extern int32_t dwc_otg_handle_common_intr( dwc_otg_core_if_t *_core_if );
4971+
4972+
4973+/**@}*/
4974+
4975+/**
4976+ * DWC_otg CIL callback structure. This structure allows the HCD and
4977+ * PCD to register functions used for starting and stopping the PCD
4978+ * and HCD for role change on for a DRD.
4979+ */
4980+typedef struct dwc_otg_cil_callbacks
4981+{
4982+ /** Start function for role change */
4983+ int (*start) (void *_p);
4984+ /** Stop Function for role change */
4985+ int (*stop) (void *_p);
4986+ /** Disconnect Function for role change */
4987+ int (*disconnect) (void *_p);
4988+ /** Resume/Remote wakeup Function */
4989+ int (*resume_wakeup) (void *_p);
4990+ /** Suspend function */
4991+ int (*suspend) (void *_p);
4992+ /** Session Start (SRP) */
4993+ int (*session_start) (void *_p);
4994+ /** Pointer passed to start() and stop() */
4995+ void *p;
4996+} dwc_otg_cil_callbacks_t;
4997+
4998+
4999+
5000+extern void dwc_otg_cil_register_pcd_callbacks( dwc_otg_core_if_t *_core_if,
5001+ dwc_otg_cil_callbacks_t *_cb,
5002+ void *_p);
5003+extern void dwc_otg_cil_register_hcd_callbacks( dwc_otg_core_if_t *_core_if,
5004+ dwc_otg_cil_callbacks_t *_cb,
5005+ void *_p);
5006+
5007+
5008+#endif
5009diff --git a/drivers/usb/dwc_otg/dwc_otg_cil_ifx.h b/drivers/usb/dwc_otg/dwc_otg_cil_ifx.h
5010new file mode 100644
5011index 0000000..b0298ec
5012--- /dev/null
5013+++ b/drivers/usb/dwc_otg/dwc_otg_cil_ifx.h
5014@@ -0,0 +1,58 @@
5015+/******************************************************************************
5016+**
5017+** FILE NAME : dwc_otg_cil_ifx.h
5018+** PROJECT : Twinpass/Danube
5019+** MODULES : DWC OTG USB
5020+**
5021+** DATE : 07 Sep. 2007
5022+** AUTHOR : Sung Winder
5023+** DESCRIPTION : Default param value.
5024+** COPYRIGHT : Copyright (c) 2007
5025+** Infineon Technologies AG
5026+** 2F, No.2, Li-Hsin Rd., Hsinchu Science Park,
5027+** Hsin-chu City, 300 Taiwan.
5028+**
5029+** This program is free software; you can redistribute it and/or modify
5030+** it under the terms of the GNU General Public License as published by
5031+** the Free Software Foundation; either version 2 of the License, or
5032+** (at your option) any later version.
5033+**
5034+** HISTORY
5035+** $Date $Author $Comment
5036+** 12 April 2007 Sung Winder Initiate Version
5037+*******************************************************************************/
5038+#if !defined(__DWC_OTG_CIL_IFX_H__)
5039+#define __DWC_OTG_CIL_IFX_H__
5040+
5041+/* ================ Default param value ================== */
5042+#define dwc_param_opt_default 1
5043+#define dwc_param_otg_cap_default DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE
5044+#define dwc_param_dma_enable_default 1
5045+#define dwc_param_dma_burst_size_default 32
5046+#define dwc_param_speed_default DWC_SPEED_PARAM_HIGH
5047+#define dwc_param_host_support_fs_ls_low_power_default 0
5048+#define dwc_param_host_ls_low_power_phy_clk_default DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ
5049+#define dwc_param_enable_dynamic_fifo_default 1
5050+#define dwc_param_data_fifo_size_default 2048
5051+#define dwc_param_dev_rx_fifo_size_default 1024
5052+#define dwc_param_dev_nperio_tx_fifo_size_default 1024
5053+#define dwc_param_dev_perio_tx_fifo_size_default 768
5054+#define dwc_param_host_rx_fifo_size_default 640
5055+#define dwc_param_host_nperio_tx_fifo_size_default 640
5056+#define dwc_param_host_perio_tx_fifo_size_default 768
5057+#define dwc_param_max_transfer_size_default 65535
5058+#define dwc_param_max_packet_count_default 511
5059+#define dwc_param_host_channels_default 16
5060+#define dwc_param_dev_endpoints_default 6
5061+#define dwc_param_phy_type_default DWC_PHY_TYPE_PARAM_UTMI
5062+#define dwc_param_phy_utmi_width_default 16
5063+#define dwc_param_phy_ulpi_ddr_default 0
5064+#define dwc_param_phy_ulpi_ext_vbus_default DWC_PHY_ULPI_INTERNAL_VBUS
5065+#define dwc_param_i2c_enable_default 0
5066+#define dwc_param_ulpi_fs_ls_default 0
5067+#define dwc_param_ts_dline_default 0
5068+
5069+/* ======================================================= */
5070+
5071+#endif // __DWC_OTG_CIL_IFX_H__
5072+
5073diff --git a/drivers/usb/dwc_otg/dwc_otg_cil_intr.c b/drivers/usb/dwc_otg/dwc_otg_cil_intr.c
5074new file mode 100644
5075index 0000000..d469ab4
5076--- /dev/null
5077+++ b/drivers/usb/dwc_otg/dwc_otg_cil_intr.c
5078@@ -0,0 +1,708 @@
5079+/* ==========================================================================
5080+ * $File: //dwh/usb_iip/dev/software/otg_ipmate/linux/drivers/dwc_otg_cil_intr.c $
5081+ * $Revision: 1.1.1.1 $
5082+ * $Date: 2009-04-17 06:15:34 $
5083+ * $Change: 553126 $
5084+ *
5085+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
5086+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
5087+ * otherwise expressly agreed to in writing between Synopsys and you.
5088+ *
5089+ * The Software IS NOT an item of Licensed Software or Licensed Product under
5090+ * any End User Software License Agreement or Agreement for Licensed Product
5091+ * with Synopsys or any supplement thereto. You are permitted to use and
5092+ * redistribute this Software in source and binary forms, with or without
5093+ * modification, provided that redistributions of source code must retain this
5094+ * notice. You may not view, use, disclose, copy or distribute this file or
5095+ * any information contained herein except pursuant to this license grant from
5096+ * Synopsys. If you do not agree with this notice, including the disclaimer
5097+ * below, then you are not authorized to use the Software.
5098+ *
5099+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
5100+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5101+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
5102+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
5103+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
5104+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
5105+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
5106+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
5107+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5108+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
5109+ * DAMAGE.
5110+ * ========================================================================== */
5111+
5112+/** @file
5113+ *
5114+ * The Core Interface Layer provides basic services for accessing and
5115+ * managing the DWC_otg hardware. These services are used by both the
5116+ * Host Controller Driver and the Peripheral Controller Driver.
5117+ *
5118+ * This file contains the Common Interrupt handlers.
5119+ */
5120+#include "dwc_otg_plat.h"
5121+#include "dwc_otg_regs.h"
5122+#include "dwc_otg_cil.h"
5123+
5124+#ifdef DEBUG
5125+inline const char *op_state_str( dwc_otg_core_if_t *_core_if )
5126+{
5127+ return (_core_if->op_state==A_HOST?"a_host":
5128+ (_core_if->op_state==A_SUSPEND?"a_suspend":
5129+ (_core_if->op_state==A_PERIPHERAL?"a_peripheral":
5130+ (_core_if->op_state==B_PERIPHERAL?"b_peripheral":
5131+ (_core_if->op_state==B_HOST?"b_host":
5132+ "unknown")))));
5133+}
5134+#endif
5135+
5136+/** This function will log a debug message
5137+ *
5138+ * @param _core_if Programming view of DWC_otg controller.
5139+ */
5140+int32_t dwc_otg_handle_mode_mismatch_intr (dwc_otg_core_if_t *_core_if)
5141+{
5142+ gintsts_data_t gintsts;
5143+ DWC_WARN("Mode Mismatch Interrupt: currently in %s mode\n",
5144+ dwc_otg_mode(_core_if) ? "Host" : "Device");
5145+
5146+ /* Clear interrupt */
5147+ gintsts.d32 = 0;
5148+ gintsts.b.modemismatch = 1;
5149+ dwc_write_reg32 (&_core_if->core_global_regs->gintsts, gintsts.d32);
5150+ return 1;
5151+}
5152+
5153+/** Start the HCD. Helper function for using the HCD callbacks.
5154+ *
5155+ * @param _core_if Programming view of DWC_otg controller.
5156+ */
5157+static inline void hcd_start( dwc_otg_core_if_t *_core_if )
5158+{
5159+ if (_core_if->hcd_cb && _core_if->hcd_cb->start) {
5160+ _core_if->hcd_cb->start( _core_if->hcd_cb->p );
5161+ }
5162+}
5163+/** Stop the HCD. Helper function for using the HCD callbacks.
5164+ *
5165+ * @param _core_if Programming view of DWC_otg controller.
5166+ */
5167+static inline void hcd_stop( dwc_otg_core_if_t *_core_if )
5168+{
5169+ if (_core_if->hcd_cb && _core_if->hcd_cb->stop) {
5170+ _core_if->hcd_cb->stop( _core_if->hcd_cb->p );
5171+ }
5172+}
5173+/** Disconnect the HCD. Helper function for using the HCD callbacks.
5174+ *
5175+ * @param _core_if Programming view of DWC_otg controller.
5176+ */
5177+static inline void hcd_disconnect( dwc_otg_core_if_t *_core_if )
5178+{
5179+ if (_core_if->hcd_cb && _core_if->hcd_cb->disconnect) {
5180+ _core_if->hcd_cb->disconnect( _core_if->hcd_cb->p );
5181+ }
5182+}
5183+/** Inform the HCD the a New Session has begun. Helper function for
5184+ * using the HCD callbacks.
5185+ *
5186+ * @param _core_if Programming view of DWC_otg controller.
5187+ */
5188+static inline void hcd_session_start( dwc_otg_core_if_t *_core_if )
5189+{
5190+ if (_core_if->hcd_cb && _core_if->hcd_cb->session_start) {
5191+ _core_if->hcd_cb->session_start( _core_if->hcd_cb->p );
5192+ }
5193+}
5194+
5195+/** Start the PCD. Helper function for using the PCD callbacks.
5196+ *
5197+ * @param _core_if Programming view of DWC_otg controller.
5198+ */
5199+static inline void pcd_start( dwc_otg_core_if_t *_core_if )
5200+{
5201+ if (_core_if->pcd_cb && _core_if->pcd_cb->start ) {
5202+ _core_if->pcd_cb->start( _core_if->pcd_cb->p );
5203+ }
5204+}
5205+/** Stop the PCD. Helper function for using the PCD callbacks.
5206+ *
5207+ * @param _core_if Programming view of DWC_otg controller.
5208+ */
5209+static inline void pcd_stop( dwc_otg_core_if_t *_core_if )
5210+{
5211+ if (_core_if->pcd_cb && _core_if->pcd_cb->stop ) {
5212+ _core_if->pcd_cb->stop( _core_if->pcd_cb->p );
5213+ }
5214+}
5215+/** Suspend the PCD. Helper function for using the PCD callbacks.
5216+ *
5217+ * @param _core_if Programming view of DWC_otg controller.
5218+ */
5219+static inline void pcd_suspend( dwc_otg_core_if_t *_core_if )
5220+{
5221+ if (_core_if->pcd_cb && _core_if->pcd_cb->suspend ) {
5222+ _core_if->pcd_cb->suspend( _core_if->pcd_cb->p );
5223+ }
5224+}
5225+/** Resume the PCD. Helper function for using the PCD callbacks.
5226+ *
5227+ * @param _core_if Programming view of DWC_otg controller.
5228+ */
5229+static inline void pcd_resume( dwc_otg_core_if_t *_core_if )
5230+{
5231+ if (_core_if->pcd_cb && _core_if->pcd_cb->resume_wakeup ) {
5232+ _core_if->pcd_cb->resume_wakeup( _core_if->pcd_cb->p );
5233+ }
5234+}
5235+
5236+/**
5237+ * This function handles the OTG Interrupts. It reads the OTG
5238+ * Interrupt Register (GOTGINT) to determine what interrupt has
5239+ * occurred.
5240+ *
5241+ * @param _core_if Programming view of DWC_otg controller.
5242+ */
5243+int32_t dwc_otg_handle_otg_intr(dwc_otg_core_if_t *_core_if)
5244+{
5245+ dwc_otg_core_global_regs_t *global_regs =
5246+ _core_if->core_global_regs;
5247+ gotgint_data_t gotgint;
5248+ gotgctl_data_t gotgctl;
5249+ gintmsk_data_t gintmsk;
5250+
5251+ gotgint.d32 = dwc_read_reg32( &global_regs->gotgint);
5252+ gotgctl.d32 = dwc_read_reg32( &global_regs->gotgctl);
5253+ DWC_DEBUGPL(DBG_CIL, "++OTG Interrupt gotgint=%0x [%s]\n", gotgint.d32,
5254+ op_state_str(_core_if));
5255+ //DWC_DEBUGPL(DBG_CIL, "gotgctl=%08x\n", gotgctl.d32 );
5256+
5257+ if (gotgint.b.sesenddet) {
5258+ DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: "
5259+ "Session End Detected++ (%s)\n",
5260+ op_state_str(_core_if));
5261+ gotgctl.d32 = dwc_read_reg32( &global_regs->gotgctl);
5262+
5263+ if (_core_if->op_state == B_HOST) {
5264+ pcd_start( _core_if );
5265+ _core_if->op_state = B_PERIPHERAL;
5266+ } else {
5267+ /* If not B_HOST and Device HNP still set. HNP
5268+ * Did not succeed!*/
5269+ if (gotgctl.b.devhnpen) {
5270+ DWC_DEBUGPL(DBG_ANY, "Session End Detected\n");
5271+ DWC_ERROR( "Device Not Connected/Responding!\n" );
5272+ }
5273+
5274+ /* If Session End Detected the B-Cable has
5275+ * been disconnected. */
5276+ /* Reset PCD and Gadget driver to a
5277+ * clean state. */
5278+ pcd_stop(_core_if);
5279+ }
5280+ gotgctl.d32 = 0;
5281+ gotgctl.b.devhnpen = 1;
5282+ dwc_modify_reg32( &global_regs->gotgctl,
5283+ gotgctl.d32, 0);
5284+ }
5285+ if (gotgint.b.sesreqsucstschng) {
5286+ DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: "
5287+ "Session Reqeust Success Status Change++\n");
5288+ gotgctl.d32 = dwc_read_reg32( &global_regs->gotgctl);
5289+ if (gotgctl.b.sesreqscs) {
5290+ if ((_core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS) &&
5291+ (_core_if->core_params->i2c_enable)) {
5292+ _core_if->srp_success = 1;
5293+ }
5294+ else {
5295+ pcd_resume( _core_if );
5296+ /* Clear Session Request */
5297+ gotgctl.d32 = 0;
5298+ gotgctl.b.sesreq = 1;
5299+ dwc_modify_reg32( &global_regs->gotgctl,
5300+ gotgctl.d32, 0);
5301+ }
5302+ }
5303+ }
5304+ if (gotgint.b.hstnegsucstschng) {
5305+ /* Print statements during the HNP interrupt handling
5306+ * can cause it to fail.*/
5307+ gotgctl.d32 = dwc_read_reg32(&global_regs->gotgctl);
5308+ if (gotgctl.b.hstnegscs) {
5309+ if (dwc_otg_is_host_mode(_core_if) ) {
5310+ _core_if->op_state = B_HOST;
5311+ /*
5312+ * Need to disable SOF interrupt immediately.
5313+ * When switching from device to host, the PCD
5314+ * interrupt handler won't handle the
5315+ * interrupt if host mode is already set. The
5316+ * HCD interrupt handler won't get called if
5317+ * the HCD state is HALT. This means that the
5318+ * interrupt does not get handled and Linux
5319+ * complains loudly.
5320+ */
5321+ gintmsk.d32 = 0;
5322+ gintmsk.b.sofintr = 1;
5323+ dwc_modify_reg32(&global_regs->gintmsk,
5324+ gintmsk.d32, 0);
5325+ pcd_stop(_core_if);
5326+ /*
5327+ * Initialize the Core for Host mode.
5328+ */
5329+ hcd_start( _core_if );
5330+ _core_if->op_state = B_HOST;
5331+ }
5332+ } else {
5333+ gotgctl.d32 = 0;
5334+ gotgctl.b.hnpreq = 1;
5335+ gotgctl.b.devhnpen = 1;
5336+ dwc_modify_reg32( &global_regs->gotgctl,
5337+ gotgctl.d32, 0);
5338+ DWC_DEBUGPL( DBG_ANY, "HNP Failed\n");
5339+ DWC_ERROR( "Device Not Connected/Responding\n" );
5340+ }
5341+ }
5342+ if (gotgint.b.hstnegdet) {
5343+ /* The disconnect interrupt is set at the same time as
5344+ * Host Negotiation Detected. During the mode
5345+ * switch all interrupts are cleared so the disconnect
5346+ * interrupt handler will not get executed.
5347+ */
5348+ DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: "
5349+ "Host Negotiation Detected++ (%s)\n",
5350+ (dwc_otg_is_host_mode(_core_if)?"Host":"Device"));
5351+ if (dwc_otg_is_device_mode(_core_if)){
5352+ DWC_DEBUGPL(DBG_ANY, "a_suspend->a_peripheral (%d)\n",_core_if->op_state);
5353+ hcd_disconnect( _core_if );
5354+ pcd_start( _core_if );
5355+ _core_if->op_state = A_PERIPHERAL;
5356+ } else {
5357+ /*
5358+ * Need to disable SOF interrupt immediately. When
5359+ * switching from device to host, the PCD interrupt
5360+ * handler won't handle the interrupt if host mode is
5361+ * already set. The HCD interrupt handler won't get
5362+ * called if the HCD state is HALT. This means that
5363+ * the interrupt does not get handled and Linux
5364+ * complains loudly.
5365+ */
5366+ gintmsk.d32 = 0;
5367+ gintmsk.b.sofintr = 1;
5368+ dwc_modify_reg32(&global_regs->gintmsk,
5369+ gintmsk.d32, 0);
5370+ pcd_stop( _core_if );
5371+ hcd_start( _core_if );
5372+ _core_if->op_state = A_HOST;
5373+ }
5374+ }
5375+ if (gotgint.b.adevtoutchng) {
5376+ DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: "
5377+ "A-Device Timeout Change++\n");
5378+ }
5379+ if (gotgint.b.debdone) {
5380+ DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: "
5381+ "Debounce Done++\n");
5382+ }
5383+
5384+ /* Clear GOTGINT */
5385+ dwc_write_reg32 (&_core_if->core_global_regs->gotgint, gotgint.d32);
5386+
5387+ return 1;
5388+}
5389+
5390+/**
5391+ * This function handles the Connector ID Status Change Interrupt. It
5392+ * reads the OTG Interrupt Register (GOTCTL) to determine whether this
5393+ * is a Device to Host Mode transition or a Host Mode to Device
5394+ * Transition.
5395+ *
5396+ * This only occurs when the cable is connected/removed from the PHY
5397+ * connector.
5398+ *
5399+ * @param _core_if Programming view of DWC_otg controller.
5400+ */
5401+int32_t dwc_otg_handle_conn_id_status_change_intr(dwc_otg_core_if_t *_core_if)
5402+{
5403+ uint32_t count = 0;
5404+
5405+ gintsts_data_t gintsts = { .d32 = 0 };
5406+ gintmsk_data_t gintmsk = { .d32 = 0 };
5407+ gotgctl_data_t gotgctl = { .d32 = 0 };
5408+
5409+ /*
5410+ * Need to disable SOF interrupt immediately. If switching from device
5411+ * to host, the PCD interrupt handler won't handle the interrupt if
5412+ * host mode is already set. The HCD interrupt handler won't get
5413+ * called if the HCD state is HALT. This means that the interrupt does
5414+ * not get handled and Linux complains loudly.
5415+ */
5416+ gintmsk.b.sofintr = 1;
5417+ dwc_modify_reg32(&_core_if->core_global_regs->gintmsk, gintmsk.d32, 0);
5418+
5419+ DWC_DEBUGPL(DBG_CIL, " ++Connector ID Status Change Interrupt++ (%s)\n",
5420+ (dwc_otg_is_host_mode(_core_if)?"Host":"Device"));
5421+ gotgctl.d32 = dwc_read_reg32(&_core_if->core_global_regs->gotgctl);
5422+ DWC_DEBUGPL(DBG_CIL, "gotgctl=%0x\n", gotgctl.d32);
5423+ DWC_DEBUGPL(DBG_CIL, "gotgctl.b.conidsts=%d\n", gotgctl.b.conidsts);
5424+
5425+ /* B-Device connector (Device Mode) */
5426+ if (gotgctl.b.conidsts) {
5427+ /* Wait for switch to device mode. */
5428+ while (!dwc_otg_is_device_mode(_core_if) ){
5429+ DWC_PRINT("Waiting for Peripheral Mode, Mode=%s\n",
5430+ (dwc_otg_is_host_mode(_core_if)?"Host":"Peripheral"));
5431+ MDELAY(100);
5432+ if (++count > 10000) *(uint32_t*)NULL=0;
5433+ }
5434+ _core_if->op_state = B_PERIPHERAL;
5435+ dwc_otg_core_init(_core_if);
5436+ dwc_otg_enable_global_interrupts(_core_if);
5437+ pcd_start( _core_if );
5438+ } else {
5439+ /* A-Device connector (Host Mode) */
5440+ while (!dwc_otg_is_host_mode(_core_if) ) {
5441+ DWC_PRINT("Waiting for Host Mode, Mode=%s\n",
5442+ (dwc_otg_is_host_mode(_core_if)?"Host":"Peripheral"));
5443+ MDELAY(100);
5444+ if (++count > 10000) *(uint32_t*)NULL=0;
5445+ }
5446+ _core_if->op_state = A_HOST;
5447+ /*
5448+ * Initialize the Core for Host mode.
5449+ */
5450+ dwc_otg_core_init(_core_if);
5451+ dwc_otg_enable_global_interrupts(_core_if);
5452+ hcd_start( _core_if );
5453+ }
5454+
5455+ /* Set flag and clear interrupt */
5456+ gintsts.b.conidstschng = 1;
5457+ dwc_write_reg32 (&_core_if->core_global_regs->gintsts, gintsts.d32);
5458+
5459+ return 1;
5460+}
5461+
5462+/**
5463+ * This interrupt indicates that a device is initiating the Session
5464+ * Request Protocol to request the host to turn on bus power so a new
5465+ * session can begin. The handler responds by turning on bus power. If
5466+ * the DWC_otg controller is in low power mode, the handler brings the
5467+ * controller out of low power mode before turning on bus power.
5468+ *
5469+ * @param _core_if Programming view of DWC_otg controller.
5470+ */
5471+int32_t dwc_otg_handle_session_req_intr( dwc_otg_core_if_t *_core_if )
5472+{
5473+#ifndef DWC_HOST_ONLY // winder
5474+ hprt0_data_t hprt0;
5475+#endif
5476+ gintsts_data_t gintsts;
5477+
5478+#ifndef DWC_HOST_ONLY
5479+ DWC_DEBUGPL(DBG_ANY, "++Session Request Interrupt++\n");
5480+
5481+ if (dwc_otg_is_device_mode(_core_if) ) {
5482+ DWC_PRINT("SRP: Device mode\n");
5483+ } else {
5484+ DWC_PRINT("SRP: Host mode\n");
5485+
5486+ /* Turn on the port power bit. */
5487+ hprt0.d32 = dwc_otg_read_hprt0( _core_if );
5488+ hprt0.b.prtpwr = 1;
5489+ dwc_write_reg32(_core_if->host_if->hprt0, hprt0.d32);
5490+
5491+ /* Start the Connection timer. So a message can be displayed
5492+ * if connect does not occur within 10 seconds. */
5493+ hcd_session_start( _core_if );
5494+ }
5495+#endif
5496+
5497+ /* Clear interrupt */
5498+ gintsts.d32 = 0;
5499+ gintsts.b.sessreqintr = 1;
5500+ dwc_write_reg32 (&_core_if->core_global_regs->gintsts, gintsts.d32);
5501+
5502+ return 1;
5503+}
5504+
5505+/**
5506+ * This interrupt indicates that the DWC_otg controller has detected a
5507+ * resume or remote wakeup sequence. If the DWC_otg controller is in
5508+ * low power mode, the handler must brings the controller out of low
5509+ * power mode. The controller automatically begins resume
5510+ * signaling. The handler schedules a time to stop resume signaling.
5511+ */
5512+int32_t dwc_otg_handle_wakeup_detected_intr( dwc_otg_core_if_t *_core_if )
5513+{
5514+ gintsts_data_t gintsts;
5515+
5516+ DWC_DEBUGPL(DBG_ANY, "++Resume and Remote Wakeup Detected Interrupt++\n");
5517+
5518+ if (dwc_otg_is_device_mode(_core_if) ) {
5519+ dctl_data_t dctl = {.d32=0};
5520+ DWC_DEBUGPL(DBG_PCD, "DSTS=0x%0x\n",
5521+ dwc_read_reg32( &_core_if->dev_if->dev_global_regs->dsts));
5522+#ifdef PARTIAL_POWER_DOWN
5523+ if (_core_if->hwcfg4.b.power_optimiz) {
5524+ pcgcctl_data_t power = {.d32=0};
5525+
5526+ power.d32 = dwc_read_reg32( _core_if->pcgcctl );
5527+ DWC_DEBUGPL(DBG_CIL, "PCGCCTL=%0x\n", power.d32);
5528+
5529+ power.b.stoppclk = 0;
5530+ dwc_write_reg32( _core_if->pcgcctl, power.d32);
5531+
5532+ power.b.pwrclmp = 0;
5533+ dwc_write_reg32( _core_if->pcgcctl, power.d32);
5534+
5535+ power.b.rstpdwnmodule = 0;
5536+ dwc_write_reg32( _core_if->pcgcctl, power.d32);
5537+ }
5538+#endif
5539+ /* Clear the Remote Wakeup Signalling */
5540+ dctl.b.rmtwkupsig = 1;
5541+ dwc_modify_reg32( &_core_if->dev_if->dev_global_regs->dctl,
5542+ dctl.d32, 0 );
5543+
5544+ if (_core_if->pcd_cb && _core_if->pcd_cb->resume_wakeup) {
5545+ _core_if->pcd_cb->resume_wakeup( _core_if->pcd_cb->p );
5546+ }
5547+
5548+ } else {
5549+ /*
5550+ * Clear the Resume after 70ms. (Need 20 ms minimum. Use 70 ms
5551+ * so that OPT tests pass with all PHYs).
5552+ */
5553+ hprt0_data_t hprt0 = {.d32=0};
5554+ pcgcctl_data_t pcgcctl = {.d32=0};
5555+ /* Restart the Phy Clock */
5556+ pcgcctl.b.stoppclk = 1;
5557+ dwc_modify_reg32(_core_if->pcgcctl, pcgcctl.d32, 0);
5558+ UDELAY(10);
5559+
5560+ /* Now wait for 70 ms. */
5561+ hprt0.d32 = dwc_otg_read_hprt0( _core_if );
5562+ DWC_DEBUGPL(DBG_ANY,"Resume: HPRT0=%0x\n", hprt0.d32);
5563+ MDELAY(70);
5564+ hprt0.b.prtres = 0; /* Resume */
5565+ dwc_write_reg32(_core_if->host_if->hprt0, hprt0.d32);
5566+ DWC_DEBUGPL(DBG_ANY,"Clear Resume: HPRT0=%0x\n", dwc_read_reg32(_core_if->host_if->hprt0));
5567+ }
5568+
5569+ /* Clear interrupt */
5570+ gintsts.d32 = 0;
5571+ gintsts.b.wkupintr = 1;
5572+ dwc_write_reg32 (&_core_if->core_global_regs->gintsts, gintsts.d32);
5573+
5574+ return 1;
5575+}
5576+
5577+/**
5578+ * This interrupt indicates that a device has been disconnected from
5579+ * the root port.
5580+ */
5581+int32_t dwc_otg_handle_disconnect_intr( dwc_otg_core_if_t *_core_if)
5582+{
5583+ gintsts_data_t gintsts;
5584+
5585+ DWC_DEBUGPL(DBG_ANY, "++Disconnect Detected Interrupt++ (%s) %s\n",
5586+ (dwc_otg_is_host_mode(_core_if)?"Host":"Device"),
5587+ op_state_str(_core_if));
5588+
5589+/** @todo Consolidate this if statement. */
5590+#ifndef DWC_HOST_ONLY
5591+ if (_core_if->op_state == B_HOST) {
5592+ /* If in device mode Disconnect and stop the HCD, then
5593+ * start the PCD. */
5594+ hcd_disconnect( _core_if );
5595+ pcd_start( _core_if );
5596+ _core_if->op_state = B_PERIPHERAL;
5597+ } else if (dwc_otg_is_device_mode(_core_if)) {
5598+ gotgctl_data_t gotgctl = { .d32 = 0 };
5599+ gotgctl.d32 = dwc_read_reg32(&_core_if->core_global_regs->gotgctl);
5600+ if (gotgctl.b.hstsethnpen==1) {
5601+ /* Do nothing, if HNP in process the OTG
5602+ * interrupt "Host Negotiation Detected"
5603+ * interrupt will do the mode switch.
5604+ */
5605+ } else if (gotgctl.b.devhnpen == 0) {
5606+ /* If in device mode Disconnect and stop the HCD, then
5607+ * start the PCD. */
5608+ hcd_disconnect( _core_if );
5609+ pcd_start( _core_if );
5610+ _core_if->op_state = B_PERIPHERAL;
5611+ } else {
5612+ DWC_DEBUGPL(DBG_ANY,"!a_peripheral && !devhnpen\n");
5613+ }
5614+ } else {
5615+ if (_core_if->op_state == A_HOST) {
5616+ /* A-Cable still connected but device disconnected. */
5617+ hcd_disconnect( _core_if );
5618+ }
5619+ }
5620+#endif
5621+/* Without OTG, we should use the disconnect function!? winder added.*/
5622+#if 1 // NO OTG, so host only!!
5623+ hcd_disconnect( _core_if );
5624+#endif
5625+
5626+ gintsts.d32 = 0;
5627+ gintsts.b.disconnect = 1;
5628+ dwc_write_reg32 (&_core_if->core_global_regs->gintsts, gintsts.d32);
5629+ return 1;
5630+}
5631+/**
5632+ * This interrupt indicates that SUSPEND state has been detected on
5633+ * the USB.
5634+ *
5635+ * For HNP the USB Suspend interrupt signals the change from
5636+ * "a_peripheral" to "a_host".
5637+ *
5638+ * When power management is enabled the core will be put in low power
5639+ * mode.
5640+ */
5641+int32_t dwc_otg_handle_usb_suspend_intr(dwc_otg_core_if_t *_core_if )
5642+{
5643+ dsts_data_t dsts;
5644+ gintsts_data_t gintsts;
5645+
5646+ //805141:<IFTW-fchang>.removed DWC_DEBUGPL(DBG_ANY,"USB SUSPEND\n");
5647+
5648+ if (dwc_otg_is_device_mode( _core_if ) ) {
5649+ /* Check the Device status register to determine if the Suspend
5650+ * state is active. */
5651+ dsts.d32 = dwc_read_reg32( &_core_if->dev_if->dev_global_regs->dsts);
5652+ DWC_DEBUGPL(DBG_PCD, "DSTS=0x%0x\n", dsts.d32);
5653+ DWC_DEBUGPL(DBG_PCD, "DSTS.Suspend Status=%d "
5654+ "HWCFG4.power Optimize=%d\n",
5655+ dsts.b.suspsts, _core_if->hwcfg4.b.power_optimiz);
5656+
5657+
5658+#ifdef PARTIAL_POWER_DOWN
5659+/** @todo Add a module parameter for power management. */
5660+
5661+ if (dsts.b.suspsts && _core_if->hwcfg4.b.power_optimiz) {
5662+ pcgcctl_data_t power = {.d32=0};
5663+ DWC_DEBUGPL(DBG_CIL, "suspend\n");
5664+
5665+ power.b.pwrclmp = 1;
5666+ dwc_write_reg32( _core_if->pcgcctl, power.d32);
5667+
5668+ power.b.rstpdwnmodule = 1;
5669+ dwc_modify_reg32( _core_if->pcgcctl, 0, power.d32);
5670+
5671+ power.b.stoppclk = 1;
5672+ dwc_modify_reg32( _core_if->pcgcctl, 0, power.d32);
5673+
5674+ } else {
5675+ DWC_DEBUGPL(DBG_ANY,"disconnect?\n");
5676+ }
5677+#endif
5678+ /* PCD callback for suspend. */
5679+ pcd_suspend(_core_if);
5680+ } else {
5681+ if (_core_if->op_state == A_PERIPHERAL) {
5682+ DWC_DEBUGPL(DBG_ANY,"a_peripheral->a_host\n");
5683+ /* Clear the a_peripheral flag, back to a_host. */
5684+ pcd_stop( _core_if );
5685+ hcd_start( _core_if );
5686+ _core_if->op_state = A_HOST;
5687+ }
5688+ }
5689+
5690+ /* Clear interrupt */
5691+ gintsts.d32 = 0;
5692+ gintsts.b.usbsuspend = 1;
5693+ dwc_write_reg32( &_core_if->core_global_regs->gintsts, gintsts.d32);
5694+
5695+ return 1;
5696+}
5697+
5698+
5699+/**
5700+ * This function returns the Core Interrupt register.
5701+ */
5702+static inline uint32_t dwc_otg_read_common_intr(dwc_otg_core_if_t *_core_if)
5703+{
5704+ gintsts_data_t gintsts;
5705+ gintmsk_data_t gintmsk;
5706+ gintmsk_data_t gintmsk_common = {.d32=0};
5707+ gintmsk_common.b.wkupintr = 1;
5708+ gintmsk_common.b.sessreqintr = 1;
5709+ gintmsk_common.b.conidstschng = 1;
5710+ gintmsk_common.b.otgintr = 1;
5711+ gintmsk_common.b.modemismatch = 1;
5712+ gintmsk_common.b.disconnect = 1;
5713+ gintmsk_common.b.usbsuspend = 1;
5714+ /** @todo: The port interrupt occurs while in device
5715+ * mode. Added code to CIL to clear the interrupt for now!
5716+ */
5717+ gintmsk_common.b.portintr = 1;
5718+
5719+ gintsts.d32 = dwc_read_reg32(&_core_if->core_global_regs->gintsts);
5720+ gintmsk.d32 = dwc_read_reg32(&_core_if->core_global_regs->gintmsk);
5721+#ifdef DEBUG
5722+ /* if any common interrupts set */
5723+ if (gintsts.d32 & gintmsk_common.d32) {
5724+ DWC_DEBUGPL(DBG_ANY, "gintsts=%08x gintmsk=%08x\n",
5725+ gintsts.d32, gintmsk.d32);
5726+ }
5727+#endif
5728+
5729+ return ((gintsts.d32 & gintmsk.d32 ) & gintmsk_common.d32);
5730+
5731+}
5732+
5733+/**
5734+ * Common interrupt handler.
5735+ *
5736+ * The common interrupts are those that occur in both Host and Device mode.
5737+ * This handler handles the following interrupts:
5738+ * - Mode Mismatch Interrupt
5739+ * - Disconnect Interrupt
5740+ * - OTG Interrupt
5741+ * - Connector ID Status Change Interrupt
5742+ * - Session Request Interrupt.
5743+ * - Resume / Remote Wakeup Detected Interrupt.
5744+ *
5745+ */
5746+extern int32_t dwc_otg_handle_common_intr( dwc_otg_core_if_t *_core_if )
5747+{
5748+ int retval = 0;
5749+ gintsts_data_t gintsts;
5750+
5751+ gintsts.d32 = dwc_otg_read_common_intr(_core_if);
5752+
5753+ if (gintsts.b.modemismatch) {
5754+ retval |= dwc_otg_handle_mode_mismatch_intr( _core_if );
5755+ }
5756+ if (gintsts.b.otgintr) {
5757+ retval |= dwc_otg_handle_otg_intr( _core_if );
5758+ }
5759+ if (gintsts.b.conidstschng) {
5760+ retval |= dwc_otg_handle_conn_id_status_change_intr( _core_if );
5761+ }
5762+ if (gintsts.b.disconnect) {
5763+ retval |= dwc_otg_handle_disconnect_intr( _core_if );
5764+ }
5765+ if (gintsts.b.sessreqintr) {
5766+ retval |= dwc_otg_handle_session_req_intr( _core_if );
5767+ }
5768+ if (gintsts.b.wkupintr) {
5769+ retval |= dwc_otg_handle_wakeup_detected_intr( _core_if );
5770+ }
5771+ if (gintsts.b.usbsuspend) {
5772+ retval |= dwc_otg_handle_usb_suspend_intr( _core_if );
5773+ }
5774+ if (gintsts.b.portintr && dwc_otg_is_device_mode(_core_if)) {
5775+ /* The port interrupt occurs while in device mode with HPRT0
5776+ * Port Enable/Disable.
5777+ */
5778+ gintsts.d32 = 0;
5779+ gintsts.b.portintr = 1;
5780+ dwc_write_reg32(&_core_if->core_global_regs->gintsts,
5781+ gintsts.d32);
5782+ retval |= 1;
5783+
5784+ }
5785+ return retval;
5786+}
5787diff --git a/drivers/usb/dwc_otg/dwc_otg_driver.c b/drivers/usb/dwc_otg/dwc_otg_driver.c
5788new file mode 100644
5789index 0000000..1b0daab
5790--- /dev/null
5791+++ b/drivers/usb/dwc_otg/dwc_otg_driver.c
5792@@ -0,0 +1,1274 @@
5793+/* ==========================================================================
5794+ * $File: //dwh/usb_iip/dev/software/otg_ipmate/linux/drivers/dwc_otg_driver.c $
5795+ * $Revision: 1.1.1.1 $
5796+ * $Date: 2009-04-17 06:15:34 $
5797+ * $Change: 631780 $
5798+ *
5799+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
5800+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
5801+ * otherwise expressly agreed to in writing between Synopsys and you.
5802+ *
5803+ * The Software IS NOT an item of Licensed Software or Licensed Product under
5804+ * any End User Software License Agreement or Agreement for Licensed Product
5805+ * with Synopsys or any supplement thereto. You are permitted to use and
5806+ * redistribute this Software in source and binary forms, with or without
5807+ * modification, provided that redistributions of source code must retain this
5808+ * notice. You may not view, use, disclose, copy or distribute this file or
5809+ * any information contained herein except pursuant to this license grant from
5810+ * Synopsys. If you do not agree with this notice, including the disclaimer
5811+ * below, then you are not authorized to use the Software.
5812+ *
5813+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
5814+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5815+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
5816+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
5817+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
5818+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
5819+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
5820+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
5821+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5822+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
5823+ * DAMAGE.
5824+ * ========================================================================== */
5825+
5826+/** @file
5827+ * The dwc_otg_driver module provides the initialization and cleanup entry
5828+ * points for the DWC_otg driver. This module will be dynamically installed
5829+ * after Linux is booted using the insmod command. When the module is
5830+ * installed, the dwc_otg_init function is called. When the module is
5831+ * removed (using rmmod), the dwc_otg_cleanup function is called.
5832+ *
5833+ * This module also defines a data structure for the dwc_otg_driver, which is
5834+ * used in conjunction with the standard ARM lm_device structure. These
5835+ * structures allow the OTG driver to comply with the standard Linux driver
5836+ * model in which devices and drivers are registered with a bus driver. This
5837+ * has the benefit that Linux can expose attributes of the driver and device
5838+ * in its special sysfs file system. Users can then read or write files in
5839+ * this file system to perform diagnostics on the driver components or the
5840+ * device.
5841+ */
5842+
5843+#include <linux/kernel.h>
5844+#include <linux/module.h>
5845+#include <linux/moduleparam.h>
5846+#include <linux/init.h>
5847+#include <linux/gpio.h>
5848+
5849+#include <linux/device.h>
5850+#include <linux/platform_device.h>
5851+
5852+#include <linux/errno.h>
5853+#include <linux/types.h>
5854+#include <linux/stat.h> /* permission constants */
5855+#include <linux/irq.h>
5856+#include <asm/io.h>
5857+
5858+#include "dwc_otg_plat.h"
5859+#include "dwc_otg_attr.h"
5860+#include "dwc_otg_driver.h"
5861+#include "dwc_otg_cil.h"
5862+#include "dwc_otg_cil_ifx.h"
5863+
5864+// #include "dwc_otg_pcd.h" // device
5865+#include "dwc_otg_hcd.h" // host
5866+
5867+#include "dwc_otg_ifx.h" // for Infineon platform specific.
5868+
5869+#define DWC_DRIVER_VERSION "2.60a 22-NOV-2006"
5870+#define DWC_DRIVER_DESC "HS OTG USB Controller driver"
5871+
5872+const char dwc_driver_name[] = "dwc_otg";
5873+
5874+static unsigned long dwc_iomem_base = IFX_USB_IOMEM_BASE;
5875+int dwc_irq = LTQ_USB_INT;
5876+//int dwc_irq = 54;
5877+//int dwc_irq = IFXMIPS_USB_OC_INT;
5878+
5879+extern int ifx_usb_hc_init(unsigned long base_addr, int irq);
5880+extern void ifx_usb_hc_remove(void);
5881+
5882+/*-------------------------------------------------------------------------*/
5883+/* Encapsulate the module parameter settings */
5884+
5885+static dwc_otg_core_params_t dwc_otg_module_params = {
5886+ .opt = -1,
5887+ .otg_cap = -1,
5888+ .dma_enable = -1,
5889+ .dma_burst_size = -1,
5890+ .speed = -1,
5891+ .host_support_fs_ls_low_power = -1,
5892+ .host_ls_low_power_phy_clk = -1,
5893+ .enable_dynamic_fifo = -1,
5894+ .data_fifo_size = -1,
5895+ .dev_rx_fifo_size = -1,
5896+ .dev_nperio_tx_fifo_size = -1,
5897+ .dev_perio_tx_fifo_size = /* dev_perio_tx_fifo_size_1 */ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 15 */
5898+ .host_rx_fifo_size = -1,
5899+ .host_nperio_tx_fifo_size = -1,
5900+ .host_perio_tx_fifo_size = -1,
5901+ .max_transfer_size = -1,
5902+ .max_packet_count = -1,
5903+ .host_channels = -1,
5904+ .dev_endpoints = -1,
5905+ .phy_type = -1,
5906+ .phy_utmi_width = -1,
5907+ .phy_ulpi_ddr = -1,
5908+ .phy_ulpi_ext_vbus = -1,
5909+ .i2c_enable = -1,
5910+ .ulpi_fs_ls = -1,
5911+ .ts_dline = -1,
5912+ .en_multiple_tx_fifo = -1,
5913+ .dev_tx_fifo_size = { /* dev_tx_fifo_size */
5914+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
5915+ }, /* 15 */
5916+ .thr_ctl = -1,
5917+ .tx_thr_length = -1,
5918+ .rx_thr_length = -1,
5919+};
5920+
5921+/**
5922+ * This function shows the Driver Version.
5923+ */
5924+static ssize_t version_show(struct device_driver *dev, char *buf)
5925+{
5926+ return snprintf(buf, sizeof(DWC_DRIVER_VERSION)+2,"%s\n",
5927+ DWC_DRIVER_VERSION);
5928+}
5929+static DRIVER_ATTR(version, S_IRUGO, version_show, NULL);
5930+
5931+/**
5932+ * Global Debug Level Mask.
5933+ */
5934+uint32_t g_dbg_lvl = 0xff; /* OFF */
5935+
5936+/**
5937+ * This function shows the driver Debug Level.
5938+ */
5939+static ssize_t dbg_level_show(struct device_driver *_drv, char *_buf)
5940+{
5941+ return sprintf(_buf, "0x%0x\n", g_dbg_lvl);
5942+}
5943+/**
5944+ * This function stores the driver Debug Level.
5945+ */
5946+static ssize_t dbg_level_store(struct device_driver *_drv, const char *_buf,
5947+ size_t _count)
5948+{
5949+ g_dbg_lvl = simple_strtoul(_buf, NULL, 16);
5950+ return _count;
5951+}
5952+static DRIVER_ATTR(debuglevel, S_IRUGO|S_IWUSR, dbg_level_show, dbg_level_store);
5953+
5954+/**
5955+ * This function is called during module intialization to verify that
5956+ * the module parameters are in a valid state.
5957+ */
5958+static int check_parameters(dwc_otg_core_if_t *core_if)
5959+{
5960+ int i;
5961+ int retval = 0;
5962+
5963+/* Checks if the parameter is outside of its valid range of values */
5964+#define DWC_OTG_PARAM_TEST(_param_,_low_,_high_) \
5965+ ((dwc_otg_module_params._param_ < (_low_)) || \
5966+ (dwc_otg_module_params._param_ > (_high_)))
5967+
5968+/* If the parameter has been set by the user, check that the parameter value is
5969+ * within the value range of values. If not, report a module error. */
5970+#define DWC_OTG_PARAM_ERR(_param_,_low_,_high_,_string_) \
5971+ do { \
5972+ if (dwc_otg_module_params._param_ != -1) { \
5973+ if (DWC_OTG_PARAM_TEST(_param_,(_low_),(_high_))) { \
5974+ DWC_ERROR("`%d' invalid for parameter `%s'\n", \
5975+ dwc_otg_module_params._param_, _string_); \
5976+ dwc_otg_module_params._param_ = dwc_param_##_param_##_default; \
5977+ retval ++; \
5978+ } \
5979+ } \
5980+ } while (0)
5981+
5982+ DWC_OTG_PARAM_ERR(opt,0,1,"opt");
5983+ DWC_OTG_PARAM_ERR(otg_cap,0,2,"otg_cap");
5984+ DWC_OTG_PARAM_ERR(dma_enable,0,1,"dma_enable");
5985+ DWC_OTG_PARAM_ERR(speed,0,1,"speed");
5986+ DWC_OTG_PARAM_ERR(host_support_fs_ls_low_power,0,1,"host_support_fs_ls_low_power");
5987+ DWC_OTG_PARAM_ERR(host_ls_low_power_phy_clk,0,1,"host_ls_low_power_phy_clk");
5988+ DWC_OTG_PARAM_ERR(enable_dynamic_fifo,0,1,"enable_dynamic_fifo");
5989+ DWC_OTG_PARAM_ERR(data_fifo_size,32,32768,"data_fifo_size");
5990+ DWC_OTG_PARAM_ERR(dev_rx_fifo_size,16,32768,"dev_rx_fifo_size");
5991+ DWC_OTG_PARAM_ERR(dev_nperio_tx_fifo_size,16,32768,"dev_nperio_tx_fifo_size");
5992+ DWC_OTG_PARAM_ERR(host_rx_fifo_size,16,32768,"host_rx_fifo_size");
5993+ DWC_OTG_PARAM_ERR(host_nperio_tx_fifo_size,16,32768,"host_nperio_tx_fifo_size");
5994+ DWC_OTG_PARAM_ERR(host_perio_tx_fifo_size,16,32768,"host_perio_tx_fifo_size");
5995+ DWC_OTG_PARAM_ERR(max_transfer_size,2047,524288,"max_transfer_size");
5996+ DWC_OTG_PARAM_ERR(max_packet_count,15,511,"max_packet_count");
5997+ DWC_OTG_PARAM_ERR(host_channels,1,16,"host_channels");
5998+ DWC_OTG_PARAM_ERR(dev_endpoints,1,15,"dev_endpoints");
5999+ DWC_OTG_PARAM_ERR(phy_type,0,2,"phy_type");
6000+ DWC_OTG_PARAM_ERR(phy_ulpi_ddr,0,1,"phy_ulpi_ddr");
6001+ DWC_OTG_PARAM_ERR(phy_ulpi_ext_vbus,0,1,"phy_ulpi_ext_vbus");
6002+ DWC_OTG_PARAM_ERR(i2c_enable,0,1,"i2c_enable");
6003+ DWC_OTG_PARAM_ERR(ulpi_fs_ls,0,1,"ulpi_fs_ls");
6004+ DWC_OTG_PARAM_ERR(ts_dline,0,1,"ts_dline");
6005+
6006+ if (dwc_otg_module_params.dma_burst_size != -1) {
6007+ if (DWC_OTG_PARAM_TEST(dma_burst_size,1,1) &&
6008+ DWC_OTG_PARAM_TEST(dma_burst_size,4,4) &&
6009+ DWC_OTG_PARAM_TEST(dma_burst_size,8,8) &&
6010+ DWC_OTG_PARAM_TEST(dma_burst_size,16,16) &&
6011+ DWC_OTG_PARAM_TEST(dma_burst_size,32,32) &&
6012+ DWC_OTG_PARAM_TEST(dma_burst_size,64,64) &&
6013+ DWC_OTG_PARAM_TEST(dma_burst_size,128,128) &&
6014+ DWC_OTG_PARAM_TEST(dma_burst_size,256,256))
6015+ {
6016+ DWC_ERROR("`%d' invalid for parameter `dma_burst_size'\n",
6017+ dwc_otg_module_params.dma_burst_size);
6018+ dwc_otg_module_params.dma_burst_size = 32;
6019+ retval ++;
6020+ }
6021+ }
6022+
6023+ if (dwc_otg_module_params.phy_utmi_width != -1) {
6024+ if (DWC_OTG_PARAM_TEST(phy_utmi_width,8,8) &&
6025+ DWC_OTG_PARAM_TEST(phy_utmi_width,16,16))
6026+ {
6027+ DWC_ERROR("`%d' invalid for parameter `phy_utmi_width'\n",
6028+ dwc_otg_module_params.phy_utmi_width);
6029+ //dwc_otg_module_params.phy_utmi_width = 16;
6030+ dwc_otg_module_params.phy_utmi_width = 8;
6031+ retval ++;
6032+ }
6033+ }
6034+
6035+ for (i=0; i<15; i++) {
6036+ /** @todo should be like above */
6037+ //DWC_OTG_PARAM_ERR(dev_perio_tx_fifo_size[i],4,768,"dev_perio_tx_fifo_size");
6038+ if (dwc_otg_module_params.dev_perio_tx_fifo_size[i] != -1) {
6039+ if (DWC_OTG_PARAM_TEST(dev_perio_tx_fifo_size[i],4,768)) {
6040+ DWC_ERROR("`%d' invalid for parameter `%s_%d'\n",
6041+ dwc_otg_module_params.dev_perio_tx_fifo_size[i], "dev_perio_tx_fifo_size", i);
6042+ dwc_otg_module_params.dev_perio_tx_fifo_size[i] = dwc_param_dev_perio_tx_fifo_size_default;
6043+ retval ++;
6044+ }
6045+ }
6046+ }
6047+
6048+ DWC_OTG_PARAM_ERR(en_multiple_tx_fifo, 0, 1, "en_multiple_tx_fifo");
6049+ for (i = 0; i < 15; i++) {
6050+ /** @todo should be like above */
6051+ //DWC_OTG_PARAM_ERR(dev_tx_fifo_size[i],4,768,"dev_tx_fifo_size");
6052+ if (dwc_otg_module_params.dev_tx_fifo_size[i] != -1) {
6053+ if (DWC_OTG_PARAM_TEST(dev_tx_fifo_size[i], 4, 768)) {
6054+ DWC_ERROR("`%d' invalid for parameter `%s_%d'\n",
6055+ dwc_otg_module_params.dev_tx_fifo_size[i],
6056+ "dev_tx_fifo_size", i);
6057+ dwc_otg_module_params.dev_tx_fifo_size[i] =
6058+ dwc_param_dev_tx_fifo_size_default;
6059+ retval++;
6060+ }
6061+ }
6062+ }
6063+ DWC_OTG_PARAM_ERR(thr_ctl, 0, 7, "thr_ctl");
6064+ DWC_OTG_PARAM_ERR(tx_thr_length, 8, 128, "tx_thr_length");
6065+ DWC_OTG_PARAM_ERR(rx_thr_length, 8, 128, "rx_thr_length");
6066+
6067+ /* At this point, all module parameters that have been set by the user
6068+ * are valid, and those that have not are left unset. Now set their
6069+ * default values and/or check the parameters against the hardware
6070+ * configurations of the OTG core. */
6071+
6072+
6073+
6074+/* This sets the parameter to the default value if it has not been set by the
6075+ * user */
6076+#define DWC_OTG_PARAM_SET_DEFAULT(_param_) \
6077+ ({ \
6078+ int changed = 1; \
6079+ if (dwc_otg_module_params._param_ == -1) { \
6080+ changed = 0; \
6081+ dwc_otg_module_params._param_ = dwc_param_##_param_##_default; \
6082+ } \
6083+ changed; \
6084+ })
6085+
6086+/* This checks the macro agains the hardware configuration to see if it is
6087+ * valid. It is possible that the default value could be invalid. In this
6088+ * case, it will report a module error if the user touched the parameter.
6089+ * Otherwise it will adjust the value without any error. */
6090+#define DWC_OTG_PARAM_CHECK_VALID(_param_,_str_,_is_valid_,_set_valid_) \
6091+ ({ \
6092+ int changed = DWC_OTG_PARAM_SET_DEFAULT(_param_); \
6093+ int error = 0; \
6094+ if (!(_is_valid_)) { \
6095+ if (changed) { \
6096+ DWC_ERROR("`%d' invalid for parameter `%s'. Check HW configuration.\n", dwc_otg_module_params._param_,_str_); \
6097+ error = 1; \
6098+ } \
6099+ dwc_otg_module_params._param_ = (_set_valid_); \
6100+ } \
6101+ error; \
6102+ })
6103+
6104+ /* OTG Cap */
6105+ retval += DWC_OTG_PARAM_CHECK_VALID(otg_cap,"otg_cap",
6106+ ({
6107+ int valid;
6108+ valid = 1;
6109+ switch (dwc_otg_module_params.otg_cap) {
6110+ case DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE:
6111+ if (core_if->hwcfg2.b.op_mode != DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG) valid = 0;
6112+ break;
6113+ case DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE:
6114+ if ((core_if->hwcfg2.b.op_mode != DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG) &&
6115+ (core_if->hwcfg2.b.op_mode != DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG) &&
6116+ (core_if->hwcfg2.b.op_mode != DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE) &&
6117+ (core_if->hwcfg2.b.op_mode != DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST))
6118+ {
6119+ valid = 0;
6120+ }
6121+ break;
6122+ case DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE:
6123+ /* always valid */
6124+ break;
6125+ }
6126+ valid;
6127+ }),
6128+ (((core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG) ||
6129+ (core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG) ||
6130+ (core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE) ||
6131+ (core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)) ?
6132+ DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE :
6133+ DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE));
6134+
6135+ retval += DWC_OTG_PARAM_CHECK_VALID(dma_enable,"dma_enable",
6136+ ((dwc_otg_module_params.dma_enable == 1) && (core_if->hwcfg2.b.architecture == 0)) ? 0 : 1,
6137+ 0);
6138+
6139+ retval += DWC_OTG_PARAM_CHECK_VALID(opt,"opt",
6140+ 1,
6141+ 0);
6142+
6143+ DWC_OTG_PARAM_SET_DEFAULT(dma_burst_size);
6144+
6145+ retval += DWC_OTG_PARAM_CHECK_VALID(host_support_fs_ls_low_power,
6146+ "host_support_fs_ls_low_power",
6147+ 1, 0);
6148+
6149+ retval += DWC_OTG_PARAM_CHECK_VALID(enable_dynamic_fifo,
6150+ "enable_dynamic_fifo",
6151+ ((dwc_otg_module_params.enable_dynamic_fifo == 0) ||
6152+ (core_if->hwcfg2.b.dynamic_fifo == 1)), 0);
6153+
6154+
6155+ retval += DWC_OTG_PARAM_CHECK_VALID(data_fifo_size,
6156+ "data_fifo_size",
6157+ (dwc_otg_module_params.data_fifo_size <= core_if->hwcfg3.b.dfifo_depth),
6158+ core_if->hwcfg3.b.dfifo_depth);
6159+
6160+ retval += DWC_OTG_PARAM_CHECK_VALID(dev_rx_fifo_size,
6161+ "dev_rx_fifo_size",
6162+ (dwc_otg_module_params.dev_rx_fifo_size <= dwc_read_reg32(&core_if->core_global_regs->grxfsiz)),
6163+ dwc_read_reg32(&core_if->core_global_regs->grxfsiz));
6164+
6165+ retval += DWC_OTG_PARAM_CHECK_VALID(dev_nperio_tx_fifo_size,
6166+ "dev_nperio_tx_fifo_size",
6167+ (dwc_otg_module_params.dev_nperio_tx_fifo_size <= (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16)),
6168+ (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16));
6169+
6170+ retval += DWC_OTG_PARAM_CHECK_VALID(host_rx_fifo_size,
6171+ "host_rx_fifo_size",
6172+ (dwc_otg_module_params.host_rx_fifo_size <= dwc_read_reg32(&core_if->core_global_regs->grxfsiz)),
6173+ dwc_read_reg32(&core_if->core_global_regs->grxfsiz));
6174+
6175+
6176+ retval += DWC_OTG_PARAM_CHECK_VALID(host_nperio_tx_fifo_size,
6177+ "host_nperio_tx_fifo_size",
6178+ (dwc_otg_module_params.host_nperio_tx_fifo_size <= (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16)),
6179+ (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16));
6180+
6181+ retval += DWC_OTG_PARAM_CHECK_VALID(host_perio_tx_fifo_size,
6182+ "host_perio_tx_fifo_size",
6183+ (dwc_otg_module_params.host_perio_tx_fifo_size <= ((dwc_read_reg32(&core_if->core_global_regs->hptxfsiz) >> 16))),
6184+ ((dwc_read_reg32(&core_if->core_global_regs->hptxfsiz) >> 16)));
6185+
6186+ retval += DWC_OTG_PARAM_CHECK_VALID(max_transfer_size,
6187+ "max_transfer_size",
6188+ (dwc_otg_module_params.max_transfer_size < (1 << (core_if->hwcfg3.b.xfer_size_cntr_width + 11))),
6189+ ((1 << (core_if->hwcfg3.b.xfer_size_cntr_width + 11)) - 1));
6190+
6191+ retval += DWC_OTG_PARAM_CHECK_VALID(max_packet_count,
6192+ "max_packet_count",
6193+ (dwc_otg_module_params.max_packet_count < (1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4))),
6194+ ((1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4)) - 1));
6195+
6196+ retval += DWC_OTG_PARAM_CHECK_VALID(host_channels,
6197+ "host_channels",
6198+ (dwc_otg_module_params.host_channels <= (core_if->hwcfg2.b.num_host_chan + 1)),
6199+ (core_if->hwcfg2.b.num_host_chan + 1));
6200+
6201+ retval += DWC_OTG_PARAM_CHECK_VALID(dev_endpoints,
6202+ "dev_endpoints",
6203+ (dwc_otg_module_params.dev_endpoints <= (core_if->hwcfg2.b.num_dev_ep)),
6204+ core_if->hwcfg2.b.num_dev_ep);
6205+
6206+/*
6207+ * Define the following to disable the FS PHY Hardware checking. This is for
6208+ * internal testing only.
6209+ *
6210+ * #define NO_FS_PHY_HW_CHECKS
6211+ */
6212+
6213+#ifdef NO_FS_PHY_HW_CHECKS
6214+ retval += DWC_OTG_PARAM_CHECK_VALID(phy_type,
6215+ "phy_type", 1, 0);
6216+#else
6217+ retval += DWC_OTG_PARAM_CHECK_VALID(phy_type,
6218+ "phy_type",
6219+ ({
6220+ int valid = 0;
6221+ if ((dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_UTMI) &&
6222+ ((core_if->hwcfg2.b.hs_phy_type == 1) ||
6223+ (core_if->hwcfg2.b.hs_phy_type == 3)))
6224+ {
6225+ valid = 1;
6226+ }
6227+ else if ((dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_ULPI) &&
6228+ ((core_if->hwcfg2.b.hs_phy_type == 2) ||
6229+ (core_if->hwcfg2.b.hs_phy_type == 3)))
6230+ {
6231+ valid = 1;
6232+ }
6233+ else if ((dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_FS) &&
6234+ (core_if->hwcfg2.b.fs_phy_type == 1))
6235+ {
6236+ valid = 1;
6237+ }
6238+ valid;
6239+ }),
6240+ ({
6241+ int set = DWC_PHY_TYPE_PARAM_FS;
6242+ if (core_if->hwcfg2.b.hs_phy_type) {
6243+ if ((core_if->hwcfg2.b.hs_phy_type == 3) ||
6244+ (core_if->hwcfg2.b.hs_phy_type == 1)) {
6245+ set = DWC_PHY_TYPE_PARAM_UTMI;
6246+ }
6247+ else {
6248+ set = DWC_PHY_TYPE_PARAM_ULPI;
6249+ }
6250+ }
6251+ set;
6252+ }));
6253+#endif
6254+
6255+ retval += DWC_OTG_PARAM_CHECK_VALID(speed,"speed",
6256+ (dwc_otg_module_params.speed == 0) && (dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_FS) ? 0 : 1,
6257+ dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_FS ? 1 : 0);
6258+
6259+ retval += DWC_OTG_PARAM_CHECK_VALID(host_ls_low_power_phy_clk,
6260+ "host_ls_low_power_phy_clk",
6261+ ((dwc_otg_module_params.host_ls_low_power_phy_clk == DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ) && (dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_FS) ? 0 : 1),
6262+ ((dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_FS) ? DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ : DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ));
6263+
6264+ DWC_OTG_PARAM_SET_DEFAULT(phy_ulpi_ddr);
6265+ DWC_OTG_PARAM_SET_DEFAULT(phy_ulpi_ext_vbus);
6266+ DWC_OTG_PARAM_SET_DEFAULT(phy_utmi_width);
6267+ DWC_OTG_PARAM_SET_DEFAULT(ulpi_fs_ls);
6268+ DWC_OTG_PARAM_SET_DEFAULT(ts_dline);
6269+
6270+#ifdef NO_FS_PHY_HW_CHECKS
6271+ retval += DWC_OTG_PARAM_CHECK_VALID(i2c_enable,
6272+ "i2c_enable", 1, 0);
6273+#else
6274+ retval += DWC_OTG_PARAM_CHECK_VALID(i2c_enable,
6275+ "i2c_enable",
6276+ (dwc_otg_module_params.i2c_enable == 1) && (core_if->hwcfg3.b.i2c == 0) ? 0 : 1,
6277+ 0);
6278+#endif
6279+
6280+ for (i=0; i<16; i++) {
6281+
6282+ int changed = 1;
6283+ int error = 0;
6284+
6285+ if (dwc_otg_module_params.dev_perio_tx_fifo_size[i] == -1) {
6286+ changed = 0;
6287+ dwc_otg_module_params.dev_perio_tx_fifo_size[i] = dwc_param_dev_perio_tx_fifo_size_default;
6288+ }
6289+ if (!(dwc_otg_module_params.dev_perio_tx_fifo_size[i] <= (dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[i])))) {
6290+ if (changed) {
6291+ DWC_ERROR("`%d' invalid for parameter `dev_perio_fifo_size_%d'. Check HW configuration.\n", dwc_otg_module_params.dev_perio_tx_fifo_size[i],i);
6292+ error = 1;
6293+ }
6294+ dwc_otg_module_params.dev_perio_tx_fifo_size[i] = dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[i]);
6295+ }
6296+ retval += error;
6297+ }
6298+
6299+ retval += DWC_OTG_PARAM_CHECK_VALID(en_multiple_tx_fifo,
6300+ "en_multiple_tx_fifo",
6301+ ((dwc_otg_module_params.en_multiple_tx_fifo == 1) &&
6302+ (core_if->hwcfg4.b.ded_fifo_en == 0)) ? 0 : 1, 0);
6303+
6304+ for (i = 0; i < 16; i++) {
6305+ int changed = 1;
6306+ int error = 0;
6307+ if (dwc_otg_module_params.dev_tx_fifo_size[i] == -1) {
6308+ changed = 0;
6309+ dwc_otg_module_params.dev_tx_fifo_size[i] =
6310+ dwc_param_dev_tx_fifo_size_default;
6311+ }
6312+ if (!(dwc_otg_module_params.dev_tx_fifo_size[i] <=
6313+ (dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[i])))) {
6314+ if (changed) {
6315+ DWC_ERROR("%d' invalid for parameter `dev_perio_fifo_size_%d'."
6316+ "Check HW configuration.\n",dwc_otg_module_params.dev_tx_fifo_size[i],i);
6317+ error = 1;
6318+ }
6319+ dwc_otg_module_params.dev_tx_fifo_size[i] =
6320+ dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[i]);
6321+ }
6322+ retval += error;
6323+ }
6324+ DWC_OTG_PARAM_SET_DEFAULT(thr_ctl);
6325+ DWC_OTG_PARAM_SET_DEFAULT(tx_thr_length);
6326+ DWC_OTG_PARAM_SET_DEFAULT(rx_thr_length);
6327+ return retval;
6328+} // check_parameters
6329+
6330+
6331+/**
6332+ * This function is the top level interrupt handler for the Common
6333+ * (Device and host modes) interrupts.
6334+ */
6335+static irqreturn_t dwc_otg_common_irq(int _irq, void *_dev)
6336+{
6337+ dwc_otg_device_t *otg_dev = _dev;
6338+ int32_t retval = IRQ_NONE;
6339+
6340+ retval = dwc_otg_handle_common_intr( otg_dev->core_if );
6341+
6342+ mask_and_ack_ifx_irq (_irq);
6343+
6344+ return IRQ_RETVAL(retval);
6345+}
6346+
6347+
6348+/**
6349+ * This function is called when a DWC_OTG device is unregistered with the
6350+ * dwc_otg_driver. This happens, for example, when the rmmod command is
6351+ * executed. The device may or may not be electrically present. If it is
6352+ * present, the driver stops device processing. Any resources used on behalf
6353+ * of this device are freed.
6354+ *
6355+ * @return
6356+ */
6357+static int
6358+dwc_otg_driver_remove(struct platform_device *_dev)
6359+{
6360+ //dwc_otg_device_t *otg_dev = dev_get_drvdata(&_dev->dev);
6361+ dwc_otg_device_t *otg_dev = platform_get_drvdata(_dev);
6362+
6363+ DWC_DEBUGPL(DBG_ANY, "%s(%p)\n", __func__, _dev);
6364+
6365+ if (otg_dev == NULL) {
6366+ /* Memory allocation for the dwc_otg_device failed. */
6367+ return 0;
6368+ }
6369+
6370+ /*
6371+ * Free the IRQ
6372+ */
6373+ if (otg_dev->common_irq_installed) {
6374+ free_irq( otg_dev->irq, otg_dev );
6375+ }
6376+
6377+#ifndef DWC_DEVICE_ONLY
6378+ if (otg_dev->hcd != NULL) {
6379+ dwc_otg_hcd_remove(&_dev->dev);
6380+ }
6381+#endif
6382+ printk("after removehcd\n");
6383+
6384+// Note: Integrate HOST and DEVICE(Gadget) is not planned yet.
6385+#ifndef DWC_HOST_ONLY
6386+ if (otg_dev->pcd != NULL) {
6387+ dwc_otg_pcd_remove(otg_dev);
6388+ }
6389+#endif
6390+ if (otg_dev->core_if != NULL) {
6391+ dwc_otg_cil_remove( otg_dev->core_if );
6392+ }
6393+ printk("after removecil\n");
6394+
6395+ /*
6396+ * Remove the device attributes
6397+ */
6398+ dwc_otg_attr_remove(&_dev->dev);
6399+ printk("after removeattr\n");
6400+
6401+ /*
6402+ * Return the memory.
6403+ */
6404+ if (otg_dev->base != NULL) {
6405+ iounmap(otg_dev->base);
6406+ }
6407+ if (otg_dev->phys_addr != 0) {
6408+ release_mem_region(otg_dev->phys_addr, otg_dev->base_len);
6409+ }
6410+ kfree(otg_dev);
6411+
6412+ /*
6413+ * Clear the drvdata pointer.
6414+ */
6415+ //dev_set_drvdata(&_dev->dev, 0);
6416+ platform_set_drvdata(_dev, 0);
6417+ return 0;
6418+}
6419+
6420+/**
6421+ * This function is called when an DWC_OTG device is bound to a
6422+ * dwc_otg_driver. It creates the driver components required to
6423+ * control the device (CIL, HCD, and PCD) and it initializes the
6424+ * device. The driver components are stored in a dwc_otg_device
6425+ * structure. A reference to the dwc_otg_device is saved in the
6426+ * lm_device. This allows the driver to access the dwc_otg_device
6427+ * structure on subsequent calls to driver methods for this device.
6428+ *
6429+ * @return
6430+ */
6431+static int __devinit
6432+dwc_otg_driver_probe(struct platform_device *_dev)
6433+{
6434+ int retval = 0;
6435+ dwc_otg_device_t *dwc_otg_device;
6436+ int pin = (int)_dev->dev.platform_data;
6437+ int32_t snpsid;
6438+ struct resource *res;
6439+ gusbcfg_data_t usbcfg = {.d32 = 0};
6440+
6441+ // GPIOs
6442+ if(pin >= 0)
6443+ {
6444+ gpio_request(pin, "usb_power");
6445+ gpio_direction_output(pin, 1);
6446+ gpio_set_value(pin, 1);
6447+ gpio_export(pin, 0);
6448+ }
6449+ dev_dbg(&_dev->dev, "dwc_otg_driver_probe (%p)\n", _dev);
6450+
6451+ dwc_otg_device = kmalloc(sizeof(dwc_otg_device_t), GFP_KERNEL);
6452+ if (dwc_otg_device == 0) {
6453+ dev_err(&_dev->dev, "kmalloc of dwc_otg_device failed\n");
6454+ retval = -ENOMEM;
6455+ goto fail;
6456+ }
6457+ memset(dwc_otg_device, 0, sizeof(*dwc_otg_device));
6458+ dwc_otg_device->reg_offset = 0xFFFFFFFF;
6459+
6460+ /*
6461+ * Retrieve the memory and IRQ resources.
6462+ */
6463+ dwc_otg_device->irq = platform_get_irq(_dev, 0);
6464+ if (dwc_otg_device->irq == 0) {
6465+ dev_err(&_dev->dev, "no device irq\n");
6466+ retval = -ENODEV;
6467+ goto fail;
6468+ }
6469+ dev_dbg(&_dev->dev, "OTG - device irq: %d\n", dwc_otg_device->irq);
6470+ res = platform_get_resource(_dev, IORESOURCE_MEM, 0);
6471+ if (res == NULL) {
6472+ dev_err(&_dev->dev, "no CSR address\n");
6473+ retval = -ENODEV;
6474+ goto fail;
6475+ }
6476+ dev_dbg(&_dev->dev, "OTG - ioresource_mem start0x%08x: end:0x%08x\n",
6477+ (unsigned)res->start, (unsigned)res->end);
6478+ dwc_otg_device->phys_addr = res->start;
6479+ dwc_otg_device->base_len = res->end - res->start + 1;
6480+ if (request_mem_region(dwc_otg_device->phys_addr, dwc_otg_device->base_len,
6481+ dwc_driver_name) == NULL) {
6482+ dev_err(&_dev->dev, "request_mem_region failed\n");
6483+ retval = -EBUSY;
6484+ goto fail;
6485+ }
6486+
6487+ /*
6488+ * Map the DWC_otg Core memory into virtual address space.
6489+ */
6490+ dwc_otg_device->base = ioremap_nocache(dwc_otg_device->phys_addr, dwc_otg_device->base_len);
6491+ if (dwc_otg_device->base == NULL) {
6492+ dev_err(&_dev->dev, "ioremap() failed\n");
6493+ retval = -ENOMEM;
6494+ goto fail;
6495+ }
6496+ dev_dbg(&_dev->dev, "mapped base=0x%08x\n", (unsigned)dwc_otg_device->base);
6497+
6498+ /*
6499+ * Attempt to ensure this device is really a DWC_otg Controller.
6500+ * Read and verify the SNPSID register contents. The value should be
6501+ * 0x45F42XXX, which corresponds to "OT2", as in "OTG version 2.XX".
6502+ */
6503+ snpsid = dwc_read_reg32((uint32_t *)((uint8_t *)dwc_otg_device->base + 0x40));
6504+ if ((snpsid & 0xFFFFF000) != 0x4F542000) {
6505+ dev_err(&_dev->dev, "Bad value for SNPSID: 0x%08x\n", snpsid);
6506+ retval = -EINVAL;
6507+ goto fail;
6508+ }
6509+
6510+ /*
6511+ * Initialize driver data to point to the global DWC_otg
6512+ * Device structure.
6513+ */
6514+ platform_set_drvdata(_dev, dwc_otg_device);
6515+ dev_dbg(&_dev->dev, "dwc_otg_device=0x%p\n", dwc_otg_device);
6516+ dwc_otg_device->core_if = dwc_otg_cil_init( dwc_otg_device->base, &dwc_otg_module_params);
6517+ if (dwc_otg_device->core_if == 0) {
6518+ dev_err(&_dev->dev, "CIL initialization failed!\n");
6519+ retval = -ENOMEM;
6520+ goto fail;
6521+ }
6522+
6523+ /*
6524+ * Validate parameter values.
6525+ */
6526+ if (check_parameters(dwc_otg_device->core_if) != 0) {
6527+ retval = -EINVAL;
6528+ goto fail;
6529+ }
6530+
6531+ /* Added for PLB DMA phys virt mapping */
6532+ //dwc_otg_device->core_if->phys_addr = dwc_otg_device->phys_addr;
6533+ /*
6534+ * Create Device Attributes in sysfs
6535+ */
6536+ dwc_otg_attr_create (&_dev->dev);
6537+
6538+ /*
6539+ * Disable the global interrupt until all the interrupt
6540+ * handlers are installed.
6541+ */
6542+ dwc_otg_disable_global_interrupts( dwc_otg_device->core_if );
6543+ /*
6544+ * Install the interrupt handler for the common interrupts before
6545+ * enabling common interrupts in core_init below.
6546+ */
6547+ DWC_DEBUGPL( DBG_CIL, "registering (common) handler for irq%d\n", dwc_otg_device->irq);
6548+
6549+ retval = request_irq((unsigned int)dwc_otg_device->irq, dwc_otg_common_irq,
6550+ //SA_INTERRUPT|SA_SHIRQ, "dwc_otg", (void *)dwc_otg_device );
6551+ IRQF_SHARED, "dwc_otg", (void *)dwc_otg_device );
6552+ //IRQF_DISABLED, "dwc_otg", (void *)dwc_otg_device );
6553+ if (retval != 0) {
6554+ DWC_ERROR("request of irq%d failed retval: %d\n", dwc_otg_device->irq, retval);
6555+ retval = -EBUSY;
6556+ goto fail;
6557+ } else {
6558+ dwc_otg_device->common_irq_installed = 1;
6559+ }
6560+
6561+ /*
6562+ * Initialize the DWC_otg core.
6563+ */
6564+ dwc_otg_core_init( dwc_otg_device->core_if );
6565+
6566+
6567+#ifndef DWC_HOST_ONLY // otg device mode. (gadget.)
6568+ /*
6569+ * Initialize the PCD
6570+ */
6571+ retval = dwc_otg_pcd_init(dwc_otg_device);
6572+ if (retval != 0) {
6573+ DWC_ERROR("dwc_otg_pcd_init failed\n");
6574+ dwc_otg_device->pcd = NULL;
6575+ goto fail;
6576+ }
6577+#endif // DWC_HOST_ONLY
6578+
6579+#ifndef DWC_DEVICE_ONLY // otg host mode. (HCD)
6580+ /*
6581+ * Initialize the HCD
6582+ */
6583+#if 1 /*fscz*/
6584+ /* force_host_mode */
6585+ usbcfg.d32 = dwc_read_reg32(&dwc_otg_device->core_if->core_global_regs ->gusbcfg);
6586+ usbcfg.b.force_host_mode = 1;
6587+ dwc_write_reg32(&dwc_otg_device->core_if->core_global_regs ->gusbcfg, usbcfg.d32);
6588+#endif
6589+ retval = dwc_otg_hcd_init(&_dev->dev, dwc_otg_device);
6590+ if (retval != 0) {
6591+ DWC_ERROR("dwc_otg_hcd_init failed\n");
6592+ dwc_otg_device->hcd = NULL;
6593+ goto fail;
6594+ }
6595+#endif // DWC_DEVICE_ONLY
6596+
6597+ /*
6598+ * Enable the global interrupt after all the interrupt
6599+ * handlers are installed.
6600+ */
6601+ dwc_otg_enable_global_interrupts( dwc_otg_device->core_if );
6602+#if 0 /*fscz*/
6603+ usbcfg.d32 = dwc_read_reg32(&dwc_otg_device->core_if->core_global_regs ->gusbcfg);
6604+ usbcfg.b.force_host_mode = 0;
6605+ dwc_write_reg32(&dwc_otg_device->core_if->core_global_regs ->gusbcfg, usbcfg.d32);
6606+#endif
6607+
6608+
6609+ return 0;
6610+
6611+fail:
6612+ dwc_otg_driver_remove(_dev);
6613+ return retval;
6614+}
6615+
6616+/**
6617+ * This structure defines the methods to be called by a bus driver
6618+ * during the lifecycle of a device on that bus. Both drivers and
6619+ * devices are registered with a bus driver. The bus driver matches
6620+ * devices to drivers based on information in the device and driver
6621+ * structures.
6622+ *
6623+ * The probe function is called when the bus driver matches a device
6624+ * to this driver. The remove function is called when a device is
6625+ * unregistered with the bus driver.
6626+ */
6627+struct platform_driver dwc_otg_driver = {
6628+ .probe = dwc_otg_driver_probe,
6629+ .remove = dwc_otg_driver_remove,
6630+// .suspend = dwc_otg_driver_suspend,
6631+// .resume = dwc_otg_driver_resume,
6632+ .driver = {
6633+ .name = dwc_driver_name,
6634+ .owner = THIS_MODULE,
6635+ },
6636+};
6637+EXPORT_SYMBOL(dwc_otg_driver);
6638+
6639+/**
6640+ * This function is called when the dwc_otg_driver is installed with the
6641+ * insmod command. It registers the dwc_otg_driver structure with the
6642+ * appropriate bus driver. This will cause the dwc_otg_driver_probe function
6643+ * to be called. In addition, the bus driver will automatically expose
6644+ * attributes defined for the device and driver in the special sysfs file
6645+ * system.
6646+ *
6647+ * @return
6648+ */
6649+static int __init dwc_otg_init(void)
6650+{
6651+ int retval = 0;
6652+
6653+ printk(KERN_INFO "%s: version %s\n", dwc_driver_name, DWC_DRIVER_VERSION);
6654+
6655+ // ifxmips setup
6656+ retval = ifx_usb_hc_init(dwc_iomem_base, dwc_irq);
6657+ if (retval < 0)
6658+ {
6659+ printk(KERN_ERR "%s retval=%d\n", __func__, retval);
6660+ return retval;
6661+ }
6662+ dwc_otg_power_on(); // ifx only!!
6663+
6664+
6665+ retval = platform_driver_register(&dwc_otg_driver);
6666+
6667+ if (retval < 0) {
6668+ printk(KERN_ERR "%s retval=%d\n", __func__, retval);
6669+ goto error1;
6670+ }
6671+
6672+ retval = driver_create_file(&dwc_otg_driver.driver, &driver_attr_version);
6673+ if (retval < 0)
6674+ {
6675+ printk(KERN_ERR "%s retval=%d\n", __func__, retval);
6676+ goto error2;
6677+ }
6678+ retval = driver_create_file(&dwc_otg_driver.driver, &driver_attr_debuglevel);
6679+ if (retval < 0)
6680+ {
6681+ printk(KERN_ERR "%s retval=%d\n", __func__, retval);
6682+ goto error3;
6683+ }
6684+ return retval;
6685+
6686+
6687+error3:
6688+ driver_remove_file(&dwc_otg_driver.driver, &driver_attr_version);
6689+error2:
6690+ driver_unregister(&dwc_otg_driver.driver);
6691+error1:
6692+ ifx_usb_hc_remove();
6693+ return retval;
6694+}
6695+module_init(dwc_otg_init);
6696+
6697+/**
6698+ * This function is called when the driver is removed from the kernel
6699+ * with the rmmod command. The driver unregisters itself with its bus
6700+ * driver.
6701+ *
6702+ */
6703+static void __exit dwc_otg_cleanup(void)
6704+{
6705+ printk(KERN_DEBUG "dwc_otg_cleanup()\n");
6706+
6707+ driver_remove_file(&dwc_otg_driver.driver, &driver_attr_debuglevel);
6708+ driver_remove_file(&dwc_otg_driver.driver, &driver_attr_version);
6709+
6710+ platform_driver_unregister(&dwc_otg_driver);
6711+ ifx_usb_hc_remove();
6712+
6713+ printk(KERN_INFO "%s module removed\n", dwc_driver_name);
6714+}
6715+module_exit(dwc_otg_cleanup);
6716+
6717+MODULE_DESCRIPTION(DWC_DRIVER_DESC);
6718+MODULE_AUTHOR("Synopsys Inc.");
6719+MODULE_LICENSE("GPL");
6720+
6721+module_param_named(otg_cap, dwc_otg_module_params.otg_cap, int, 0444);
6722+MODULE_PARM_DESC(otg_cap, "OTG Capabilities 0=HNP&SRP 1=SRP Only 2=None");
6723+module_param_named(opt, dwc_otg_module_params.opt, int, 0444);
6724+MODULE_PARM_DESC(opt, "OPT Mode");
6725+module_param_named(dma_enable, dwc_otg_module_params.dma_enable, int, 0444);
6726+MODULE_PARM_DESC(dma_enable, "DMA Mode 0=Slave 1=DMA enabled");
6727+module_param_named(dma_burst_size, dwc_otg_module_params.dma_burst_size, int, 0444);
6728+MODULE_PARM_DESC(dma_burst_size, "DMA Burst Size 1, 4, 8, 16, 32, 64, 128, 256");
6729+module_param_named(speed, dwc_otg_module_params.speed, int, 0444);
6730+MODULE_PARM_DESC(speed, "Speed 0=High Speed 1=Full Speed");
6731+module_param_named(host_support_fs_ls_low_power, dwc_otg_module_params.host_support_fs_ls_low_power, int, 0444);
6732+MODULE_PARM_DESC(host_support_fs_ls_low_power, "Support Low Power w/FS or LS 0=Support 1=Don't Support");
6733+module_param_named(host_ls_low_power_phy_clk, dwc_otg_module_params.host_ls_low_power_phy_clk, int, 0444);
6734+MODULE_PARM_DESC(host_ls_low_power_phy_clk, "Low Speed Low Power Clock 0=48Mhz 1=6Mhz");
6735+module_param_named(enable_dynamic_fifo, dwc_otg_module_params.enable_dynamic_fifo, int, 0444);
6736+MODULE_PARM_DESC(enable_dynamic_fifo, "0=cC Setting 1=Allow Dynamic Sizing");
6737+module_param_named(data_fifo_size, dwc_otg_module_params.data_fifo_size, int, 0444);
6738+MODULE_PARM_DESC(data_fifo_size, "Total number of words in the data FIFO memory 32-32768");
6739+module_param_named(dev_rx_fifo_size, dwc_otg_module_params.dev_rx_fifo_size, int, 0444);
6740+MODULE_PARM_DESC(dev_rx_fifo_size, "Number of words in the Rx FIFO 16-32768");
6741+module_param_named(dev_nperio_tx_fifo_size, dwc_otg_module_params.dev_nperio_tx_fifo_size, int, 0444);
6742+MODULE_PARM_DESC(dev_nperio_tx_fifo_size, "Number of words in the non-periodic Tx FIFO 16-32768");
6743+module_param_named(dev_perio_tx_fifo_size_1, dwc_otg_module_params.dev_perio_tx_fifo_size[0], int, 0444);
6744+MODULE_PARM_DESC(dev_perio_tx_fifo_size_1, "Number of words in the periodic Tx FIFO 4-768");
6745+module_param_named(dev_perio_tx_fifo_size_2, dwc_otg_module_params.dev_perio_tx_fifo_size[1], int, 0444);
6746+MODULE_PARM_DESC(dev_perio_tx_fifo_size_2, "Number of words in the periodic Tx FIFO 4-768");
6747+module_param_named(dev_perio_tx_fifo_size_3, dwc_otg_module_params.dev_perio_tx_fifo_size[2], int, 0444);
6748+MODULE_PARM_DESC(dev_perio_tx_fifo_size_3, "Number of words in the periodic Tx FIFO 4-768");
6749+module_param_named(dev_perio_tx_fifo_size_4, dwc_otg_module_params.dev_perio_tx_fifo_size[3], int, 0444);
6750+MODULE_PARM_DESC(dev_perio_tx_fifo_size_4, "Number of words in the periodic Tx FIFO 4-768");
6751+module_param_named(dev_perio_tx_fifo_size_5, dwc_otg_module_params.dev_perio_tx_fifo_size[4], int, 0444);
6752+MODULE_PARM_DESC(dev_perio_tx_fifo_size_5, "Number of words in the periodic Tx FIFO 4-768");
6753+module_param_named(dev_perio_tx_fifo_size_6, dwc_otg_module_params.dev_perio_tx_fifo_size[5], int, 0444);
6754+MODULE_PARM_DESC(dev_perio_tx_fifo_size_6, "Number of words in the periodic Tx FIFO 4-768");
6755+module_param_named(dev_perio_tx_fifo_size_7, dwc_otg_module_params.dev_perio_tx_fifo_size[6], int, 0444);
6756+MODULE_PARM_DESC(dev_perio_tx_fifo_size_7, "Number of words in the periodic Tx FIFO 4-768");
6757+module_param_named(dev_perio_tx_fifo_size_8, dwc_otg_module_params.dev_perio_tx_fifo_size[7], int, 0444);
6758+MODULE_PARM_DESC(dev_perio_tx_fifo_size_8, "Number of words in the periodic Tx FIFO 4-768");
6759+module_param_named(dev_perio_tx_fifo_size_9, dwc_otg_module_params.dev_perio_tx_fifo_size[8], int, 0444);
6760+MODULE_PARM_DESC(dev_perio_tx_fifo_size_9, "Number of words in the periodic Tx FIFO 4-768");
6761+module_param_named(dev_perio_tx_fifo_size_10, dwc_otg_module_params.dev_perio_tx_fifo_size[9], int, 0444);
6762+MODULE_PARM_DESC(dev_perio_tx_fifo_size_10, "Number of words in the periodic Tx FIFO 4-768");
6763+module_param_named(dev_perio_tx_fifo_size_11, dwc_otg_module_params.dev_perio_tx_fifo_size[10], int, 0444);
6764+MODULE_PARM_DESC(dev_perio_tx_fifo_size_11, "Number of words in the periodic Tx FIFO 4-768");
6765+module_param_named(dev_perio_tx_fifo_size_12, dwc_otg_module_params.dev_perio_tx_fifo_size[11], int, 0444);
6766+MODULE_PARM_DESC(dev_perio_tx_fifo_size_12, "Number of words in the periodic Tx FIFO 4-768");
6767+module_param_named(dev_perio_tx_fifo_size_13, dwc_otg_module_params.dev_perio_tx_fifo_size[12], int, 0444);
6768+MODULE_PARM_DESC(dev_perio_tx_fifo_size_13, "Number of words in the periodic Tx FIFO 4-768");
6769+module_param_named(dev_perio_tx_fifo_size_14, dwc_otg_module_params.dev_perio_tx_fifo_size[13], int, 0444);
6770+MODULE_PARM_DESC(dev_perio_tx_fifo_size_14, "Number of words in the periodic Tx FIFO 4-768");
6771+module_param_named(dev_perio_tx_fifo_size_15, dwc_otg_module_params.dev_perio_tx_fifo_size[14], int, 0444);
6772+MODULE_PARM_DESC(dev_perio_tx_fifo_size_15, "Number of words in the periodic Tx FIFO 4-768");
6773+module_param_named(host_rx_fifo_size, dwc_otg_module_params.host_rx_fifo_size, int, 0444);
6774+MODULE_PARM_DESC(host_rx_fifo_size, "Number of words in the Rx FIFO 16-32768");
6775+module_param_named(host_nperio_tx_fifo_size, dwc_otg_module_params.host_nperio_tx_fifo_size, int, 0444);
6776+MODULE_PARM_DESC(host_nperio_tx_fifo_size, "Number of words in the non-periodic Tx FIFO 16-32768");
6777+module_param_named(host_perio_tx_fifo_size, dwc_otg_module_params.host_perio_tx_fifo_size, int, 0444);
6778+MODULE_PARM_DESC(host_perio_tx_fifo_size, "Number of words in the host periodic Tx FIFO 16-32768");
6779+module_param_named(max_transfer_size, dwc_otg_module_params.max_transfer_size, int, 0444);
6780+/** @todo Set the max to 512K, modify checks */
6781+MODULE_PARM_DESC(max_transfer_size, "The maximum transfer size supported in bytes 2047-65535");
6782+module_param_named(max_packet_count, dwc_otg_module_params.max_packet_count, int, 0444);
6783+MODULE_PARM_DESC(max_packet_count, "The maximum number of packets in a transfer 15-511");
6784+module_param_named(host_channels, dwc_otg_module_params.host_channels, int, 0444);
6785+MODULE_PARM_DESC(host_channels, "The number of host channel registers to use 1-16");
6786+module_param_named(dev_endpoints, dwc_otg_module_params.dev_endpoints, int, 0444);
6787+MODULE_PARM_DESC(dev_endpoints, "The number of endpoints in addition to EP0 available for device mode 1-15");
6788+module_param_named(phy_type, dwc_otg_module_params.phy_type, int, 0444);
6789+MODULE_PARM_DESC(phy_type, "0=Reserved 1=UTMI+ 2=ULPI");
6790+module_param_named(phy_utmi_width, dwc_otg_module_params.phy_utmi_width, int, 0444);
6791+MODULE_PARM_DESC(phy_utmi_width, "Specifies the UTMI+ Data Width 8 or 16 bits");
6792+module_param_named(phy_ulpi_ddr, dwc_otg_module_params.phy_ulpi_ddr, int, 0444);
6793+MODULE_PARM_DESC(phy_ulpi_ddr, "ULPI at double or single data rate 0=Single 1=Double");
6794+module_param_named(phy_ulpi_ext_vbus, dwc_otg_module_params.phy_ulpi_ext_vbus, int, 0444);
6795+MODULE_PARM_DESC(phy_ulpi_ext_vbus, "ULPI PHY using internal or external vbus 0=Internal");
6796+module_param_named(i2c_enable, dwc_otg_module_params.i2c_enable, int, 0444);
6797+MODULE_PARM_DESC(i2c_enable, "FS PHY Interface");
6798+module_param_named(ulpi_fs_ls, dwc_otg_module_params.ulpi_fs_ls, int, 0444);
6799+MODULE_PARM_DESC(ulpi_fs_ls, "ULPI PHY FS/LS mode only");
6800+module_param_named(ts_dline, dwc_otg_module_params.ts_dline, int, 0444);
6801+MODULE_PARM_DESC(ts_dline, "Term select Dline pulsing for all PHYs");
6802+module_param_named(debug, g_dbg_lvl, int, 0444);
6803+MODULE_PARM_DESC(debug, "0");
6804+module_param_named(en_multiple_tx_fifo,
6805+ dwc_otg_module_params.en_multiple_tx_fifo, int, 0444);
6806+MODULE_PARM_DESC(en_multiple_tx_fifo,
6807+ "Dedicated Non Periodic Tx FIFOs 0=disabled 1=enabled");
6808+module_param_named(dev_tx_fifo_size_1,
6809+ dwc_otg_module_params.dev_tx_fifo_size[0], int, 0444);
6810+MODULE_PARM_DESC(dev_tx_fifo_size_1, "Number of words in the Tx FIFO 4-768");
6811+module_param_named(dev_tx_fifo_size_2,
6812+ dwc_otg_module_params.dev_tx_fifo_size[1], int, 0444);
6813+MODULE_PARM_DESC(dev_tx_fifo_size_2, "Number of words in the Tx FIFO 4-768");
6814+module_param_named(dev_tx_fifo_size_3,
6815+ dwc_otg_module_params.dev_tx_fifo_size[2], int, 0444);
6816+MODULE_PARM_DESC(dev_tx_fifo_size_3, "Number of words in the Tx FIFO 4-768");
6817+module_param_named(dev_tx_fifo_size_4,
6818+ dwc_otg_module_params.dev_tx_fifo_size[3], int, 0444);
6819+MODULE_PARM_DESC(dev_tx_fifo_size_4, "Number of words in the Tx FIFO 4-768");
6820+module_param_named(dev_tx_fifo_size_5,
6821+ dwc_otg_module_params.dev_tx_fifo_size[4], int, 0444);
6822+MODULE_PARM_DESC(dev_tx_fifo_size_5, "Number of words in the Tx FIFO 4-768");
6823+module_param_named(dev_tx_fifo_size_6,
6824+ dwc_otg_module_params.dev_tx_fifo_size[5], int, 0444);
6825+MODULE_PARM_DESC(dev_tx_fifo_size_6, "Number of words in the Tx FIFO 4-768");
6826+module_param_named(dev_tx_fifo_size_7,
6827+ dwc_otg_module_params.dev_tx_fifo_size[6], int, 0444);
6828+MODULE_PARM_DESC(dev_tx_fifo_size_7, "Number of words in the Tx FIFO 4-768");
6829+module_param_named(dev_tx_fifo_size_8,
6830+ dwc_otg_module_params.dev_tx_fifo_size[7], int, 0444);
6831+MODULE_PARM_DESC(dev_tx_fifo_size_8, "Number of words in the Tx FIFO 4-768");
6832+module_param_named(dev_tx_fifo_size_9,
6833+ dwc_otg_module_params.dev_tx_fifo_size[8], int, 0444);
6834+MODULE_PARM_DESC(dev_tx_fifo_size_9, "Number of words in the Tx FIFO 4-768");
6835+module_param_named(dev_tx_fifo_size_10,
6836+ dwc_otg_module_params.dev_tx_fifo_size[9], int, 0444);
6837+MODULE_PARM_DESC(dev_tx_fifo_size_10, "Number of words in the Tx FIFO 4-768");
6838+module_param_named(dev_tx_fifo_size_11,
6839+ dwc_otg_module_params.dev_tx_fifo_size[10], int, 0444);
6840+MODULE_PARM_DESC(dev_tx_fifo_size_11, "Number of words in the Tx FIFO 4-768");
6841+module_param_named(dev_tx_fifo_size_12,
6842+ dwc_otg_module_params.dev_tx_fifo_size[11], int, 0444);
6843+MODULE_PARM_DESC(dev_tx_fifo_size_12, "Number of words in the Tx FIFO 4-768");
6844+module_param_named(dev_tx_fifo_size_13,
6845+ dwc_otg_module_params.dev_tx_fifo_size[12], int, 0444);
6846+MODULE_PARM_DESC(dev_tx_fifo_size_13, "Number of words in the Tx FIFO 4-768");
6847+module_param_named(dev_tx_fifo_size_14,
6848+ dwc_otg_module_params.dev_tx_fifo_size[13], int, 0444);
6849+MODULE_PARM_DESC(dev_tx_fifo_size_14, "Number of words in the Tx FIFO 4-768");
6850+module_param_named(dev_tx_fifo_size_15,
6851+ dwc_otg_module_params.dev_tx_fifo_size[14], int, 0444);
6852+MODULE_PARM_DESC(dev_tx_fifo_size_15, "Number of words in the Tx FIFO 4-768");
6853+module_param_named(thr_ctl, dwc_otg_module_params.thr_ctl, int, 0444);
6854+MODULE_PARM_DESC(thr_ctl, "Thresholding enable flag bit"
6855+ "0 - non ISO Tx thr., 1 - ISO Tx thr., 2 - Rx thr.- bit 0=disabled 1=enabled");
6856+module_param_named(tx_thr_length, dwc_otg_module_params.tx_thr_length, int, 0444);
6857+MODULE_PARM_DESC(tx_thr_length, "Tx Threshold length in 32 bit DWORDs");
6858+module_param_named(rx_thr_length, dwc_otg_module_params.rx_thr_length, int, 0444);
6859+MODULE_PARM_DESC(rx_thr_length, "Rx Threshold length in 32 bit DWORDs");
6860+module_param_named (iomem_base, dwc_iomem_base, ulong, 0444);
6861+MODULE_PARM_DESC (dwc_iomem_base, "The base address of the DWC_OTG register.");
6862+module_param_named (irq, dwc_irq, int, 0444);
6863+MODULE_PARM_DESC (dwc_irq, "The interrupt number");
6864+
6865+/** @page "Module Parameters"
6866+ *
6867+ * The following parameters may be specified when starting the module.
6868+ * These parameters define how the DWC_otg controller should be
6869+ * configured. Parameter values are passed to the CIL initialization
6870+ * function dwc_otg_cil_init
6871+ *
6872+ * Example: <code>modprobe dwc_otg speed=1 otg_cap=1</code>
6873+ *
6874+
6875+ <table>
6876+ <tr><td>Parameter Name</td><td>Meaning</td></tr>
6877+
6878+ <tr>
6879+ <td>otg_cap</td>
6880+ <td>Specifies the OTG capabilities. The driver will automatically detect the
6881+ value for this parameter if none is specified.
6882+ - 0: HNP and SRP capable (default, if available)
6883+ - 1: SRP Only capable
6884+ - 2: No HNP/SRP capable
6885+ </td></tr>
6886+
6887+ <tr>
6888+ <td>dma_enable</td>
6889+ <td>Specifies whether to use slave or DMA mode for accessing the data FIFOs.
6890+ The driver will automatically detect the value for this parameter if none is
6891+ specified.
6892+ - 0: Slave
6893+ - 1: DMA (default, if available)
6894+ </td></tr>
6895+
6896+ <tr>
6897+ <td>dma_burst_size</td>
6898+ <td>The DMA Burst size (applicable only for External DMA Mode).
6899+ - Values: 1, 4, 8 16, 32, 64, 128, 256 (default 32)
6900+ </td></tr>
6901+
6902+ <tr>
6903+ <td>speed</td>
6904+ <td>Specifies the maximum speed of operation in host and device mode. The
6905+ actual speed depends on the speed of the attached device and the value of
6906+ phy_type.
6907+ - 0: High Speed (default)
6908+ - 1: Full Speed
6909+ </td></tr>
6910+
6911+ <tr>
6912+ <td>host_support_fs_ls_low_power</td>
6913+ <td>Specifies whether low power mode is supported when attached to a Full
6914+ Speed or Low Speed device in host mode.
6915+ - 0: Don't support low power mode (default)
6916+ - 1: Support low power mode
6917+ </td></tr>
6918+
6919+ <tr>
6920+ <td>host_ls_low_power_phy_clk</td>
6921+ <td>Specifies the PHY clock rate in low power mode when connected to a Low
6922+ Speed device in host mode. This parameter is applicable only if
6923+ HOST_SUPPORT_FS_LS_LOW_POWER is enabled.
6924+ - 0: 48 MHz (default)
6925+ - 1: 6 MHz
6926+ </td></tr>
6927+
6928+ <tr>
6929+ <td>enable_dynamic_fifo</td>
6930+ <td> Specifies whether FIFOs may be resized by the driver software.
6931+ - 0: Use cC FIFO size parameters
6932+ - 1: Allow dynamic FIFO sizing (default)
6933+ </td></tr>
6934+
6935+ <tr>
6936+ <td>data_fifo_size</td>
6937+ <td>Total number of 4-byte words in the data FIFO memory. This memory
6938+ includes the Rx FIFO, non-periodic Tx FIFO, and periodic Tx FIFOs.
6939+ - Values: 32 to 32768 (default 8192)
6940+
6941+ Note: The total FIFO memory depth in the FPGA configuration is 8192.
6942+ </td></tr>
6943+
6944+ <tr>
6945+ <td>dev_rx_fifo_size</td>
6946+ <td>Number of 4-byte words in the Rx FIFO in device mode when dynamic
6947+ FIFO sizing is enabled.
6948+ - Values: 16 to 32768 (default 1064)
6949+ </td></tr>
6950+
6951+ <tr>
6952+ <td>dev_nperio_tx_fifo_size</td>
6953+ <td>Number of 4-byte words in the non-periodic Tx FIFO in device mode when
6954+ dynamic FIFO sizing is enabled.
6955+ - Values: 16 to 32768 (default 1024)
6956+ </td></tr>
6957+
6958+ <tr>
6959+ <td>dev_perio_tx_fifo_size_n (n = 1 to 15)</td>
6960+ <td>Number of 4-byte words in each of the periodic Tx FIFOs in device mode
6961+ when dynamic FIFO sizing is enabled.
6962+ - Values: 4 to 768 (default 256)
6963+ </td></tr>
6964+
6965+ <tr>
6966+ <td>host_rx_fifo_size</td>
6967+ <td>Number of 4-byte words in the Rx FIFO in host mode when dynamic FIFO
6968+ sizing is enabled.
6969+ - Values: 16 to 32768 (default 1024)
6970+ </td></tr>
6971+
6972+ <tr>
6973+ <td>host_nperio_tx_fifo_size</td>
6974+ <td>Number of 4-byte words in the non-periodic Tx FIFO in host mode when
6975+ dynamic FIFO sizing is enabled in the core.
6976+ - Values: 16 to 32768 (default 1024)
6977+ </td></tr>
6978+
6979+ <tr>
6980+ <td>host_perio_tx_fifo_size</td>
6981+ <td>Number of 4-byte words in the host periodic Tx FIFO when dynamic FIFO
6982+ sizing is enabled.
6983+ - Values: 16 to 32768 (default 1024)
6984+ </td></tr>
6985+
6986+ <tr>
6987+ <td>max_transfer_size</td>
6988+ <td>The maximum transfer size supported in bytes.
6989+ - Values: 2047 to 65,535 (default 65,535)
6990+ </td></tr>
6991+
6992+ <tr>
6993+ <td>max_packet_count</td>
6994+ <td>The maximum number of packets in a transfer.
6995+ - Values: 15 to 511 (default 511)
6996+ </td></tr>
6997+
6998+ <tr>
6999+ <td>host_channels</td>
7000+ <td>The number of host channel registers to use.
7001+ - Values: 1 to 16 (default 12)
7002+
7003+ Note: The FPGA configuration supports a maximum of 12 host channels.
7004+ </td></tr>
7005+
7006+ <tr>
7007+ <td>dev_endpoints</td>
7008+ <td>The number of endpoints in addition to EP0 available for device mode
7009+ operations.
7010+ - Values: 1 to 15 (default 6 IN and OUT)
7011+
7012+ Note: The FPGA configuration supports a maximum of 6 IN and OUT endpoints in
7013+ addition to EP0.
7014+ </td></tr>
7015+
7016+ <tr>
7017+ <td>phy_type</td>
7018+ <td>Specifies the type of PHY interface to use. By default, the driver will
7019+ automatically detect the phy_type.
7020+ - 0: Full Speed
7021+ - 1: UTMI+ (default, if available)
7022+ - 2: ULPI
7023+ </td></tr>
7024+
7025+ <tr>
7026+ <td>phy_utmi_width</td>
7027+ <td>Specifies the UTMI+ Data Width. This parameter is applicable for a
7028+ phy_type of UTMI+. Also, this parameter is applicable only if the
7029+ OTG_HSPHY_WIDTH cC parameter was set to "8 and 16 bits", meaning that the
7030+ core has been configured to work at either data path width.
7031+ - Values: 8 or 16 bits (default 16)
7032+ </td></tr>
7033+
7034+ <tr>
7035+ <td>phy_ulpi_ddr</td>
7036+ <td>Specifies whether the ULPI operates at double or single data rate. This
7037+ parameter is only applicable if phy_type is ULPI.
7038+ - 0: single data rate ULPI interface with 8 bit wide data bus (default)
7039+ - 1: double data rate ULPI interface with 4 bit wide data bus
7040+ </td></tr>
7041+
7042+ <tr>
7043+ <td>i2c_enable</td>
7044+ <td>Specifies whether to use the I2C interface for full speed PHY. This
7045+ parameter is only applicable if PHY_TYPE is FS.
7046+ - 0: Disabled (default)
7047+ - 1: Enabled
7048+ </td></tr>
7049+
7050+ <tr>
7051+ <td>otg_en_multiple_tx_fifo</td>
7052+ <td>Specifies whether dedicatedto tx fifos are enabled for non periodic IN EPs.
7053+ The driver will automatically detect the value for this parameter if none is
7054+ specified.
7055+ - 0: Disabled
7056+ - 1: Enabled (default, if available)
7057+ </td></tr>
7058+
7059+ <tr>
7060+ <td>dev_tx_fifo_size_n (n = 1 to 15)</td>
7061+ <td>Number of 4-byte words in each of the Tx FIFOs in device mode
7062+ when dynamic FIFO sizing is enabled.
7063+ - Values: 4 to 768 (default 256)
7064+ </td></tr>
7065+
7066+*/
7067diff --git a/drivers/usb/dwc_otg/dwc_otg_driver.h b/drivers/usb/dwc_otg/dwc_otg_driver.h
7068new file mode 100644
7069index 0000000..7e6940d
7070--- /dev/null
7071+++ b/drivers/usb/dwc_otg/dwc_otg_driver.h
7072@@ -0,0 +1,84 @@
7073+/* ==========================================================================
7074+ * $File: //dwh/usb_iip/dev/software/otg_ipmate/linux/drivers/dwc_otg_driver.h $
7075+ * $Revision: 1.1.1.1 $
7076+ * $Date: 2009-04-17 06:15:34 $
7077+ * $Change: 510275 $
7078+ *
7079+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
7080+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
7081+ * otherwise expressly agreed to in writing between Synopsys and you.
7082+ *
7083+ * The Software IS NOT an item of Licensed Software or Licensed Product under
7084+ * any End User Software License Agreement or Agreement for Licensed Product
7085+ * with Synopsys or any supplement thereto. You are permitted to use and
7086+ * redistribute this Software in source and binary forms, with or without
7087+ * modification, provided that redistributions of source code must retain this
7088+ * notice. You may not view, use, disclose, copy or distribute this file or
7089+ * any information contained herein except pursuant to this license grant from
7090+ * Synopsys. If you do not agree with this notice, including the disclaimer
7091+ * below, then you are not authorized to use the Software.
7092+ *
7093+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
7094+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
7095+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
7096+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
7097+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
7098+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
7099+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
7100+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
7101+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
7102+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
7103+ * DAMAGE.
7104+ * ========================================================================== */
7105+
7106+#if !defined(__DWC_OTG_DRIVER_H__)
7107+#define __DWC_OTG_DRIVER_H__
7108+
7109+/** @file
7110+ * This file contains the interface to the Linux driver.
7111+ */
7112+#include "dwc_otg_cil.h"
7113+
7114+/* Type declarations */
7115+struct dwc_otg_pcd;
7116+struct dwc_otg_hcd;
7117+
7118+/**
7119+ * This structure is a wrapper that encapsulates the driver components used to
7120+ * manage a single DWC_otg controller.
7121+ */
7122+typedef struct dwc_otg_device
7123+{
7124+ /** Base address returned from ioremap() */
7125+ void *base;
7126+
7127+ /** Pointer to the core interface structure. */
7128+ dwc_otg_core_if_t *core_if;
7129+
7130+ /** Register offset for Diagnostic API.*/
7131+ uint32_t reg_offset;
7132+
7133+ /** Pointer to the PCD structure. */
7134+ struct dwc_otg_pcd *pcd;
7135+
7136+ /** Pointer to the HCD structure. */
7137+ struct dwc_otg_hcd *hcd;
7138+
7139+ /** Flag to indicate whether the common IRQ handler is installed. */
7140+ uint8_t common_irq_installed;
7141+
7142+ /** Interrupt request number. */
7143+ unsigned int irq;
7144+
7145+ /** Physical address of Control and Status registers, used by
7146+ * release_mem_region().
7147+ */
7148+ resource_size_t phys_addr;
7149+
7150+ /** Length of memory region, used by release_mem_region(). */
7151+ unsigned long base_len;
7152+} dwc_otg_device_t;
7153+
7154+//#define dev_dbg(fake, format, arg...) printk(KERN_CRIT __FILE__ ":%d: " format "\n" , __LINE__, ## arg)
7155+
7156+#endif
7157diff --git a/drivers/usb/dwc_otg/dwc_otg_hcd.c b/drivers/usb/dwc_otg/dwc_otg_hcd.c
7158new file mode 100644
7159index 0000000..ad6bc72
7160--- /dev/null
7161+++ b/drivers/usb/dwc_otg/dwc_otg_hcd.c
7162@@ -0,0 +1,2870 @@
7163+/* ==========================================================================
7164+ * $File: //dwh/usb_iip/dev/software/otg_ipmate/linux/drivers/dwc_otg_hcd.c $
7165+ * $Revision: 1.1.1.1 $
7166+ * $Date: 2009-04-17 06:15:34 $
7167+ * $Change: 631780 $
7168+ *
7169+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
7170+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
7171+ * otherwise expressly agreed to in writing between Synopsys and you.
7172+ *
7173+ * The Software IS NOT an item of Licensed Software or Licensed Product under
7174+ * any End User Software License Agreement or Agreement for Licensed Product
7175+ * with Synopsys or any supplement thereto. You are permitted to use and
7176+ * redistribute this Software in source and binary forms, with or without
7177+ * modification, provided that redistributions of source code must retain this
7178+ * notice. You may not view, use, disclose, copy or distribute this file or
7179+ * any information contained herein except pursuant to this license grant from
7180+ * Synopsys. If you do not agree with this notice, including the disclaimer
7181+ * below, then you are not authorized to use the Software.
7182+ *
7183+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
7184+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
7185+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
7186+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
7187+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
7188+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
7189+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
7190+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
7191+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
7192+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
7193+ * DAMAGE.
7194+ * ========================================================================== */
7195+#ifndef DWC_DEVICE_ONLY
7196+
7197+/**
7198+ * @file
7199+ *
7200+ * This file contains the implementation of the HCD. In Linux, the HCD
7201+ * implements the hc_driver API.
7202+ */
7203+#include <linux/kernel.h>
7204+#include <linux/module.h>
7205+#include <linux/moduleparam.h>
7206+#include <linux/init.h>
7207+
7208+#include <linux/device.h>
7209+
7210+#include <linux/errno.h>
7211+#include <linux/list.h>
7212+#include <linux/interrupt.h>
7213+#include <linux/string.h>
7214+
7215+#include <linux/dma-mapping.h>
7216+
7217+#include "dwc_otg_driver.h"
7218+#include "dwc_otg_hcd.h"
7219+#include "dwc_otg_regs.h"
7220+
7221+#include <asm/irq.h>
7222+#include "dwc_otg_ifx.h" // for Infineon platform specific.
7223+extern atomic_t release_later;
7224+
7225+static u64 dma_mask = DMA_BIT_MASK(32);
7226+
7227+static const char dwc_otg_hcd_name [] = "dwc_otg_hcd";
7228+static const struct hc_driver dwc_otg_hc_driver =
7229+{
7230+ .description = dwc_otg_hcd_name,
7231+ .product_desc = "DWC OTG Controller",
7232+ .hcd_priv_size = sizeof(dwc_otg_hcd_t),
7233+ .irq = dwc_otg_hcd_irq,
7234+ .flags = HCD_MEMORY | HCD_USB2,
7235+ //.reset =
7236+ .start = dwc_otg_hcd_start,
7237+ //.suspend =
7238+ //.resume =
7239+ .stop = dwc_otg_hcd_stop,
7240+ .urb_enqueue = dwc_otg_hcd_urb_enqueue,
7241+ .urb_dequeue = dwc_otg_hcd_urb_dequeue,
7242+ .endpoint_disable = dwc_otg_hcd_endpoint_disable,
7243+ .get_frame_number = dwc_otg_hcd_get_frame_number,
7244+ .hub_status_data = dwc_otg_hcd_hub_status_data,
7245+ .hub_control = dwc_otg_hcd_hub_control,
7246+ //.hub_suspend =
7247+ //.hub_resume =
7248+};
7249+
7250+
7251+/**
7252+ * Work queue function for starting the HCD when A-Cable is connected.
7253+ * The dwc_otg_hcd_start() must be called in a process context.
7254+ */
7255+static void hcd_start_func(struct work_struct *work)
7256+{
7257+ struct dwc_otg_hcd *priv =
7258+ container_of(work, struct dwc_otg_hcd, start_work);
7259+ struct usb_hcd *usb_hcd = (struct usb_hcd *)priv->_p;
7260+ DWC_DEBUGPL(DBG_HCDV, "%s() %p\n", __func__, usb_hcd);
7261+ if (usb_hcd) {
7262+ dwc_otg_hcd_start(usb_hcd);
7263+ }
7264+}
7265+
7266+
7267+/**
7268+ * HCD Callback function for starting the HCD when A-Cable is
7269+ * connected.
7270+ *
7271+ * @param _p void pointer to the <code>struct usb_hcd</code>
7272+ */
7273+static int32_t dwc_otg_hcd_start_cb(void *_p)
7274+{
7275+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(_p);
7276+ dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
7277+ hprt0_data_t hprt0;
7278+ if (core_if->op_state == B_HOST) {
7279+ /*
7280+ * Reset the port. During a HNP mode switch the reset
7281+ * needs to occur within 1ms and have a duration of at
7282+ * least 50ms.
7283+ */
7284+ hprt0.d32 = dwc_otg_read_hprt0 (core_if);
7285+ hprt0.b.prtrst = 1;
7286+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
7287+ ((struct usb_hcd *)_p)->self.is_b_host = 1;
7288+ } else {
7289+ ((struct usb_hcd *)_p)->self.is_b_host = 0;
7290+ }
7291+ /* Need to start the HCD in a non-interrupt context. */
7292+ INIT_WORK(&dwc_otg_hcd->start_work, hcd_start_func);
7293+ dwc_otg_hcd->_p = _p;
7294+ schedule_work(&dwc_otg_hcd->start_work);
7295+ return 1;
7296+}
7297+
7298+
7299+/**
7300+ * HCD Callback function for stopping the HCD.
7301+ *
7302+ * @param _p void pointer to the <code>struct usb_hcd</code>
7303+ */
7304+static int32_t dwc_otg_hcd_stop_cb( void *_p )
7305+{
7306+ struct usb_hcd *usb_hcd = (struct usb_hcd *)_p;
7307+ DWC_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, _p);
7308+ dwc_otg_hcd_stop( usb_hcd );
7309+ return 1;
7310+}
7311+static void del_xfer_timers(dwc_otg_hcd_t *_hcd)
7312+{
7313+#ifdef DEBUG
7314+ int i;
7315+ int num_channels = _hcd->core_if->core_params->host_channels;
7316+ for (i = 0; i < num_channels; i++) {
7317+ del_timer(&_hcd->core_if->hc_xfer_timer[i]);
7318+ }
7319+#endif /* */
7320+}
7321+
7322+static void del_timers(dwc_otg_hcd_t *_hcd)
7323+{
7324+ del_xfer_timers(_hcd);
7325+ del_timer(&_hcd->conn_timer);
7326+}
7327+
7328+/**
7329+ * Processes all the URBs in a single list of QHs. Completes them with
7330+ * -ETIMEDOUT and frees the QTD.
7331+ */
7332+static void kill_urbs_in_qh_list(dwc_otg_hcd_t * _hcd,
7333+ struct list_head *_qh_list)
7334+{
7335+ struct list_head *qh_item;
7336+ dwc_otg_qh_t *qh;
7337+ struct list_head *qtd_item;
7338+ dwc_otg_qtd_t *qtd;
7339+
7340+ list_for_each(qh_item, _qh_list) {
7341+ qh = list_entry(qh_item, dwc_otg_qh_t, qh_list_entry);
7342+ for (qtd_item = qh->qtd_list.next; qtd_item != &qh->qtd_list;
7343+ qtd_item = qh->qtd_list.next) {
7344+ qtd = list_entry(qtd_item, dwc_otg_qtd_t, qtd_list_entry);
7345+ if (qtd->urb != NULL) {
7346+ dwc_otg_hcd_complete_urb(_hcd, qtd->urb,-ETIMEDOUT);
7347+ }
7348+ dwc_otg_hcd_qtd_remove_and_free(qtd);
7349+ }
7350+ }
7351+}
7352+
7353+/**
7354+ * Responds with an error status of ETIMEDOUT to all URBs in the non-periodic
7355+ * and periodic schedules. The QTD associated with each URB is removed from
7356+ * the schedule and freed. This function may be called when a disconnect is
7357+ * detected or when the HCD is being stopped.
7358+ */
7359+static void kill_all_urbs(dwc_otg_hcd_t *_hcd)
7360+{
7361+ kill_urbs_in_qh_list(_hcd, &_hcd->non_periodic_sched_deferred);
7362+ kill_urbs_in_qh_list(_hcd, &_hcd->non_periodic_sched_inactive);
7363+ kill_urbs_in_qh_list(_hcd, &_hcd->non_periodic_sched_active);
7364+ kill_urbs_in_qh_list(_hcd, &_hcd->periodic_sched_inactive);
7365+ kill_urbs_in_qh_list(_hcd, &_hcd->periodic_sched_ready);
7366+ kill_urbs_in_qh_list(_hcd, &_hcd->periodic_sched_assigned);
7367+ kill_urbs_in_qh_list(_hcd, &_hcd->periodic_sched_queued);
7368+}
7369+
7370+/**
7371+ * HCD Callback function for disconnect of the HCD.
7372+ *
7373+ * @param _p void pointer to the <code>struct usb_hcd</code>
7374+ */
7375+static int32_t dwc_otg_hcd_disconnect_cb( void *_p )
7376+{
7377+ gintsts_data_t intr;
7378+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (_p);
7379+
7380+ DWC_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, _p);
7381+
7382+ /*
7383+ * Set status flags for the hub driver.
7384+ */
7385+ dwc_otg_hcd->flags.b.port_connect_status_change = 1;
7386+ dwc_otg_hcd->flags.b.port_connect_status = 0;
7387+
7388+ /*
7389+ * Shutdown any transfers in process by clearing the Tx FIFO Empty
7390+ * interrupt mask and status bits and disabling subsequent host
7391+ * channel interrupts.
7392+ */
7393+ intr.d32 = 0;
7394+ intr.b.nptxfempty = 1;
7395+ intr.b.ptxfempty = 1;
7396+ intr.b.hcintr = 1;
7397+ dwc_modify_reg32 (&dwc_otg_hcd->core_if->core_global_regs->gintmsk, intr.d32, 0);
7398+ dwc_modify_reg32 (&dwc_otg_hcd->core_if->core_global_regs->gintsts, intr.d32, 0);
7399+
7400+ del_timers(dwc_otg_hcd);
7401+
7402+ /*
7403+ * Turn off the vbus power only if the core has transitioned to device
7404+ * mode. If still in host mode, need to keep power on to detect a
7405+ * reconnection.
7406+ */
7407+ if (dwc_otg_is_device_mode(dwc_otg_hcd->core_if)) {
7408+ if (dwc_otg_hcd->core_if->op_state != A_SUSPEND) {
7409+ hprt0_data_t hprt0 = { .d32=0 };
7410+ DWC_PRINT("Disconnect: PortPower off\n");
7411+ hprt0.b.prtpwr = 0;
7412+ dwc_write_reg32(dwc_otg_hcd->core_if->host_if->hprt0, hprt0.d32);
7413+ }
7414+
7415+ dwc_otg_disable_host_interrupts( dwc_otg_hcd->core_if );
7416+ }
7417+
7418+ /* Respond with an error status to all URBs in the schedule. */
7419+ kill_all_urbs(dwc_otg_hcd);
7420+
7421+ if (dwc_otg_is_host_mode(dwc_otg_hcd->core_if)) {
7422+ /* Clean up any host channels that were in use. */
7423+ int num_channels;
7424+ int i;
7425+ dwc_hc_t *channel;
7426+ dwc_otg_hc_regs_t *hc_regs;
7427+ hcchar_data_t hcchar;
7428+
7429+ num_channels = dwc_otg_hcd->core_if->core_params->host_channels;
7430+
7431+ if (!dwc_otg_hcd->core_if->dma_enable) {
7432+ /* Flush out any channel requests in slave mode. */
7433+ for (i = 0; i < num_channels; i++) {
7434+ channel = dwc_otg_hcd->hc_ptr_array[i];
7435+ if (list_empty(&channel->hc_list_entry)) {
7436+ hc_regs = dwc_otg_hcd->core_if->host_if->hc_regs[i];
7437+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
7438+ if (hcchar.b.chen) {
7439+ hcchar.b.chen = 0;
7440+ hcchar.b.chdis = 1;
7441+ hcchar.b.epdir = 0;
7442+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
7443+ }
7444+ }
7445+ }
7446+ }
7447+
7448+ for (i = 0; i < num_channels; i++) {
7449+ channel = dwc_otg_hcd->hc_ptr_array[i];
7450+ if (list_empty(&channel->hc_list_entry)) {
7451+ hc_regs = dwc_otg_hcd->core_if->host_if->hc_regs[i];
7452+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
7453+ if (hcchar.b.chen) {
7454+ /* Halt the channel. */
7455+ hcchar.b.chdis = 1;
7456+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
7457+ }
7458+
7459+ dwc_otg_hc_cleanup(dwc_otg_hcd->core_if, channel);
7460+ list_add_tail(&channel->hc_list_entry,
7461+ &dwc_otg_hcd->free_hc_list);
7462+ }
7463+ }
7464+ }
7465+
7466+ /* A disconnect will end the session so the B-Device is no
7467+ * longer a B-host. */
7468+ ((struct usb_hcd *)_p)->self.is_b_host = 0;
7469+
7470+ return 1;
7471+}
7472+
7473+/**
7474+ * Connection timeout function. An OTG host is required to display a
7475+ * message if the device does not connect within 10 seconds.
7476+ */
7477+void dwc_otg_hcd_connect_timeout( unsigned long _ptr )
7478+{
7479+ DWC_DEBUGPL(DBG_HCDV, "%s(%x)\n", __func__, (int)_ptr);
7480+ DWC_PRINT( "Connect Timeout\n");
7481+ DWC_ERROR( "Device Not Connected/Responding\n" );
7482+}
7483+
7484+/**
7485+ * Start the connection timer. An OTG host is required to display a
7486+ * message if the device does not connect within 10 seconds. The
7487+ * timer is deleted if a port connect interrupt occurs before the
7488+ * timer expires.
7489+ */
7490+static void dwc_otg_hcd_start_connect_timer( dwc_otg_hcd_t *_hcd)
7491+{
7492+ init_timer( &_hcd->conn_timer );
7493+ _hcd->conn_timer.function = dwc_otg_hcd_connect_timeout;
7494+ _hcd->conn_timer.data = (unsigned long)0;
7495+ _hcd->conn_timer.expires = jiffies + (HZ*10);
7496+ add_timer( &_hcd->conn_timer );
7497+}
7498+
7499+/**
7500+ * HCD Callback function for disconnect of the HCD.
7501+ *
7502+ * @param _p void pointer to the <code>struct usb_hcd</code>
7503+ */
7504+static int32_t dwc_otg_hcd_session_start_cb( void *_p )
7505+{
7506+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (_p);
7507+ DWC_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, _p);
7508+ dwc_otg_hcd_start_connect_timer( dwc_otg_hcd );
7509+ return 1;
7510+}
7511+
7512+/**
7513+ * HCD Callback structure for handling mode switching.
7514+ */
7515+static dwc_otg_cil_callbacks_t hcd_cil_callbacks = {
7516+ .start = dwc_otg_hcd_start_cb,
7517+ .stop = dwc_otg_hcd_stop_cb,
7518+ .disconnect = dwc_otg_hcd_disconnect_cb,
7519+ .session_start = dwc_otg_hcd_session_start_cb,
7520+ .p = 0,
7521+};
7522+
7523+
7524+/**
7525+ * Reset tasklet function
7526+ */
7527+static void reset_tasklet_func (unsigned long data)
7528+{
7529+ dwc_otg_hcd_t *dwc_otg_hcd = (dwc_otg_hcd_t*)data;
7530+ dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
7531+ hprt0_data_t hprt0;
7532+
7533+ DWC_DEBUGPL(DBG_HCDV, "USB RESET tasklet called\n");
7534+
7535+ hprt0.d32 = dwc_otg_read_hprt0 (core_if);
7536+ hprt0.b.prtrst = 1;
7537+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
7538+ mdelay (60);
7539+
7540+ hprt0.b.prtrst = 0;
7541+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
7542+ dwc_otg_hcd->flags.b.port_reset_change = 1;
7543+
7544+ return;
7545+}
7546+
7547+static struct tasklet_struct reset_tasklet = {
7548+ .next = NULL,
7549+ .state = 0,
7550+ .count = ATOMIC_INIT(0),
7551+ .func = reset_tasklet_func,
7552+ .data = 0,
7553+};
7554+
7555+/**
7556+ * Initializes the HCD. This function allocates memory for and initializes the
7557+ * static parts of the usb_hcd and dwc_otg_hcd structures. It also registers the
7558+ * USB bus with the core and calls the hc_driver->start() function. It returns
7559+ * a negative error on failure.
7560+ */
7561+int init_hcd_usecs(dwc_otg_hcd_t *_hcd);
7562+
7563+int __devinit dwc_otg_hcd_init(struct device *_dev, dwc_otg_device_t * dwc_otg_device)
7564+{
7565+ struct usb_hcd *hcd = NULL;
7566+ dwc_otg_hcd_t *dwc_otg_hcd = NULL;
7567+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
7568+
7569+ int num_channels;
7570+ int i;
7571+ dwc_hc_t *channel;
7572+
7573+ int retval = 0;
7574+
7575+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT\n");
7576+
7577+ /*
7578+ * Allocate memory for the base HCD plus the DWC OTG HCD.
7579+ * Initialize the base HCD.
7580+ */
7581+ hcd = usb_create_hcd(&dwc_otg_hc_driver, _dev, dev_name(_dev));
7582+ if (hcd == NULL) {
7583+ retval = -ENOMEM;
7584+ goto error1;
7585+ }
7586+ dev_set_drvdata(_dev, dwc_otg_device); /* fscz restore */
7587+ hcd->regs = otg_dev->base;
7588+ hcd->rsrc_start = (int)otg_dev->base;
7589+
7590+ hcd->self.otg_port = 1;
7591+
7592+ /* Initialize the DWC OTG HCD. */
7593+ dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
7594+ dwc_otg_hcd->core_if = otg_dev->core_if;
7595+ otg_dev->hcd = dwc_otg_hcd;
7596+
7597+ /* Register the HCD CIL Callbacks */
7598+ dwc_otg_cil_register_hcd_callbacks(otg_dev->core_if,
7599+ &hcd_cil_callbacks, hcd);
7600+
7601+ /* Initialize the non-periodic schedule. */
7602+ INIT_LIST_HEAD(&dwc_otg_hcd->non_periodic_sched_inactive);
7603+ INIT_LIST_HEAD(&dwc_otg_hcd->non_periodic_sched_active);
7604+ INIT_LIST_HEAD(&dwc_otg_hcd->non_periodic_sched_deferred);
7605+
7606+ /* Initialize the periodic schedule. */
7607+ INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_inactive);
7608+ INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_ready);
7609+ INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_assigned);
7610+ INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_queued);
7611+
7612+ /*
7613+ * Create a host channel descriptor for each host channel implemented
7614+ * in the controller. Initialize the channel descriptor array.
7615+ */
7616+ INIT_LIST_HEAD(&dwc_otg_hcd->free_hc_list);
7617+ num_channels = dwc_otg_hcd->core_if->core_params->host_channels;
7618+ for (i = 0; i < num_channels; i++) {
7619+ channel = kmalloc(sizeof(dwc_hc_t), GFP_KERNEL);
7620+ if (channel == NULL) {
7621+ retval = -ENOMEM;
7622+ DWC_ERROR("%s: host channel allocation failed\n", __func__);
7623+ goto error2;
7624+ }
7625+ memset(channel, 0, sizeof(dwc_hc_t));
7626+ channel->hc_num = i;
7627+ dwc_otg_hcd->hc_ptr_array[i] = channel;
7628+#ifdef DEBUG
7629+ init_timer(&dwc_otg_hcd->core_if->hc_xfer_timer[i]);
7630+#endif
7631+
7632+ DWC_DEBUGPL(DBG_HCDV, "HCD Added channel #%d, hc=%p\n", i, channel);
7633+ }
7634+
7635+ /* Initialize the Connection timeout timer. */
7636+ init_timer( &dwc_otg_hcd->conn_timer );
7637+
7638+ /* Initialize reset tasklet. */
7639+ reset_tasklet.data = (unsigned long) dwc_otg_hcd;
7640+ dwc_otg_hcd->reset_tasklet = &reset_tasklet;
7641+
7642+ /* Set device flags indicating whether the HCD supports DMA. */
7643+ if (otg_dev->core_if->dma_enable) {
7644+ DWC_PRINT("Using DMA mode\n");
7645+ //_dev->dma_mask = (void *)~0;
7646+ //_dev->coherent_dma_mask = ~0;
7647+ _dev->dma_mask = &dma_mask;
7648+ _dev->coherent_dma_mask = DMA_BIT_MASK(32);
7649+ } else {
7650+ DWC_PRINT("Using Slave mode\n");
7651+ _dev->dma_mask = (void *)0;
7652+ _dev->coherent_dma_mask = 0;
7653+ }
7654+
7655+ init_hcd_usecs(dwc_otg_hcd);
7656+ /*
7657+ * Finish generic HCD initialization and start the HCD. This function
7658+ * allocates the DMA buffer pool, registers the USB bus, requests the
7659+ * IRQ line, and calls dwc_otg_hcd_start method.
7660+ */
7661+ retval = usb_add_hcd(hcd, otg_dev->irq, IRQF_SHARED);
7662+ if (retval < 0) {
7663+ goto error2;
7664+ }
7665+
7666+ /*
7667+ * Allocate space for storing data on status transactions. Normally no
7668+ * data is sent, but this space acts as a bit bucket. This must be
7669+ * done after usb_add_hcd since that function allocates the DMA buffer
7670+ * pool.
7671+ */
7672+ if (otg_dev->core_if->dma_enable) {
7673+ dwc_otg_hcd->status_buf =
7674+ dma_alloc_coherent(_dev,
7675+ DWC_OTG_HCD_STATUS_BUF_SIZE,
7676+ &dwc_otg_hcd->status_buf_dma,
7677+ GFP_KERNEL | GFP_DMA);
7678+ } else {
7679+ dwc_otg_hcd->status_buf = kmalloc(DWC_OTG_HCD_STATUS_BUF_SIZE,
7680+ GFP_KERNEL);
7681+ }
7682+ if (dwc_otg_hcd->status_buf == NULL) {
7683+ retval = -ENOMEM;
7684+ DWC_ERROR("%s: status_buf allocation failed\n", __func__);
7685+ goto error3;
7686+ }
7687+
7688+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Initialized HCD, bus=%s, usbbus=%d\n",
7689+ dev_name(_dev), hcd->self.busnum);
7690+
7691+ return 0;
7692+
7693+ /* Error conditions */
7694+error3:
7695+ usb_remove_hcd(hcd);
7696+error2:
7697+ dwc_otg_hcd_free(hcd);
7698+ usb_put_hcd(hcd);
7699+error1:
7700+ return retval;
7701+}
7702+
7703+/**
7704+ * Removes the HCD.
7705+ * Frees memory and resources associated with the HCD and deregisters the bus.
7706+ */
7707+void dwc_otg_hcd_remove(struct device *_dev)
7708+{
7709+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
7710+ dwc_otg_hcd_t *dwc_otg_hcd = otg_dev->hcd;
7711+ struct usb_hcd *hcd = dwc_otg_hcd_to_hcd(dwc_otg_hcd);
7712+
7713+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD REMOVE\n");
7714+
7715+ /* Turn off all interrupts */
7716+ dwc_write_reg32 (&dwc_otg_hcd->core_if->core_global_regs->gintmsk, 0);
7717+ dwc_modify_reg32 (&dwc_otg_hcd->core_if->core_global_regs->gahbcfg, 1, 0);
7718+
7719+ usb_remove_hcd(hcd);
7720+
7721+ dwc_otg_hcd_free(hcd);
7722+
7723+ usb_put_hcd(hcd);
7724+
7725+ return;
7726+}
7727+
7728+
7729+/* =========================================================================
7730+ * Linux HC Driver Functions
7731+ * ========================================================================= */
7732+
7733+/**
7734+ * Initializes dynamic portions of the DWC_otg HCD state.
7735+ */
7736+static void hcd_reinit(dwc_otg_hcd_t *_hcd)
7737+{
7738+ struct list_head *item;
7739+ int num_channels;
7740+ int i;
7741+ dwc_hc_t *channel;
7742+
7743+ _hcd->flags.d32 = 0;
7744+
7745+ _hcd->non_periodic_qh_ptr = &_hcd->non_periodic_sched_active;
7746+ _hcd->available_host_channels = _hcd->core_if->core_params->host_channels;
7747+
7748+ /*
7749+ * Put all channels in the free channel list and clean up channel
7750+ * states.
7751+ */
7752+ item = _hcd->free_hc_list.next;
7753+ while (item != &_hcd->free_hc_list) {
7754+ list_del(item);
7755+ item = _hcd->free_hc_list.next;
7756+ }
7757+ num_channels = _hcd->core_if->core_params->host_channels;
7758+ for (i = 0; i < num_channels; i++) {
7759+ channel = _hcd->hc_ptr_array[i];
7760+ list_add_tail(&channel->hc_list_entry, &_hcd->free_hc_list);
7761+ dwc_otg_hc_cleanup(_hcd->core_if, channel);
7762+ }
7763+
7764+ /* Initialize the DWC core for host mode operation. */
7765+ dwc_otg_core_host_init(_hcd->core_if);
7766+}
7767+
7768+/** Initializes the DWC_otg controller and its root hub and prepares it for host
7769+ * mode operation. Activates the root port. Returns 0 on success and a negative
7770+ * error code on failure. */
7771+int dwc_otg_hcd_start(struct usb_hcd *_hcd)
7772+{
7773+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (_hcd);
7774+ dwc_otg_core_if_t * core_if = dwc_otg_hcd->core_if;
7775+ struct usb_bus *bus;
7776+
7777+ // int retval;
7778+
7779+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD START\n");
7780+
7781+ bus = hcd_to_bus(_hcd);
7782+
7783+ /* Initialize the bus state. If the core is in Device Mode
7784+ * HALT the USB bus and return. */
7785+ if (dwc_otg_is_device_mode (core_if)) {
7786+ _hcd->state = HC_STATE_HALT;
7787+ return 0;
7788+ }
7789+ _hcd->state = HC_STATE_RUNNING;
7790+
7791+ /* Initialize and connect root hub if one is not already attached */
7792+ if (bus->root_hub) {
7793+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Has Root Hub\n");
7794+ /* Inform the HUB driver to resume. */
7795+ usb_hcd_resume_root_hub(_hcd);
7796+ }
7797+ else {
7798+#if 0
7799+ struct usb_device *udev;
7800+ udev = usb_alloc_dev(NULL, bus, 0);
7801+ if (!udev) {
7802+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Error udev alloc\n");
7803+ return -ENODEV;
7804+ }
7805+ udev->speed = USB_SPEED_HIGH;
7806+ /* Not needed - VJ
7807+ if ((retval = usb_hcd_register_root_hub(udev, _hcd)) != 0) {
7808+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Error registering %d\n", retval);
7809+ return -ENODEV;
7810+ }
7811+ */
7812+#else
7813+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Error udev alloc\n");
7814+#endif
7815+ }
7816+
7817+ hcd_reinit(dwc_otg_hcd);
7818+
7819+ return 0;
7820+}
7821+
7822+static void qh_list_free(dwc_otg_hcd_t *_hcd, struct list_head *_qh_list)
7823+{
7824+ struct list_head *item;
7825+ dwc_otg_qh_t *qh;
7826+
7827+ if (_qh_list->next == NULL) {
7828+ /* The list hasn't been initialized yet. */
7829+ return;
7830+ }
7831+
7832+ /* Ensure there are no QTDs or URBs left. */
7833+ kill_urbs_in_qh_list(_hcd, _qh_list);
7834+
7835+ for (item = _qh_list->next; item != _qh_list; item = _qh_list->next) {
7836+ qh = list_entry(item, dwc_otg_qh_t, qh_list_entry);
7837+ dwc_otg_hcd_qh_remove_and_free(_hcd, qh);
7838+ }
7839+}
7840+
7841+/**
7842+ * Halts the DWC_otg host mode operations in a clean manner. USB transfers are
7843+ * stopped.
7844+ */
7845+void dwc_otg_hcd_stop(struct usb_hcd *_hcd)
7846+{
7847+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (_hcd);
7848+ hprt0_data_t hprt0 = { .d32=0 };
7849+
7850+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD STOP\n");
7851+
7852+ /* Turn off all host-specific interrupts. */
7853+ dwc_otg_disable_host_interrupts( dwc_otg_hcd->core_if );
7854+
7855+ /*
7856+ * The root hub should be disconnected before this function is called.
7857+ * The disconnect will clear the QTD lists (via ..._hcd_urb_dequeue)
7858+ * and the QH lists (via ..._hcd_endpoint_disable).
7859+ */
7860+
7861+ /* Turn off the vbus power */
7862+ DWC_PRINT("PortPower off\n");
7863+ hprt0.b.prtpwr = 0;
7864+ dwc_write_reg32(dwc_otg_hcd->core_if->host_if->hprt0, hprt0.d32);
7865+
7866+ return;
7867+}
7868+
7869+
7870+/** Returns the current frame number. */
7871+int dwc_otg_hcd_get_frame_number(struct usb_hcd *_hcd)
7872+{
7873+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(_hcd);
7874+ hfnum_data_t hfnum;
7875+
7876+ hfnum.d32 = dwc_read_reg32(&dwc_otg_hcd->core_if->
7877+ host_if->host_global_regs->hfnum);
7878+
7879+#ifdef DEBUG_SOF
7880+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD GET FRAME NUMBER %d\n", hfnum.b.frnum);
7881+#endif
7882+ return hfnum.b.frnum;
7883+}
7884+
7885+/**
7886+ * Frees secondary storage associated with the dwc_otg_hcd structure contained
7887+ * in the struct usb_hcd field.
7888+ */
7889+void dwc_otg_hcd_free(struct usb_hcd *_hcd)
7890+{
7891+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(_hcd);
7892+ int i;
7893+
7894+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD FREE\n");
7895+
7896+ del_timers(dwc_otg_hcd);
7897+
7898+ /* Free memory for QH/QTD lists */
7899+ qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->non_periodic_sched_inactive);
7900+ qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->non_periodic_sched_deferred);
7901+ qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->non_periodic_sched_active);
7902+ qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_inactive);
7903+ qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_ready);
7904+ qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_assigned);
7905+ qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_queued);
7906+
7907+ /* Free memory for the host channels. */
7908+ for (i = 0; i < MAX_EPS_CHANNELS; i++) {
7909+ dwc_hc_t *hc = dwc_otg_hcd->hc_ptr_array[i];
7910+ if (hc != NULL) {
7911+ DWC_DEBUGPL(DBG_HCDV, "HCD Free channel #%i, hc=%p\n", i, hc);
7912+ kfree(hc);
7913+ }
7914+ }
7915+
7916+ if (dwc_otg_hcd->core_if->dma_enable) {
7917+ if (dwc_otg_hcd->status_buf_dma) {
7918+ dma_free_coherent(_hcd->self.controller,
7919+ DWC_OTG_HCD_STATUS_BUF_SIZE,
7920+ dwc_otg_hcd->status_buf,
7921+ dwc_otg_hcd->status_buf_dma);
7922+ }
7923+ } else if (dwc_otg_hcd->status_buf != NULL) {
7924+ kfree(dwc_otg_hcd->status_buf);
7925+ }
7926+
7927+ return;
7928+}
7929+
7930+
7931+#ifdef DEBUG
7932+static void dump_urb_info(struct urb *_urb, char* _fn_name)
7933+{
7934+ DWC_PRINT("%s, urb %p\n", _fn_name, _urb);
7935+ DWC_PRINT(" Device address: %d\n", usb_pipedevice(_urb->pipe));
7936+ DWC_PRINT(" Endpoint: %d, %s\n", usb_pipeendpoint(_urb->pipe),
7937+ (usb_pipein(_urb->pipe) ? "IN" : "OUT"));
7938+ DWC_PRINT(" Endpoint type: %s\n",
7939+ ({char *pipetype;
7940+ switch (usb_pipetype(_urb->pipe)) {
7941+ case PIPE_CONTROL: pipetype = "CONTROL"; break;
7942+ case PIPE_BULK: pipetype = "BULK"; break;
7943+ case PIPE_INTERRUPT: pipetype = "INTERRUPT"; break;
7944+ case PIPE_ISOCHRONOUS: pipetype = "ISOCHRONOUS"; break;
7945+ default: pipetype = "UNKNOWN"; break;
7946+ }; pipetype;}));
7947+ DWC_PRINT(" Speed: %s\n",
7948+ ({char *speed;
7949+ switch (_urb->dev->speed) {
7950+ case USB_SPEED_HIGH: speed = "HIGH"; break;
7951+ case USB_SPEED_FULL: speed = "FULL"; break;
7952+ case USB_SPEED_LOW: speed = "LOW"; break;
7953+ default: speed = "UNKNOWN"; break;
7954+ }; speed;}));
7955+ DWC_PRINT(" Max packet size: %d\n",
7956+ usb_maxpacket(_urb->dev, _urb->pipe, usb_pipeout(_urb->pipe)));
7957+ DWC_PRINT(" Data buffer length: %d\n", _urb->transfer_buffer_length);
7958+ DWC_PRINT(" Transfer buffer: %p, Transfer DMA: %p\n",
7959+ _urb->transfer_buffer, (void *)_urb->transfer_dma);
7960+ DWC_PRINT(" Setup buffer: %p, Setup DMA: %p\n",
7961+ _urb->setup_packet, (void *)_urb->setup_dma);
7962+ DWC_PRINT(" Interval: %d\n", _urb->interval);
7963+ if (usb_pipetype(_urb->pipe) == PIPE_ISOCHRONOUS) {
7964+ int i;
7965+ for (i = 0; i < _urb->number_of_packets; i++) {
7966+ DWC_PRINT(" ISO Desc %d:\n", i);
7967+ DWC_PRINT(" offset: %d, length %d\n",
7968+ _urb->iso_frame_desc[i].offset,
7969+ _urb->iso_frame_desc[i].length);
7970+ }
7971+ }
7972+}
7973+
7974+static void dump_channel_info(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *qh)
7975+{
7976+ if (qh->channel != NULL) {
7977+ dwc_hc_t *hc = qh->channel;
7978+ struct list_head *item;
7979+ dwc_otg_qh_t *qh_item;
7980+ int num_channels = _hcd->core_if->core_params->host_channels;
7981+ int i;
7982+
7983+ dwc_otg_hc_regs_t *hc_regs;
7984+ hcchar_data_t hcchar;
7985+ hcsplt_data_t hcsplt;
7986+ hctsiz_data_t hctsiz;
7987+ uint32_t hcdma;
7988+
7989+ hc_regs = _hcd->core_if->host_if->hc_regs[hc->hc_num];
7990+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
7991+ hcsplt.d32 = dwc_read_reg32(&hc_regs->hcsplt);
7992+ hctsiz.d32 = dwc_read_reg32(&hc_regs->hctsiz);
7993+ hcdma = dwc_read_reg32(&hc_regs->hcdma);
7994+
7995+ DWC_PRINT(" Assigned to channel %p:\n", hc);
7996+ DWC_PRINT(" hcchar 0x%08x, hcsplt 0x%08x\n", hcchar.d32, hcsplt.d32);
7997+ DWC_PRINT(" hctsiz 0x%08x, hcdma 0x%08x\n", hctsiz.d32, hcdma);
7998+ DWC_PRINT(" dev_addr: %d, ep_num: %d, ep_is_in: %d\n",
7999+ hc->dev_addr, hc->ep_num, hc->ep_is_in);
8000+ DWC_PRINT(" ep_type: %d\n", hc->ep_type);
8001+ DWC_PRINT(" max_packet: %d\n", hc->max_packet);
8002+ DWC_PRINT(" data_pid_start: %d\n", hc->data_pid_start);
8003+ DWC_PRINT(" xfer_started: %d\n", hc->xfer_started);
8004+ DWC_PRINT(" halt_status: %d\n", hc->halt_status);
8005+ DWC_PRINT(" xfer_buff: %p\n", hc->xfer_buff);
8006+ DWC_PRINT(" xfer_len: %d\n", hc->xfer_len);
8007+ DWC_PRINT(" qh: %p\n", hc->qh);
8008+ DWC_PRINT(" NP inactive sched:\n");
8009+ list_for_each(item, &_hcd->non_periodic_sched_inactive) {
8010+ qh_item = list_entry(item, dwc_otg_qh_t, qh_list_entry);
8011+ DWC_PRINT(" %p\n", qh_item);
8012+ } DWC_PRINT(" NP active sched:\n");
8013+ list_for_each(item, &_hcd->non_periodic_sched_deferred) {
8014+ qh_item = list_entry(item, dwc_otg_qh_t, qh_list_entry);
8015+ DWC_PRINT(" %p\n", qh_item);
8016+ } DWC_PRINT(" NP deferred sched:\n");
8017+ list_for_each(item, &_hcd->non_periodic_sched_active) {
8018+ qh_item = list_entry(item, dwc_otg_qh_t, qh_list_entry);
8019+ DWC_PRINT(" %p\n", qh_item);
8020+ } DWC_PRINT(" Channels: \n");
8021+ for (i = 0; i < num_channels; i++) {
8022+ dwc_hc_t *hc = _hcd->hc_ptr_array[i];
8023+ DWC_PRINT(" %2d: %p\n", i, hc);
8024+ }
8025+ }
8026+}
8027+#endif // DEBUG
8028+
8029+/** Starts processing a USB transfer request specified by a USB Request Block
8030+ * (URB). mem_flags indicates the type of memory allocation to use while
8031+ * processing this URB. */
8032+int dwc_otg_hcd_urb_enqueue(struct usb_hcd *_hcd,
8033+ struct urb *_urb,
8034+ gfp_t _mem_flags)
8035+{
8036+ unsigned long flags;
8037+ int retval;
8038+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (_hcd);
8039+ dwc_otg_qtd_t *qtd;
8040+
8041+ local_irq_save(flags);
8042+ retval = usb_hcd_link_urb_to_ep(_hcd, _urb);
8043+ if (retval) {
8044+ local_irq_restore(flags);
8045+ return retval;
8046+ }
8047+#ifdef DEBUG
8048+ if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
8049+ dump_urb_info(_urb, "dwc_otg_hcd_urb_enqueue");
8050+ }
8051+#endif // DEBUG
8052+ if (!dwc_otg_hcd->flags.b.port_connect_status) {
8053+ /* No longer connected. */
8054+ local_irq_restore(flags);
8055+ return -ENODEV;
8056+ }
8057+
8058+ qtd = dwc_otg_hcd_qtd_create (_urb);
8059+ if (qtd == NULL) {
8060+ local_irq_restore(flags);
8061+ DWC_ERROR("DWC OTG HCD URB Enqueue failed creating QTD\n");
8062+ return -ENOMEM;
8063+ }
8064+
8065+ retval = dwc_otg_hcd_qtd_add (qtd, dwc_otg_hcd);
8066+ if (retval < 0) {
8067+ DWC_ERROR("DWC OTG HCD URB Enqueue failed adding QTD. "
8068+ "Error status %d\n", retval);
8069+ dwc_otg_hcd_qtd_free(qtd);
8070+ }
8071+
8072+ local_irq_restore (flags);
8073+ return retval;
8074+}
8075+
8076+/** Aborts/cancels a USB transfer request. Always returns 0 to indicate
8077+ * success. */
8078+int dwc_otg_hcd_urb_dequeue(struct usb_hcd *_hcd, struct urb *_urb, int _status)
8079+{
8080+ unsigned long flags;
8081+ dwc_otg_hcd_t *dwc_otg_hcd;
8082+ dwc_otg_qtd_t *urb_qtd;
8083+ dwc_otg_qh_t *qh;
8084+ int retval;
8085+ //struct usb_host_endpoint *_ep = NULL;
8086+
8087+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD URB Dequeue\n");
8088+
8089+ local_irq_save(flags);
8090+
8091+ retval = usb_hcd_check_unlink_urb(_hcd, _urb, _status);
8092+ if (retval) {
8093+ local_irq_restore(flags);
8094+ return retval;
8095+ }
8096+
8097+ dwc_otg_hcd = hcd_to_dwc_otg_hcd(_hcd);
8098+ urb_qtd = (dwc_otg_qtd_t *)_urb->hcpriv;
8099+ if (urb_qtd == NULL) {
8100+ printk("urb_qtd is NULL for _urb %08x\n",(unsigned)_urb);
8101+ goto done;
8102+ }
8103+ qh = (dwc_otg_qh_t *) urb_qtd->qtd_qh_ptr;
8104+ if (qh == NULL) {
8105+ goto done;
8106+ }
8107+
8108+#ifdef DEBUG
8109+ if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
8110+ dump_urb_info(_urb, "dwc_otg_hcd_urb_dequeue");
8111+ if (urb_qtd == qh->qtd_in_process) {
8112+ dump_channel_info(dwc_otg_hcd, qh);
8113+ }
8114+ }
8115+#endif // DEBUG
8116+
8117+ if (urb_qtd == qh->qtd_in_process) {
8118+ /* The QTD is in process (it has been assigned to a channel). */
8119+
8120+ if (dwc_otg_hcd->flags.b.port_connect_status) {
8121+ /*
8122+ * If still connected (i.e. in host mode), halt the
8123+ * channel so it can be used for other transfers. If
8124+ * no longer connected, the host registers can't be
8125+ * written to halt the channel since the core is in
8126+ * device mode.
8127+ */
8128+ dwc_otg_hc_halt(dwc_otg_hcd->core_if, qh->channel,
8129+ DWC_OTG_HC_XFER_URB_DEQUEUE);
8130+ }
8131+ }
8132+
8133+ /*
8134+ * Free the QTD and clean up the associated QH. Leave the QH in the
8135+ * schedule if it has any remaining QTDs.
8136+ */
8137+ dwc_otg_hcd_qtd_remove_and_free(urb_qtd);
8138+ if (urb_qtd == qh->qtd_in_process) {
8139+ dwc_otg_hcd_qh_deactivate(dwc_otg_hcd, qh, 0);
8140+ qh->channel = NULL;
8141+ qh->qtd_in_process = NULL;
8142+ } else if (list_empty(&qh->qtd_list)) {
8143+ dwc_otg_hcd_qh_remove(dwc_otg_hcd, qh);
8144+ }
8145+
8146+done:
8147+ local_irq_restore(flags);
8148+ _urb->hcpriv = NULL;
8149+
8150+ /* Higher layer software sets URB status. */
8151+ usb_hcd_unlink_urb_from_ep(_hcd, _urb);
8152+ usb_hcd_giveback_urb(_hcd, _urb, _status);
8153+ if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
8154+ DWC_PRINT("Called usb_hcd_giveback_urb()\n");
8155+ DWC_PRINT(" urb->status = %d\n", _urb->status);
8156+ }
8157+
8158+ return 0;
8159+}
8160+
8161+
8162+/** Frees resources in the DWC_otg controller related to a given endpoint. Also
8163+ * clears state in the HCD related to the endpoint. Any URBs for the endpoint
8164+ * must already be dequeued. */
8165+void dwc_otg_hcd_endpoint_disable(struct usb_hcd *_hcd,
8166+ struct usb_host_endpoint *_ep)
8167+
8168+{
8169+ dwc_otg_qh_t *qh;
8170+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(_hcd);
8171+
8172+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD EP DISABLE: _bEndpointAddress=0x%02x, "
8173+ "endpoint=%d\n", _ep->desc.bEndpointAddress,
8174+ dwc_ep_addr_to_endpoint(_ep->desc.bEndpointAddress));
8175+
8176+ qh = (dwc_otg_qh_t *)(_ep->hcpriv);
8177+ if (qh != NULL) {
8178+#ifdef DEBUG
8179+ /** Check that the QTD list is really empty */
8180+ if (!list_empty(&qh->qtd_list)) {
8181+ DWC_WARN("DWC OTG HCD EP DISABLE:"
8182+ " QTD List for this endpoint is not empty\n");
8183+ }
8184+#endif // DEBUG
8185+
8186+ dwc_otg_hcd_qh_remove_and_free(dwc_otg_hcd, qh);
8187+ _ep->hcpriv = NULL;
8188+ }
8189+
8190+ return;
8191+}
8192+extern int dwc_irq;
8193+/** Handles host mode interrupts for the DWC_otg controller. Returns IRQ_NONE if
8194+ * there was no interrupt to handle. Returns IRQ_HANDLED if there was a valid
8195+ * interrupt.
8196+ *
8197+ * This function is called by the USB core when an interrupt occurs */
8198+irqreturn_t dwc_otg_hcd_irq(struct usb_hcd *_hcd)
8199+{
8200+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (_hcd);
8201+
8202+ mask_and_ack_ifx_irq (dwc_irq);
8203+ return IRQ_RETVAL(dwc_otg_hcd_handle_intr(dwc_otg_hcd));
8204+}
8205+
8206+/** Creates Status Change bitmap for the root hub and root port. The bitmap is
8207+ * returned in buf. Bit 0 is the status change indicator for the root hub. Bit 1
8208+ * is the status change indicator for the single root port. Returns 1 if either
8209+ * change indicator is 1, otherwise returns 0. */
8210+int dwc_otg_hcd_hub_status_data(struct usb_hcd *_hcd, char *_buf)
8211+{
8212+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (_hcd);
8213+
8214+ _buf[0] = 0;
8215+ _buf[0] |= (dwc_otg_hcd->flags.b.port_connect_status_change ||
8216+ dwc_otg_hcd->flags.b.port_reset_change ||
8217+ dwc_otg_hcd->flags.b.port_enable_change ||
8218+ dwc_otg_hcd->flags.b.port_suspend_change ||
8219+ dwc_otg_hcd->flags.b.port_over_current_change) << 1;
8220+
8221+#ifdef DEBUG
8222+ if (_buf[0]) {
8223+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB STATUS DATA:"
8224+ " Root port status changed\n");
8225+ DWC_DEBUGPL(DBG_HCDV, " port_connect_status_change: %d\n",
8226+ dwc_otg_hcd->flags.b.port_connect_status_change);
8227+ DWC_DEBUGPL(DBG_HCDV, " port_reset_change: %d\n",
8228+ dwc_otg_hcd->flags.b.port_reset_change);
8229+ DWC_DEBUGPL(DBG_HCDV, " port_enable_change: %d\n",
8230+ dwc_otg_hcd->flags.b.port_enable_change);
8231+ DWC_DEBUGPL(DBG_HCDV, " port_suspend_change: %d\n",
8232+ dwc_otg_hcd->flags.b.port_suspend_change);
8233+ DWC_DEBUGPL(DBG_HCDV, " port_over_current_change: %d\n",
8234+ dwc_otg_hcd->flags.b.port_over_current_change);
8235+ }
8236+#endif // DEBUG
8237+ return (_buf[0] != 0);
8238+}
8239+
8240+#ifdef DWC_HS_ELECT_TST
8241+/*
8242+ * Quick and dirty hack to implement the HS Electrical Test
8243+ * SINGLE_STEP_GET_DEVICE_DESCRIPTOR feature.
8244+ *
8245+ * This code was copied from our userspace app "hset". It sends a
8246+ * Get Device Descriptor control sequence in two parts, first the
8247+ * Setup packet by itself, followed some time later by the In and
8248+ * Ack packets. Rather than trying to figure out how to add this
8249+ * functionality to the normal driver code, we just hijack the
8250+ * hardware, using these two function to drive the hardware
8251+ * directly.
8252+ */
8253+
8254+dwc_otg_core_global_regs_t *global_regs;
8255+dwc_otg_host_global_regs_t *hc_global_regs;
8256+dwc_otg_hc_regs_t *hc_regs;
8257+uint32_t *data_fifo;
8258+
8259+static void do_setup(void)
8260+{
8261+ gintsts_data_t gintsts;
8262+ hctsiz_data_t hctsiz;
8263+ hcchar_data_t hcchar;
8264+ haint_data_t haint;
8265+ hcint_data_t hcint;
8266+
8267+ /* Enable HAINTs */
8268+ dwc_write_reg32(&hc_global_regs->haintmsk, 0x0001);
8269+
8270+ /* Enable HCINTs */
8271+ dwc_write_reg32(&hc_regs->hcintmsk, 0x04a3);
8272+
8273+ /* Read GINTSTS */
8274+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8275+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
8276+
8277+ /* Read HAINT */
8278+ haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
8279+ //fprintf(stderr, "HAINT: %08x\n", haint.d32);
8280+
8281+ /* Read HCINT */
8282+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
8283+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
8284+
8285+ /* Read HCCHAR */
8286+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8287+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
8288+
8289+ /* Clear HCINT */
8290+ dwc_write_reg32(&hc_regs->hcint, hcint.d32);
8291+
8292+ /* Clear HAINT */
8293+ dwc_write_reg32(&hc_global_regs->haint, haint.d32);
8294+
8295+ /* Clear GINTSTS */
8296+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
8297+
8298+ /* Read GINTSTS */
8299+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8300+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
8301+
8302+ /*
8303+ * Send Setup packet (Get Device Descriptor)
8304+ */
8305+
8306+ /* Make sure channel is disabled */
8307+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8308+ if (hcchar.b.chen) {
8309+ //fprintf(stderr, "Channel already enabled 1, HCCHAR = %08x\n", hcchar.d32);
8310+ hcchar.b.chdis = 1;
8311+ // hcchar.b.chen = 1;
8312+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
8313+ //sleep(1);
8314+ MDELAY(1000);
8315+
8316+ /* Read GINTSTS */
8317+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8318+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
8319+
8320+ /* Read HAINT */
8321+ haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
8322+ //fprintf(stderr, "HAINT: %08x\n", haint.d32);
8323+
8324+ /* Read HCINT */
8325+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
8326+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
8327+
8328+ /* Read HCCHAR */
8329+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8330+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
8331+
8332+ /* Clear HCINT */
8333+ dwc_write_reg32(&hc_regs->hcint, hcint.d32);
8334+
8335+ /* Clear HAINT */
8336+ dwc_write_reg32(&hc_global_regs->haint, haint.d32);
8337+
8338+ /* Clear GINTSTS */
8339+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
8340+
8341+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8342+ //if (hcchar.b.chen) {
8343+ // fprintf(stderr, "** Channel _still_ enabled 1, HCCHAR = %08x **\n", hcchar.d32);
8344+ //}
8345+ }
8346+
8347+ /* Set HCTSIZ */
8348+ hctsiz.d32 = 0;
8349+ hctsiz.b.xfersize = 8;
8350+ hctsiz.b.pktcnt = 1;
8351+ hctsiz.b.pid = DWC_OTG_HC_PID_SETUP;
8352+ dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
8353+
8354+ /* Set HCCHAR */
8355+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8356+ hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;
8357+ hcchar.b.epdir = 0;
8358+ hcchar.b.epnum = 0;
8359+ hcchar.b.mps = 8;
8360+ hcchar.b.chen = 1;
8361+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
8362+
8363+ /* Fill FIFO with Setup data for Get Device Descriptor */
8364+ data_fifo = (uint32_t *)((char *)global_regs + 0x1000);
8365+ dwc_write_reg32(data_fifo++, 0x01000680);
8366+ dwc_write_reg32(data_fifo++, 0x00080000);
8367+
8368+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8369+ //fprintf(stderr, "Waiting for HCINTR intr 1, GINTSTS = %08x\n", gintsts.d32);
8370+
8371+ /* Wait for host channel interrupt */
8372+ do {
8373+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8374+ } while (gintsts.b.hcintr == 0);
8375+
8376+ //fprintf(stderr, "Got HCINTR intr 1, GINTSTS = %08x\n", gintsts.d32);
8377+
8378+ /* Disable HCINTs */
8379+ dwc_write_reg32(&hc_regs->hcintmsk, 0x0000);
8380+
8381+ /* Disable HAINTs */
8382+ dwc_write_reg32(&hc_global_regs->haintmsk, 0x0000);
8383+
8384+ /* Read HAINT */
8385+ haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
8386+ //fprintf(stderr, "HAINT: %08x\n", haint.d32);
8387+
8388+ /* Read HCINT */
8389+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
8390+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
8391+
8392+ /* Read HCCHAR */
8393+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8394+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
8395+
8396+ /* Clear HCINT */
8397+ dwc_write_reg32(&hc_regs->hcint, hcint.d32);
8398+
8399+ /* Clear HAINT */
8400+ dwc_write_reg32(&hc_global_regs->haint, haint.d32);
8401+
8402+ /* Clear GINTSTS */
8403+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
8404+
8405+ /* Read GINTSTS */
8406+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8407+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
8408+}
8409+
8410+static void do_in_ack(void)
8411+{
8412+ gintsts_data_t gintsts;
8413+ hctsiz_data_t hctsiz;
8414+ hcchar_data_t hcchar;
8415+ haint_data_t haint;
8416+ hcint_data_t hcint;
8417+ host_grxsts_data_t grxsts;
8418+
8419+ /* Enable HAINTs */
8420+ dwc_write_reg32(&hc_global_regs->haintmsk, 0x0001);
8421+
8422+ /* Enable HCINTs */
8423+ dwc_write_reg32(&hc_regs->hcintmsk, 0x04a3);
8424+
8425+ /* Read GINTSTS */
8426+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8427+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
8428+
8429+ /* Read HAINT */
8430+ haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
8431+ //fprintf(stderr, "HAINT: %08x\n", haint.d32);
8432+
8433+ /* Read HCINT */
8434+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
8435+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
8436+
8437+ /* Read HCCHAR */
8438+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8439+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
8440+
8441+ /* Clear HCINT */
8442+ dwc_write_reg32(&hc_regs->hcint, hcint.d32);
8443+
8444+ /* Clear HAINT */
8445+ dwc_write_reg32(&hc_global_regs->haint, haint.d32);
8446+
8447+ /* Clear GINTSTS */
8448+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
8449+
8450+ /* Read GINTSTS */
8451+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8452+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
8453+
8454+ /*
8455+ * Receive Control In packet
8456+ */
8457+
8458+ /* Make sure channel is disabled */
8459+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8460+ if (hcchar.b.chen) {
8461+ //fprintf(stderr, "Channel already enabled 2, HCCHAR = %08x\n", hcchar.d32);
8462+ hcchar.b.chdis = 1;
8463+ hcchar.b.chen = 1;
8464+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
8465+ //sleep(1);
8466+ MDELAY(1000);
8467+
8468+ /* Read GINTSTS */
8469+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8470+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
8471+
8472+ /* Read HAINT */
8473+ haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
8474+ //fprintf(stderr, "HAINT: %08x\n", haint.d32);
8475+
8476+ /* Read HCINT */
8477+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
8478+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
8479+
8480+ /* Read HCCHAR */
8481+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8482+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
8483+
8484+ /* Clear HCINT */
8485+ dwc_write_reg32(&hc_regs->hcint, hcint.d32);
8486+
8487+ /* Clear HAINT */
8488+ dwc_write_reg32(&hc_global_regs->haint, haint.d32);
8489+
8490+ /* Clear GINTSTS */
8491+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
8492+
8493+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8494+ //if (hcchar.b.chen) {
8495+ // fprintf(stderr, "** Channel _still_ enabled 2, HCCHAR = %08x **\n", hcchar.d32);
8496+ //}
8497+ }
8498+
8499+ /* Set HCTSIZ */
8500+ hctsiz.d32 = 0;
8501+ hctsiz.b.xfersize = 8;
8502+ hctsiz.b.pktcnt = 1;
8503+ hctsiz.b.pid = DWC_OTG_HC_PID_DATA1;
8504+ dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
8505+
8506+ /* Set HCCHAR */
8507+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8508+ hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;
8509+ hcchar.b.epdir = 1;
8510+ hcchar.b.epnum = 0;
8511+ hcchar.b.mps = 8;
8512+ hcchar.b.chen = 1;
8513+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
8514+
8515+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8516+ //fprintf(stderr, "Waiting for RXSTSQLVL intr 1, GINTSTS = %08x\n", gintsts.d32);
8517+
8518+ /* Wait for receive status queue interrupt */
8519+ do {
8520+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8521+ } while (gintsts.b.rxstsqlvl == 0);
8522+
8523+ //fprintf(stderr, "Got RXSTSQLVL intr 1, GINTSTS = %08x\n", gintsts.d32);
8524+
8525+ /* Read RXSTS */
8526+ grxsts.d32 = dwc_read_reg32(&global_regs->grxstsp);
8527+ //fprintf(stderr, "GRXSTS: %08x\n", grxsts.d32);
8528+
8529+ /* Clear RXSTSQLVL in GINTSTS */
8530+ gintsts.d32 = 0;
8531+ gintsts.b.rxstsqlvl = 1;
8532+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
8533+
8534+ switch (grxsts.b.pktsts) {
8535+ case DWC_GRXSTS_PKTSTS_IN:
8536+ /* Read the data into the host buffer */
8537+ if (grxsts.b.bcnt > 0) {
8538+ int i;
8539+ int word_count = (grxsts.b.bcnt + 3) / 4;
8540+
8541+ data_fifo = (uint32_t *)((char *)global_regs + 0x1000);
8542+
8543+ for (i = 0; i < word_count; i++) {
8544+ (void)dwc_read_reg32(data_fifo++);
8545+ }
8546+ }
8547+
8548+ //fprintf(stderr, "Received %u bytes\n", (unsigned)grxsts.b.bcnt);
8549+ break;
8550+
8551+ default:
8552+ //fprintf(stderr, "** Unexpected GRXSTS packet status 1 **\n");
8553+ break;
8554+ }
8555+
8556+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8557+ //fprintf(stderr, "Waiting for RXSTSQLVL intr 2, GINTSTS = %08x\n", gintsts.d32);
8558+
8559+ /* Wait for receive status queue interrupt */
8560+ do {
8561+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8562+ } while (gintsts.b.rxstsqlvl == 0);
8563+
8564+ //fprintf(stderr, "Got RXSTSQLVL intr 2, GINTSTS = %08x\n", gintsts.d32);
8565+
8566+ /* Read RXSTS */
8567+ grxsts.d32 = dwc_read_reg32(&global_regs->grxstsp);
8568+ //fprintf(stderr, "GRXSTS: %08x\n", grxsts.d32);
8569+
8570+ /* Clear RXSTSQLVL in GINTSTS */
8571+ gintsts.d32 = 0;
8572+ gintsts.b.rxstsqlvl = 1;
8573+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
8574+
8575+ switch (grxsts.b.pktsts) {
8576+ case DWC_GRXSTS_PKTSTS_IN_XFER_COMP:
8577+ break;
8578+
8579+ default:
8580+ //fprintf(stderr, "** Unexpected GRXSTS packet status 2 **\n");
8581+ break;
8582+ }
8583+
8584+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8585+ //fprintf(stderr, "Waiting for HCINTR intr 2, GINTSTS = %08x\n", gintsts.d32);
8586+
8587+ /* Wait for host channel interrupt */
8588+ do {
8589+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8590+ } while (gintsts.b.hcintr == 0);
8591+
8592+ //fprintf(stderr, "Got HCINTR intr 2, GINTSTS = %08x\n", gintsts.d32);
8593+
8594+ /* Read HAINT */
8595+ haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
8596+ //fprintf(stderr, "HAINT: %08x\n", haint.d32);
8597+
8598+ /* Read HCINT */
8599+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
8600+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
8601+
8602+ /* Read HCCHAR */
8603+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8604+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
8605+
8606+ /* Clear HCINT */
8607+ dwc_write_reg32(&hc_regs->hcint, hcint.d32);
8608+
8609+ /* Clear HAINT */
8610+ dwc_write_reg32(&hc_global_regs->haint, haint.d32);
8611+
8612+ /* Clear GINTSTS */
8613+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
8614+
8615+ /* Read GINTSTS */
8616+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8617+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
8618+
8619+ // usleep(100000);
8620+ // mdelay(100);
8621+ MDELAY(1);
8622+
8623+ /*
8624+ * Send handshake packet
8625+ */
8626+
8627+ /* Read HAINT */
8628+ haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
8629+ //fprintf(stderr, "HAINT: %08x\n", haint.d32);
8630+
8631+ /* Read HCINT */
8632+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
8633+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
8634+
8635+ /* Read HCCHAR */
8636+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8637+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
8638+
8639+ /* Clear HCINT */
8640+ dwc_write_reg32(&hc_regs->hcint, hcint.d32);
8641+
8642+ /* Clear HAINT */
8643+ dwc_write_reg32(&hc_global_regs->haint, haint.d32);
8644+
8645+ /* Clear GINTSTS */
8646+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
8647+
8648+ /* Read GINTSTS */
8649+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8650+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
8651+
8652+ /* Make sure channel is disabled */
8653+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8654+ if (hcchar.b.chen) {
8655+ //fprintf(stderr, "Channel already enabled 3, HCCHAR = %08x\n", hcchar.d32);
8656+ hcchar.b.chdis = 1;
8657+ hcchar.b.chen = 1;
8658+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
8659+ //sleep(1);
8660+ MDELAY(1000);
8661+
8662+ /* Read GINTSTS */
8663+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8664+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
8665+
8666+ /* Read HAINT */
8667+ haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
8668+ //fprintf(stderr, "HAINT: %08x\n", haint.d32);
8669+
8670+ /* Read HCINT */
8671+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
8672+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
8673+
8674+ /* Read HCCHAR */
8675+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8676+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
8677+
8678+ /* Clear HCINT */
8679+ dwc_write_reg32(&hc_regs->hcint, hcint.d32);
8680+
8681+ /* Clear HAINT */
8682+ dwc_write_reg32(&hc_global_regs->haint, haint.d32);
8683+
8684+ /* Clear GINTSTS */
8685+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
8686+
8687+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8688+ //if (hcchar.b.chen) {
8689+ // fprintf(stderr, "** Channel _still_ enabled 3, HCCHAR = %08x **\n", hcchar.d32);
8690+ //}
8691+ }
8692+
8693+ /* Set HCTSIZ */
8694+ hctsiz.d32 = 0;
8695+ hctsiz.b.xfersize = 0;
8696+ hctsiz.b.pktcnt = 1;
8697+ hctsiz.b.pid = DWC_OTG_HC_PID_DATA1;
8698+ dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
8699+
8700+ /* Set HCCHAR */
8701+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8702+ hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;
8703+ hcchar.b.epdir = 0;
8704+ hcchar.b.epnum = 0;
8705+ hcchar.b.mps = 8;
8706+ hcchar.b.chen = 1;
8707+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
8708+
8709+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8710+ //fprintf(stderr, "Waiting for HCINTR intr 3, GINTSTS = %08x\n", gintsts.d32);
8711+
8712+ /* Wait for host channel interrupt */
8713+ do {
8714+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8715+ } while (gintsts.b.hcintr == 0);
8716+
8717+ //fprintf(stderr, "Got HCINTR intr 3, GINTSTS = %08x\n", gintsts.d32);
8718+
8719+ /* Disable HCINTs */
8720+ dwc_write_reg32(&hc_regs->hcintmsk, 0x0000);
8721+
8722+ /* Disable HAINTs */
8723+ dwc_write_reg32(&hc_global_regs->haintmsk, 0x0000);
8724+
8725+ /* Read HAINT */
8726+ haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
8727+ //fprintf(stderr, "HAINT: %08x\n", haint.d32);
8728+
8729+ /* Read HCINT */
8730+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
8731+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
8732+
8733+ /* Read HCCHAR */
8734+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8735+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
8736+
8737+ /* Clear HCINT */
8738+ dwc_write_reg32(&hc_regs->hcint, hcint.d32);
8739+
8740+ /* Clear HAINT */
8741+ dwc_write_reg32(&hc_global_regs->haint, haint.d32);
8742+
8743+ /* Clear GINTSTS */
8744+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
8745+
8746+ /* Read GINTSTS */
8747+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
8748+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
8749+}
8750+#endif /* DWC_HS_ELECT_TST */
8751+
8752+/** Handles hub class-specific requests.*/
8753+int dwc_otg_hcd_hub_control(struct usb_hcd *_hcd,
8754+ u16 _typeReq,
8755+ u16 _wValue,
8756+ u16 _wIndex,
8757+ char *_buf,
8758+ u16 _wLength)
8759+{
8760+ int retval = 0;
8761+
8762+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (_hcd);
8763+ dwc_otg_core_if_t *core_if = hcd_to_dwc_otg_hcd (_hcd)->core_if;
8764+ struct usb_hub_descriptor *desc;
8765+ hprt0_data_t hprt0 = {.d32 = 0};
8766+
8767+ uint32_t port_status;
8768+
8769+ switch (_typeReq) {
8770+ case ClearHubFeature:
8771+ DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
8772+ "ClearHubFeature 0x%x\n", _wValue);
8773+ switch (_wValue) {
8774+ case C_HUB_LOCAL_POWER:
8775+ case C_HUB_OVER_CURRENT:
8776+ /* Nothing required here */
8777+ break;
8778+ default:
8779+ retval = -EINVAL;
8780+ DWC_ERROR ("DWC OTG HCD - "
8781+ "ClearHubFeature request %xh unknown\n", _wValue);
8782+ }
8783+ break;
8784+ case ClearPortFeature:
8785+ if (!_wIndex || _wIndex > 1)
8786+ goto error;
8787+
8788+ switch (_wValue) {
8789+ case USB_PORT_FEAT_ENABLE:
8790+ DWC_DEBUGPL (DBG_ANY, "DWC OTG HCD HUB CONTROL - "
8791+ "ClearPortFeature USB_PORT_FEAT_ENABLE\n");
8792+ hprt0.d32 = dwc_otg_read_hprt0 (core_if);
8793+ hprt0.b.prtena = 1;
8794+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
8795+ break;
8796+ case USB_PORT_FEAT_SUSPEND:
8797+ DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
8798+ "ClearPortFeature USB_PORT_FEAT_SUSPEND\n");
8799+ hprt0.d32 = dwc_otg_read_hprt0 (core_if);
8800+ hprt0.b.prtres = 1;
8801+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
8802+ /* Clear Resume bit */
8803+ mdelay (100);
8804+ hprt0.b.prtres = 0;
8805+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
8806+ break;
8807+ case USB_PORT_FEAT_POWER:
8808+ DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
8809+ "ClearPortFeature USB_PORT_FEAT_POWER\n");
8810+ hprt0.d32 = dwc_otg_read_hprt0 (core_if);
8811+ hprt0.b.prtpwr = 0;
8812+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
8813+ break;
8814+ case USB_PORT_FEAT_INDICATOR:
8815+ DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
8816+ "ClearPortFeature USB_PORT_FEAT_INDICATOR\n");
8817+ /* Port inidicator not supported */
8818+ break;
8819+ case USB_PORT_FEAT_C_CONNECTION:
8820+ /* Clears drivers internal connect status change
8821+ * flag */
8822+ DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
8823+ "ClearPortFeature USB_PORT_FEAT_C_CONNECTION\n");
8824+ dwc_otg_hcd->flags.b.port_connect_status_change = 0;
8825+ break;
8826+ case USB_PORT_FEAT_C_RESET:
8827+ /* Clears the driver's internal Port Reset Change
8828+ * flag */
8829+ DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
8830+ "ClearPortFeature USB_PORT_FEAT_C_RESET\n");
8831+ dwc_otg_hcd->flags.b.port_reset_change = 0;
8832+ break;
8833+ case USB_PORT_FEAT_C_ENABLE:
8834+ /* Clears the driver's internal Port
8835+ * Enable/Disable Change flag */
8836+ DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
8837+ "ClearPortFeature USB_PORT_FEAT_C_ENABLE\n");
8838+ dwc_otg_hcd->flags.b.port_enable_change = 0;
8839+ break;
8840+ case USB_PORT_FEAT_C_SUSPEND:
8841+ /* Clears the driver's internal Port Suspend
8842+ * Change flag, which is set when resume signaling on
8843+ * the host port is complete */
8844+ DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
8845+ "ClearPortFeature USB_PORT_FEAT_C_SUSPEND\n");
8846+ dwc_otg_hcd->flags.b.port_suspend_change = 0;
8847+ break;
8848+ case USB_PORT_FEAT_C_OVER_CURRENT:
8849+ DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
8850+ "ClearPortFeature USB_PORT_FEAT_C_OVER_CURRENT\n");
8851+ dwc_otg_hcd->flags.b.port_over_current_change = 0;
8852+ break;
8853+ default:
8854+ retval = -EINVAL;
8855+ DWC_ERROR ("DWC OTG HCD - "
8856+ "ClearPortFeature request %xh "
8857+ "unknown or unsupported\n", _wValue);
8858+ }
8859+ break;
8860+ case GetHubDescriptor:
8861+ DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
8862+ "GetHubDescriptor\n");
8863+ desc = (struct usb_hub_descriptor *)_buf;
8864+ desc->bDescLength = 9;
8865+ desc->bDescriptorType = 0x29;
8866+ desc->bNbrPorts = 1;
8867+ desc->wHubCharacteristics = 0x08;
8868+ desc->bPwrOn2PwrGood = 1;
8869+ desc->bHubContrCurrent = 0;
8870+ desc->u.hs.DeviceRemovable[0] = 0;
8871+ desc->u.hs.DeviceRemovable[1] = 0xff;
8872+ break;
8873+ case GetHubStatus:
8874+ DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
8875+ "GetHubStatus\n");
8876+ memset (_buf, 0, 4);
8877+ break;
8878+ case GetPortStatus:
8879+ DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
8880+ "GetPortStatus\n");
8881+
8882+ if (!_wIndex || _wIndex > 1)
8883+ goto error;
8884+
8885+ port_status = 0;
8886+
8887+ if (dwc_otg_hcd->flags.b.port_connect_status_change)
8888+ port_status |= (1 << USB_PORT_FEAT_C_CONNECTION);
8889+
8890+ if (dwc_otg_hcd->flags.b.port_enable_change)
8891+ port_status |= (1 << USB_PORT_FEAT_C_ENABLE);
8892+
8893+ if (dwc_otg_hcd->flags.b.port_suspend_change)
8894+ port_status |= (1 << USB_PORT_FEAT_C_SUSPEND);
8895+
8896+ if (dwc_otg_hcd->flags.b.port_reset_change)
8897+ port_status |= (1 << USB_PORT_FEAT_C_RESET);
8898+
8899+ if (dwc_otg_hcd->flags.b.port_over_current_change) {
8900+ DWC_ERROR("Device Not Supported\n");
8901+ port_status |= (1 << USB_PORT_FEAT_C_OVER_CURRENT);
8902+ }
8903+
8904+ if (!dwc_otg_hcd->flags.b.port_connect_status) {
8905+ printk("DISCONNECTED PORT\n");
8906+ /*
8907+ * The port is disconnected, which means the core is
8908+ * either in device mode or it soon will be. Just
8909+ * return 0's for the remainder of the port status
8910+ * since the port register can't be read if the core
8911+ * is in device mode.
8912+ */
8913+#if 1 // winder.
8914+ *((u32 *) _buf) = cpu_to_le32(port_status);
8915+#else
8916+ *((__le32 *) _buf) = cpu_to_le32(port_status);
8917+#endif
8918+ break;
8919+ }
8920+
8921+ hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
8922+ DWC_DEBUGPL(DBG_HCDV, " HPRT0: 0x%08x\n", hprt0.d32);
8923+
8924+ if (hprt0.b.prtconnsts)
8925+ port_status |= (1 << USB_PORT_FEAT_CONNECTION);
8926+
8927+ if (hprt0.b.prtena)
8928+ port_status |= (1 << USB_PORT_FEAT_ENABLE);
8929+
8930+ if (hprt0.b.prtsusp)
8931+ port_status |= (1 << USB_PORT_FEAT_SUSPEND);
8932+
8933+ if (hprt0.b.prtovrcurract)
8934+ port_status |= (1 << USB_PORT_FEAT_OVER_CURRENT);
8935+
8936+ if (hprt0.b.prtrst)
8937+ port_status |= (1 << USB_PORT_FEAT_RESET);
8938+
8939+ if (hprt0.b.prtpwr)
8940+ port_status |= (1 << USB_PORT_FEAT_POWER);
8941+
8942+ if (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_HIGH_SPEED)
8943+ port_status |= USB_PORT_STAT_HIGH_SPEED;
8944+
8945+ else if (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_LOW_SPEED)
8946+ port_status |= (1 << USB_PORT_FEAT_LOWSPEED);
8947+
8948+ if (hprt0.b.prttstctl)
8949+ port_status |= (1 << USB_PORT_FEAT_TEST);
8950+
8951+ /* USB_PORT_FEAT_INDICATOR unsupported always 0 */
8952+#if 1 // winder.
8953+ *((u32 *) _buf) = cpu_to_le32(port_status);
8954+#else
8955+ *((__le32 *) _buf) = cpu_to_le32(port_status);
8956+#endif
8957+
8958+ break;
8959+ case SetHubFeature:
8960+ DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
8961+ "SetHubFeature\n");
8962+ /* No HUB features supported */
8963+ break;
8964+ case SetPortFeature:
8965+ if (_wValue != USB_PORT_FEAT_TEST && (!_wIndex || _wIndex > 1))
8966+ goto error;
8967+
8968+ if (!dwc_otg_hcd->flags.b.port_connect_status) {
8969+ /*
8970+ * The port is disconnected, which means the core is
8971+ * either in device mode or it soon will be. Just
8972+ * return without doing anything since the port
8973+ * register can't be written if the core is in device
8974+ * mode.
8975+ */
8976+ break;
8977+ }
8978+
8979+ switch (_wValue) {
8980+ case USB_PORT_FEAT_SUSPEND:
8981+ DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
8982+ "SetPortFeature - USB_PORT_FEAT_SUSPEND\n");
8983+ if (_hcd->self.otg_port == _wIndex
8984+ && _hcd->self.b_hnp_enable) {
8985+ gotgctl_data_t gotgctl = {.d32=0};
8986+ gotgctl.b.hstsethnpen = 1;
8987+ dwc_modify_reg32(&core_if->core_global_regs->
8988+ gotgctl, 0, gotgctl.d32);
8989+ core_if->op_state = A_SUSPEND;
8990+ }
8991+ hprt0.d32 = dwc_otg_read_hprt0 (core_if);
8992+ hprt0.b.prtsusp = 1;
8993+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
8994+ //DWC_PRINT( "SUSPEND: HPRT0=%0x\n", hprt0.d32);
8995+ /* Suspend the Phy Clock */
8996+ {
8997+ pcgcctl_data_t pcgcctl = {.d32=0};
8998+ pcgcctl.b.stoppclk = 1;
8999+ dwc_write_reg32(core_if->pcgcctl, pcgcctl.d32);
9000+ }
9001+
9002+ /* For HNP the bus must be suspended for at least 200ms.*/
9003+ if (_hcd->self.b_hnp_enable) {
9004+ mdelay(200);
9005+ //DWC_PRINT( "SUSPEND: wait complete! (%d)\n", _hcd->state);
9006+ }
9007+ break;
9008+ case USB_PORT_FEAT_POWER:
9009+ DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9010+ "SetPortFeature - USB_PORT_FEAT_POWER\n");
9011+ hprt0.d32 = dwc_otg_read_hprt0 (core_if);
9012+ hprt0.b.prtpwr = 1;
9013+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
9014+ break;
9015+ case USB_PORT_FEAT_RESET:
9016+ DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9017+ "SetPortFeature - USB_PORT_FEAT_RESET\n");
9018+ hprt0.d32 = dwc_otg_read_hprt0 (core_if);
9019+ /* TODO: Is this for OTG protocol??
9020+ * We shoudl remove OTG totally for Danube system.
9021+ * But, in the future, maybe we need this.
9022+ */
9023+#if 1 // winder
9024+ hprt0.b.prtrst = 1;
9025+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
9026+#else
9027+ /* When B-Host the Port reset bit is set in
9028+ * the Start HCD Callback function, so that
9029+ * the reset is started within 1ms of the HNP
9030+ * success interrupt. */
9031+ if (!_hcd->self.is_b_host) {
9032+ hprt0.b.prtrst = 1;
9033+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
9034+ }
9035+#endif
9036+ /* Clear reset bit in 10ms (FS/LS) or 50ms (HS) */
9037+ MDELAY (60);
9038+ hprt0.b.prtrst = 0;
9039+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
9040+ break;
9041+
9042+#ifdef DWC_HS_ELECT_TST
9043+ case USB_PORT_FEAT_TEST:
9044+ {
9045+ uint32_t t;
9046+ gintmsk_data_t gintmsk;
9047+
9048+ t = (_wIndex >> 8); /* MSB wIndex USB */
9049+ DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9050+ "SetPortFeature - USB_PORT_FEAT_TEST %d\n", t);
9051+ printk("USB_PORT_FEAT_TEST %d\n", t);
9052+ if (t < 6) {
9053+ hprt0.d32 = dwc_otg_read_hprt0 (core_if);
9054+ hprt0.b.prttstctl = t;
9055+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
9056+ } else {
9057+ /* Setup global vars with reg addresses (quick and
9058+ * dirty hack, should be cleaned up)
9059+ */
9060+ global_regs = core_if->core_global_regs;
9061+ hc_global_regs = core_if->host_if->host_global_regs;
9062+ hc_regs = (dwc_otg_hc_regs_t *)((char *)global_regs + 0x500);
9063+ data_fifo = (uint32_t *)((char *)global_regs + 0x1000);
9064+
9065+ if (t == 6) { /* HS_HOST_PORT_SUSPEND_RESUME */
9066+ /* Save current interrupt mask */
9067+ gintmsk.d32 = dwc_read_reg32(&global_regs->gintmsk);
9068+
9069+ /* Disable all interrupts while we muck with
9070+ * the hardware directly
9071+ */
9072+ dwc_write_reg32(&global_regs->gintmsk, 0);
9073+
9074+ /* 15 second delay per the test spec */
9075+ mdelay(15000);
9076+
9077+ /* Drive suspend on the root port */
9078+ hprt0.d32 = dwc_otg_read_hprt0 (core_if);
9079+ hprt0.b.prtsusp = 1;
9080+ hprt0.b.prtres = 0;
9081+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
9082+
9083+ /* 15 second delay per the test spec */
9084+ mdelay(15000);
9085+
9086+ /* Drive resume on the root port */
9087+ hprt0.d32 = dwc_otg_read_hprt0 (core_if);
9088+ hprt0.b.prtsusp = 0;
9089+ hprt0.b.prtres = 1;
9090+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
9091+ mdelay(100);
9092+
9093+ /* Clear the resume bit */
9094+ hprt0.b.prtres = 0;
9095+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
9096+
9097+ /* Restore interrupts */
9098+ dwc_write_reg32(&global_regs->gintmsk, gintmsk.d32);
9099+ } else if (t == 7) { /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR setup */
9100+ /* Save current interrupt mask */
9101+ gintmsk.d32 = dwc_read_reg32(&global_regs->gintmsk);
9102+
9103+ /* Disable all interrupts while we muck with
9104+ * the hardware directly
9105+ */
9106+ dwc_write_reg32(&global_regs->gintmsk, 0);
9107+
9108+ /* 15 second delay per the test spec */
9109+ mdelay(15000);
9110+
9111+ /* Send the Setup packet */
9112+ do_setup();
9113+
9114+ /* 15 second delay so nothing else happens for awhile */
9115+ mdelay(15000);
9116+
9117+ /* Restore interrupts */
9118+ dwc_write_reg32(&global_regs->gintmsk, gintmsk.d32);
9119+ } else if (t == 8) { /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR execute */
9120+ /* Save current interrupt mask */
9121+ gintmsk.d32 = dwc_read_reg32(&global_regs->gintmsk);
9122+
9123+ /* Disable all interrupts while we muck with
9124+ * the hardware directly
9125+ */
9126+ dwc_write_reg32(&global_regs->gintmsk, 0);
9127+
9128+ /* Send the Setup packet */
9129+ do_setup();
9130+
9131+ /* 15 second delay so nothing else happens for awhile */
9132+ mdelay(15000);
9133+
9134+ /* Send the In and Ack packets */
9135+ do_in_ack();
9136+
9137+ /* 15 second delay so nothing else happens for awhile */
9138+ mdelay(15000);
9139+
9140+ /* Restore interrupts */
9141+ dwc_write_reg32(&global_regs->gintmsk, gintmsk.d32);
9142+ }
9143+ }
9144+ break;
9145+ }
9146+#endif /* DWC_HS_ELECT_TST */
9147+
9148+ case USB_PORT_FEAT_INDICATOR:
9149+ DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9150+ "SetPortFeature - USB_PORT_FEAT_INDICATOR\n");
9151+ /* Not supported */
9152+ break;
9153+ default:
9154+ retval = -EINVAL;
9155+ DWC_ERROR ("DWC OTG HCD - "
9156+ "SetPortFeature request %xh "
9157+ "unknown or unsupported\n", _wValue);
9158+ break;
9159+ }
9160+ break;
9161+ default:
9162+error:
9163+ retval = -EINVAL;
9164+ DWC_WARN ("DWC OTG HCD - "
9165+ "Unknown hub control request type or invalid typeReq: %xh wIndex: %xh wValue: %xh\n",
9166+ _typeReq, _wIndex, _wValue);
9167+ break;
9168+ }
9169+
9170+ return retval;
9171+}
9172+
9173+
9174+/**
9175+ * Assigns transactions from a QTD to a free host channel and initializes the
9176+ * host channel to perform the transactions. The host channel is removed from
9177+ * the free list.
9178+ *
9179+ * @param _hcd The HCD state structure.
9180+ * @param _qh Transactions from the first QTD for this QH are selected and
9181+ * assigned to a free host channel.
9182+ */
9183+static void assign_and_init_hc(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh)
9184+{
9185+ dwc_hc_t *hc;
9186+ dwc_otg_qtd_t *qtd;
9187+ struct urb *urb;
9188+
9189+ DWC_DEBUGPL(DBG_HCDV, "%s(%p,%p)\n", __func__, _hcd, _qh);
9190+
9191+ hc = list_entry(_hcd->free_hc_list.next, dwc_hc_t, hc_list_entry);
9192+
9193+ /* Remove the host channel from the free list. */
9194+ list_del_init(&hc->hc_list_entry);
9195+
9196+ qtd = list_entry(_qh->qtd_list.next, dwc_otg_qtd_t, qtd_list_entry);
9197+ urb = qtd->urb;
9198+ _qh->channel = hc;
9199+ _qh->qtd_in_process = qtd;
9200+
9201+ /*
9202+ * Use usb_pipedevice to determine device address. This address is
9203+ * 0 before the SET_ADDRESS command and the correct address afterward.
9204+ */
9205+ hc->dev_addr = usb_pipedevice(urb->pipe);
9206+ hc->ep_num = usb_pipeendpoint(urb->pipe);
9207+
9208+ if (urb->dev->speed == USB_SPEED_LOW) {
9209+ hc->speed = DWC_OTG_EP_SPEED_LOW;
9210+ } else if (urb->dev->speed == USB_SPEED_FULL) {
9211+ hc->speed = DWC_OTG_EP_SPEED_FULL;
9212+ } else {
9213+ hc->speed = DWC_OTG_EP_SPEED_HIGH;
9214+ }
9215+ hc->max_packet = dwc_max_packet(_qh->maxp);
9216+
9217+ hc->xfer_started = 0;
9218+ hc->halt_status = DWC_OTG_HC_XFER_NO_HALT_STATUS;
9219+ hc->error_state = (qtd->error_count > 0);
9220+ hc->halt_on_queue = 0;
9221+ hc->halt_pending = 0;
9222+ hc->requests = 0;
9223+
9224+ /*
9225+ * The following values may be modified in the transfer type section
9226+ * below. The xfer_len value may be reduced when the transfer is
9227+ * started to accommodate the max widths of the XferSize and PktCnt
9228+ * fields in the HCTSIZn register.
9229+ */
9230+ hc->do_ping = _qh->ping_state;
9231+ hc->ep_is_in = (usb_pipein(urb->pipe) != 0);
9232+ hc->data_pid_start = _qh->data_toggle;
9233+ hc->multi_count = 1;
9234+
9235+ if (_hcd->core_if->dma_enable) {
9236+ hc->xfer_buff = (uint8_t *)(u32)urb->transfer_dma + urb->actual_length;
9237+ } else {
9238+ hc->xfer_buff = (uint8_t *)urb->transfer_buffer + urb->actual_length;
9239+ }
9240+ hc->xfer_len = urb->transfer_buffer_length - urb->actual_length;
9241+ hc->xfer_count = 0;
9242+
9243+ /*
9244+ * Set the split attributes
9245+ */
9246+ hc->do_split = 0;
9247+ if (_qh->do_split) {
9248+ hc->do_split = 1;
9249+ hc->xact_pos = qtd->isoc_split_pos;
9250+ hc->complete_split = qtd->complete_split;
9251+ hc->hub_addr = urb->dev->tt->hub->devnum;
9252+ hc->port_addr = urb->dev->ttport;
9253+ }
9254+
9255+ switch (usb_pipetype(urb->pipe)) {
9256+ case PIPE_CONTROL:
9257+ hc->ep_type = DWC_OTG_EP_TYPE_CONTROL;
9258+ switch (qtd->control_phase) {
9259+ case DWC_OTG_CONTROL_SETUP:
9260+ DWC_DEBUGPL(DBG_HCDV, " Control setup transaction\n");
9261+ hc->do_ping = 0;
9262+ hc->ep_is_in = 0;
9263+ hc->data_pid_start = DWC_OTG_HC_PID_SETUP;
9264+ if (_hcd->core_if->dma_enable) {
9265+ hc->xfer_buff = (uint8_t *)(u32)urb->setup_dma;
9266+ } else {
9267+ hc->xfer_buff = (uint8_t *)urb->setup_packet;
9268+ }
9269+ hc->xfer_len = 8;
9270+ break;
9271+ case DWC_OTG_CONTROL_DATA:
9272+ DWC_DEBUGPL(DBG_HCDV, " Control data transaction\n");
9273+ hc->data_pid_start = qtd->data_toggle;
9274+ break;
9275+ case DWC_OTG_CONTROL_STATUS:
9276+ /*
9277+ * Direction is opposite of data direction or IN if no
9278+ * data.
9279+ */
9280+ DWC_DEBUGPL(DBG_HCDV, " Control status transaction\n");
9281+ if (urb->transfer_buffer_length == 0) {
9282+ hc->ep_is_in = 1;
9283+ } else {
9284+ hc->ep_is_in = (usb_pipein(urb->pipe) != USB_DIR_IN);
9285+ }
9286+ if (hc->ep_is_in) {
9287+ hc->do_ping = 0;
9288+ }
9289+ hc->data_pid_start = DWC_OTG_HC_PID_DATA1;
9290+ hc->xfer_len = 0;
9291+ if (_hcd->core_if->dma_enable) {
9292+ hc->xfer_buff = (uint8_t *)_hcd->status_buf_dma;
9293+ } else {
9294+ hc->xfer_buff = (uint8_t *)_hcd->status_buf;
9295+ }
9296+ break;
9297+ }
9298+ break;
9299+ case PIPE_BULK:
9300+ hc->ep_type = DWC_OTG_EP_TYPE_BULK;
9301+ break;
9302+ case PIPE_INTERRUPT:
9303+ hc->ep_type = DWC_OTG_EP_TYPE_INTR;
9304+ break;
9305+ case PIPE_ISOCHRONOUS:
9306+ {
9307+ struct usb_iso_packet_descriptor *frame_desc;
9308+ frame_desc = &urb->iso_frame_desc[qtd->isoc_frame_index];
9309+ hc->ep_type = DWC_OTG_EP_TYPE_ISOC;
9310+ if (_hcd->core_if->dma_enable) {
9311+ hc->xfer_buff = (uint8_t *)(u32)urb->transfer_dma;
9312+ } else {
9313+ hc->xfer_buff = (uint8_t *)urb->transfer_buffer;
9314+ }
9315+ hc->xfer_buff += frame_desc->offset + qtd->isoc_split_offset;
9316+ hc->xfer_len = frame_desc->length - qtd->isoc_split_offset;
9317+
9318+ if (hc->xact_pos == DWC_HCSPLIT_XACTPOS_ALL) {
9319+ if (hc->xfer_len <= 188) {
9320+ hc->xact_pos = DWC_HCSPLIT_XACTPOS_ALL;
9321+ }
9322+ else {
9323+ hc->xact_pos = DWC_HCSPLIT_XACTPOS_BEGIN;
9324+ }
9325+ }
9326+ }
9327+ break;
9328+ }
9329+
9330+ if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
9331+ hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
9332+ /*
9333+ * This value may be modified when the transfer is started to
9334+ * reflect the actual transfer length.
9335+ */
9336+ hc->multi_count = dwc_hb_mult(_qh->maxp);
9337+ }
9338+
9339+ dwc_otg_hc_init(_hcd->core_if, hc);
9340+ hc->qh = _qh;
9341+}
9342+#define DEBUG_HOST_CHANNELS
9343+#ifdef DEBUG_HOST_CHANNELS
9344+static int last_sel_trans_num_per_scheduled = 0;
9345+module_param(last_sel_trans_num_per_scheduled, int, 0444);
9346+
9347+static int last_sel_trans_num_nonper_scheduled = 0;
9348+module_param(last_sel_trans_num_nonper_scheduled, int, 0444);
9349+
9350+static int last_sel_trans_num_avail_hc_at_start = 0;
9351+module_param(last_sel_trans_num_avail_hc_at_start, int, 0444);
9352+
9353+static int last_sel_trans_num_avail_hc_at_end = 0;
9354+module_param(last_sel_trans_num_avail_hc_at_end, int, 0444);
9355+#endif /* DEBUG_HOST_CHANNELS */
9356+
9357+/**
9358+ * This function selects transactions from the HCD transfer schedule and
9359+ * assigns them to available host channels. It is called from HCD interrupt
9360+ * handler functions.
9361+ *
9362+ * @param _hcd The HCD state structure.
9363+ *
9364+ * @return The types of new transactions that were assigned to host channels.
9365+ */
9366+dwc_otg_transaction_type_e dwc_otg_hcd_select_transactions(dwc_otg_hcd_t *_hcd)
9367+{
9368+ struct list_head *qh_ptr;
9369+ dwc_otg_qh_t *qh;
9370+ int num_channels;
9371+ unsigned long flags;
9372+ dwc_otg_transaction_type_e ret_val = DWC_OTG_TRANSACTION_NONE;
9373+
9374+#ifdef DEBUG_SOF
9375+ DWC_DEBUGPL(DBG_HCD, " Select Transactions\n");
9376+#endif /* */
9377+
9378+#ifdef DEBUG_HOST_CHANNELS
9379+ last_sel_trans_num_per_scheduled = 0;
9380+ last_sel_trans_num_nonper_scheduled = 0;
9381+ last_sel_trans_num_avail_hc_at_start = _hcd->available_host_channels;
9382+#endif /* DEBUG_HOST_CHANNELS */
9383+
9384+ /* Process entries in the periodic ready list. */
9385+ num_channels = _hcd->core_if->core_params->host_channels;
9386+ qh_ptr = _hcd->periodic_sched_ready.next;
9387+ while (qh_ptr != &_hcd->periodic_sched_ready
9388+ && !list_empty(&_hcd->free_hc_list)) {
9389+
9390+ // Make sure we leave one channel for non periodic transactions.
9391+ local_irq_save(flags);
9392+ if (_hcd->available_host_channels <= 1) {
9393+ local_irq_restore(flags);
9394+ break;
9395+ }
9396+ _hcd->available_host_channels--;
9397+ local_irq_restore(flags);
9398+#ifdef DEBUG_HOST_CHANNELS
9399+ last_sel_trans_num_per_scheduled++;
9400+#endif /* DEBUG_HOST_CHANNELS */
9401+
9402+ qh = list_entry(qh_ptr, dwc_otg_qh_t, qh_list_entry);
9403+ assign_and_init_hc(_hcd, qh);
9404+
9405+ /*
9406+ * Move the QH from the periodic ready schedule to the
9407+ * periodic assigned schedule.
9408+ */
9409+ qh_ptr = qh_ptr->next;
9410+ local_irq_save(flags);
9411+ list_move(&qh->qh_list_entry, &_hcd->periodic_sched_assigned);
9412+ local_irq_restore(flags);
9413+ ret_val = DWC_OTG_TRANSACTION_PERIODIC;
9414+ }
9415+
9416+ /*
9417+ * Process entries in the deferred portion of the non-periodic list.
9418+ * A NAK put them here and, at the right time, they need to be
9419+ * placed on the sched_inactive list.
9420+ */
9421+ qh_ptr = _hcd->non_periodic_sched_deferred.next;
9422+ while (qh_ptr != &_hcd->non_periodic_sched_deferred) {
9423+ uint16_t frame_number =
9424+ dwc_otg_hcd_get_frame_number(dwc_otg_hcd_to_hcd(_hcd));
9425+ qh = list_entry(qh_ptr, dwc_otg_qh_t, qh_list_entry);
9426+ qh_ptr = qh_ptr->next;
9427+
9428+ if (dwc_frame_num_le(qh->sched_frame, frame_number)) {
9429+ // NAK did this
9430+ /*
9431+ * Move the QH from the non periodic deferred schedule to
9432+ * the non periodic inactive schedule.
9433+ */
9434+ local_irq_save(flags);
9435+ list_move(&qh->qh_list_entry,
9436+ &_hcd->non_periodic_sched_inactive);
9437+ local_irq_restore(flags);
9438+ }
9439+ }
9440+
9441+ /*
9442+ * Process entries in the inactive portion of the non-periodic
9443+ * schedule. Some free host channels may not be used if they are
9444+ * reserved for periodic transfers.
9445+ */
9446+ qh_ptr = _hcd->non_periodic_sched_inactive.next;
9447+ num_channels = _hcd->core_if->core_params->host_channels;
9448+ while (qh_ptr != &_hcd->non_periodic_sched_inactive
9449+ && !list_empty(&_hcd->free_hc_list)) {
9450+
9451+ local_irq_save(flags);
9452+ if (_hcd->available_host_channels < 1) {
9453+ local_irq_restore(flags);
9454+ break;
9455+ }
9456+ _hcd->available_host_channels--;
9457+ local_irq_restore(flags);
9458+#ifdef DEBUG_HOST_CHANNELS
9459+ last_sel_trans_num_nonper_scheduled++;
9460+#endif /* DEBUG_HOST_CHANNELS */
9461+
9462+ qh = list_entry(qh_ptr, dwc_otg_qh_t, qh_list_entry);
9463+ assign_and_init_hc(_hcd, qh);
9464+
9465+ /*
9466+ * Move the QH from the non-periodic inactive schedule to the
9467+ * non-periodic active schedule.
9468+ */
9469+ qh_ptr = qh_ptr->next;
9470+ local_irq_save(flags);
9471+ list_move(&qh->qh_list_entry, &_hcd->non_periodic_sched_active);
9472+ local_irq_restore(flags);
9473+
9474+ if (ret_val == DWC_OTG_TRANSACTION_NONE) {
9475+ ret_val = DWC_OTG_TRANSACTION_NON_PERIODIC;
9476+ } else {
9477+ ret_val = DWC_OTG_TRANSACTION_ALL;
9478+ }
9479+
9480+ }
9481+#ifdef DEBUG_HOST_CHANNELS
9482+ last_sel_trans_num_avail_hc_at_end = _hcd->available_host_channels;
9483+#endif /* DEBUG_HOST_CHANNELS */
9484+
9485+ return ret_val;
9486+}
9487+
9488+/**
9489+ * Attempts to queue a single transaction request for a host channel
9490+ * associated with either a periodic or non-periodic transfer. This function
9491+ * assumes that there is space available in the appropriate request queue. For
9492+ * an OUT transfer or SETUP transaction in Slave mode, it checks whether space
9493+ * is available in the appropriate Tx FIFO.
9494+ *
9495+ * @param _hcd The HCD state structure.
9496+ * @param _hc Host channel descriptor associated with either a periodic or
9497+ * non-periodic transfer.
9498+ * @param _fifo_dwords_avail Number of DWORDs available in the periodic Tx
9499+ * FIFO for periodic transfers or the non-periodic Tx FIFO for non-periodic
9500+ * transfers.
9501+ *
9502+ * @return 1 if a request is queued and more requests may be needed to
9503+ * complete the transfer, 0 if no more requests are required for this
9504+ * transfer, -1 if there is insufficient space in the Tx FIFO.
9505+ */
9506+static int queue_transaction(dwc_otg_hcd_t *_hcd,
9507+ dwc_hc_t *_hc,
9508+ uint16_t _fifo_dwords_avail)
9509+{
9510+ int retval;
9511+
9512+ if (_hcd->core_if->dma_enable) {
9513+ if (!_hc->xfer_started) {
9514+ dwc_otg_hc_start_transfer(_hcd->core_if, _hc);
9515+ _hc->qh->ping_state = 0;
9516+ }
9517+ retval = 0;
9518+ } else if (_hc->halt_pending) {
9519+ /* Don't queue a request if the channel has been halted. */
9520+ retval = 0;
9521+ } else if (_hc->halt_on_queue) {
9522+ dwc_otg_hc_halt(_hcd->core_if, _hc, _hc->halt_status);
9523+ retval = 0;
9524+ } else if (_hc->do_ping) {
9525+ if (!_hc->xfer_started) {
9526+ dwc_otg_hc_start_transfer(_hcd->core_if, _hc);
9527+ }
9528+ retval = 0;
9529+ } else if (!_hc->ep_is_in ||
9530+ _hc->data_pid_start == DWC_OTG_HC_PID_SETUP) {
9531+ if ((_fifo_dwords_avail * 4) >= _hc->max_packet) {
9532+ if (!_hc->xfer_started) {
9533+ dwc_otg_hc_start_transfer(_hcd->core_if, _hc);
9534+ retval = 1;
9535+ } else {
9536+ retval = dwc_otg_hc_continue_transfer(_hcd->core_if, _hc);
9537+ }
9538+ } else {
9539+ retval = -1;
9540+ }
9541+ } else {
9542+ if (!_hc->xfer_started) {
9543+ dwc_otg_hc_start_transfer(_hcd->core_if, _hc);
9544+ retval = 1;
9545+ } else {
9546+ retval = dwc_otg_hc_continue_transfer(_hcd->core_if, _hc);
9547+ }
9548+ }
9549+
9550+ return retval;
9551+}
9552+
9553+/**
9554+ * Processes active non-periodic channels and queues transactions for these
9555+ * channels to the DWC_otg controller. After queueing transactions, the NP Tx
9556+ * FIFO Empty interrupt is enabled if there are more transactions to queue as
9557+ * NP Tx FIFO or request queue space becomes available. Otherwise, the NP Tx
9558+ * FIFO Empty interrupt is disabled.
9559+ */
9560+static void process_non_periodic_channels(dwc_otg_hcd_t *_hcd)
9561+{
9562+ gnptxsts_data_t tx_status;
9563+ struct list_head *orig_qh_ptr;
9564+ dwc_otg_qh_t *qh;
9565+ int status;
9566+ int no_queue_space = 0;
9567+ int no_fifo_space = 0;
9568+ int more_to_do = 0;
9569+
9570+ dwc_otg_core_global_regs_t *global_regs = _hcd->core_if->core_global_regs;
9571+
9572+ DWC_DEBUGPL(DBG_HCDV, "Queue non-periodic transactions\n");
9573+#ifdef DEBUG
9574+ tx_status.d32 = dwc_read_reg32(&global_regs->gnptxsts);
9575+ DWC_DEBUGPL(DBG_HCDV, " NP Tx Req Queue Space Avail (before queue): %d\n",
9576+ tx_status.b.nptxqspcavail);
9577+ DWC_DEBUGPL(DBG_HCDV, " NP Tx FIFO Space Avail (before queue): %d\n",
9578+ tx_status.b.nptxfspcavail);
9579+#endif
9580+ /*
9581+ * Keep track of the starting point. Skip over the start-of-list
9582+ * entry.
9583+ */
9584+ if (_hcd->non_periodic_qh_ptr == &_hcd->non_periodic_sched_active) {
9585+ _hcd->non_periodic_qh_ptr = _hcd->non_periodic_qh_ptr->next;
9586+ }
9587+ orig_qh_ptr = _hcd->non_periodic_qh_ptr;
9588+
9589+ /*
9590+ * Process once through the active list or until no more space is
9591+ * available in the request queue or the Tx FIFO.
9592+ */
9593+ do {
9594+ tx_status.d32 = dwc_read_reg32(&global_regs->gnptxsts);
9595+ if (!_hcd->core_if->dma_enable && tx_status.b.nptxqspcavail == 0) {
9596+ no_queue_space = 1;
9597+ break;
9598+ }
9599+
9600+ qh = list_entry(_hcd->non_periodic_qh_ptr, dwc_otg_qh_t, qh_list_entry);
9601+ status = queue_transaction(_hcd, qh->channel, tx_status.b.nptxfspcavail);
9602+
9603+ if (status > 0) {
9604+ more_to_do = 1;
9605+ } else if (status < 0) {
9606+ no_fifo_space = 1;
9607+ break;
9608+ }
9609+
9610+ /* Advance to next QH, skipping start-of-list entry. */
9611+ _hcd->non_periodic_qh_ptr = _hcd->non_periodic_qh_ptr->next;
9612+ if (_hcd->non_periodic_qh_ptr == &_hcd->non_periodic_sched_active) {
9613+ _hcd->non_periodic_qh_ptr = _hcd->non_periodic_qh_ptr->next;
9614+ }
9615+
9616+ } while (_hcd->non_periodic_qh_ptr != orig_qh_ptr);
9617+
9618+ if (!_hcd->core_if->dma_enable) {
9619+ gintmsk_data_t intr_mask = {.d32 = 0};
9620+ intr_mask.b.nptxfempty = 1;
9621+
9622+#ifdef DEBUG
9623+ tx_status.d32 = dwc_read_reg32(&global_regs->gnptxsts);
9624+ DWC_DEBUGPL(DBG_HCDV, " NP Tx Req Queue Space Avail (after queue): %d\n",
9625+ tx_status.b.nptxqspcavail);
9626+ DWC_DEBUGPL(DBG_HCDV, " NP Tx FIFO Space Avail (after queue): %d\n",
9627+ tx_status.b.nptxfspcavail);
9628+#endif
9629+ if (more_to_do || no_queue_space || no_fifo_space) {
9630+ /*
9631+ * May need to queue more transactions as the request
9632+ * queue or Tx FIFO empties. Enable the non-periodic
9633+ * Tx FIFO empty interrupt. (Always use the half-empty
9634+ * level to ensure that new requests are loaded as
9635+ * soon as possible.)
9636+ */
9637+ dwc_modify_reg32(&global_regs->gintmsk, 0, intr_mask.d32);
9638+ } else {
9639+ /*
9640+ * Disable the Tx FIFO empty interrupt since there are
9641+ * no more transactions that need to be queued right
9642+ * now. This function is called from interrupt
9643+ * handlers to queue more transactions as transfer
9644+ * states change.
9645+ */
9646+ dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, 0);
9647+ }
9648+ }
9649+}
9650+
9651+/**
9652+ * Processes periodic channels for the next frame and queues transactions for
9653+ * these channels to the DWC_otg controller. After queueing transactions, the
9654+ * Periodic Tx FIFO Empty interrupt is enabled if there are more transactions
9655+ * to queue as Periodic Tx FIFO or request queue space becomes available.
9656+ * Otherwise, the Periodic Tx FIFO Empty interrupt is disabled.
9657+ */
9658+static void process_periodic_channels(dwc_otg_hcd_t *_hcd)
9659+{
9660+ hptxsts_data_t tx_status;
9661+ struct list_head *qh_ptr;
9662+ dwc_otg_qh_t *qh;
9663+ int status;
9664+ int no_queue_space = 0;
9665+ int no_fifo_space = 0;
9666+
9667+ dwc_otg_host_global_regs_t *host_regs;
9668+ host_regs = _hcd->core_if->host_if->host_global_regs;
9669+
9670+ DWC_DEBUGPL(DBG_HCDV, "Queue periodic transactions\n");
9671+#ifdef DEBUG
9672+ tx_status.d32 = dwc_read_reg32(&host_regs->hptxsts);
9673+ DWC_DEBUGPL(DBG_HCDV, " P Tx Req Queue Space Avail (before queue): %d\n",
9674+ tx_status.b.ptxqspcavail);
9675+ DWC_DEBUGPL(DBG_HCDV, " P Tx FIFO Space Avail (before queue): %d\n",
9676+ tx_status.b.ptxfspcavail);
9677+#endif
9678+
9679+ qh_ptr = _hcd->periodic_sched_assigned.next;
9680+ while (qh_ptr != &_hcd->periodic_sched_assigned) {
9681+ tx_status.d32 = dwc_read_reg32(&host_regs->hptxsts);
9682+ if (tx_status.b.ptxqspcavail == 0) {
9683+ no_queue_space = 1;
9684+ break;
9685+ }
9686+
9687+ qh = list_entry(qh_ptr, dwc_otg_qh_t, qh_list_entry);
9688+
9689+ /*
9690+ * Set a flag if we're queuing high-bandwidth in slave mode.
9691+ * The flag prevents any halts to get into the request queue in
9692+ * the middle of multiple high-bandwidth packets getting queued.
9693+ */
9694+ if ((!_hcd->core_if->dma_enable) &&
9695+ (qh->channel->multi_count > 1))
9696+ {
9697+ _hcd->core_if->queuing_high_bandwidth = 1;
9698+ }
9699+
9700+ status = queue_transaction(_hcd, qh->channel, tx_status.b.ptxfspcavail);
9701+ if (status < 0) {
9702+ no_fifo_space = 1;
9703+ break;
9704+ }
9705+
9706+ /*
9707+ * In Slave mode, stay on the current transfer until there is
9708+ * nothing more to do or the high-bandwidth request count is
9709+ * reached. In DMA mode, only need to queue one request. The
9710+ * controller automatically handles multiple packets for
9711+ * high-bandwidth transfers.
9712+ */
9713+ if (_hcd->core_if->dma_enable ||
9714+ (status == 0 ||
9715+ qh->channel->requests == qh->channel->multi_count)) {
9716+ qh_ptr = qh_ptr->next;
9717+ /*
9718+ * Move the QH from the periodic assigned schedule to
9719+ * the periodic queued schedule.
9720+ */
9721+ list_move(&qh->qh_list_entry, &_hcd->periodic_sched_queued);
9722+
9723+ /* done queuing high bandwidth */
9724+ _hcd->core_if->queuing_high_bandwidth = 0;
9725+ }
9726+ }
9727+
9728+ if (!_hcd->core_if->dma_enable) {
9729+ dwc_otg_core_global_regs_t *global_regs;
9730+ gintmsk_data_t intr_mask = {.d32 = 0};
9731+
9732+ global_regs = _hcd->core_if->core_global_regs;
9733+ intr_mask.b.ptxfempty = 1;
9734+#ifdef DEBUG
9735+ tx_status.d32 = dwc_read_reg32(&host_regs->hptxsts);
9736+ DWC_DEBUGPL(DBG_HCDV, " P Tx Req Queue Space Avail (after queue): %d\n",
9737+ tx_status.b.ptxqspcavail);
9738+ DWC_DEBUGPL(DBG_HCDV, " P Tx FIFO Space Avail (after queue): %d\n",
9739+ tx_status.b.ptxfspcavail);
9740+#endif
9741+ if (!(list_empty(&_hcd->periodic_sched_assigned)) ||
9742+ no_queue_space || no_fifo_space) {
9743+ /*
9744+ * May need to queue more transactions as the request
9745+ * queue or Tx FIFO empties. Enable the periodic Tx
9746+ * FIFO empty interrupt. (Always use the half-empty
9747+ * level to ensure that new requests are loaded as
9748+ * soon as possible.)
9749+ */
9750+ dwc_modify_reg32(&global_regs->gintmsk, 0, intr_mask.d32);
9751+ } else {
9752+ /*
9753+ * Disable the Tx FIFO empty interrupt since there are
9754+ * no more transactions that need to be queued right
9755+ * now. This function is called from interrupt
9756+ * handlers to queue more transactions as transfer
9757+ * states change.
9758+ */
9759+ dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, 0);
9760+ }
9761+ }
9762+}
9763+
9764+/**
9765+ * This function processes the currently active host channels and queues
9766+ * transactions for these channels to the DWC_otg controller. It is called
9767+ * from HCD interrupt handler functions.
9768+ *
9769+ * @param _hcd The HCD state structure.
9770+ * @param _tr_type The type(s) of transactions to queue (non-periodic,
9771+ * periodic, or both).
9772+ */
9773+void dwc_otg_hcd_queue_transactions(dwc_otg_hcd_t *_hcd,
9774+ dwc_otg_transaction_type_e _tr_type)
9775+{
9776+#ifdef DEBUG_SOF
9777+ DWC_DEBUGPL(DBG_HCD, "Queue Transactions\n");
9778+#endif
9779+ /* Process host channels associated with periodic transfers. */
9780+ if ((_tr_type == DWC_OTG_TRANSACTION_PERIODIC ||
9781+ _tr_type == DWC_OTG_TRANSACTION_ALL) &&
9782+ !list_empty(&_hcd->periodic_sched_assigned)) {
9783+
9784+ process_periodic_channels(_hcd);
9785+ }
9786+
9787+ /* Process host channels associated with non-periodic transfers. */
9788+ if ((_tr_type == DWC_OTG_TRANSACTION_NON_PERIODIC ||
9789+ _tr_type == DWC_OTG_TRANSACTION_ALL)) {
9790+ if (!list_empty(&_hcd->non_periodic_sched_active)) {
9791+ process_non_periodic_channels(_hcd);
9792+ } else {
9793+ /*
9794+ * Ensure NP Tx FIFO empty interrupt is disabled when
9795+ * there are no non-periodic transfers to process.
9796+ */
9797+ gintmsk_data_t gintmsk = {.d32 = 0};
9798+ gintmsk.b.nptxfempty = 1;
9799+ dwc_modify_reg32(&_hcd->core_if->core_global_regs->gintmsk, gintmsk.d32, 0);
9800+ }
9801+ }
9802+}
9803+
9804+/**
9805+ * Sets the final status of an URB and returns it to the device driver. Any
9806+ * required cleanup of the URB is performed.
9807+ */
9808+void dwc_otg_hcd_complete_urb(dwc_otg_hcd_t * _hcd, struct urb *_urb,
9809+ int _status)
9810+ __releases(_hcd->lock)
9811+__acquires(_hcd->lock)
9812+{
9813+#ifdef DEBUG
9814+ if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
9815+ DWC_PRINT("%s: urb %p, device %d, ep %d %s, status=%d\n",
9816+ __func__, _urb, usb_pipedevice(_urb->pipe),
9817+ usb_pipeendpoint(_urb->pipe),
9818+ usb_pipein(_urb->pipe) ? "IN" : "OUT", _status);
9819+ if (usb_pipetype(_urb->pipe) == PIPE_ISOCHRONOUS) {
9820+ int i;
9821+ for (i = 0; i < _urb->number_of_packets; i++) {
9822+ DWC_PRINT(" ISO Desc %d status: %d\n",
9823+ i, _urb->iso_frame_desc[i].status);
9824+ }
9825+ }
9826+ }
9827+#endif
9828+
9829+ _urb->status = _status;
9830+ _urb->hcpriv = NULL;
9831+ usb_hcd_unlink_urb_from_ep(dwc_otg_hcd_to_hcd(_hcd), _urb);
9832+ spin_unlock(&_hcd->lock);
9833+ usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(_hcd), _urb, _status);
9834+ spin_lock(&_hcd->lock);
9835+}
9836+
9837+/*
9838+ * Returns the Queue Head for an URB.
9839+ */
9840+dwc_otg_qh_t *dwc_urb_to_qh(struct urb *_urb)
9841+{
9842+ struct usb_host_endpoint *ep = dwc_urb_to_endpoint(_urb);
9843+ return (dwc_otg_qh_t *)ep->hcpriv;
9844+}
9845+
9846+#ifdef DEBUG
9847+void dwc_print_setup_data (uint8_t *setup)
9848+{
9849+ int i;
9850+ if (CHK_DEBUG_LEVEL(DBG_HCD)){
9851+ DWC_PRINT("Setup Data = MSB ");
9852+ for (i=7; i>=0; i--) DWC_PRINT ("%02x ", setup[i]);
9853+ DWC_PRINT("\n");
9854+ DWC_PRINT(" bmRequestType Tranfer = %s\n", (setup[0]&0x80) ? "Device-to-Host" : "Host-to-Device");
9855+ DWC_PRINT(" bmRequestType Type = ");
9856+ switch ((setup[0]&0x60) >> 5) {
9857+ case 0: DWC_PRINT("Standard\n"); break;
9858+ case 1: DWC_PRINT("Class\n"); break;
9859+ case 2: DWC_PRINT("Vendor\n"); break;
9860+ case 3: DWC_PRINT("Reserved\n"); break;
9861+ }
9862+ DWC_PRINT(" bmRequestType Recipient = ");
9863+ switch (setup[0]&0x1f) {
9864+ case 0: DWC_PRINT("Device\n"); break;
9865+ case 1: DWC_PRINT("Interface\n"); break;
9866+ case 2: DWC_PRINT("Endpoint\n"); break;
9867+ case 3: DWC_PRINT("Other\n"); break;
9868+ default: DWC_PRINT("Reserved\n"); break;
9869+ }
9870+ DWC_PRINT(" bRequest = 0x%0x\n", setup[1]);
9871+ DWC_PRINT(" wValue = 0x%0x\n", *((uint16_t *)&setup[2]));
9872+ DWC_PRINT(" wIndex = 0x%0x\n", *((uint16_t *)&setup[4]));
9873+ DWC_PRINT(" wLength = 0x%0x\n\n", *((uint16_t *)&setup[6]));
9874+ }
9875+}
9876+#endif
9877+
9878+void dwc_otg_hcd_dump_frrem(dwc_otg_hcd_t *_hcd) {
9879+#ifdef DEBUG
9880+#if 0
9881+ DWC_PRINT("Frame remaining at SOF:\n");
9882+ DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
9883+ _hcd->frrem_samples, _hcd->frrem_accum,
9884+ (_hcd->frrem_samples > 0) ?
9885+ _hcd->frrem_accum/_hcd->frrem_samples : 0);
9886+
9887+ DWC_PRINT("\n");
9888+ DWC_PRINT("Frame remaining at start_transfer (uframe 7):\n");
9889+ DWC_PRINT(" samples %u, accum %u, avg %u\n",
9890+ _hcd->core_if->hfnum_7_samples, _hcd->core_if->hfnum_7_frrem_accum,
9891+ (_hcd->core_if->hfnum_7_samples > 0) ?
9892+ _hcd->core_if->hfnum_7_frrem_accum/_hcd->core_if->hfnum_7_samples : 0);
9893+ DWC_PRINT("Frame remaining at start_transfer (uframe 0):\n");
9894+ DWC_PRINT(" samples %u, accum %u, avg %u\n",
9895+ _hcd->core_if->hfnum_0_samples, _hcd->core_if->hfnum_0_frrem_accum,
9896+ (_hcd->core_if->hfnum_0_samples > 0) ?
9897+ _hcd->core_if->hfnum_0_frrem_accum/_hcd->core_if->hfnum_0_samples : 0);
9898+ DWC_PRINT("Frame remaining at start_transfer (uframe 1-6):\n");
9899+ DWC_PRINT(" samples %u, accum %u, avg %u\n",
9900+ _hcd->core_if->hfnum_other_samples, _hcd->core_if->hfnum_other_frrem_accum,
9901+ (_hcd->core_if->hfnum_other_samples > 0) ?
9902+ _hcd->core_if->hfnum_other_frrem_accum/_hcd->core_if->hfnum_other_samples : 0);
9903+
9904+ DWC_PRINT("\n");
9905+ DWC_PRINT("Frame remaining at sample point A (uframe 7):\n");
9906+ DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
9907+ _hcd->hfnum_7_samples_a, _hcd->hfnum_7_frrem_accum_a,
9908+ (_hcd->hfnum_7_samples_a > 0) ?
9909+ _hcd->hfnum_7_frrem_accum_a/_hcd->hfnum_7_samples_a : 0);
9910+ DWC_PRINT("Frame remaining at sample point A (uframe 0):\n");
9911+ DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
9912+ _hcd->hfnum_0_samples_a, _hcd->hfnum_0_frrem_accum_a,
9913+ (_hcd->hfnum_0_samples_a > 0) ?
9914+ _hcd->hfnum_0_frrem_accum_a/_hcd->hfnum_0_samples_a : 0);
9915+ DWC_PRINT("Frame remaining at sample point A (uframe 1-6):\n");
9916+ DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
9917+ _hcd->hfnum_other_samples_a, _hcd->hfnum_other_frrem_accum_a,
9918+ (_hcd->hfnum_other_samples_a > 0) ?
9919+ _hcd->hfnum_other_frrem_accum_a/_hcd->hfnum_other_samples_a : 0);
9920+
9921+ DWC_PRINT("\n");
9922+ DWC_PRINT("Frame remaining at sample point B (uframe 7):\n");
9923+ DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
9924+ _hcd->hfnum_7_samples_b, _hcd->hfnum_7_frrem_accum_b,
9925+ (_hcd->hfnum_7_samples_b > 0) ?
9926+ _hcd->hfnum_7_frrem_accum_b/_hcd->hfnum_7_samples_b : 0);
9927+ DWC_PRINT("Frame remaining at sample point B (uframe 0):\n");
9928+ DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
9929+ _hcd->hfnum_0_samples_b, _hcd->hfnum_0_frrem_accum_b,
9930+ (_hcd->hfnum_0_samples_b > 0) ?
9931+ _hcd->hfnum_0_frrem_accum_b/_hcd->hfnum_0_samples_b : 0);
9932+ DWC_PRINT("Frame remaining at sample point B (uframe 1-6):\n");
9933+ DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
9934+ _hcd->hfnum_other_samples_b, _hcd->hfnum_other_frrem_accum_b,
9935+ (_hcd->hfnum_other_samples_b > 0) ?
9936+ _hcd->hfnum_other_frrem_accum_b/_hcd->hfnum_other_samples_b : 0);
9937+#endif
9938+#endif
9939+}
9940+
9941+void dwc_otg_hcd_dump_state(dwc_otg_hcd_t *_hcd)
9942+{
9943+#ifdef DEBUG
9944+ int num_channels;
9945+ int i;
9946+ gnptxsts_data_t np_tx_status;
9947+ hptxsts_data_t p_tx_status;
9948+
9949+ num_channels = _hcd->core_if->core_params->host_channels;
9950+ DWC_PRINT("\n");
9951+ DWC_PRINT("************************************************************\n");
9952+ DWC_PRINT("HCD State:\n");
9953+ DWC_PRINT(" Num channels: %d\n", num_channels);
9954+ for (i = 0; i < num_channels; i++) {
9955+ dwc_hc_t *hc = _hcd->hc_ptr_array[i];
9956+ DWC_PRINT(" Channel %d:\n", i);
9957+ DWC_PRINT(" dev_addr: %d, ep_num: %d, ep_is_in: %d\n",
9958+ hc->dev_addr, hc->ep_num, hc->ep_is_in);
9959+ DWC_PRINT(" speed: %d\n", hc->speed);
9960+ DWC_PRINT(" ep_type: %d\n", hc->ep_type);
9961+ DWC_PRINT(" max_packet: %d\n", hc->max_packet);
9962+ DWC_PRINT(" data_pid_start: %d\n", hc->data_pid_start);
9963+ DWC_PRINT(" multi_count: %d\n", hc->multi_count);
9964+ DWC_PRINT(" xfer_started: %d\n", hc->xfer_started);
9965+ DWC_PRINT(" xfer_buff: %p\n", hc->xfer_buff);
9966+ DWC_PRINT(" xfer_len: %d\n", hc->xfer_len);
9967+ DWC_PRINT(" xfer_count: %d\n", hc->xfer_count);
9968+ DWC_PRINT(" halt_on_queue: %d\n", hc->halt_on_queue);
9969+ DWC_PRINT(" halt_pending: %d\n", hc->halt_pending);
9970+ DWC_PRINT(" halt_status: %d\n", hc->halt_status);
9971+ DWC_PRINT(" do_split: %d\n", hc->do_split);
9972+ DWC_PRINT(" complete_split: %d\n", hc->complete_split);
9973+ DWC_PRINT(" hub_addr: %d\n", hc->hub_addr);
9974+ DWC_PRINT(" port_addr: %d\n", hc->port_addr);
9975+ DWC_PRINT(" xact_pos: %d\n", hc->xact_pos);
9976+ DWC_PRINT(" requests: %d\n", hc->requests);
9977+ DWC_PRINT(" qh: %p\n", hc->qh);
9978+ if (hc->xfer_started) {
9979+ hfnum_data_t hfnum;
9980+ hcchar_data_t hcchar;
9981+ hctsiz_data_t hctsiz;
9982+ hcint_data_t hcint;
9983+ hcintmsk_data_t hcintmsk;
9984+ hfnum.d32 = dwc_read_reg32(&_hcd->core_if->host_if->host_global_regs->hfnum);
9985+ hcchar.d32 = dwc_read_reg32(&_hcd->core_if->host_if->hc_regs[i]->hcchar);
9986+ hctsiz.d32 = dwc_read_reg32(&_hcd->core_if->host_if->hc_regs[i]->hctsiz);
9987+ hcint.d32 = dwc_read_reg32(&_hcd->core_if->host_if->hc_regs[i]->hcint);
9988+ hcintmsk.d32 = dwc_read_reg32(&_hcd->core_if->host_if->hc_regs[i]->hcintmsk);
9989+ DWC_PRINT(" hfnum: 0x%08x\n", hfnum.d32);
9990+ DWC_PRINT(" hcchar: 0x%08x\n", hcchar.d32);
9991+ DWC_PRINT(" hctsiz: 0x%08x\n", hctsiz.d32);
9992+ DWC_PRINT(" hcint: 0x%08x\n", hcint.d32);
9993+ DWC_PRINT(" hcintmsk: 0x%08x\n", hcintmsk.d32);
9994+ }
9995+ if (hc->xfer_started && (hc->qh != NULL) && (hc->qh->qtd_in_process != NULL)) {
9996+ dwc_otg_qtd_t *qtd;
9997+ struct urb *urb;
9998+ qtd = hc->qh->qtd_in_process;
9999+ urb = qtd->urb;
10000+ DWC_PRINT(" URB Info:\n");
10001+ DWC_PRINT(" qtd: %p, urb: %p\n", qtd, urb);
10002+ if (urb != NULL) {
10003+ DWC_PRINT(" Dev: %d, EP: %d %s\n",
10004+ usb_pipedevice(urb->pipe), usb_pipeendpoint(urb->pipe),
10005+ usb_pipein(urb->pipe) ? "IN" : "OUT");
10006+ DWC_PRINT(" Max packet size: %d\n",
10007+ usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)));
10008+ DWC_PRINT(" transfer_buffer: %p\n", urb->transfer_buffer);
10009+ DWC_PRINT(" transfer_dma: %p\n", (void *)urb->transfer_dma);
10010+ DWC_PRINT(" transfer_buffer_length: %d\n", urb->transfer_buffer_length);
10011+ DWC_PRINT(" actual_length: %d\n", urb->actual_length);
10012+ }
10013+ }
10014+ }
10015+ //DWC_PRINT(" non_periodic_channels: %d\n", _hcd->non_periodic_channels);
10016+ //DWC_PRINT(" periodic_channels: %d\n", _hcd->periodic_channels);
10017+ DWC_PRINT(" available_channels: %d\n", _hcd->available_host_channels);
10018+ DWC_PRINT(" periodic_usecs: %d\n", _hcd->periodic_usecs);
10019+ np_tx_status.d32 = dwc_read_reg32(&_hcd->core_if->core_global_regs->gnptxsts);
10020+ DWC_PRINT(" NP Tx Req Queue Space Avail: %d\n", np_tx_status.b.nptxqspcavail);
10021+ DWC_PRINT(" NP Tx FIFO Space Avail: %d\n", np_tx_status.b.nptxfspcavail);
10022+ p_tx_status.d32 = dwc_read_reg32(&_hcd->core_if->host_if->host_global_regs->hptxsts);
10023+ DWC_PRINT(" P Tx Req Queue Space Avail: %d\n", p_tx_status.b.ptxqspcavail);
10024+ DWC_PRINT(" P Tx FIFO Space Avail: %d\n", p_tx_status.b.ptxfspcavail);
10025+ dwc_otg_hcd_dump_frrem(_hcd);
10026+ dwc_otg_dump_global_registers(_hcd->core_if);
10027+ dwc_otg_dump_host_registers(_hcd->core_if);
10028+ DWC_PRINT("************************************************************\n");
10029+ DWC_PRINT("\n");
10030+#endif
10031+}
10032+#endif /* DWC_DEVICE_ONLY */
10033diff --git a/drivers/usb/dwc_otg/dwc_otg_hcd.h b/drivers/usb/dwc_otg/dwc_otg_hcd.h
10034new file mode 100644
10035index 0000000..8a20dff
10036--- /dev/null
10037+++ b/drivers/usb/dwc_otg/dwc_otg_hcd.h
10038@@ -0,0 +1,676 @@
10039+/* ==========================================================================
10040+ * $File: //dwh/usb_iip/dev/software/otg_ipmate/linux/drivers/dwc_otg_hcd.h $
10041+ * $Revision: 1.1.1.1 $
10042+ * $Date: 2009-04-17 06:15:34 $
10043+ * $Change: 537387 $
10044+ *
10045+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
10046+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
10047+ * otherwise expressly agreed to in writing between Synopsys and you.
10048+ *
10049+ * The Software IS NOT an item of Licensed Software or Licensed Product under
10050+ * any End User Software License Agreement or Agreement for Licensed Product
10051+ * with Synopsys or any supplement thereto. You are permitted to use and
10052+ * redistribute this Software in source and binary forms, with or without
10053+ * modification, provided that redistributions of source code must retain this
10054+ * notice. You may not view, use, disclose, copy or distribute this file or
10055+ * any information contained herein except pursuant to this license grant from
10056+ * Synopsys. If you do not agree with this notice, including the disclaimer
10057+ * below, then you are not authorized to use the Software.
10058+ *
10059+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
10060+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
10061+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
10062+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
10063+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
10064+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
10065+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
10066+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
10067+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
10068+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
10069+ * DAMAGE.
10070+ * ========================================================================== */
10071+#ifndef DWC_DEVICE_ONLY
10072+#if !defined(__DWC_HCD_H__)
10073+#define __DWC_HCD_H__
10074+
10075+#include <linux/list.h>
10076+#include <linux/usb.h>
10077+#include <linux/usb/hcd.h>
10078+
10079+struct lm_device;
10080+struct dwc_otg_device;
10081+
10082+#include "dwc_otg_cil.h"
10083+//#include "dwc_otg_ifx.h" // winder
10084+
10085+
10086+/**
10087+ * @file
10088+ *
10089+ * This file contains the structures, constants, and interfaces for
10090+ * the Host Contoller Driver (HCD).
10091+ *
10092+ * The Host Controller Driver (HCD) is responsible for translating requests
10093+ * from the USB Driver into the appropriate actions on the DWC_otg controller.
10094+ * It isolates the USBD from the specifics of the controller by providing an
10095+ * API to the USBD.
10096+ */
10097+
10098+/**
10099+ * Phases for control transfers.
10100+ */
10101+typedef enum dwc_otg_control_phase {
10102+ DWC_OTG_CONTROL_SETUP,
10103+ DWC_OTG_CONTROL_DATA,
10104+ DWC_OTG_CONTROL_STATUS
10105+} dwc_otg_control_phase_e;
10106+
10107+/** Transaction types. */
10108+typedef enum dwc_otg_transaction_type {
10109+ DWC_OTG_TRANSACTION_NONE,
10110+ DWC_OTG_TRANSACTION_PERIODIC,
10111+ DWC_OTG_TRANSACTION_NON_PERIODIC,
10112+ DWC_OTG_TRANSACTION_ALL
10113+} dwc_otg_transaction_type_e;
10114+
10115+/**
10116+ * A Queue Transfer Descriptor (QTD) holds the state of a bulk, control,
10117+ * interrupt, or isochronous transfer. A single QTD is created for each URB
10118+ * (of one of these types) submitted to the HCD. The transfer associated with
10119+ * a QTD may require one or multiple transactions.
10120+ *
10121+ * A QTD is linked to a Queue Head, which is entered in either the
10122+ * non-periodic or periodic schedule for execution. When a QTD is chosen for
10123+ * execution, some or all of its transactions may be executed. After
10124+ * execution, the state of the QTD is updated. The QTD may be retired if all
10125+ * its transactions are complete or if an error occurred. Otherwise, it
10126+ * remains in the schedule so more transactions can be executed later.
10127+ */
10128+struct dwc_otg_qh;
10129+typedef struct dwc_otg_qtd {
10130+ /**
10131+ * Determines the PID of the next data packet for the data phase of
10132+ * control transfers. Ignored for other transfer types.<br>
10133+ * One of the following values:
10134+ * - DWC_OTG_HC_PID_DATA0
10135+ * - DWC_OTG_HC_PID_DATA1
10136+ */
10137+ uint8_t data_toggle;
10138+
10139+ /** Current phase for control transfers (Setup, Data, or Status). */
10140+ dwc_otg_control_phase_e control_phase;
10141+
10142+ /** Keep track of the current split type
10143+ * for FS/LS endpoints on a HS Hub */
10144+ uint8_t complete_split;
10145+
10146+ /** How many bytes transferred during SSPLIT OUT */
10147+ uint32_t ssplit_out_xfer_count;
10148+
10149+ /**
10150+ * Holds the number of bus errors that have occurred for a transaction
10151+ * within this transfer.
10152+ */
10153+ uint8_t error_count;
10154+
10155+ /**
10156+ * Index of the next frame descriptor for an isochronous transfer. A
10157+ * frame descriptor describes the buffer position and length of the
10158+ * data to be transferred in the next scheduled (micro)frame of an
10159+ * isochronous transfer. It also holds status for that transaction.
10160+ * The frame index starts at 0.
10161+ */
10162+ int isoc_frame_index;
10163+
10164+ /** Position of the ISOC split on full/low speed */
10165+ uint8_t isoc_split_pos;
10166+
10167+ /** Position of the ISOC split in the buffer for the current frame */
10168+ uint16_t isoc_split_offset;
10169+
10170+ /** URB for this transfer */
10171+ struct urb *urb;
10172+
10173+ /** This list of QTDs */
10174+ struct list_head qtd_list_entry;
10175+
10176+ /* Field to track the qh pointer */
10177+ struct dwc_otg_qh *qtd_qh_ptr;
10178+} dwc_otg_qtd_t;
10179+
10180+/**
10181+ * A Queue Head (QH) holds the static characteristics of an endpoint and
10182+ * maintains a list of transfers (QTDs) for that endpoint. A QH structure may
10183+ * be entered in either the non-periodic or periodic schedule.
10184+ */
10185+typedef struct dwc_otg_qh {
10186+ /**
10187+ * Endpoint type.
10188+ * One of the following values:
10189+ * - USB_ENDPOINT_XFER_CONTROL
10190+ * - USB_ENDPOINT_XFER_ISOC
10191+ * - USB_ENDPOINT_XFER_BULK
10192+ * - USB_ENDPOINT_XFER_INT
10193+ */
10194+ uint8_t ep_type;
10195+ uint8_t ep_is_in;
10196+
10197+ /** wMaxPacketSize Field of Endpoint Descriptor. */
10198+ uint16_t maxp;
10199+
10200+ /**
10201+ * Determines the PID of the next data packet for non-control
10202+ * transfers. Ignored for control transfers.<br>
10203+ * One of the following values:
10204+ * - DWC_OTG_HC_PID_DATA0
10205+ * - DWC_OTG_HC_PID_DATA1
10206+ */
10207+ uint8_t data_toggle;
10208+
10209+ /** Ping state if 1. */
10210+ uint8_t ping_state;
10211+
10212+ /**
10213+ * List of QTDs for this QH.
10214+ */
10215+ struct list_head qtd_list;
10216+
10217+ /** Host channel currently processing transfers for this QH. */
10218+ dwc_hc_t *channel;
10219+
10220+ /** QTD currently assigned to a host channel for this QH. */
10221+ dwc_otg_qtd_t *qtd_in_process;
10222+
10223+ /** Full/low speed endpoint on high-speed hub requires split. */
10224+ uint8_t do_split;
10225+
10226+ /** @name Periodic schedule information */
10227+ /** @{ */
10228+
10229+ /** Bandwidth in microseconds per (micro)frame. */
10230+ uint8_t usecs;
10231+
10232+ /** Interval between transfers in (micro)frames. */
10233+ uint16_t interval;
10234+
10235+ /**
10236+ * (micro)frame to initialize a periodic transfer. The transfer
10237+ * executes in the following (micro)frame.
10238+ */
10239+ uint16_t sched_frame;
10240+
10241+ /** (micro)frame at which last start split was initialized. */
10242+ uint16_t start_split_frame;
10243+
10244+ /** @} */
10245+
10246+ uint16_t speed;
10247+ uint16_t frame_usecs[8];
10248+ /** Entry for QH in either the periodic or non-periodic schedule. */
10249+ struct list_head qh_list_entry;
10250+} dwc_otg_qh_t;
10251+
10252+/**
10253+ * This structure holds the state of the HCD, including the non-periodic and
10254+ * periodic schedules.
10255+ */
10256+typedef struct dwc_otg_hcd {
10257+ spinlock_t lock;
10258+
10259+ /** DWC OTG Core Interface Layer */
10260+ dwc_otg_core_if_t *core_if;
10261+
10262+ /** Internal DWC HCD Flags */
10263+ volatile union dwc_otg_hcd_internal_flags {
10264+ uint32_t d32;
10265+ struct {
10266+ unsigned port_connect_status_change : 1;
10267+ unsigned port_connect_status : 1;
10268+ unsigned port_reset_change : 1;
10269+ unsigned port_enable_change : 1;
10270+ unsigned port_suspend_change : 1;
10271+ unsigned port_over_current_change : 1;
10272+ unsigned reserved : 27;
10273+ } b;
10274+ } flags;
10275+
10276+ /**
10277+ * Inactive items in the non-periodic schedule. This is a list of
10278+ * Queue Heads. Transfers associated with these Queue Heads are not
10279+ * currently assigned to a host channel.
10280+ */
10281+ struct list_head non_periodic_sched_inactive;
10282+
10283+ /**
10284+ * Deferred items in the non-periodic schedule. This is a list of
10285+ * Queue Heads. Transfers associated with these Queue Heads are not
10286+ * currently assigned to a host channel.
10287+ * When we get an NAK, the QH goes here.
10288+ */
10289+ struct list_head non_periodic_sched_deferred;
10290+
10291+ /**
10292+ * Active items in the non-periodic schedule. This is a list of
10293+ * Queue Heads. Transfers associated with these Queue Heads are
10294+ * currently assigned to a host channel.
10295+ */
10296+ struct list_head non_periodic_sched_active;
10297+
10298+ /**
10299+ * Pointer to the next Queue Head to process in the active
10300+ * non-periodic schedule.
10301+ */
10302+ struct list_head *non_periodic_qh_ptr;
10303+
10304+ /**
10305+ * Inactive items in the periodic schedule. This is a list of QHs for
10306+ * periodic transfers that are _not_ scheduled for the next frame.
10307+ * Each QH in the list has an interval counter that determines when it
10308+ * needs to be scheduled for execution. This scheduling mechanism
10309+ * allows only a simple calculation for periodic bandwidth used (i.e.
10310+ * must assume that all periodic transfers may need to execute in the
10311+ * same frame). However, it greatly simplifies scheduling and should
10312+ * be sufficient for the vast majority of OTG hosts, which need to
10313+ * connect to a small number of peripherals at one time.
10314+ *
10315+ * Items move from this list to periodic_sched_ready when the QH
10316+ * interval counter is 0 at SOF.
10317+ */
10318+ struct list_head periodic_sched_inactive;
10319+
10320+ /**
10321+ * List of periodic QHs that are ready for execution in the next
10322+ * frame, but have not yet been assigned to host channels.
10323+ *
10324+ * Items move from this list to periodic_sched_assigned as host
10325+ * channels become available during the current frame.
10326+ */
10327+ struct list_head periodic_sched_ready;
10328+
10329+ /**
10330+ * List of periodic QHs to be executed in the next frame that are
10331+ * assigned to host channels.
10332+ *
10333+ * Items move from this list to periodic_sched_queued as the
10334+ * transactions for the QH are queued to the DWC_otg controller.
10335+ */
10336+ struct list_head periodic_sched_assigned;
10337+
10338+ /**
10339+ * List of periodic QHs that have been queued for execution.
10340+ *
10341+ * Items move from this list to either periodic_sched_inactive or
10342+ * periodic_sched_ready when the channel associated with the transfer
10343+ * is released. If the interval for the QH is 1, the item moves to
10344+ * periodic_sched_ready because it must be rescheduled for the next
10345+ * frame. Otherwise, the item moves to periodic_sched_inactive.
10346+ */
10347+ struct list_head periodic_sched_queued;
10348+
10349+ /**
10350+ * Total bandwidth claimed so far for periodic transfers. This value
10351+ * is in microseconds per (micro)frame. The assumption is that all
10352+ * periodic transfers may occur in the same (micro)frame.
10353+ */
10354+ uint16_t periodic_usecs;
10355+
10356+ /**
10357+ * Total bandwidth claimed so far for all periodic transfers
10358+ * in a frame.
10359+ * This will include a mixture of HS and FS transfers.
10360+ * Units are microseconds per (micro)frame.
10361+ * We have a budget per frame and have to schedule
10362+ * transactions accordingly.
10363+ * Watch out for the fact that things are actually scheduled for the
10364+ * "next frame".
10365+ */
10366+ uint16_t frame_usecs[8];
10367+
10368+ /**
10369+ * Frame number read from the core at SOF. The value ranges from 0 to
10370+ * DWC_HFNUM_MAX_FRNUM.
10371+ */
10372+ uint16_t frame_number;
10373+
10374+ /**
10375+ * Free host channels in the controller. This is a list of
10376+ * dwc_hc_t items.
10377+ */
10378+ struct list_head free_hc_list;
10379+
10380+ /**
10381+ * Number of available host channels.
10382+ */
10383+ int available_host_channels;
10384+
10385+ /**
10386+ * Array of pointers to the host channel descriptors. Allows accessing
10387+ * a host channel descriptor given the host channel number. This is
10388+ * useful in interrupt handlers.
10389+ */
10390+ dwc_hc_t *hc_ptr_array[MAX_EPS_CHANNELS];
10391+
10392+ /**
10393+ * Buffer to use for any data received during the status phase of a
10394+ * control transfer. Normally no data is transferred during the status
10395+ * phase. This buffer is used as a bit bucket.
10396+ */
10397+ uint8_t *status_buf;
10398+
10399+ /**
10400+ * DMA address for status_buf.
10401+ */
10402+ dma_addr_t status_buf_dma;
10403+#define DWC_OTG_HCD_STATUS_BUF_SIZE 64
10404+
10405+ /**
10406+ * Structure to allow starting the HCD in a non-interrupt context
10407+ * during an OTG role change.
10408+ */
10409+ struct work_struct start_work;
10410+ struct usb_hcd *_p;
10411+
10412+ /**
10413+ * Connection timer. An OTG host must display a message if the device
10414+ * does not connect. Started when the VBus power is turned on via
10415+ * sysfs attribute "buspower".
10416+ */
10417+ struct timer_list conn_timer;
10418+
10419+ /* Tasket to do a reset */
10420+ struct tasklet_struct *reset_tasklet;
10421+
10422+#ifdef DEBUG
10423+ uint32_t frrem_samples;
10424+ uint64_t frrem_accum;
10425+
10426+ uint32_t hfnum_7_samples_a;
10427+ uint64_t hfnum_7_frrem_accum_a;
10428+ uint32_t hfnum_0_samples_a;
10429+ uint64_t hfnum_0_frrem_accum_a;
10430+ uint32_t hfnum_other_samples_a;
10431+ uint64_t hfnum_other_frrem_accum_a;
10432+
10433+ uint32_t hfnum_7_samples_b;
10434+ uint64_t hfnum_7_frrem_accum_b;
10435+ uint32_t hfnum_0_samples_b;
10436+ uint64_t hfnum_0_frrem_accum_b;
10437+ uint32_t hfnum_other_samples_b;
10438+ uint64_t hfnum_other_frrem_accum_b;
10439+#endif
10440+
10441+} dwc_otg_hcd_t;
10442+
10443+/** Gets the dwc_otg_hcd from a struct usb_hcd */
10444+static inline dwc_otg_hcd_t *hcd_to_dwc_otg_hcd(struct usb_hcd *hcd)
10445+{
10446+ return (dwc_otg_hcd_t *)(hcd->hcd_priv);
10447+}
10448+
10449+/** Gets the struct usb_hcd that contains a dwc_otg_hcd_t. */
10450+static inline struct usb_hcd *dwc_otg_hcd_to_hcd(dwc_otg_hcd_t *dwc_otg_hcd)
10451+{
10452+ return container_of((void *)dwc_otg_hcd, struct usb_hcd, hcd_priv);
10453+}
10454+
10455+/** @name HCD Create/Destroy Functions */
10456+/** @{ */
10457+extern int __devinit dwc_otg_hcd_init(struct device *_dev, dwc_otg_device_t * dwc_otg_device);
10458+extern void dwc_otg_hcd_remove(struct device *_dev);
10459+/** @} */
10460+
10461+/** @name Linux HC Driver API Functions */
10462+/** @{ */
10463+
10464+extern int dwc_otg_hcd_start(struct usb_hcd *hcd);
10465+extern void dwc_otg_hcd_stop(struct usb_hcd *hcd);
10466+extern int dwc_otg_hcd_get_frame_number(struct usb_hcd *hcd);
10467+extern void dwc_otg_hcd_free(struct usb_hcd *hcd);
10468+
10469+extern int dwc_otg_hcd_urb_enqueue(struct usb_hcd *hcd,
10470+ struct urb *urb,
10471+ gfp_t mem_flags);
10472+extern int dwc_otg_hcd_urb_dequeue(struct usb_hcd *hcd,
10473+ struct urb *urb,
10474+ int status);
10475+extern irqreturn_t dwc_otg_hcd_irq(struct usb_hcd *hcd);
10476+
10477+extern void dwc_otg_hcd_endpoint_disable(struct usb_hcd *hcd,
10478+ struct usb_host_endpoint *ep);
10479+
10480+extern int dwc_otg_hcd_hub_status_data(struct usb_hcd *hcd,
10481+ char *buf);
10482+extern int dwc_otg_hcd_hub_control(struct usb_hcd *hcd,
10483+ u16 typeReq,
10484+ u16 wValue,
10485+ u16 wIndex,
10486+ char *buf,
10487+ u16 wLength);
10488+
10489+/** @} */
10490+
10491+/** @name Transaction Execution Functions */
10492+/** @{ */
10493+extern dwc_otg_transaction_type_e dwc_otg_hcd_select_transactions(dwc_otg_hcd_t *_hcd);
10494+extern void dwc_otg_hcd_queue_transactions(dwc_otg_hcd_t *_hcd,
10495+ dwc_otg_transaction_type_e _tr_type);
10496+extern void dwc_otg_hcd_complete_urb(dwc_otg_hcd_t *_hcd, struct urb *_urb,
10497+ int _status);
10498+/** @} */
10499+
10500+/** @name Interrupt Handler Functions */
10501+/** @{ */
10502+extern int32_t dwc_otg_hcd_handle_intr (dwc_otg_hcd_t *_dwc_otg_hcd);
10503+extern int32_t dwc_otg_hcd_handle_sof_intr (dwc_otg_hcd_t *_dwc_otg_hcd);
10504+extern int32_t dwc_otg_hcd_handle_rx_status_q_level_intr (dwc_otg_hcd_t *_dwc_otg_hcd);
10505+extern int32_t dwc_otg_hcd_handle_np_tx_fifo_empty_intr (dwc_otg_hcd_t *_dwc_otg_hcd);
10506+extern int32_t dwc_otg_hcd_handle_perio_tx_fifo_empty_intr (dwc_otg_hcd_t *_dwc_otg_hcd);
10507+extern int32_t dwc_otg_hcd_handle_incomplete_periodic_intr(dwc_otg_hcd_t *_dwc_otg_hcd);
10508+extern int32_t dwc_otg_hcd_handle_port_intr (dwc_otg_hcd_t *_dwc_otg_hcd);
10509+extern int32_t dwc_otg_hcd_handle_conn_id_status_change_intr (dwc_otg_hcd_t *_dwc_otg_hcd);
10510+extern int32_t dwc_otg_hcd_handle_disconnect_intr (dwc_otg_hcd_t *_dwc_otg_hcd);
10511+extern int32_t dwc_otg_hcd_handle_hc_intr (dwc_otg_hcd_t *_dwc_otg_hcd);
10512+extern int32_t dwc_otg_hcd_handle_hc_n_intr (dwc_otg_hcd_t *_dwc_otg_hcd, uint32_t _num);
10513+extern int32_t dwc_otg_hcd_handle_session_req_intr (dwc_otg_hcd_t *_dwc_otg_hcd);
10514+extern int32_t dwc_otg_hcd_handle_wakeup_detected_intr (dwc_otg_hcd_t *_dwc_otg_hcd);
10515+/** @} */
10516+
10517+
10518+/** @name Schedule Queue Functions */
10519+/** @{ */
10520+
10521+/* Implemented in dwc_otg_hcd_queue.c */
10522+extern dwc_otg_qh_t *dwc_otg_hcd_qh_create (dwc_otg_hcd_t *_hcd, struct urb *_urb);
10523+extern void dwc_otg_hcd_qh_init (dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh, struct urb *_urb);
10524+extern void dwc_otg_hcd_qh_free (dwc_otg_qh_t *_qh);
10525+extern int dwc_otg_hcd_qh_add (dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh);
10526+extern void dwc_otg_hcd_qh_remove (dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh);
10527+extern void dwc_otg_hcd_qh_deactivate (dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh, int sched_csplit);
10528+extern int dwc_otg_hcd_qh_deferr (dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh, int delay);
10529+
10530+/** Remove and free a QH */
10531+static inline void dwc_otg_hcd_qh_remove_and_free (dwc_otg_hcd_t *_hcd,
10532+ dwc_otg_qh_t *_qh)
10533+{
10534+ dwc_otg_hcd_qh_remove (_hcd, _qh);
10535+ dwc_otg_hcd_qh_free (_qh);
10536+}
10537+
10538+/** Allocates memory for a QH structure.
10539+ * @return Returns the memory allocate or NULL on error. */
10540+static inline dwc_otg_qh_t *dwc_otg_hcd_qh_alloc (void)
10541+{
10542+#ifdef _SC_BUILD_
10543+ return (dwc_otg_qh_t *) kmalloc (sizeof(dwc_otg_qh_t), GFP_ATOMIC);
10544+#else
10545+ return (dwc_otg_qh_t *) kmalloc (sizeof(dwc_otg_qh_t), GFP_KERNEL);
10546+#endif
10547+}
10548+
10549+extern dwc_otg_qtd_t *dwc_otg_hcd_qtd_create (struct urb *urb);
10550+extern void dwc_otg_hcd_qtd_init (dwc_otg_qtd_t *qtd, struct urb *urb);
10551+extern int dwc_otg_hcd_qtd_add (dwc_otg_qtd_t *qtd, dwc_otg_hcd_t *dwc_otg_hcd);
10552+
10553+/** Allocates memory for a QTD structure.
10554+ * @return Returns the memory allocate or NULL on error. */
10555+static inline dwc_otg_qtd_t *dwc_otg_hcd_qtd_alloc (void)
10556+{
10557+#ifdef _SC_BUILD_
10558+ return (dwc_otg_qtd_t *) kmalloc (sizeof(dwc_otg_qtd_t), GFP_ATOMIC);
10559+#else
10560+ return (dwc_otg_qtd_t *) kmalloc (sizeof(dwc_otg_qtd_t), GFP_KERNEL);
10561+#endif
10562+}
10563+
10564+/** Frees the memory for a QTD structure. QTD should already be removed from
10565+ * list.
10566+ * @param[in] _qtd QTD to free.*/
10567+static inline void dwc_otg_hcd_qtd_free (dwc_otg_qtd_t *_qtd)
10568+{
10569+ kfree (_qtd);
10570+}
10571+
10572+/** Removes a QTD from list.
10573+ * @param[in] _qtd QTD to remove from list. */
10574+static inline void dwc_otg_hcd_qtd_remove (dwc_otg_qtd_t *_qtd)
10575+{
10576+ unsigned long flags;
10577+ local_irq_save (flags);
10578+ list_del (&_qtd->qtd_list_entry);
10579+ local_irq_restore (flags);
10580+}
10581+
10582+/** Remove and free a QTD */
10583+static inline void dwc_otg_hcd_qtd_remove_and_free (dwc_otg_qtd_t *_qtd)
10584+{
10585+ dwc_otg_hcd_qtd_remove (_qtd);
10586+ dwc_otg_hcd_qtd_free (_qtd);
10587+}
10588+
10589+/** @} */
10590+
10591+
10592+/** @name Internal Functions */
10593+/** @{ */
10594+dwc_otg_qh_t *dwc_urb_to_qh(struct urb *_urb);
10595+void dwc_otg_hcd_dump_frrem(dwc_otg_hcd_t *_hcd);
10596+void dwc_otg_hcd_dump_state(dwc_otg_hcd_t *_hcd);
10597+/** @} */
10598+
10599+
10600+/** Gets the usb_host_endpoint associated with an URB. */
10601+static inline struct usb_host_endpoint *dwc_urb_to_endpoint(struct urb *_urb)
10602+{
10603+ struct usb_device *dev = _urb->dev;
10604+ int ep_num = usb_pipeendpoint(_urb->pipe);
10605+ if (usb_pipein(_urb->pipe))
10606+ return dev->ep_in[ep_num];
10607+ else
10608+ return dev->ep_out[ep_num];
10609+}
10610+
10611+/**
10612+ * Gets the endpoint number from a _bEndpointAddress argument. The endpoint is
10613+ * qualified with its direction (possible 32 endpoints per device).
10614+ */
10615+#define dwc_ep_addr_to_endpoint(_bEndpointAddress_) \
10616+ ((_bEndpointAddress_ & USB_ENDPOINT_NUMBER_MASK) | \
10617+ ((_bEndpointAddress_ & USB_DIR_IN) != 0) << 4)
10618+
10619+/** Gets the QH that contains the list_head */
10620+#define dwc_list_to_qh(_list_head_ptr_) (container_of(_list_head_ptr_,dwc_otg_qh_t,qh_list_entry))
10621+
10622+/** Gets the QTD that contains the list_head */
10623+#define dwc_list_to_qtd(_list_head_ptr_) (container_of(_list_head_ptr_,dwc_otg_qtd_t,qtd_list_entry))
10624+
10625+/** Check if QH is non-periodic */
10626+#define dwc_qh_is_non_per(_qh_ptr_) ((_qh_ptr_->ep_type == USB_ENDPOINT_XFER_BULK) || \
10627+ (_qh_ptr_->ep_type == USB_ENDPOINT_XFER_CONTROL))
10628+
10629+/** High bandwidth multiplier as encoded in highspeed endpoint descriptors */
10630+#define dwc_hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
10631+
10632+/** Packet size for any kind of endpoint descriptor */
10633+#define dwc_max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff)
10634+
10635+/**
10636+ * Returns true if _frame1 is less than or equal to _frame2. The comparison is
10637+ * done modulo DWC_HFNUM_MAX_FRNUM. This accounts for the rollover of the
10638+ * frame number when the max frame number is reached.
10639+ */
10640+static inline int dwc_frame_num_le(uint16_t _frame1, uint16_t _frame2)
10641+{
10642+ return ((_frame2 - _frame1) & DWC_HFNUM_MAX_FRNUM) <=
10643+ (DWC_HFNUM_MAX_FRNUM >> 1);
10644+}
10645+
10646+/**
10647+ * Returns true if _frame1 is greater than _frame2. The comparison is done
10648+ * modulo DWC_HFNUM_MAX_FRNUM. This accounts for the rollover of the frame
10649+ * number when the max frame number is reached.
10650+ */
10651+static inline int dwc_frame_num_gt(uint16_t _frame1, uint16_t _frame2)
10652+{
10653+ return (_frame1 != _frame2) &&
10654+ (((_frame1 - _frame2) & DWC_HFNUM_MAX_FRNUM) <
10655+ (DWC_HFNUM_MAX_FRNUM >> 1));
10656+}
10657+
10658+/**
10659+ * Increments _frame by the amount specified by _inc. The addition is done
10660+ * modulo DWC_HFNUM_MAX_FRNUM. Returns the incremented value.
10661+ */
10662+static inline uint16_t dwc_frame_num_inc(uint16_t _frame, uint16_t _inc)
10663+{
10664+ return (_frame + _inc) & DWC_HFNUM_MAX_FRNUM;
10665+}
10666+
10667+static inline uint16_t dwc_full_frame_num (uint16_t _frame)
10668+{
10669+ return ((_frame) & DWC_HFNUM_MAX_FRNUM) >> 3;
10670+}
10671+
10672+static inline uint16_t dwc_micro_frame_num (uint16_t _frame)
10673+{
10674+ return (_frame) & 0x7;
10675+}
10676+
10677+#ifdef DEBUG
10678+/**
10679+ * Macro to sample the remaining PHY clocks left in the current frame. This
10680+ * may be used during debugging to determine the average time it takes to
10681+ * execute sections of code. There are two possible sample points, "a" and
10682+ * "b", so the _letter argument must be one of these values.
10683+ *
10684+ * To dump the average sample times, read the "hcd_frrem" sysfs attribute. For
10685+ * example, "cat /sys/devices/lm0/hcd_frrem".
10686+ */
10687+#define dwc_sample_frrem(_hcd, _qh, _letter) \
10688+{ \
10689+ hfnum_data_t hfnum; \
10690+ dwc_otg_qtd_t *qtd; \
10691+ qtd = list_entry(_qh->qtd_list.next, dwc_otg_qtd_t, qtd_list_entry); \
10692+ if (usb_pipeint(qtd->urb->pipe) && _qh->start_split_frame != 0 && !qtd->complete_split) { \
10693+ hfnum.d32 = dwc_read_reg32(&_hcd->core_if->host_if->host_global_regs->hfnum); \
10694+ switch (hfnum.b.frnum & 0x7) { \
10695+ case 7: \
10696+ _hcd->hfnum_7_samples_##_letter++; \
10697+ _hcd->hfnum_7_frrem_accum_##_letter += hfnum.b.frrem; \
10698+ break; \
10699+ case 0: \
10700+ _hcd->hfnum_0_samples_##_letter++; \
10701+ _hcd->hfnum_0_frrem_accum_##_letter += hfnum.b.frrem; \
10702+ break; \
10703+ default: \
10704+ _hcd->hfnum_other_samples_##_letter++; \
10705+ _hcd->hfnum_other_frrem_accum_##_letter += hfnum.b.frrem; \
10706+ break; \
10707+ } \
10708+ } \
10709+}
10710+#else // DEBUG
10711+#define dwc_sample_frrem(_hcd, _qh, _letter)
10712+#endif // DEBUG
10713+#endif // __DWC_HCD_H__
10714+#endif /* DWC_DEVICE_ONLY */
10715diff --git a/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c b/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c
10716new file mode 100644
10717index 0000000..834b5e0
10718--- /dev/null
10719+++ b/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c
10720@@ -0,0 +1,1841 @@
10721+/* ==========================================================================
10722+ * $File: //dwh/usb_iip/dev/software/otg_ipmate/linux/drivers/dwc_otg_hcd_intr.c $
10723+ * $Revision: 1.1.1.1 $
10724+ * $Date: 2009-04-17 06:15:34 $
10725+ * $Change: 553126 $
10726+ *
10727+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
10728+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
10729+ * otherwise expressly agreed to in writing between Synopsys and you.
10730+ *
10731+ * The Software IS NOT an item of Licensed Software or Licensed Product under
10732+ * any End User Software License Agreement or Agreement for Licensed Product
10733+ * with Synopsys or any supplement thereto. You are permitted to use and
10734+ * redistribute this Software in source and binary forms, with or without
10735+ * modification, provided that redistributions of source code must retain this
10736+ * notice. You may not view, use, disclose, copy or distribute this file or
10737+ * any information contained herein except pursuant to this license grant from
10738+ * Synopsys. If you do not agree with this notice, including the disclaimer
10739+ * below, then you are not authorized to use the Software.
10740+ *
10741+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
10742+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
10743+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
10744+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
10745+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
10746+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
10747+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
10748+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
10749+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
10750+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
10751+ * DAMAGE.
10752+ * ========================================================================== */
10753+#ifndef DWC_DEVICE_ONLY
10754+
10755+#include "dwc_otg_driver.h"
10756+#include "dwc_otg_hcd.h"
10757+#include "dwc_otg_regs.h"
10758+
10759+const int erratum_usb09_patched = 0;
10760+const int deferral_on = 1;
10761+const int nak_deferral_delay = 8;
10762+const int nyet_deferral_delay = 1;
10763+/** @file
10764+ * This file contains the implementation of the HCD Interrupt handlers.
10765+ */
10766+
10767+/** This function handles interrupts for the HCD. */
10768+int32_t dwc_otg_hcd_handle_intr (dwc_otg_hcd_t *_dwc_otg_hcd)
10769+{
10770+ int retval = 0;
10771+
10772+ dwc_otg_core_if_t *core_if = _dwc_otg_hcd->core_if;
10773+ gintsts_data_t gintsts;
10774+#ifdef DEBUG
10775+ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
10776+#endif
10777+
10778+ /* Check if HOST Mode */
10779+ if (dwc_otg_is_host_mode(core_if)) {
10780+ gintsts.d32 = dwc_otg_read_core_intr(core_if);
10781+ if (!gintsts.d32) {
10782+ return 0;
10783+ }
10784+
10785+#ifdef DEBUG
10786+ /* Don't print debug message in the interrupt handler on SOF */
10787+# ifndef DEBUG_SOF
10788+ if (gintsts.d32 != DWC_SOF_INTR_MASK)
10789+# endif
10790+ DWC_DEBUGPL (DBG_HCD, "\n");
10791+#endif
10792+
10793+#ifdef DEBUG
10794+# ifndef DEBUG_SOF
10795+ if (gintsts.d32 != DWC_SOF_INTR_MASK)
10796+# endif
10797+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Interrupt Detected gintsts&gintmsk=0x%08x\n", gintsts.d32);
10798+#endif
10799+
10800+ if (gintsts.b.sofintr) {
10801+ retval |= dwc_otg_hcd_handle_sof_intr (_dwc_otg_hcd);
10802+ }
10803+ if (gintsts.b.rxstsqlvl) {
10804+ retval |= dwc_otg_hcd_handle_rx_status_q_level_intr (_dwc_otg_hcd);
10805+ }
10806+ if (gintsts.b.nptxfempty) {
10807+ retval |= dwc_otg_hcd_handle_np_tx_fifo_empty_intr (_dwc_otg_hcd);
10808+ }
10809+ if (gintsts.b.i2cintr) {
10810+ /** @todo Implement i2cintr handler. */
10811+ }
10812+ if (gintsts.b.portintr) {
10813+ retval |= dwc_otg_hcd_handle_port_intr (_dwc_otg_hcd);
10814+ }
10815+ if (gintsts.b.hcintr) {
10816+ retval |= dwc_otg_hcd_handle_hc_intr (_dwc_otg_hcd);
10817+ }
10818+ if (gintsts.b.ptxfempty) {
10819+ retval |= dwc_otg_hcd_handle_perio_tx_fifo_empty_intr (_dwc_otg_hcd);
10820+ }
10821+#ifdef DEBUG
10822+# ifndef DEBUG_SOF
10823+ if (gintsts.d32 != DWC_SOF_INTR_MASK)
10824+# endif
10825+ {
10826+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Finished Servicing Interrupts\n");
10827+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD gintsts=0x%08x\n",
10828+ dwc_read_reg32(&global_regs->gintsts));
10829+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD gintmsk=0x%08x\n",
10830+ dwc_read_reg32(&global_regs->gintmsk));
10831+ }
10832+#endif
10833+
10834+#ifdef DEBUG
10835+# ifndef DEBUG_SOF
10836+ if (gintsts.d32 != DWC_SOF_INTR_MASK)
10837+# endif
10838+ DWC_DEBUGPL (DBG_HCD, "\n");
10839+#endif
10840+
10841+ }
10842+
10843+ return retval;
10844+}
10845+
10846+#ifdef DWC_TRACK_MISSED_SOFS
10847+#warning Compiling code to track missed SOFs
10848+#define FRAME_NUM_ARRAY_SIZE 1000
10849+/**
10850+ * This function is for debug only.
10851+ */
10852+static inline void track_missed_sofs(uint16_t _curr_frame_number) {
10853+ static uint16_t frame_num_array[FRAME_NUM_ARRAY_SIZE];
10854+ static uint16_t last_frame_num_array[FRAME_NUM_ARRAY_SIZE];
10855+ static int frame_num_idx = 0;
10856+ static uint16_t last_frame_num = DWC_HFNUM_MAX_FRNUM;
10857+ static int dumped_frame_num_array = 0;
10858+
10859+ if (frame_num_idx < FRAME_NUM_ARRAY_SIZE) {
10860+ if ((((last_frame_num + 1) & DWC_HFNUM_MAX_FRNUM) != _curr_frame_number)) {
10861+ frame_num_array[frame_num_idx] = _curr_frame_number;
10862+ last_frame_num_array[frame_num_idx++] = last_frame_num;
10863+ }
10864+ } else if (!dumped_frame_num_array) {
10865+ int i;
10866+ printk(KERN_EMERG USB_DWC "Frame Last Frame\n");
10867+ printk(KERN_EMERG USB_DWC "----- ----------\n");
10868+ for (i = 0; i < FRAME_NUM_ARRAY_SIZE; i++) {
10869+ printk(KERN_EMERG USB_DWC "0x%04x 0x%04x\n",
10870+ frame_num_array[i], last_frame_num_array[i]);
10871+ }
10872+ dumped_frame_num_array = 1;
10873+ }
10874+ last_frame_num = _curr_frame_number;
10875+}
10876+#endif
10877+
10878+/**
10879+ * Handles the start-of-frame interrupt in host mode. Non-periodic
10880+ * transactions may be queued to the DWC_otg controller for the current
10881+ * (micro)frame. Periodic transactions may be queued to the controller for the
10882+ * next (micro)frame.
10883+ */
10884+int32_t dwc_otg_hcd_handle_sof_intr (dwc_otg_hcd_t *_hcd)
10885+{
10886+ hfnum_data_t hfnum;
10887+ struct list_head *qh_entry;
10888+ dwc_otg_qh_t *qh;
10889+ dwc_otg_transaction_type_e tr_type;
10890+ gintsts_data_t gintsts = {.d32 = 0};
10891+
10892+ hfnum.d32 = dwc_read_reg32(&_hcd->core_if->host_if->host_global_regs->hfnum);
10893+
10894+#ifdef DEBUG_SOF
10895+ DWC_DEBUGPL(DBG_HCD, "--Start of Frame Interrupt--\n");
10896+#endif
10897+
10898+ _hcd->frame_number = hfnum.b.frnum;
10899+
10900+#ifdef DEBUG
10901+ _hcd->frrem_accum += hfnum.b.frrem;
10902+ _hcd->frrem_samples++;
10903+#endif
10904+
10905+#ifdef DWC_TRACK_MISSED_SOFS
10906+ track_missed_sofs(_hcd->frame_number);
10907+#endif
10908+
10909+ /* Determine whether any periodic QHs should be executed. */
10910+ qh_entry = _hcd->periodic_sched_inactive.next;
10911+ while (qh_entry != &_hcd->periodic_sched_inactive) {
10912+ qh = list_entry(qh_entry, dwc_otg_qh_t, qh_list_entry);
10913+ qh_entry = qh_entry->next;
10914+ if (dwc_frame_num_le(qh->sched_frame, _hcd->frame_number)) {
10915+ /*
10916+ * Move QH to the ready list to be executed next
10917+ * (micro)frame.
10918+ */
10919+ list_move(&qh->qh_list_entry, &_hcd->periodic_sched_ready);
10920+ }
10921+ }
10922+
10923+ tr_type = dwc_otg_hcd_select_transactions(_hcd);
10924+ if (tr_type != DWC_OTG_TRANSACTION_NONE) {
10925+ dwc_otg_hcd_queue_transactions(_hcd, tr_type);
10926+ }
10927+
10928+ /* Clear interrupt */
10929+ gintsts.b.sofintr = 1;
10930+ dwc_write_reg32(&_hcd->core_if->core_global_regs->gintsts, gintsts.d32);
10931+
10932+ return 1;
10933+}
10934+
10935+/** Handles the Rx Status Queue Level Interrupt, which indicates that there is at
10936+ * least one packet in the Rx FIFO. The packets are moved from the FIFO to
10937+ * memory if the DWC_otg controller is operating in Slave mode. */
10938+int32_t dwc_otg_hcd_handle_rx_status_q_level_intr (dwc_otg_hcd_t *_dwc_otg_hcd)
10939+{
10940+ host_grxsts_data_t grxsts;
10941+ dwc_hc_t *hc = NULL;
10942+
10943+ DWC_DEBUGPL(DBG_HCD, "--RxStsQ Level Interrupt--\n");
10944+
10945+ grxsts.d32 = dwc_read_reg32(&_dwc_otg_hcd->core_if->core_global_regs->grxstsp);
10946+
10947+ hc = _dwc_otg_hcd->hc_ptr_array[grxsts.b.chnum];
10948+
10949+ /* Packet Status */
10950+ DWC_DEBUGPL(DBG_HCDV, " Ch num = %d\n", grxsts.b.chnum);
10951+ DWC_DEBUGPL(DBG_HCDV, " Count = %d\n", grxsts.b.bcnt);
10952+ DWC_DEBUGPL(DBG_HCDV, " DPID = %d, hc.dpid = %d\n", grxsts.b.dpid, hc->data_pid_start);
10953+ DWC_DEBUGPL(DBG_HCDV, " PStatus = %d\n", grxsts.b.pktsts);
10954+
10955+ switch (grxsts.b.pktsts) {
10956+ case DWC_GRXSTS_PKTSTS_IN:
10957+ /* Read the data into the host buffer. */
10958+ if (grxsts.b.bcnt > 0) {
10959+ dwc_otg_read_packet(_dwc_otg_hcd->core_if,
10960+ hc->xfer_buff,
10961+ grxsts.b.bcnt);
10962+
10963+ /* Update the HC fields for the next packet received. */
10964+ hc->xfer_count += grxsts.b.bcnt;
10965+ hc->xfer_buff += grxsts.b.bcnt;
10966+ }
10967+
10968+ case DWC_GRXSTS_PKTSTS_IN_XFER_COMP:
10969+ case DWC_GRXSTS_PKTSTS_DATA_TOGGLE_ERR:
10970+ case DWC_GRXSTS_PKTSTS_CH_HALTED:
10971+ /* Handled in interrupt, just ignore data */
10972+ break;
10973+ default:
10974+ DWC_ERROR ("RX_STS_Q Interrupt: Unknown status %d\n", grxsts.b.pktsts);
10975+ break;
10976+ }
10977+
10978+ return 1;
10979+}
10980+
10981+/** This interrupt occurs when the non-periodic Tx FIFO is half-empty. More
10982+ * data packets may be written to the FIFO for OUT transfers. More requests
10983+ * may be written to the non-periodic request queue for IN transfers. This
10984+ * interrupt is enabled only in Slave mode. */
10985+int32_t dwc_otg_hcd_handle_np_tx_fifo_empty_intr (dwc_otg_hcd_t *_dwc_otg_hcd)
10986+{
10987+ DWC_DEBUGPL(DBG_HCD, "--Non-Periodic TxFIFO Empty Interrupt--\n");
10988+ dwc_otg_hcd_queue_transactions(_dwc_otg_hcd,
10989+ DWC_OTG_TRANSACTION_NON_PERIODIC);
10990+ return 1;
10991+}
10992+
10993+/** This interrupt occurs when the periodic Tx FIFO is half-empty. More data
10994+ * packets may be written to the FIFO for OUT transfers. More requests may be
10995+ * written to the periodic request queue for IN transfers. This interrupt is
10996+ * enabled only in Slave mode. */
10997+int32_t dwc_otg_hcd_handle_perio_tx_fifo_empty_intr (dwc_otg_hcd_t *_dwc_otg_hcd)
10998+{
10999+ DWC_DEBUGPL(DBG_HCD, "--Periodic TxFIFO Empty Interrupt--\n");
11000+ dwc_otg_hcd_queue_transactions(_dwc_otg_hcd,
11001+ DWC_OTG_TRANSACTION_PERIODIC);
11002+ return 1;
11003+}
11004+
11005+/** There are multiple conditions that can cause a port interrupt. This function
11006+ * determines which interrupt conditions have occurred and handles them
11007+ * appropriately. */
11008+int32_t dwc_otg_hcd_handle_port_intr (dwc_otg_hcd_t *_dwc_otg_hcd)
11009+{
11010+ int retval = 0;
11011+ hprt0_data_t hprt0;
11012+ hprt0_data_t hprt0_modify;
11013+
11014+ hprt0.d32 = dwc_read_reg32(_dwc_otg_hcd->core_if->host_if->hprt0);
11015+ hprt0_modify.d32 = dwc_read_reg32(_dwc_otg_hcd->core_if->host_if->hprt0);
11016+
11017+ /* Clear appropriate bits in HPRT0 to clear the interrupt bit in
11018+ * GINTSTS */
11019+
11020+ hprt0_modify.b.prtena = 0;
11021+ hprt0_modify.b.prtconndet = 0;
11022+ hprt0_modify.b.prtenchng = 0;
11023+ hprt0_modify.b.prtovrcurrchng = 0;
11024+
11025+ /* Port Connect Detected
11026+ * Set flag and clear if detected */
11027+ if (hprt0.b.prtconndet) {
11028+ DWC_DEBUGPL(DBG_HCD, "--Port Interrupt HPRT0=0x%08x "
11029+ "Port Connect Detected--\n", hprt0.d32);
11030+ _dwc_otg_hcd->flags.b.port_connect_status_change = 1;
11031+ _dwc_otg_hcd->flags.b.port_connect_status = 1;
11032+ hprt0_modify.b.prtconndet = 1;
11033+
11034+ /* B-Device has connected, Delete the connection timer. */
11035+ del_timer( &_dwc_otg_hcd->conn_timer );
11036+
11037+ /* The Hub driver asserts a reset when it sees port connect
11038+ * status change flag */
11039+ retval |= 1;
11040+ }
11041+
11042+ /* Port Enable Changed
11043+ * Clear if detected - Set internal flag if disabled */
11044+ if (hprt0.b.prtenchng) {
11045+ DWC_DEBUGPL(DBG_HCD, " --Port Interrupt HPRT0=0x%08x "
11046+ "Port Enable Changed--\n", hprt0.d32);
11047+ hprt0_modify.b.prtenchng = 1;
11048+ if (hprt0.b.prtena == 1) {
11049+ int do_reset = 0;
11050+ dwc_otg_core_params_t *params = _dwc_otg_hcd->core_if->core_params;
11051+ dwc_otg_core_global_regs_t *global_regs = _dwc_otg_hcd->core_if->core_global_regs;
11052+ dwc_otg_host_if_t *host_if = _dwc_otg_hcd->core_if->host_if;
11053+
11054+ /* Check if we need to adjust the PHY clock speed for
11055+ * low power and adjust it */
11056+ if (params->host_support_fs_ls_low_power)
11057+ {
11058+ gusbcfg_data_t usbcfg;
11059+
11060+ usbcfg.d32 = dwc_read_reg32 (&global_regs->gusbcfg);
11061+
11062+ if ((hprt0.b.prtspd == DWC_HPRT0_PRTSPD_LOW_SPEED) ||
11063+ (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_FULL_SPEED))
11064+ {
11065+ /*
11066+ * Low power
11067+ */
11068+ hcfg_data_t hcfg;
11069+ if (usbcfg.b.phylpwrclksel == 0) {
11070+ /* Set PHY low power clock select for FS/LS devices */
11071+ usbcfg.b.phylpwrclksel = 1;
11072+ dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
11073+ do_reset = 1;
11074+ }
11075+
11076+ hcfg.d32 = dwc_read_reg32(&host_if->host_global_regs->hcfg);
11077+
11078+ if ((hprt0.b.prtspd == DWC_HPRT0_PRTSPD_LOW_SPEED) &&
11079+ (params->host_ls_low_power_phy_clk ==
11080+ DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ))
11081+ {
11082+ /* 6 MHZ */
11083+ DWC_DEBUGPL(DBG_CIL, "FS_PHY programming HCFG to 6 MHz (Low Power)\n");
11084+ if (hcfg.b.fslspclksel != DWC_HCFG_6_MHZ) {
11085+ hcfg.b.fslspclksel = DWC_HCFG_6_MHZ;
11086+ dwc_write_reg32(&host_if->host_global_regs->hcfg,
11087+ hcfg.d32);
11088+ do_reset = 1;
11089+ }
11090+ }
11091+ else {
11092+ /* 48 MHZ */
11093+ DWC_DEBUGPL(DBG_CIL, "FS_PHY programming HCFG to 48 MHz ()\n");
11094+ if (hcfg.b.fslspclksel != DWC_HCFG_48_MHZ) {
11095+ hcfg.b.fslspclksel = DWC_HCFG_48_MHZ;
11096+ dwc_write_reg32(&host_if->host_global_regs->hcfg,
11097+ hcfg.d32);
11098+ do_reset = 1;
11099+ }
11100+ }
11101+ }
11102+ else {
11103+ /*
11104+ * Not low power
11105+ */
11106+ if (usbcfg.b.phylpwrclksel == 1) {
11107+ usbcfg.b.phylpwrclksel = 0;
11108+ dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
11109+ do_reset = 1;
11110+ }
11111+ }
11112+
11113+ if (do_reset) {
11114+ tasklet_schedule(_dwc_otg_hcd->reset_tasklet);
11115+ }
11116+ }
11117+
11118+ if (!do_reset) {
11119+ /* Port has been enabled set the reset change flag */
11120+ _dwc_otg_hcd->flags.b.port_reset_change = 1;
11121+ }
11122+
11123+ } else {
11124+ _dwc_otg_hcd->flags.b.port_enable_change = 1;
11125+ }
11126+ retval |= 1;
11127+ }
11128+
11129+ /** Overcurrent Change Interrupt */
11130+ if (hprt0.b.prtovrcurrchng) {
11131+ DWC_DEBUGPL(DBG_HCD, " --Port Interrupt HPRT0=0x%08x "
11132+ "Port Overcurrent Changed--\n", hprt0.d32);
11133+ _dwc_otg_hcd->flags.b.port_over_current_change = 1;
11134+ hprt0_modify.b.prtovrcurrchng = 1;
11135+ retval |= 1;
11136+ }
11137+
11138+ /* Clear Port Interrupts */
11139+ dwc_write_reg32(_dwc_otg_hcd->core_if->host_if->hprt0, hprt0_modify.d32);
11140+
11141+ return retval;
11142+}
11143+
11144+
11145+/** This interrupt indicates that one or more host channels has a pending
11146+ * interrupt. There are multiple conditions that can cause each host channel
11147+ * interrupt. This function determines which conditions have occurred for each
11148+ * host channel interrupt and handles them appropriately. */
11149+int32_t dwc_otg_hcd_handle_hc_intr (dwc_otg_hcd_t *_dwc_otg_hcd)
11150+{
11151+ int i;
11152+ int retval = 0;
11153+ haint_data_t haint;
11154+
11155+ /* Clear appropriate bits in HCINTn to clear the interrupt bit in
11156+ * GINTSTS */
11157+
11158+ haint.d32 = dwc_otg_read_host_all_channels_intr(_dwc_otg_hcd->core_if);
11159+
11160+ for (i=0; i<_dwc_otg_hcd->core_if->core_params->host_channels; i++) {
11161+ if (haint.b2.chint & (1 << i)) {
11162+ retval |= dwc_otg_hcd_handle_hc_n_intr (_dwc_otg_hcd, i);
11163+ }
11164+ }
11165+
11166+ return retval;
11167+}
11168+
11169+/* Macro used to clear one channel interrupt */
11170+#define clear_hc_int(_hc_regs_,_intr_) \
11171+do { \
11172+ hcint_data_t hcint_clear = {.d32 = 0}; \
11173+ hcint_clear.b._intr_ = 1; \
11174+ dwc_write_reg32(&((_hc_regs_)->hcint), hcint_clear.d32); \
11175+} while (0)
11176+
11177+/*
11178+ * Macro used to disable one channel interrupt. Channel interrupts are
11179+ * disabled when the channel is halted or released by the interrupt handler.
11180+ * There is no need to handle further interrupts of that type until the
11181+ * channel is re-assigned. In fact, subsequent handling may cause crashes
11182+ * because the channel structures are cleaned up when the channel is released.
11183+ */
11184+#define disable_hc_int(_hc_regs_,_intr_) \
11185+do { \
11186+ hcintmsk_data_t hcintmsk = {.d32 = 0}; \
11187+ hcintmsk.b._intr_ = 1; \
11188+ dwc_modify_reg32(&((_hc_regs_)->hcintmsk), hcintmsk.d32, 0); \
11189+} while (0)
11190+
11191+/**
11192+ * Gets the actual length of a transfer after the transfer halts. _halt_status
11193+ * holds the reason for the halt.
11194+ *
11195+ * For IN transfers where _halt_status is DWC_OTG_HC_XFER_COMPLETE,
11196+ * *_short_read is set to 1 upon return if less than the requested
11197+ * number of bytes were transferred. Otherwise, *_short_read is set to 0 upon
11198+ * return. _short_read may also be NULL on entry, in which case it remains
11199+ * unchanged.
11200+ */
11201+static uint32_t get_actual_xfer_length(dwc_hc_t *_hc,
11202+ dwc_otg_hc_regs_t *_hc_regs,
11203+ dwc_otg_qtd_t *_qtd,
11204+ dwc_otg_halt_status_e _halt_status,
11205+ int *_short_read)
11206+{
11207+ hctsiz_data_t hctsiz;
11208+ uint32_t length;
11209+
11210+ if (_short_read != NULL) {
11211+ *_short_read = 0;
11212+ }
11213+ hctsiz.d32 = dwc_read_reg32(&_hc_regs->hctsiz);
11214+
11215+ if (_halt_status == DWC_OTG_HC_XFER_COMPLETE) {
11216+ if (_hc->ep_is_in) {
11217+ length = _hc->xfer_len - hctsiz.b.xfersize;
11218+ if (_short_read != NULL) {
11219+ *_short_read = (hctsiz.b.xfersize != 0);
11220+ }
11221+ } else if (_hc->qh->do_split) {
11222+ length = _qtd->ssplit_out_xfer_count;
11223+ } else {
11224+ length = _hc->xfer_len;
11225+ }
11226+ } else {
11227+ /*
11228+ * Must use the hctsiz.pktcnt field to determine how much data
11229+ * has been transferred. This field reflects the number of
11230+ * packets that have been transferred via the USB. This is
11231+ * always an integral number of packets if the transfer was
11232+ * halted before its normal completion. (Can't use the
11233+ * hctsiz.xfersize field because that reflects the number of
11234+ * bytes transferred via the AHB, not the USB).
11235+ */
11236+ length = (_hc->start_pkt_count - hctsiz.b.pktcnt) * _hc->max_packet;
11237+ }
11238+
11239+ return length;
11240+}
11241+
11242+/**
11243+ * Updates the state of the URB after a Transfer Complete interrupt on the
11244+ * host channel. Updates the actual_length field of the URB based on the
11245+ * number of bytes transferred via the host channel. Sets the URB status
11246+ * if the data transfer is finished.
11247+ *
11248+ * @return 1 if the data transfer specified by the URB is completely finished,
11249+ * 0 otherwise.
11250+ */
11251+static int update_urb_state_xfer_comp(dwc_hc_t *_hc,
11252+ dwc_otg_hc_regs_t * _hc_regs, struct urb *_urb,
11253+ dwc_otg_qtd_t * _qtd, int *status)
11254+{
11255+ int xfer_done = 0;
11256+ int short_read = 0;
11257+
11258+ _urb->actual_length += get_actual_xfer_length(_hc, _hc_regs, _qtd,
11259+ DWC_OTG_HC_XFER_COMPLETE,
11260+ &short_read);
11261+
11262+ if (short_read || (_urb->actual_length == _urb->transfer_buffer_length)) {
11263+ xfer_done = 1;
11264+ if (short_read && (_urb->transfer_flags & URB_SHORT_NOT_OK)) {
11265+ *status = -EREMOTEIO;
11266+ } else {
11267+ *status = 0;
11268+ }
11269+ }
11270+
11271+#ifdef DEBUG
11272+ {
11273+ hctsiz_data_t hctsiz;
11274+ hctsiz.d32 = dwc_read_reg32(&_hc_regs->hctsiz);
11275+ DWC_DEBUGPL(DBG_HCDV, "DWC_otg: %s: %s, channel %d\n",
11276+ __func__, (_hc->ep_is_in ? "IN" : "OUT"), _hc->hc_num);
11277+ DWC_DEBUGPL(DBG_HCDV, " hc->xfer_len %d\n", _hc->xfer_len);
11278+ DWC_DEBUGPL(DBG_HCDV, " hctsiz.xfersize %d\n", hctsiz.b.xfersize);
11279+ DWC_DEBUGPL(DBG_HCDV, " urb->transfer_buffer_length %d\n",
11280+ _urb->transfer_buffer_length);
11281+ DWC_DEBUGPL(DBG_HCDV, " urb->actual_length %d\n", _urb->actual_length);
11282+ DWC_DEBUGPL(DBG_HCDV, " short_read %d, xfer_done %d\n",
11283+ short_read, xfer_done);
11284+ }
11285+#endif
11286+
11287+ return xfer_done;
11288+}
11289+
11290+/*
11291+ * Save the starting data toggle for the next transfer. The data toggle is
11292+ * saved in the QH for non-control transfers and it's saved in the QTD for
11293+ * control transfers.
11294+ */
11295+static void save_data_toggle(dwc_hc_t *_hc,
11296+ dwc_otg_hc_regs_t *_hc_regs,
11297+ dwc_otg_qtd_t *_qtd)
11298+{
11299+ hctsiz_data_t hctsiz;
11300+ hctsiz.d32 = dwc_read_reg32(&_hc_regs->hctsiz);
11301+
11302+ if (_hc->ep_type != DWC_OTG_EP_TYPE_CONTROL) {
11303+ dwc_otg_qh_t *qh = _hc->qh;
11304+ if (hctsiz.b.pid == DWC_HCTSIZ_DATA0) {
11305+ qh->data_toggle = DWC_OTG_HC_PID_DATA0;
11306+ } else {
11307+ qh->data_toggle = DWC_OTG_HC_PID_DATA1;
11308+ }
11309+ } else {
11310+ if (hctsiz.b.pid == DWC_HCTSIZ_DATA0) {
11311+ _qtd->data_toggle = DWC_OTG_HC_PID_DATA0;
11312+ } else {
11313+ _qtd->data_toggle = DWC_OTG_HC_PID_DATA1;
11314+ }
11315+ }
11316+}
11317+
11318+/**
11319+ * Frees the first QTD in the QH's list if free_qtd is 1. For non-periodic
11320+ * QHs, removes the QH from the active non-periodic schedule. If any QTDs are
11321+ * still linked to the QH, the QH is added to the end of the inactive
11322+ * non-periodic schedule. For periodic QHs, removes the QH from the periodic
11323+ * schedule if no more QTDs are linked to the QH.
11324+ */
11325+static void deactivate_qh(dwc_otg_hcd_t *_hcd,
11326+ dwc_otg_qh_t *_qh,
11327+ int free_qtd)
11328+{
11329+ int continue_split = 0;
11330+ dwc_otg_qtd_t *qtd;
11331+
11332+ DWC_DEBUGPL(DBG_HCDV, " %s(%p,%p,%d)\n", __func__, _hcd, _qh, free_qtd);
11333+
11334+ qtd = list_entry(_qh->qtd_list.next, dwc_otg_qtd_t, qtd_list_entry);
11335+
11336+ if (qtd->complete_split) {
11337+ continue_split = 1;
11338+ }
11339+ else if ((qtd->isoc_split_pos == DWC_HCSPLIT_XACTPOS_MID) ||
11340+ (qtd->isoc_split_pos == DWC_HCSPLIT_XACTPOS_END))
11341+ {
11342+ continue_split = 1;
11343+ }
11344+
11345+ if (free_qtd) {
11346+ /*
11347+ * Note that this was previously a call to
11348+ * dwc_otg_hcd_qtd_remove_and_free(qtd), which frees the qtd.
11349+ * However, that call frees the qtd memory, and we continue in the
11350+ * interrupt logic to access it many more times, including writing
11351+ * to it. With slub debugging on, it is clear that we were writing
11352+ * to memory we had freed.
11353+ * Call this instead, and now I have moved the freeing of the memory to
11354+ * the end of processing this interrupt.
11355+ */
11356+ //dwc_otg_hcd_qtd_remove_and_free(qtd);
11357+ dwc_otg_hcd_qtd_remove(qtd);
11358+
11359+ continue_split = 0;
11360+ }
11361+
11362+ _qh->channel = NULL;
11363+ _qh->qtd_in_process = NULL;
11364+ dwc_otg_hcd_qh_deactivate(_hcd, _qh, continue_split);
11365+}
11366+
11367+/**
11368+ * Updates the state of an Isochronous URB when the transfer is stopped for
11369+ * any reason. The fields of the current entry in the frame descriptor array
11370+ * are set based on the transfer state and the input _halt_status. Completes
11371+ * the Isochronous URB if all the URB frames have been completed.
11372+ *
11373+ * @return DWC_OTG_HC_XFER_COMPLETE if there are more frames remaining to be
11374+ * transferred in the URB. Otherwise return DWC_OTG_HC_XFER_URB_COMPLETE.
11375+ */
11376+static dwc_otg_halt_status_e
11377+update_isoc_urb_state(dwc_otg_hcd_t *_hcd,
11378+ dwc_hc_t *_hc,
11379+ dwc_otg_hc_regs_t *_hc_regs,
11380+ dwc_otg_qtd_t *_qtd,
11381+ dwc_otg_halt_status_e _halt_status)
11382+{
11383+ struct urb *urb = _qtd->urb;
11384+ dwc_otg_halt_status_e ret_val = _halt_status;
11385+ struct usb_iso_packet_descriptor *frame_desc;
11386+
11387+ frame_desc = &urb->iso_frame_desc[_qtd->isoc_frame_index];
11388+ switch (_halt_status) {
11389+ case DWC_OTG_HC_XFER_COMPLETE:
11390+ frame_desc->status = 0;
11391+ frame_desc->actual_length =
11392+ get_actual_xfer_length(_hc, _hc_regs, _qtd,
11393+ _halt_status, NULL);
11394+ break;
11395+ case DWC_OTG_HC_XFER_FRAME_OVERRUN:
11396+ urb->error_count++;
11397+ if (_hc->ep_is_in) {
11398+ frame_desc->status = -ENOSR;
11399+ } else {
11400+ frame_desc->status = -ECOMM;
11401+ }
11402+ frame_desc->actual_length = 0;
11403+ break;
11404+ case DWC_OTG_HC_XFER_BABBLE_ERR:
11405+ urb->error_count++;
11406+ frame_desc->status = -EOVERFLOW;
11407+ /* Don't need to update actual_length in this case. */
11408+ break;
11409+ case DWC_OTG_HC_XFER_XACT_ERR:
11410+ urb->error_count++;
11411+ frame_desc->status = -EPROTO;
11412+ frame_desc->actual_length =
11413+ get_actual_xfer_length(_hc, _hc_regs, _qtd,
11414+ _halt_status, NULL);
11415+ default:
11416+ DWC_ERROR("%s: Unhandled _halt_status (%d)\n", __func__,
11417+ _halt_status);
11418+ BUG();
11419+ break;
11420+ }
11421+
11422+ if (++_qtd->isoc_frame_index == urb->number_of_packets) {
11423+ /*
11424+ * urb->status is not used for isoc transfers.
11425+ * The individual frame_desc statuses are used instead.
11426+ */
11427+ dwc_otg_hcd_complete_urb(_hcd, urb, 0);
11428+ ret_val = DWC_OTG_HC_XFER_URB_COMPLETE;
11429+ } else {
11430+ ret_val = DWC_OTG_HC_XFER_COMPLETE;
11431+ }
11432+
11433+ return ret_val;
11434+}
11435+
11436+/**
11437+ * Releases a host channel for use by other transfers. Attempts to select and
11438+ * queue more transactions since at least one host channel is available.
11439+ *
11440+ * @param _hcd The HCD state structure.
11441+ * @param _hc The host channel to release.
11442+ * @param _qtd The QTD associated with the host channel. This QTD may be freed
11443+ * if the transfer is complete or an error has occurred.
11444+ * @param _halt_status Reason the channel is being released. This status
11445+ * determines the actions taken by this function.
11446+ */
11447+static void release_channel(dwc_otg_hcd_t *_hcd,
11448+ dwc_hc_t *_hc,
11449+ dwc_otg_qtd_t *_qtd,
11450+ dwc_otg_halt_status_e _halt_status,
11451+ int *must_free)
11452+{
11453+ dwc_otg_transaction_type_e tr_type;
11454+ int free_qtd;
11455+ dwc_otg_qh_t * _qh;
11456+ int deact = 1;
11457+ int retry_delay = 1;
11458+ unsigned long flags;
11459+
11460+ DWC_DEBUGPL(DBG_HCDV, " %s: channel %d, halt_status %d\n", __func__,
11461+ _hc->hc_num, _halt_status);
11462+
11463+ switch (_halt_status) {
11464+ case DWC_OTG_HC_XFER_NYET:
11465+ case DWC_OTG_HC_XFER_NAK:
11466+ if (_halt_status == DWC_OTG_HC_XFER_NYET) {
11467+ retry_delay = nyet_deferral_delay;
11468+ } else {
11469+ retry_delay = nak_deferral_delay;
11470+ }
11471+ free_qtd = 0;
11472+ if (deferral_on && _hc->do_split) {
11473+ _qh = _hc->qh;
11474+ if (_qh) {
11475+ deact = dwc_otg_hcd_qh_deferr(_hcd, _qh , retry_delay);
11476+ }
11477+ }
11478+ break;
11479+ case DWC_OTG_HC_XFER_URB_COMPLETE:
11480+ free_qtd = 1;
11481+ break;
11482+ case DWC_OTG_HC_XFER_AHB_ERR:
11483+ case DWC_OTG_HC_XFER_STALL:
11484+ case DWC_OTG_HC_XFER_BABBLE_ERR:
11485+ free_qtd = 1;
11486+ break;
11487+ case DWC_OTG_HC_XFER_XACT_ERR:
11488+ if (_qtd->error_count >= 3) {
11489+ DWC_DEBUGPL(DBG_HCDV, " Complete URB with transaction error\n");
11490+ free_qtd = 1;
11491+ //_qtd->urb->status = -EPROTO;
11492+ dwc_otg_hcd_complete_urb(_hcd, _qtd->urb, -EPROTO);
11493+ } else {
11494+ free_qtd = 0;
11495+ }
11496+ break;
11497+ case DWC_OTG_HC_XFER_URB_DEQUEUE:
11498+ /*
11499+ * The QTD has already been removed and the QH has been
11500+ * deactivated. Don't want to do anything except release the
11501+ * host channel and try to queue more transfers.
11502+ */
11503+ goto cleanup;
11504+ case DWC_OTG_HC_XFER_NO_HALT_STATUS:
11505+ DWC_ERROR("%s: No halt_status, channel %d\n", __func__, _hc->hc_num);
11506+ free_qtd = 0;
11507+ break;
11508+ default:
11509+ free_qtd = 0;
11510+ break;
11511+ }
11512+ if (free_qtd) {
11513+ /* Only change must_free to true (do not set to zero here -- it is
11514+ * pre-initialized to zero).
11515+ */
11516+ *must_free = 1;
11517+ }
11518+ if (deact) {
11519+ deactivate_qh(_hcd, _hc->qh, free_qtd);
11520+ }
11521+ cleanup:
11522+ /*
11523+ * Release the host channel for use by other transfers. The cleanup
11524+ * function clears the channel interrupt enables and conditions, so
11525+ * there's no need to clear the Channel Halted interrupt separately.
11526+ */
11527+ dwc_otg_hc_cleanup(_hcd->core_if, _hc);
11528+ list_add_tail(&_hc->hc_list_entry, &_hcd->free_hc_list);
11529+
11530+ local_irq_save(flags);
11531+ _hcd->available_host_channels++;
11532+ local_irq_restore(flags);
11533+ /* Try to queue more transfers now that there's a free channel, */
11534+ /* unless erratum_usb09_patched is set */
11535+ if (!erratum_usb09_patched) {
11536+ tr_type = dwc_otg_hcd_select_transactions(_hcd);
11537+ if (tr_type != DWC_OTG_TRANSACTION_NONE) {
11538+ dwc_otg_hcd_queue_transactions(_hcd, tr_type);
11539+ }
11540+ }
11541+}
11542+
11543+/**
11544+ * Halts a host channel. If the channel cannot be halted immediately because
11545+ * the request queue is full, this function ensures that the FIFO empty
11546+ * interrupt for the appropriate queue is enabled so that the halt request can
11547+ * be queued when there is space in the request queue.
11548+ *
11549+ * This function may also be called in DMA mode. In that case, the channel is
11550+ * simply released since the core always halts the channel automatically in
11551+ * DMA mode.
11552+ */
11553+static void halt_channel(dwc_otg_hcd_t *_hcd,
11554+ dwc_hc_t *_hc,
11555+ dwc_otg_qtd_t *_qtd,
11556+ dwc_otg_halt_status_e _halt_status, int *must_free)
11557+{
11558+ if (_hcd->core_if->dma_enable) {
11559+ release_channel(_hcd, _hc, _qtd, _halt_status, must_free);
11560+ return;
11561+ }
11562+
11563+ /* Slave mode processing... */
11564+ dwc_otg_hc_halt(_hcd->core_if, _hc, _halt_status);
11565+
11566+ if (_hc->halt_on_queue) {
11567+ gintmsk_data_t gintmsk = {.d32 = 0};
11568+ dwc_otg_core_global_regs_t *global_regs;
11569+ global_regs = _hcd->core_if->core_global_regs;
11570+
11571+ if (_hc->ep_type == DWC_OTG_EP_TYPE_CONTROL ||
11572+ _hc->ep_type == DWC_OTG_EP_TYPE_BULK) {
11573+ /*
11574+ * Make sure the Non-periodic Tx FIFO empty interrupt
11575+ * is enabled so that the non-periodic schedule will
11576+ * be processed.
11577+ */
11578+ gintmsk.b.nptxfempty = 1;
11579+ dwc_modify_reg32(&global_regs->gintmsk, 0, gintmsk.d32);
11580+ } else {
11581+ /*
11582+ * Move the QH from the periodic queued schedule to
11583+ * the periodic assigned schedule. This allows the
11584+ * halt to be queued when the periodic schedule is
11585+ * processed.
11586+ */
11587+ list_move(&_hc->qh->qh_list_entry,
11588+ &_hcd->periodic_sched_assigned);
11589+
11590+ /*
11591+ * Make sure the Periodic Tx FIFO Empty interrupt is
11592+ * enabled so that the periodic schedule will be
11593+ * processed.
11594+ */
11595+ gintmsk.b.ptxfempty = 1;
11596+ dwc_modify_reg32(&global_regs->gintmsk, 0, gintmsk.d32);
11597+ }
11598+ }
11599+}
11600+
11601+/**
11602+ * Performs common cleanup for non-periodic transfers after a Transfer
11603+ * Complete interrupt. This function should be called after any endpoint type
11604+ * specific handling is finished to release the host channel.
11605+ */
11606+static void complete_non_periodic_xfer(dwc_otg_hcd_t *_hcd,
11607+ dwc_hc_t *_hc,
11608+ dwc_otg_hc_regs_t *_hc_regs,
11609+ dwc_otg_qtd_t *_qtd,
11610+ dwc_otg_halt_status_e _halt_status, int *must_free)
11611+{
11612+ hcint_data_t hcint;
11613+
11614+ _qtd->error_count = 0;
11615+
11616+ hcint.d32 = dwc_read_reg32(&_hc_regs->hcint);
11617+ if (hcint.b.nyet) {
11618+ /*
11619+ * Got a NYET on the last transaction of the transfer. This
11620+ * means that the endpoint should be in the PING state at the
11621+ * beginning of the next transfer.
11622+ */
11623+ _hc->qh->ping_state = 1;
11624+ clear_hc_int(_hc_regs,nyet);
11625+ }
11626+
11627+ /*
11628+ * Always halt and release the host channel to make it available for
11629+ * more transfers. There may still be more phases for a control
11630+ * transfer or more data packets for a bulk transfer at this point,
11631+ * but the host channel is still halted. A channel will be reassigned
11632+ * to the transfer when the non-periodic schedule is processed after
11633+ * the channel is released. This allows transactions to be queued
11634+ * properly via dwc_otg_hcd_queue_transactions, which also enables the
11635+ * Tx FIFO Empty interrupt if necessary.
11636+ */
11637+ if (_hc->ep_is_in) {
11638+ /*
11639+ * IN transfers in Slave mode require an explicit disable to
11640+ * halt the channel. (In DMA mode, this call simply releases
11641+ * the channel.)
11642+ */
11643+ halt_channel(_hcd, _hc, _qtd, _halt_status, must_free);
11644+ } else {
11645+ /*
11646+ * The channel is automatically disabled by the core for OUT
11647+ * transfers in Slave mode.
11648+ */
11649+ release_channel(_hcd, _hc, _qtd, _halt_status, must_free);
11650+ }
11651+}
11652+
11653+/**
11654+ * Performs common cleanup for periodic transfers after a Transfer Complete
11655+ * interrupt. This function should be called after any endpoint type specific
11656+ * handling is finished to release the host channel.
11657+ */
11658+static void complete_periodic_xfer(dwc_otg_hcd_t *_hcd,
11659+ dwc_hc_t *_hc,
11660+ dwc_otg_hc_regs_t *_hc_regs,
11661+ dwc_otg_qtd_t *_qtd,
11662+ dwc_otg_halt_status_e _halt_status, int *must_free)
11663+{
11664+ hctsiz_data_t hctsiz;
11665+ _qtd->error_count = 0;
11666+
11667+ hctsiz.d32 = dwc_read_reg32(&_hc_regs->hctsiz);
11668+ if (!_hc->ep_is_in || hctsiz.b.pktcnt == 0) {
11669+ /* Core halts channel in these cases. */
11670+ release_channel(_hcd, _hc, _qtd, _halt_status, must_free);
11671+ } else {
11672+ /* Flush any outstanding requests from the Tx queue. */
11673+ halt_channel(_hcd, _hc, _qtd, _halt_status, must_free);
11674+ }
11675+}
11676+
11677+/**
11678+ * Handles a host channel Transfer Complete interrupt. This handler may be
11679+ * called in either DMA mode or Slave mode.
11680+ */
11681+static int32_t handle_hc_xfercomp_intr(dwc_otg_hcd_t *_hcd,
11682+ dwc_hc_t *_hc,
11683+ dwc_otg_hc_regs_t *_hc_regs,
11684+ dwc_otg_qtd_t *_qtd, int *must_free)
11685+{
11686+ int urb_xfer_done;
11687+ dwc_otg_halt_status_e halt_status = DWC_OTG_HC_XFER_COMPLETE;
11688+ struct urb *urb = _qtd->urb;
11689+ int pipe_type = usb_pipetype(urb->pipe);
11690+ int status = -EINPROGRESS;
11691+
11692+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
11693+ "Transfer Complete--\n", _hc->hc_num);
11694+
11695+ /*
11696+ * Handle xfer complete on CSPLIT.
11697+ */
11698+ if (_hc->qh->do_split) {
11699+ _qtd->complete_split = 0;
11700+ }
11701+
11702+ /* Update the QTD and URB states. */
11703+ switch (pipe_type) {
11704+ case PIPE_CONTROL:
11705+ switch (_qtd->control_phase) {
11706+ case DWC_OTG_CONTROL_SETUP:
11707+ if (urb->transfer_buffer_length > 0) {
11708+ _qtd->control_phase = DWC_OTG_CONTROL_DATA;
11709+ } else {
11710+ _qtd->control_phase = DWC_OTG_CONTROL_STATUS;
11711+ }
11712+ DWC_DEBUGPL(DBG_HCDV, " Control setup transaction done\n");
11713+ halt_status = DWC_OTG_HC_XFER_COMPLETE;
11714+ break;
11715+ case DWC_OTG_CONTROL_DATA: {
11716+ urb_xfer_done = update_urb_state_xfer_comp(_hc, _hc_regs,urb, _qtd, &status);
11717+ if (urb_xfer_done) {
11718+ _qtd->control_phase = DWC_OTG_CONTROL_STATUS;
11719+ DWC_DEBUGPL(DBG_HCDV, " Control data transfer done\n");
11720+ } else {
11721+ save_data_toggle(_hc, _hc_regs, _qtd);
11722+ }
11723+ halt_status = DWC_OTG_HC_XFER_COMPLETE;
11724+ break;
11725+ }
11726+ case DWC_OTG_CONTROL_STATUS:
11727+ DWC_DEBUGPL(DBG_HCDV, " Control transfer complete\n");
11728+ if (status == -EINPROGRESS) {
11729+ status = 0;
11730+ }
11731+ dwc_otg_hcd_complete_urb(_hcd, urb, status);
11732+ halt_status = DWC_OTG_HC_XFER_URB_COMPLETE;
11733+ break;
11734+ }
11735+
11736+ complete_non_periodic_xfer(_hcd, _hc, _hc_regs, _qtd,
11737+ halt_status, must_free);
11738+ break;
11739+ case PIPE_BULK:
11740+ DWC_DEBUGPL(DBG_HCDV, " Bulk transfer complete\n");
11741+ urb_xfer_done = update_urb_state_xfer_comp(_hc, _hc_regs, urb, _qtd, &status);
11742+ if (urb_xfer_done) {
11743+ dwc_otg_hcd_complete_urb(_hcd, urb, status);
11744+ halt_status = DWC_OTG_HC_XFER_URB_COMPLETE;
11745+ } else {
11746+ halt_status = DWC_OTG_HC_XFER_COMPLETE;
11747+ }
11748+
11749+ save_data_toggle(_hc, _hc_regs, _qtd);
11750+ complete_non_periodic_xfer(_hcd, _hc, _hc_regs, _qtd,halt_status, must_free);
11751+ break;
11752+ case PIPE_INTERRUPT:
11753+ DWC_DEBUGPL(DBG_HCDV, " Interrupt transfer complete\n");
11754+ update_urb_state_xfer_comp(_hc, _hc_regs, urb, _qtd, &status);
11755+
11756+ /*
11757+ * Interrupt URB is done on the first transfer complete
11758+ * interrupt.
11759+ */
11760+ dwc_otg_hcd_complete_urb(_hcd, urb, status);
11761+ save_data_toggle(_hc, _hc_regs, _qtd);
11762+ complete_periodic_xfer(_hcd, _hc, _hc_regs, _qtd,
11763+ DWC_OTG_HC_XFER_URB_COMPLETE, must_free);
11764+ break;
11765+ case PIPE_ISOCHRONOUS:
11766+ DWC_DEBUGPL(DBG_HCDV, " Isochronous transfer complete\n");
11767+ if (_qtd->isoc_split_pos == DWC_HCSPLIT_XACTPOS_ALL)
11768+ {
11769+ halt_status = update_isoc_urb_state(_hcd, _hc, _hc_regs, _qtd,
11770+ DWC_OTG_HC_XFER_COMPLETE);
11771+ }
11772+ complete_periodic_xfer(_hcd, _hc, _hc_regs, _qtd, halt_status, must_free);
11773+ break;
11774+ }
11775+
11776+ disable_hc_int(_hc_regs,xfercompl);
11777+
11778+ return 1;
11779+}
11780+
11781+/**
11782+ * Handles a host channel STALL interrupt. This handler may be called in
11783+ * either DMA mode or Slave mode.
11784+ */
11785+static int32_t handle_hc_stall_intr(dwc_otg_hcd_t *_hcd,
11786+ dwc_hc_t *_hc,
11787+ dwc_otg_hc_regs_t *_hc_regs,
11788+ dwc_otg_qtd_t *_qtd, int *must_free)
11789+{
11790+ struct urb *urb = _qtd->urb;
11791+ int pipe_type = usb_pipetype(urb->pipe);
11792+
11793+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
11794+ "STALL Received--\n", _hc->hc_num);
11795+
11796+ if (pipe_type == PIPE_CONTROL) {
11797+ dwc_otg_hcd_complete_urb(_hcd, _qtd->urb, -EPIPE);
11798+ }
11799+
11800+ if (pipe_type == PIPE_BULK || pipe_type == PIPE_INTERRUPT) {
11801+ dwc_otg_hcd_complete_urb(_hcd, _qtd->urb, -EPIPE);
11802+ /*
11803+ * USB protocol requires resetting the data toggle for bulk
11804+ * and interrupt endpoints when a CLEAR_FEATURE(ENDPOINT_HALT)
11805+ * setup command is issued to the endpoint. Anticipate the
11806+ * CLEAR_FEATURE command since a STALL has occurred and reset
11807+ * the data toggle now.
11808+ */
11809+ _hc->qh->data_toggle = 0;
11810+ }
11811+
11812+ halt_channel(_hcd, _hc, _qtd, DWC_OTG_HC_XFER_STALL, must_free);
11813+ disable_hc_int(_hc_regs,stall);
11814+
11815+ return 1;
11816+}
11817+
11818+/*
11819+ * Updates the state of the URB when a transfer has been stopped due to an
11820+ * abnormal condition before the transfer completes. Modifies the
11821+ * actual_length field of the URB to reflect the number of bytes that have
11822+ * actually been transferred via the host channel.
11823+ */
11824+static void update_urb_state_xfer_intr(dwc_hc_t *_hc,
11825+ dwc_otg_hc_regs_t *_hc_regs,
11826+ struct urb *_urb,
11827+ dwc_otg_qtd_t *_qtd,
11828+ dwc_otg_halt_status_e _halt_status)
11829+{
11830+ uint32_t bytes_transferred = get_actual_xfer_length(_hc, _hc_regs, _qtd,
11831+ _halt_status, NULL);
11832+ _urb->actual_length += bytes_transferred;
11833+
11834+#ifdef DEBUG
11835+ {
11836+ hctsiz_data_t hctsiz;
11837+ hctsiz.d32 = dwc_read_reg32(&_hc_regs->hctsiz);
11838+ DWC_DEBUGPL(DBG_HCDV, "DWC_otg: %s: %s, channel %d\n",
11839+ __func__, (_hc->ep_is_in ? "IN" : "OUT"), _hc->hc_num);
11840+ DWC_DEBUGPL(DBG_HCDV, " _hc->start_pkt_count %d\n", _hc->start_pkt_count);
11841+ DWC_DEBUGPL(DBG_HCDV, " hctsiz.pktcnt %d\n", hctsiz.b.pktcnt);
11842+ DWC_DEBUGPL(DBG_HCDV, " _hc->max_packet %d\n", _hc->max_packet);
11843+ DWC_DEBUGPL(DBG_HCDV, " bytes_transferred %d\n", bytes_transferred);
11844+ DWC_DEBUGPL(DBG_HCDV, " _urb->actual_length %d\n", _urb->actual_length);
11845+ DWC_DEBUGPL(DBG_HCDV, " _urb->transfer_buffer_length %d\n",
11846+ _urb->transfer_buffer_length);
11847+ }
11848+#endif
11849+}
11850+
11851+/**
11852+ * Handles a host channel NAK interrupt. This handler may be called in either
11853+ * DMA mode or Slave mode.
11854+ */
11855+static int32_t handle_hc_nak_intr(dwc_otg_hcd_t *_hcd,
11856+ dwc_hc_t *_hc,
11857+ dwc_otg_hc_regs_t *_hc_regs,
11858+ dwc_otg_qtd_t *_qtd, int *must_free)
11859+{
11860+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
11861+ "NAK Received--\n", _hc->hc_num);
11862+
11863+ /*
11864+ * Handle NAK for IN/OUT SSPLIT/CSPLIT transfers, bulk, control, and
11865+ * interrupt. Re-start the SSPLIT transfer.
11866+ */
11867+ if (_hc->do_split) {
11868+ if (_hc->complete_split) {
11869+ _qtd->error_count = 0;
11870+ }
11871+ _qtd->complete_split = 0;
11872+ halt_channel(_hcd, _hc, _qtd, DWC_OTG_HC_XFER_NAK, must_free);
11873+ goto handle_nak_done;
11874+ }
11875+
11876+ switch (usb_pipetype(_qtd->urb->pipe)) {
11877+ case PIPE_CONTROL:
11878+ case PIPE_BULK:
11879+ if (_hcd->core_if->dma_enable && _hc->ep_is_in) {
11880+ /*
11881+ * NAK interrupts are enabled on bulk/control IN
11882+ * transfers in DMA mode for the sole purpose of
11883+ * resetting the error count after a transaction error
11884+ * occurs. The core will continue transferring data.
11885+ */
11886+ _qtd->error_count = 0;
11887+ goto handle_nak_done;
11888+ }
11889+
11890+ /*
11891+ * NAK interrupts normally occur during OUT transfers in DMA
11892+ * or Slave mode. For IN transfers, more requests will be
11893+ * queued as request queue space is available.
11894+ */
11895+ _qtd->error_count = 0;
11896+
11897+ if (!_hc->qh->ping_state) {
11898+ update_urb_state_xfer_intr(_hc, _hc_regs, _qtd->urb,
11899+ _qtd, DWC_OTG_HC_XFER_NAK);
11900+ save_data_toggle(_hc, _hc_regs, _qtd);
11901+ if (_qtd->urb->dev->speed == USB_SPEED_HIGH) {
11902+ _hc->qh->ping_state = 1;
11903+ }
11904+ }
11905+
11906+ /*
11907+ * Halt the channel so the transfer can be re-started from
11908+ * the appropriate point or the PING protocol will
11909+ * start/continue.
11910+ */
11911+ halt_channel(_hcd, _hc, _qtd, DWC_OTG_HC_XFER_NAK, must_free);
11912+ break;
11913+ case PIPE_INTERRUPT:
11914+ _qtd->error_count = 0;
11915+ halt_channel(_hcd, _hc, _qtd, DWC_OTG_HC_XFER_NAK, must_free);
11916+ break;
11917+ case PIPE_ISOCHRONOUS:
11918+ /* Should never get called for isochronous transfers. */
11919+ BUG();
11920+ break;
11921+ }
11922+
11923+ handle_nak_done:
11924+ disable_hc_int(_hc_regs,nak);
11925+
11926+ return 1;
11927+}
11928+
11929+/**
11930+ * Handles a host channel ACK interrupt. This interrupt is enabled when
11931+ * performing the PING protocol in Slave mode, when errors occur during
11932+ * either Slave mode or DMA mode, and during Start Split transactions.
11933+ */
11934+static int32_t handle_hc_ack_intr(dwc_otg_hcd_t *_hcd,
11935+ dwc_hc_t * _hc, dwc_otg_hc_regs_t * _hc_regs, dwc_otg_qtd_t * _qtd, int *must_free)
11936+{
11937+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
11938+ "ACK Received--\n", _hc->hc_num);
11939+
11940+ if (_hc->do_split) {
11941+ /*
11942+ * Handle ACK on SSPLIT.
11943+ * ACK should not occur in CSPLIT.
11944+ */
11945+ if ((!_hc->ep_is_in) && (_hc->data_pid_start != DWC_OTG_HC_PID_SETUP)) {
11946+ _qtd->ssplit_out_xfer_count = _hc->xfer_len;
11947+ }
11948+ if (!(_hc->ep_type == DWC_OTG_EP_TYPE_ISOC && !_hc->ep_is_in)) {
11949+ /* Don't need complete for isochronous out transfers. */
11950+ _qtd->complete_split = 1;
11951+ }
11952+
11953+ /* ISOC OUT */
11954+ if ((_hc->ep_type == DWC_OTG_EP_TYPE_ISOC) && !_hc->ep_is_in) {
11955+ switch (_hc->xact_pos) {
11956+ case DWC_HCSPLIT_XACTPOS_ALL:
11957+ break;
11958+ case DWC_HCSPLIT_XACTPOS_END:
11959+ _qtd->isoc_split_pos = DWC_HCSPLIT_XACTPOS_ALL;
11960+ _qtd->isoc_split_offset = 0;
11961+ break;
11962+ case DWC_HCSPLIT_XACTPOS_BEGIN:
11963+ case DWC_HCSPLIT_XACTPOS_MID:
11964+ /*
11965+ * For BEGIN or MID, calculate the length for
11966+ * the next microframe to determine the correct
11967+ * SSPLIT token, either MID or END.
11968+ */
11969+ do {
11970+ struct usb_iso_packet_descriptor *frame_desc;
11971+
11972+ frame_desc = &_qtd->urb->iso_frame_desc[_qtd->isoc_frame_index];
11973+ _qtd->isoc_split_offset += 188;
11974+
11975+ if ((frame_desc->length - _qtd->isoc_split_offset) <= 188) {
11976+ _qtd->isoc_split_pos = DWC_HCSPLIT_XACTPOS_END;
11977+ }
11978+ else {
11979+ _qtd->isoc_split_pos = DWC_HCSPLIT_XACTPOS_MID;
11980+ }
11981+
11982+ } while(0);
11983+ break;
11984+ }
11985+ } else {
11986+ halt_channel(_hcd, _hc, _qtd, DWC_OTG_HC_XFER_ACK, must_free);
11987+ }
11988+ } else {
11989+ _qtd->error_count = 0;
11990+
11991+ if (_hc->qh->ping_state) {
11992+ _hc->qh->ping_state = 0;
11993+ /*
11994+ * Halt the channel so the transfer can be re-started
11995+ * from the appropriate point. This only happens in
11996+ * Slave mode. In DMA mode, the ping_state is cleared
11997+ * when the transfer is started because the core
11998+ * automatically executes the PING, then the transfer.
11999+ */
12000+ halt_channel(_hcd, _hc, _qtd, DWC_OTG_HC_XFER_ACK, must_free);
12001+ } else {
12002+ halt_channel(_hcd, _hc, _qtd, _hc->halt_status, must_free);
12003+ }
12004+ }
12005+
12006+ /*
12007+ * If the ACK occurred when _not_ in the PING state, let the channel
12008+ * continue transferring data after clearing the error count.
12009+ */
12010+
12011+ disable_hc_int(_hc_regs,ack);
12012+
12013+ return 1;
12014+}
12015+
12016+/**
12017+ * Handles a host channel NYET interrupt. This interrupt should only occur on
12018+ * Bulk and Control OUT endpoints and for complete split transactions. If a
12019+ * NYET occurs at the same time as a Transfer Complete interrupt, it is
12020+ * handled in the xfercomp interrupt handler, not here. This handler may be
12021+ * called in either DMA mode or Slave mode.
12022+ */
12023+static int32_t handle_hc_nyet_intr(dwc_otg_hcd_t *_hcd,
12024+ dwc_hc_t *_hc,
12025+ dwc_otg_hc_regs_t *_hc_regs,
12026+ dwc_otg_qtd_t *_qtd, int *must_free)
12027+{
12028+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
12029+ "NYET Received--\n", _hc->hc_num);
12030+
12031+ /*
12032+ * NYET on CSPLIT
12033+ * re-do the CSPLIT immediately on non-periodic
12034+ */
12035+ if ((_hc->do_split) && (_hc->complete_split)) {
12036+ if ((_hc->ep_type == DWC_OTG_EP_TYPE_INTR) ||
12037+ (_hc->ep_type == DWC_OTG_EP_TYPE_ISOC)) {
12038+ int frnum = dwc_otg_hcd_get_frame_number(dwc_otg_hcd_to_hcd(_hcd));
12039+
12040+ if (dwc_full_frame_num(frnum) !=
12041+ dwc_full_frame_num(_hc->qh->sched_frame)) {
12042+ /*
12043+ * No longer in the same full speed frame.
12044+ * Treat this as a transaction error.
12045+ */
12046+#if 0
12047+ /** @todo Fix system performance so this can
12048+ * be treated as an error. Right now complete
12049+ * splits cannot be scheduled precisely enough
12050+ * due to other system activity, so this error
12051+ * occurs regularly in Slave mode.
12052+ */
12053+ _qtd->error_count++;
12054+#endif
12055+ _qtd->complete_split = 0;
12056+ halt_channel(_hcd, _hc, _qtd, DWC_OTG_HC_XFER_XACT_ERR, must_free);
12057+ /** @todo add support for isoc release */
12058+ goto handle_nyet_done;
12059+ }
12060+ }
12061+
12062+ halt_channel(_hcd, _hc, _qtd, DWC_OTG_HC_XFER_NYET, must_free);
12063+ goto handle_nyet_done;
12064+ }
12065+
12066+ _hc->qh->ping_state = 1;
12067+ _qtd->error_count = 0;
12068+
12069+ update_urb_state_xfer_intr(_hc, _hc_regs, _qtd->urb, _qtd,
12070+ DWC_OTG_HC_XFER_NYET);
12071+ save_data_toggle(_hc, _hc_regs, _qtd);
12072+
12073+ /*
12074+ * Halt the channel and re-start the transfer so the PING
12075+ * protocol will start.
12076+ */
12077+ halt_channel(_hcd, _hc, _qtd, DWC_OTG_HC_XFER_NYET, must_free);
12078+
12079+handle_nyet_done:
12080+ disable_hc_int(_hc_regs,nyet);
12081+ clear_hc_int(_hc_regs, nyet);
12082+ return 1;
12083+}
12084+
12085+/**
12086+ * Handles a host channel babble interrupt. This handler may be called in
12087+ * either DMA mode or Slave mode.
12088+ */
12089+static int32_t handle_hc_babble_intr(dwc_otg_hcd_t *_hcd,
12090+ dwc_hc_t * _hc, dwc_otg_hc_regs_t * _hc_regs, dwc_otg_qtd_t * _qtd, int *must_free)
12091+{
12092+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
12093+ "Babble Error--\n", _hc->hc_num);
12094+ if (_hc->ep_type != DWC_OTG_EP_TYPE_ISOC) {
12095+ dwc_otg_hcd_complete_urb(_hcd, _qtd->urb, -EOVERFLOW);
12096+ halt_channel(_hcd, _hc, _qtd, DWC_OTG_HC_XFER_BABBLE_ERR, must_free);
12097+ } else {
12098+ dwc_otg_halt_status_e halt_status;
12099+ halt_status = update_isoc_urb_state(_hcd, _hc, _hc_regs, _qtd,
12100+ DWC_OTG_HC_XFER_BABBLE_ERR);
12101+ halt_channel(_hcd, _hc, _qtd, halt_status, must_free);
12102+ }
12103+ disable_hc_int(_hc_regs,bblerr);
12104+ return 1;
12105+}
12106+
12107+/**
12108+ * Handles a host channel AHB error interrupt. This handler is only called in
12109+ * DMA mode.
12110+ */
12111+static int32_t handle_hc_ahberr_intr(dwc_otg_hcd_t *_hcd,
12112+ dwc_hc_t *_hc,
12113+ dwc_otg_hc_regs_t *_hc_regs,
12114+ dwc_otg_qtd_t *_qtd)
12115+{
12116+ hcchar_data_t hcchar;
12117+ hcsplt_data_t hcsplt;
12118+ hctsiz_data_t hctsiz;
12119+ uint32_t hcdma;
12120+ struct urb *urb = _qtd->urb;
12121+
12122+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
12123+ "AHB Error--\n", _hc->hc_num);
12124+
12125+ hcchar.d32 = dwc_read_reg32(&_hc_regs->hcchar);
12126+ hcsplt.d32 = dwc_read_reg32(&_hc_regs->hcsplt);
12127+ hctsiz.d32 = dwc_read_reg32(&_hc_regs->hctsiz);
12128+ hcdma = dwc_read_reg32(&_hc_regs->hcdma);
12129+
12130+ DWC_ERROR("AHB ERROR, Channel %d\n", _hc->hc_num);
12131+ DWC_ERROR(" hcchar 0x%08x, hcsplt 0x%08x\n", hcchar.d32, hcsplt.d32);
12132+ DWC_ERROR(" hctsiz 0x%08x, hcdma 0x%08x\n", hctsiz.d32, hcdma);
12133+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD URB Enqueue\n");
12134+ DWC_ERROR(" Device address: %d\n", usb_pipedevice(urb->pipe));
12135+ DWC_ERROR(" Endpoint: %d, %s\n", usb_pipeendpoint(urb->pipe),
12136+ (usb_pipein(urb->pipe) ? "IN" : "OUT"));
12137+ DWC_ERROR(" Endpoint type: %s\n",
12138+ ({char *pipetype;
12139+ switch (usb_pipetype(urb->pipe)) {
12140+ case PIPE_CONTROL: pipetype = "CONTROL"; break;
12141+ case PIPE_BULK: pipetype = "BULK"; break;
12142+ case PIPE_INTERRUPT: pipetype = "INTERRUPT"; break;
12143+ case PIPE_ISOCHRONOUS: pipetype = "ISOCHRONOUS"; break;
12144+ default: pipetype = "UNKNOWN"; break;
12145+ }; pipetype;}));
12146+ DWC_ERROR(" Speed: %s\n",
12147+ ({char *speed;
12148+ switch (urb->dev->speed) {
12149+ case USB_SPEED_HIGH: speed = "HIGH"; break;
12150+ case USB_SPEED_FULL: speed = "FULL"; break;
12151+ case USB_SPEED_LOW: speed = "LOW"; break;
12152+ default: speed = "UNKNOWN"; break;
12153+ }; speed;}));
12154+ DWC_ERROR(" Max packet size: %d\n",
12155+ usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)));
12156+ DWC_ERROR(" Data buffer length: %d\n", urb->transfer_buffer_length);
12157+ DWC_ERROR(" Transfer buffer: %p, Transfer DMA: %p\n",
12158+ urb->transfer_buffer, (void *)(u32)urb->transfer_dma);
12159+ DWC_ERROR(" Setup buffer: %p, Setup DMA: %p\n",
12160+ urb->setup_packet, (void *)(u32)urb->setup_dma);
12161+ DWC_ERROR(" Interval: %d\n", urb->interval);
12162+
12163+ dwc_otg_hcd_complete_urb(_hcd, urb, -EIO);
12164+
12165+ /*
12166+ * Force a channel halt. Don't call halt_channel because that won't
12167+ * write to the HCCHARn register in DMA mode to force the halt.
12168+ */
12169+ dwc_otg_hc_halt(_hcd->core_if, _hc, DWC_OTG_HC_XFER_AHB_ERR);
12170+
12171+ disable_hc_int(_hc_regs,ahberr);
12172+ return 1;
12173+}
12174+
12175+/**
12176+ * Handles a host channel transaction error interrupt. This handler may be
12177+ * called in either DMA mode or Slave mode.
12178+ */
12179+static int32_t handle_hc_xacterr_intr(dwc_otg_hcd_t *_hcd,
12180+ dwc_hc_t * _hc, dwc_otg_hc_regs_t * _hc_regs, dwc_otg_qtd_t * _qtd, int *must_free)
12181+{
12182+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
12183+ "Transaction Error--\n", _hc->hc_num);
12184+
12185+ switch (usb_pipetype(_qtd->urb->pipe)) {
12186+ case PIPE_CONTROL:
12187+ case PIPE_BULK:
12188+ _qtd->error_count++;
12189+ if (!_hc->qh->ping_state) {
12190+ update_urb_state_xfer_intr(_hc, _hc_regs, _qtd->urb,
12191+ _qtd, DWC_OTG_HC_XFER_XACT_ERR);
12192+ save_data_toggle(_hc, _hc_regs, _qtd);
12193+ if (!_hc->ep_is_in && _qtd->urb->dev->speed == USB_SPEED_HIGH) {
12194+ _hc->qh->ping_state = 1;
12195+ }
12196+ }
12197+
12198+ /*
12199+ * Halt the channel so the transfer can be re-started from
12200+ * the appropriate point or the PING protocol will start.
12201+ */
12202+ halt_channel(_hcd, _hc, _qtd, DWC_OTG_HC_XFER_XACT_ERR, must_free);
12203+ break;
12204+ case PIPE_INTERRUPT:
12205+ _qtd->error_count++;
12206+ if ((_hc->do_split) && (_hc->complete_split)) {
12207+ _qtd->complete_split = 0;
12208+ }
12209+ halt_channel(_hcd, _hc, _qtd, DWC_OTG_HC_XFER_XACT_ERR, must_free);
12210+ break;
12211+ case PIPE_ISOCHRONOUS:
12212+ {
12213+ dwc_otg_halt_status_e halt_status;
12214+ halt_status = update_isoc_urb_state(_hcd, _hc, _hc_regs, _qtd,
12215+ DWC_OTG_HC_XFER_XACT_ERR);
12216+
12217+ halt_channel(_hcd, _hc, _qtd, halt_status, must_free);
12218+ }
12219+ break;
12220+ }
12221+
12222+
12223+ disable_hc_int(_hc_regs,xacterr);
12224+
12225+ return 1;
12226+}
12227+
12228+/**
12229+ * Handles a host channel frame overrun interrupt. This handler may be called
12230+ * in either DMA mode or Slave mode.
12231+ */
12232+static int32_t handle_hc_frmovrun_intr(dwc_otg_hcd_t *_hcd,
12233+ dwc_hc_t * _hc, dwc_otg_hc_regs_t * _hc_regs, dwc_otg_qtd_t * _qtd, int *must_free)
12234+{
12235+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
12236+ "Frame Overrun--\n", _hc->hc_num);
12237+
12238+ switch (usb_pipetype(_qtd->urb->pipe)) {
12239+ case PIPE_CONTROL:
12240+ case PIPE_BULK:
12241+ break;
12242+ case PIPE_INTERRUPT:
12243+ halt_channel(_hcd, _hc, _qtd, DWC_OTG_HC_XFER_FRAME_OVERRUN, must_free);
12244+ break;
12245+ case PIPE_ISOCHRONOUS:
12246+ {
12247+ dwc_otg_halt_status_e halt_status;
12248+ halt_status = update_isoc_urb_state(_hcd, _hc, _hc_regs, _qtd,
12249+ DWC_OTG_HC_XFER_FRAME_OVERRUN);
12250+
12251+ halt_channel(_hcd, _hc, _qtd, halt_status, must_free);
12252+ }
12253+ break;
12254+ }
12255+
12256+ disable_hc_int(_hc_regs,frmovrun);
12257+
12258+ return 1;
12259+}
12260+
12261+/**
12262+ * Handles a host channel data toggle error interrupt. This handler may be
12263+ * called in either DMA mode or Slave mode.
12264+ */
12265+static int32_t handle_hc_datatglerr_intr(dwc_otg_hcd_t *_hcd,
12266+ dwc_hc_t * _hc, dwc_otg_hc_regs_t * _hc_regs, dwc_otg_qtd_t * _qtd, int *must_free)
12267+{
12268+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
12269+ "Data Toggle Error--\n", _hc->hc_num);
12270+
12271+ if (_hc->ep_is_in) {
12272+ _qtd->error_count = 0;
12273+ } else {
12274+ DWC_ERROR("Data Toggle Error on OUT transfer,"
12275+ "channel %d\n", _hc->hc_num);
12276+ }
12277+
12278+ disable_hc_int(_hc_regs,datatglerr);
12279+
12280+ return 1;
12281+}
12282+
12283+#ifdef DEBUG
12284+/**
12285+ * This function is for debug only. It checks that a valid halt status is set
12286+ * and that HCCHARn.chdis is clear. If there's a problem, corrective action is
12287+ * taken and a warning is issued.
12288+ * @return 1 if halt status is ok, 0 otherwise.
12289+ */
12290+static inline int halt_status_ok(dwc_otg_hcd_t *_hcd,
12291+ dwc_hc_t * _hc, dwc_otg_hc_regs_t * _hc_regs, dwc_otg_qtd_t * _qtd, int *must_free)
12292+{
12293+ hcchar_data_t hcchar;
12294+ hctsiz_data_t hctsiz;
12295+ hcint_data_t hcint;
12296+ hcintmsk_data_t hcintmsk;
12297+ hcsplt_data_t hcsplt;
12298+
12299+ if (_hc->halt_status == DWC_OTG_HC_XFER_NO_HALT_STATUS) {
12300+ /*
12301+ * This code is here only as a check. This condition should
12302+ * never happen. Ignore the halt if it does occur.
12303+ */
12304+ hcchar.d32 = dwc_read_reg32(&_hc_regs->hcchar);
12305+ hctsiz.d32 = dwc_read_reg32(&_hc_regs->hctsiz);
12306+ hcint.d32 = dwc_read_reg32(&_hc_regs->hcint);
12307+ hcintmsk.d32 = dwc_read_reg32(&_hc_regs->hcintmsk);
12308+ hcsplt.d32 = dwc_read_reg32(&_hc_regs->hcsplt);
12309+ DWC_WARN("%s: _hc->halt_status == DWC_OTG_HC_XFER_NO_HALT_STATUS, "
12310+ "channel %d, hcchar 0x%08x, hctsiz 0x%08x, "
12311+ "hcint 0x%08x, hcintmsk 0x%08x, "
12312+ "hcsplt 0x%08x, qtd->complete_split %d\n",
12313+ __func__, _hc->hc_num, hcchar.d32, hctsiz.d32,
12314+ hcint.d32, hcintmsk.d32,
12315+ hcsplt.d32, _qtd->complete_split);
12316+
12317+ DWC_WARN("%s: no halt status, channel %d, ignoring interrupt\n",
12318+ __func__, _hc->hc_num);
12319+ DWC_WARN("\n");
12320+ clear_hc_int(_hc_regs,chhltd);
12321+ return 0;
12322+ }
12323+
12324+ /*
12325+ * This code is here only as a check. hcchar.chdis should
12326+ * never be set when the halt interrupt occurs. Halt the
12327+ * channel again if it does occur.
12328+ */
12329+ hcchar.d32 = dwc_read_reg32(&_hc_regs->hcchar);
12330+ if (hcchar.b.chdis) {
12331+ DWC_WARN("%s: hcchar.chdis set unexpectedly, "
12332+ "hcchar 0x%08x, trying to halt again\n",
12333+ __func__, hcchar.d32);
12334+ clear_hc_int(_hc_regs,chhltd);
12335+ _hc->halt_pending = 0;
12336+ halt_channel(_hcd, _hc, _qtd, _hc->halt_status, must_free);
12337+ return 0;
12338+ }
12339+
12340+ return 1;
12341+}
12342+#endif
12343+
12344+/**
12345+ * Handles a host Channel Halted interrupt in DMA mode. This handler
12346+ * determines the reason the channel halted and proceeds accordingly.
12347+ */
12348+static void handle_hc_chhltd_intr_dma(dwc_otg_hcd_t *_hcd,
12349+ dwc_hc_t * _hc, dwc_otg_hc_regs_t * _hc_regs, dwc_otg_qtd_t * _qtd, int *must_free)
12350+{
12351+ hcint_data_t hcint;
12352+ hcintmsk_data_t hcintmsk;
12353+
12354+ if (_hc->halt_status == DWC_OTG_HC_XFER_URB_DEQUEUE ||
12355+ _hc->halt_status == DWC_OTG_HC_XFER_AHB_ERR) {
12356+ /*
12357+ * Just release the channel. A dequeue can happen on a
12358+ * transfer timeout. In the case of an AHB Error, the channel
12359+ * was forced to halt because there's no way to gracefully
12360+ * recover.
12361+ */
12362+ release_channel(_hcd, _hc, _qtd, _hc->halt_status, must_free);
12363+ return;
12364+ }
12365+
12366+ /* Read the HCINTn register to determine the cause for the halt. */
12367+ hcint.d32 = dwc_read_reg32(&_hc_regs->hcint);
12368+ hcintmsk.d32 = dwc_read_reg32(&_hc_regs->hcintmsk);
12369+
12370+ if (hcint.b.xfercomp) {
12371+ /** @todo This is here because of a possible hardware bug. Spec
12372+ * says that on SPLIT-ISOC OUT transfers in DMA mode that a HALT
12373+ * interrupt w/ACK bit set should occur, but I only see the
12374+ * XFERCOMP bit, even with it masked out. This is a workaround
12375+ * for that behavior. Should fix this when hardware is fixed.
12376+ */
12377+ if ((_hc->ep_type == DWC_OTG_EP_TYPE_ISOC) && (!_hc->ep_is_in)) {
12378+ handle_hc_ack_intr(_hcd, _hc, _hc_regs, _qtd, must_free);
12379+ }
12380+ handle_hc_xfercomp_intr(_hcd, _hc, _hc_regs, _qtd, must_free);
12381+ } else if (hcint.b.stall) {
12382+ handle_hc_stall_intr(_hcd, _hc, _hc_regs, _qtd, must_free);
12383+ } else if (hcint.b.xacterr) {
12384+ /*
12385+ * Must handle xacterr before nak or ack. Could get a xacterr
12386+ * at the same time as either of these on a BULK/CONTROL OUT
12387+ * that started with a PING. The xacterr takes precedence.
12388+ */
12389+ handle_hc_xacterr_intr(_hcd, _hc, _hc_regs, _qtd, must_free);
12390+ } else if (hcint.b.nyet) {
12391+ /*
12392+ * Must handle nyet before nak or ack. Could get a nyet at the
12393+ * same time as either of those on a BULK/CONTROL OUT that
12394+ * started with a PING. The nyet takes precedence.
12395+ */
12396+ handle_hc_nyet_intr(_hcd, _hc, _hc_regs, _qtd, must_free);
12397+ } else if (hcint.b.bblerr) {
12398+ handle_hc_babble_intr(_hcd, _hc, _hc_regs, _qtd, must_free);
12399+ } else if (hcint.b.frmovrun) {
12400+ handle_hc_frmovrun_intr(_hcd, _hc, _hc_regs, _qtd, must_free);
12401+ } else if (hcint.b.datatglerr) {
12402+ handle_hc_datatglerr_intr(_hcd, _hc, _hc_regs, _qtd, must_free);
12403+ _hc->qh->data_toggle = 0;
12404+ halt_channel(_hcd, _hc, _qtd, _hc->halt_status, must_free);
12405+ } else if (hcint.b.nak && !hcintmsk.b.nak) {
12406+ /*
12407+ * If nak is not masked, it's because a non-split IN transfer
12408+ * is in an error state. In that case, the nak is handled by
12409+ * the nak interrupt handler, not here. Handle nak here for
12410+ * BULK/CONTROL OUT transfers, which halt on a NAK to allow
12411+ * rewinding the buffer pointer.
12412+ */
12413+ handle_hc_nak_intr(_hcd, _hc, _hc_regs, _qtd, must_free);
12414+ } else if (hcint.b.ack && !hcintmsk.b.ack) {
12415+ /*
12416+ * If ack is not masked, it's because a non-split IN transfer
12417+ * is in an error state. In that case, the ack is handled by
12418+ * the ack interrupt handler, not here. Handle ack here for
12419+ * split transfers. Start splits halt on ACK.
12420+ */
12421+ handle_hc_ack_intr(_hcd, _hc, _hc_regs, _qtd, must_free);
12422+ } else {
12423+ if (_hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
12424+ _hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
12425+ /*
12426+ * A periodic transfer halted with no other channel
12427+ * interrupts set. Assume it was halted by the core
12428+ * because it could not be completed in its scheduled
12429+ * (micro)frame.
12430+ */
12431+#ifdef DEBUG
12432+ DWC_PRINT("%s: Halt channel %d (assume incomplete periodic transfer)\n",
12433+ __func__, _hc->hc_num);
12434+#endif /* */
12435+ halt_channel(_hcd, _hc, _qtd,
12436+ DWC_OTG_HC_XFER_PERIODIC_INCOMPLETE, must_free);
12437+ } else {
12438+#ifdef DEBUG
12439+ DWC_ERROR("%s: Channel %d, DMA Mode -- ChHltd set, but reason "
12440+ "for halting is unknown, nyet %d, hcint 0x%08x, intsts 0x%08x\n",
12441+ __func__, _hc->hc_num, hcint.b.nyet, hcint.d32,
12442+ dwc_read_reg32(&_hcd->core_if->core_global_regs->gintsts));
12443+#endif
12444+ halt_channel(_hcd, _hc, _qtd, _hc->halt_status, must_free);
12445+ }
12446+ }
12447+}
12448+
12449+/**
12450+ * Handles a host channel Channel Halted interrupt.
12451+ *
12452+ * In slave mode, this handler is called only when the driver specifically
12453+ * requests a halt. This occurs during handling other host channel interrupts
12454+ * (e.g. nak, xacterr, stall, nyet, etc.).
12455+ *
12456+ * In DMA mode, this is the interrupt that occurs when the core has finished
12457+ * processing a transfer on a channel. Other host channel interrupts (except
12458+ * ahberr) are disabled in DMA mode.
12459+ */
12460+static int32_t handle_hc_chhltd_intr(dwc_otg_hcd_t *_hcd,
12461+ dwc_hc_t * _hc, dwc_otg_hc_regs_t * _hc_regs, dwc_otg_qtd_t * _qtd, int *must_free)
12462+{
12463+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
12464+ "Channel Halted--\n", _hc->hc_num);
12465+
12466+ if (_hcd->core_if->dma_enable) {
12467+ handle_hc_chhltd_intr_dma(_hcd, _hc, _hc_regs, _qtd, must_free);
12468+ } else {
12469+#ifdef DEBUG
12470+ if (!halt_status_ok(_hcd, _hc, _hc_regs, _qtd, must_free)) {
12471+ return 1;
12472+ }
12473+#endif /* */
12474+ release_channel(_hcd, _hc, _qtd, _hc->halt_status, must_free);
12475+ }
12476+
12477+ return 1;
12478+}
12479+
12480+/** Handles interrupt for a specific Host Channel */
12481+int32_t dwc_otg_hcd_handle_hc_n_intr (dwc_otg_hcd_t *_dwc_otg_hcd, uint32_t _num)
12482+{
12483+ int must_free = 0;
12484+ int retval = 0;
12485+ hcint_data_t hcint;
12486+ hcintmsk_data_t hcintmsk;
12487+ dwc_hc_t *hc;
12488+ dwc_otg_hc_regs_t *hc_regs;
12489+ dwc_otg_qtd_t *qtd;
12490+
12491+ DWC_DEBUGPL(DBG_HCDV, "--Host Channel Interrupt--, Channel %d\n", _num);
12492+
12493+ hc = _dwc_otg_hcd->hc_ptr_array[_num];
12494+ hc_regs = _dwc_otg_hcd->core_if->host_if->hc_regs[_num];
12495+ qtd = list_entry(hc->qh->qtd_list.next, dwc_otg_qtd_t, qtd_list_entry);
12496+
12497+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
12498+ hcintmsk.d32 = dwc_read_reg32(&hc_regs->hcintmsk);
12499+ DWC_DEBUGPL(DBG_HCDV, " hcint 0x%08x, hcintmsk 0x%08x, hcint&hcintmsk 0x%08x\n",
12500+ hcint.d32, hcintmsk.d32, (hcint.d32 & hcintmsk.d32));
12501+ hcint.d32 = hcint.d32 & hcintmsk.d32;
12502+
12503+ if (!_dwc_otg_hcd->core_if->dma_enable) {
12504+ if ((hcint.b.chhltd) && (hcint.d32 != 0x2)) {
12505+ hcint.b.chhltd = 0;
12506+ }
12507+ }
12508+
12509+ if (hcint.b.xfercomp) {
12510+ retval |= handle_hc_xfercomp_intr(_dwc_otg_hcd, hc, hc_regs, qtd, &must_free);
12511+ /*
12512+ * If NYET occurred at same time as Xfer Complete, the NYET is
12513+ * handled by the Xfer Complete interrupt handler. Don't want
12514+ * to call the NYET interrupt handler in this case.
12515+ */
12516+ hcint.b.nyet = 0;
12517+ }
12518+ if (hcint.b.chhltd) {
12519+ retval |= handle_hc_chhltd_intr(_dwc_otg_hcd, hc, hc_regs, qtd, &must_free);
12520+ }
12521+ if (hcint.b.ahberr) {
12522+ retval |= handle_hc_ahberr_intr(_dwc_otg_hcd, hc, hc_regs, qtd);
12523+ }
12524+ if (hcint.b.stall) {
12525+ retval |= handle_hc_stall_intr(_dwc_otg_hcd, hc, hc_regs, qtd, &must_free);
12526+ }
12527+ if (hcint.b.nak) {
12528+ retval |= handle_hc_nak_intr(_dwc_otg_hcd, hc, hc_regs, qtd, &must_free);
12529+ }
12530+ if (hcint.b.ack) {
12531+ retval |= handle_hc_ack_intr(_dwc_otg_hcd, hc, hc_regs, qtd, &must_free);
12532+ }
12533+ if (hcint.b.nyet) {
12534+ retval |= handle_hc_nyet_intr(_dwc_otg_hcd, hc, hc_regs, qtd, &must_free);
12535+ }
12536+ if (hcint.b.xacterr) {
12537+ retval |= handle_hc_xacterr_intr(_dwc_otg_hcd, hc, hc_regs, qtd, &must_free);
12538+ }
12539+ if (hcint.b.bblerr) {
12540+ retval |= handle_hc_babble_intr(_dwc_otg_hcd, hc, hc_regs, qtd, &must_free);
12541+ }
12542+ if (hcint.b.frmovrun) {
12543+ retval |= handle_hc_frmovrun_intr(_dwc_otg_hcd, hc, hc_regs, qtd, &must_free);
12544+ }
12545+ if (hcint.b.datatglerr) {
12546+ retval |= handle_hc_datatglerr_intr(_dwc_otg_hcd, hc, hc_regs, qtd, &must_free);
12547+ }
12548+
12549+ /*
12550+ * Logic to free the qtd here, at the end of the hc intr
12551+ * processing, if the handling of this interrupt determined
12552+ * that it needs to be freed.
12553+ */
12554+ if (must_free) {
12555+ /* Free the qtd here now that we are done using it. */
12556+ dwc_otg_hcd_qtd_free(qtd);
12557+ }
12558+ return retval;
12559+}
12560+
12561+#endif /* DWC_DEVICE_ONLY */
12562diff --git a/drivers/usb/dwc_otg/dwc_otg_hcd_queue.c b/drivers/usb/dwc_otg/dwc_otg_hcd_queue.c
12563new file mode 100644
12564index 0000000..fcb5ce6
12565--- /dev/null
12566+++ b/drivers/usb/dwc_otg/dwc_otg_hcd_queue.c
12567@@ -0,0 +1,794 @@
12568+/* ==========================================================================
12569+ * $File: //dwh/usb_iip/dev/software/otg_ipmate/linux/drivers/dwc_otg_hcd_queue.c $
12570+ * $Revision: 1.1.1.1 $
12571+ * $Date: 2009-04-17 06:15:34 $
12572+ * $Change: 537387 $
12573+ *
12574+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
12575+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
12576+ * otherwise expressly agreed to in writing between Synopsys and you.
12577+ *
12578+ * The Software IS NOT an item of Licensed Software or Licensed Product under
12579+ * any End User Software License Agreement or Agreement for Licensed Product
12580+ * with Synopsys or any supplement thereto. You are permitted to use and
12581+ * redistribute this Software in source and binary forms, with or without
12582+ * modification, provided that redistributions of source code must retain this
12583+ * notice. You may not view, use, disclose, copy or distribute this file or
12584+ * any information contained herein except pursuant to this license grant from
12585+ * Synopsys. If you do not agree with this notice, including the disclaimer
12586+ * below, then you are not authorized to use the Software.
12587+ *
12588+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
12589+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
12590+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
12591+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
12592+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
12593+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
12594+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
12595+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
12596+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
12597+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
12598+ * DAMAGE.
12599+ * ========================================================================== */
12600+#ifndef DWC_DEVICE_ONLY
12601+
12602+/**
12603+ * @file
12604+ *
12605+ * This file contains the functions to manage Queue Heads and Queue
12606+ * Transfer Descriptors.
12607+ */
12608+#include <linux/kernel.h>
12609+#include <linux/module.h>
12610+#include <linux/moduleparam.h>
12611+#include <linux/init.h>
12612+#include <linux/device.h>
12613+#include <linux/errno.h>
12614+#include <linux/list.h>
12615+#include <linux/interrupt.h>
12616+#include <linux/string.h>
12617+
12618+#include "dwc_otg_driver.h"
12619+#include "dwc_otg_hcd.h"
12620+#include "dwc_otg_regs.h"
12621+
12622+/**
12623+ * This function allocates and initializes a QH.
12624+ *
12625+ * @param _hcd The HCD state structure for the DWC OTG controller.
12626+ * @param[in] _urb Holds the information about the device/endpoint that we need
12627+ * to initialize the QH.
12628+ *
12629+ * @return Returns pointer to the newly allocated QH, or NULL on error. */
12630+dwc_otg_qh_t *dwc_otg_hcd_qh_create (dwc_otg_hcd_t *_hcd, struct urb *_urb)
12631+{
12632+ dwc_otg_qh_t *qh;
12633+
12634+ /* Allocate memory */
12635+ /** @todo add memflags argument */
12636+ qh = dwc_otg_hcd_qh_alloc ();
12637+ if (qh == NULL) {
12638+ return NULL;
12639+ }
12640+
12641+ dwc_otg_hcd_qh_init (_hcd, qh, _urb);
12642+ return qh;
12643+}
12644+
12645+/** Free each QTD in the QH's QTD-list then free the QH. QH should already be
12646+ * removed from a list. QTD list should already be empty if called from URB
12647+ * Dequeue.
12648+ *
12649+ * @param[in] _qh The QH to free.
12650+ */
12651+void dwc_otg_hcd_qh_free (dwc_otg_qh_t *_qh)
12652+{
12653+ dwc_otg_qtd_t *qtd;
12654+ struct list_head *pos;
12655+ unsigned long flags;
12656+
12657+ /* Free each QTD in the QTD list */
12658+ local_irq_save (flags);
12659+ for (pos = _qh->qtd_list.next;
12660+ pos != &_qh->qtd_list;
12661+ pos = _qh->qtd_list.next)
12662+ {
12663+ list_del (pos);
12664+ qtd = dwc_list_to_qtd (pos);
12665+ dwc_otg_hcd_qtd_free (qtd);
12666+ }
12667+ local_irq_restore (flags);
12668+
12669+ kfree (_qh);
12670+ return;
12671+}
12672+
12673+/** Initializes a QH structure.
12674+ *
12675+ * @param[in] _hcd The HCD state structure for the DWC OTG controller.
12676+ * @param[in] _qh The QH to init.
12677+ * @param[in] _urb Holds the information about the device/endpoint that we need
12678+ * to initialize the QH. */
12679+#define SCHEDULE_SLOP 10
12680+void dwc_otg_hcd_qh_init(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh, struct urb *_urb)
12681+{
12682+ memset (_qh, 0, sizeof (dwc_otg_qh_t));
12683+
12684+ /* Initialize QH */
12685+ switch (usb_pipetype(_urb->pipe)) {
12686+ case PIPE_CONTROL:
12687+ _qh->ep_type = USB_ENDPOINT_XFER_CONTROL;
12688+ break;
12689+ case PIPE_BULK:
12690+ _qh->ep_type = USB_ENDPOINT_XFER_BULK;
12691+ break;
12692+ case PIPE_ISOCHRONOUS:
12693+ _qh->ep_type = USB_ENDPOINT_XFER_ISOC;
12694+ break;
12695+ case PIPE_INTERRUPT:
12696+ _qh->ep_type = USB_ENDPOINT_XFER_INT;
12697+ break;
12698+ }
12699+
12700+ _qh->ep_is_in = usb_pipein(_urb->pipe) ? 1 : 0;
12701+
12702+ _qh->data_toggle = DWC_OTG_HC_PID_DATA0;
12703+ _qh->maxp = usb_maxpacket(_urb->dev, _urb->pipe, !(usb_pipein(_urb->pipe)));
12704+ INIT_LIST_HEAD(&_qh->qtd_list);
12705+ INIT_LIST_HEAD(&_qh->qh_list_entry);
12706+ _qh->channel = NULL;
12707+
12708+ /* FS/LS Enpoint on HS Hub
12709+ * NOT virtual root hub */
12710+ _qh->do_split = 0;
12711+ _qh->speed = _urb->dev->speed;
12712+ if (((_urb->dev->speed == USB_SPEED_LOW) ||
12713+ (_urb->dev->speed == USB_SPEED_FULL)) &&
12714+ (_urb->dev->tt) && (_urb->dev->tt->hub) && (_urb->dev->tt->hub->devnum != 1)) {
12715+ DWC_DEBUGPL(DBG_HCD, "QH init: EP %d: TT found at hub addr %d, for port %d\n",
12716+ usb_pipeendpoint(_urb->pipe), _urb->dev->tt->hub->devnum,
12717+ _urb->dev->ttport);
12718+ _qh->do_split = 1;
12719+ }
12720+
12721+ if (_qh->ep_type == USB_ENDPOINT_XFER_INT ||
12722+ _qh->ep_type == USB_ENDPOINT_XFER_ISOC) {
12723+ /* Compute scheduling parameters once and save them. */
12724+ hprt0_data_t hprt;
12725+
12726+ /** @todo Account for split transfers in the bus time. */
12727+ int bytecount = dwc_hb_mult(_qh->maxp) * dwc_max_packet(_qh->maxp);
12728+ _qh->usecs = NS_TO_US(usb_calc_bus_time(_urb->dev->speed,
12729+ usb_pipein(_urb->pipe),
12730+ (_qh->ep_type == USB_ENDPOINT_XFER_ISOC),bytecount));
12731+
12732+ /* Start in a slightly future (micro)frame. */
12733+ _qh->sched_frame = dwc_frame_num_inc(_hcd->frame_number, SCHEDULE_SLOP);
12734+ _qh->interval = _urb->interval;
12735+#if 0
12736+ /* Increase interrupt polling rate for debugging. */
12737+ if (_qh->ep_type == USB_ENDPOINT_XFER_INT) {
12738+ _qh->interval = 8;
12739+ }
12740+#endif
12741+ hprt.d32 = dwc_read_reg32(_hcd->core_if->host_if->hprt0);
12742+ if ((hprt.b.prtspd == DWC_HPRT0_PRTSPD_HIGH_SPEED) &&
12743+ ((_urb->dev->speed == USB_SPEED_LOW) ||
12744+ (_urb->dev->speed == USB_SPEED_FULL)))
12745+ {
12746+ _qh->interval *= 8;
12747+ _qh->sched_frame |= 0x7;
12748+ _qh->start_split_frame = _qh->sched_frame;
12749+ }
12750+ }
12751+
12752+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD QH Initialized\n");
12753+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - qh = %p\n", _qh);
12754+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - Device Address = %d\n",
12755+ _urb->dev->devnum);
12756+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - Endpoint %d, %s\n",
12757+ usb_pipeendpoint(_urb->pipe),
12758+ usb_pipein(_urb->pipe) == USB_DIR_IN ? "IN" : "OUT");
12759+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - Speed = %s\n",
12760+ ({ char *speed; switch (_urb->dev->speed) {
12761+ case USB_SPEED_LOW: speed = "low"; break;
12762+ case USB_SPEED_FULL: speed = "full"; break;
12763+ case USB_SPEED_HIGH: speed = "high"; break;
12764+ default: speed = "?"; break;
12765+ }; speed;}));
12766+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - Type = %s\n",
12767+ ({ char *type; switch (_qh->ep_type) {
12768+ case USB_ENDPOINT_XFER_ISOC: type = "isochronous"; break;
12769+ case USB_ENDPOINT_XFER_INT: type = "interrupt"; break;
12770+ case USB_ENDPOINT_XFER_CONTROL: type = "control"; break;
12771+ case USB_ENDPOINT_XFER_BULK: type = "bulk"; break;
12772+ default: type = "?"; break;
12773+ }; type;}));
12774+#ifdef DEBUG
12775+ if (_qh->ep_type == USB_ENDPOINT_XFER_INT) {
12776+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - usecs = %d\n",
12777+ _qh->usecs);
12778+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - interval = %d\n",
12779+ _qh->interval);
12780+ }
12781+#endif
12782+
12783+ return;
12784+}
12785+
12786+/**
12787+ * Microframe scheduler
12788+ * track the total use in hcd->frame_usecs
12789+ * keep each qh use in qh->frame_usecs
12790+ * when surrendering the qh then donate the time back
12791+ */
12792+const unsigned short max_uframe_usecs[]={ 100, 100, 100, 100, 100, 100, 30, 0 };
12793+
12794+/*
12795+ * called from dwc_otg_hcd.c:dwc_otg_hcd_init
12796+ */
12797+int init_hcd_usecs(dwc_otg_hcd_t *_hcd)
12798+{
12799+ int i;
12800+ for (i=0; i<8; i++) {
12801+ _hcd->frame_usecs[i] = max_uframe_usecs[i];
12802+ }
12803+ return 0;
12804+}
12805+
12806+static int find_single_uframe(dwc_otg_hcd_t * _hcd, dwc_otg_qh_t * _qh)
12807+{
12808+ int i;
12809+ unsigned short utime;
12810+ int t_left;
12811+ int ret;
12812+ int done;
12813+
12814+ ret = -1;
12815+ utime = _qh->usecs;
12816+ t_left = utime;
12817+ i = 0;
12818+ done = 0;
12819+ while (done == 0) {
12820+ /* At the start _hcd->frame_usecs[i] = max_uframe_usecs[i]; */
12821+ if (utime <= _hcd->frame_usecs[i]) {
12822+ _hcd->frame_usecs[i] -= utime;
12823+ _qh->frame_usecs[i] += utime;
12824+ t_left -= utime;
12825+ ret = i;
12826+ done = 1;
12827+ return ret;
12828+ } else {
12829+ i++;
12830+ if (i == 8) {
12831+ done = 1;
12832+ ret = -1;
12833+ }
12834+ }
12835+ }
12836+ return ret;
12837+}
12838+
12839+/*
12840+ * use this for FS apps that can span multiple uframes
12841+ */
12842+static int find_multi_uframe(dwc_otg_hcd_t * _hcd, dwc_otg_qh_t * _qh)
12843+{
12844+ int i;
12845+ int j;
12846+ unsigned short utime;
12847+ int t_left;
12848+ int ret;
12849+ int done;
12850+ unsigned short xtime;
12851+
12852+ ret = -1;
12853+ utime = _qh->usecs;
12854+ t_left = utime;
12855+ i = 0;
12856+ done = 0;
12857+loop:
12858+ while (done == 0) {
12859+ if(_hcd->frame_usecs[i] <= 0) {
12860+ i++;
12861+ if (i == 8) {
12862+ done = 1;
12863+ ret = -1;
12864+ }
12865+ goto loop;
12866+ }
12867+
12868+ /*
12869+ * we need n consequtive slots
12870+ * so use j as a start slot j plus j+1 must be enough time (for now)
12871+ */
12872+ xtime= _hcd->frame_usecs[i];
12873+ for (j = i+1 ; j < 8 ; j++ ) {
12874+ /*
12875+ * if we add this frame remaining time to xtime we may
12876+ * be OK, if not we need to test j for a complete frame
12877+ */
12878+ if ((xtime+_hcd->frame_usecs[j]) < utime) {
12879+ if (_hcd->frame_usecs[j] < max_uframe_usecs[j]) {
12880+ j = 8;
12881+ ret = -1;
12882+ continue;
12883+ }
12884+ }
12885+ if (xtime >= utime) {
12886+ ret = i;
12887+ j = 8; /* stop loop with a good value ret */
12888+ continue;
12889+ }
12890+ /* add the frame time to x time */
12891+ xtime += _hcd->frame_usecs[j];
12892+ /* we must have a fully available next frame or break */
12893+ if ((xtime < utime)
12894+ && (_hcd->frame_usecs[j] == max_uframe_usecs[j])) {
12895+ ret = -1;
12896+ j = 8; /* stop loop with a bad value ret */
12897+ continue;
12898+ }
12899+ }
12900+ if (ret >= 0) {
12901+ t_left = utime;
12902+ for (j = i; (t_left>0) && (j < 8); j++ ) {
12903+ t_left -= _hcd->frame_usecs[j];
12904+ if ( t_left <= 0 ) {
12905+ _qh->frame_usecs[j] += _hcd->frame_usecs[j] + t_left;
12906+ _hcd->frame_usecs[j]= -t_left;
12907+ ret = i;
12908+ done = 1;
12909+ } else {
12910+ _qh->frame_usecs[j] += _hcd->frame_usecs[j];
12911+ _hcd->frame_usecs[j] = 0;
12912+ }
12913+ }
12914+ } else {
12915+ i++;
12916+ if (i == 8) {
12917+ done = 1;
12918+ ret = -1;
12919+ }
12920+ }
12921+ }
12922+ return ret;
12923+}
12924+
12925+static int find_uframe(dwc_otg_hcd_t * _hcd, dwc_otg_qh_t * _qh)
12926+{
12927+ int ret;
12928+ ret = -1;
12929+
12930+ if (_qh->speed == USB_SPEED_HIGH) {
12931+ /* if this is a hs transaction we need a full frame */
12932+ ret = find_single_uframe(_hcd, _qh);
12933+ } else {
12934+ /* if this is a fs transaction we may need a sequence of frames */
12935+ ret = find_multi_uframe(_hcd, _qh);
12936+ }
12937+ return ret;
12938+}
12939+
12940+/**
12941+ * Checks that the max transfer size allowed in a host channel is large enough
12942+ * to handle the maximum data transfer in a single (micro)frame for a periodic
12943+ * transfer.
12944+ *
12945+ * @param _hcd The HCD state structure for the DWC OTG controller.
12946+ * @param _qh QH for a periodic endpoint.
12947+ *
12948+ * @return 0 if successful, negative error code otherwise.
12949+ */
12950+static int check_max_xfer_size(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh)
12951+{
12952+ int status;
12953+ uint32_t max_xfer_size;
12954+ uint32_t max_channel_xfer_size;
12955+
12956+ status = 0;
12957+
12958+ max_xfer_size = dwc_max_packet(_qh->maxp) * dwc_hb_mult(_qh->maxp);
12959+ max_channel_xfer_size = _hcd->core_if->core_params->max_transfer_size;
12960+
12961+ if (max_xfer_size > max_channel_xfer_size) {
12962+ DWC_NOTICE("%s: Periodic xfer length %d > "
12963+ "max xfer length for channel %d\n",
12964+ __func__, max_xfer_size, max_channel_xfer_size);
12965+ status = -ENOSPC;
12966+ }
12967+
12968+ return status;
12969+}
12970+
12971+/**
12972+ * Schedules an interrupt or isochronous transfer in the periodic schedule.
12973+ *
12974+ * @param _hcd The HCD state structure for the DWC OTG controller.
12975+ * @param _qh QH for the periodic transfer. The QH should already contain the
12976+ * scheduling information.
12977+ *
12978+ * @return 0 if successful, negative error code otherwise.
12979+ */
12980+static int schedule_periodic(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh)
12981+{
12982+ int status = 0;
12983+
12984+ int frame;
12985+ status = find_uframe(_hcd, _qh);
12986+ frame = -1;
12987+ if (status == 0) {
12988+ frame = 7;
12989+ } else {
12990+ if (status > 0 )
12991+ frame = status-1;
12992+ }
12993+
12994+ /* Set the new frame up */
12995+ if (frame > -1) {
12996+ _qh->sched_frame &= ~0x7;
12997+ _qh->sched_frame |= (frame & 7);
12998+ }
12999+
13000+ if (status != -1 )
13001+ status = 0;
13002+ if (status) {
13003+ DWC_NOTICE("%s: Insufficient periodic bandwidth for "
13004+ "periodic transfer.\n", __func__);
13005+ return status;
13006+ }
13007+
13008+ status = check_max_xfer_size(_hcd, _qh);
13009+ if (status) {
13010+ DWC_NOTICE("%s: Channel max transfer size too small "
13011+ "for periodic transfer.\n", __func__);
13012+ return status;
13013+ }
13014+
13015+ /* Always start in the inactive schedule. */
13016+ list_add_tail(&_qh->qh_list_entry, &_hcd->periodic_sched_inactive);
13017+
13018+
13019+ /* Update claimed usecs per (micro)frame. */
13020+ _hcd->periodic_usecs += _qh->usecs;
13021+
13022+ /* Update average periodic bandwidth claimed and # periodic reqs for usbfs. */
13023+ hcd_to_bus(dwc_otg_hcd_to_hcd(_hcd))->bandwidth_allocated += _qh->usecs / _qh->interval;
13024+ if (_qh->ep_type == USB_ENDPOINT_XFER_INT) {
13025+ hcd_to_bus(dwc_otg_hcd_to_hcd(_hcd))->bandwidth_int_reqs++;
13026+ DWC_DEBUGPL(DBG_HCD, "Scheduled intr: qh %p, usecs %d, period %d\n",
13027+ _qh, _qh->usecs, _qh->interval);
13028+ } else {
13029+ hcd_to_bus(dwc_otg_hcd_to_hcd(_hcd))->bandwidth_isoc_reqs++;
13030+ DWC_DEBUGPL(DBG_HCD, "Scheduled isoc: qh %p, usecs %d, period %d\n",
13031+ _qh, _qh->usecs, _qh->interval);
13032+ }
13033+
13034+ return status;
13035+}
13036+
13037+/**
13038+ * This function adds a QH to either the non periodic or periodic schedule if
13039+ * it is not already in the schedule. If the QH is already in the schedule, no
13040+ * action is taken.
13041+ *
13042+ * @return 0 if successful, negative error code otherwise.
13043+ */
13044+int dwc_otg_hcd_qh_add (dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh)
13045+{
13046+ unsigned long flags;
13047+ int status = 0;
13048+
13049+ local_irq_save(flags);
13050+
13051+ if (!list_empty(&_qh->qh_list_entry)) {
13052+ /* QH already in a schedule. */
13053+ goto done;
13054+ }
13055+
13056+ /* Add the new QH to the appropriate schedule */
13057+ if (dwc_qh_is_non_per(_qh)) {
13058+ /* Always start in the inactive schedule. */
13059+ list_add_tail(&_qh->qh_list_entry, &_hcd->non_periodic_sched_inactive);
13060+ } else {
13061+ status = schedule_periodic(_hcd, _qh);
13062+ }
13063+
13064+ done:
13065+ local_irq_restore(flags);
13066+
13067+ return status;
13068+}
13069+
13070+/**
13071+ * This function adds a QH to the non periodic deferred schedule.
13072+ *
13073+ * @return 0 if successful, negative error code otherwise.
13074+ */
13075+int dwc_otg_hcd_qh_add_deferred(dwc_otg_hcd_t * _hcd, dwc_otg_qh_t * _qh)
13076+{
13077+ unsigned long flags;
13078+ local_irq_save(flags);
13079+ if (!list_empty(&_qh->qh_list_entry)) {
13080+ /* QH already in a schedule. */
13081+ goto done;
13082+ }
13083+
13084+ /* Add the new QH to the non periodic deferred schedule */
13085+ if (dwc_qh_is_non_per(_qh)) {
13086+ list_add_tail(&_qh->qh_list_entry,
13087+ &_hcd->non_periodic_sched_deferred);
13088+ }
13089+done:
13090+ local_irq_restore(flags);
13091+ return 0;
13092+}
13093+
13094+/**
13095+ * Removes an interrupt or isochronous transfer from the periodic schedule.
13096+ *
13097+ * @param _hcd The HCD state structure for the DWC OTG controller.
13098+ * @param _qh QH for the periodic transfer.
13099+ */
13100+static void deschedule_periodic(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh)
13101+{
13102+ int i;
13103+ list_del_init(&_qh->qh_list_entry);
13104+
13105+
13106+ /* Update claimed usecs per (micro)frame. */
13107+ _hcd->periodic_usecs -= _qh->usecs;
13108+
13109+ for (i = 0; i < 8; i++) {
13110+ _hcd->frame_usecs[i] += _qh->frame_usecs[i];
13111+ _qh->frame_usecs[i] = 0;
13112+ }
13113+ /* Update average periodic bandwidth claimed and # periodic reqs for usbfs. */
13114+ hcd_to_bus(dwc_otg_hcd_to_hcd(_hcd))->bandwidth_allocated -= _qh->usecs / _qh->interval;
13115+
13116+ if (_qh->ep_type == USB_ENDPOINT_XFER_INT) {
13117+ hcd_to_bus(dwc_otg_hcd_to_hcd(_hcd))->bandwidth_int_reqs--;
13118+ DWC_DEBUGPL(DBG_HCD, "Descheduled intr: qh %p, usecs %d, period %d\n",
13119+ _qh, _qh->usecs, _qh->interval);
13120+ } else {
13121+ hcd_to_bus(dwc_otg_hcd_to_hcd(_hcd))->bandwidth_isoc_reqs--;
13122+ DWC_DEBUGPL(DBG_HCD, "Descheduled isoc: qh %p, usecs %d, period %d\n",
13123+ _qh, _qh->usecs, _qh->interval);
13124+ }
13125+}
13126+
13127+/**
13128+ * Removes a QH from either the non-periodic or periodic schedule. Memory is
13129+ * not freed.
13130+ *
13131+ * @param[in] _hcd The HCD state structure.
13132+ * @param[in] _qh QH to remove from schedule. */
13133+void dwc_otg_hcd_qh_remove (dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh)
13134+{
13135+ unsigned long flags;
13136+
13137+ local_irq_save(flags);
13138+
13139+ if (list_empty(&_qh->qh_list_entry)) {
13140+ /* QH is not in a schedule. */
13141+ goto done;
13142+ }
13143+
13144+ if (dwc_qh_is_non_per(_qh)) {
13145+ if (_hcd->non_periodic_qh_ptr == &_qh->qh_list_entry) {
13146+ _hcd->non_periodic_qh_ptr = _hcd->non_periodic_qh_ptr->next;
13147+ }
13148+ list_del_init(&_qh->qh_list_entry);
13149+ } else {
13150+ deschedule_periodic(_hcd, _qh);
13151+ }
13152+
13153+ done:
13154+ local_irq_restore(flags);
13155+}
13156+
13157+/**
13158+ * Defers a QH. For non-periodic QHs, removes the QH from the active
13159+ * non-periodic schedule. The QH is added to the deferred non-periodic
13160+ * schedule if any QTDs are still attached to the QH.
13161+ */
13162+int dwc_otg_hcd_qh_deferr(dwc_otg_hcd_t * _hcd, dwc_otg_qh_t * _qh, int delay)
13163+{
13164+ int deact = 1;
13165+ unsigned long flags;
13166+ local_irq_save(flags);
13167+ if (dwc_qh_is_non_per(_qh)) {
13168+ _qh->sched_frame =
13169+ dwc_frame_num_inc(_hcd->frame_number,
13170+ delay);
13171+ _qh->channel = NULL;
13172+ _qh->qtd_in_process = NULL;
13173+ deact = 0;
13174+ dwc_otg_hcd_qh_remove(_hcd, _qh);
13175+ if (!list_empty(&_qh->qtd_list)) {
13176+ /* Add back to deferred non-periodic schedule. */
13177+ dwc_otg_hcd_qh_add_deferred(_hcd, _qh);
13178+ }
13179+ }
13180+ local_irq_restore(flags);
13181+ return deact;
13182+}
13183+
13184+/**
13185+ * Deactivates a QH. For non-periodic QHs, removes the QH from the active
13186+ * non-periodic schedule. The QH is added to the inactive non-periodic
13187+ * schedule if any QTDs are still attached to the QH.
13188+ *
13189+ * For periodic QHs, the QH is removed from the periodic queued schedule. If
13190+ * there are any QTDs still attached to the QH, the QH is added to either the
13191+ * periodic inactive schedule or the periodic ready schedule and its next
13192+ * scheduled frame is calculated. The QH is placed in the ready schedule if
13193+ * the scheduled frame has been reached already. Otherwise it's placed in the
13194+ * inactive schedule. If there are no QTDs attached to the QH, the QH is
13195+ * completely removed from the periodic schedule.
13196+ */
13197+void dwc_otg_hcd_qh_deactivate(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh, int sched_next_periodic_split)
13198+{
13199+ unsigned long flags;
13200+ local_irq_save(flags);
13201+
13202+ if (dwc_qh_is_non_per(_qh)) {
13203+ dwc_otg_hcd_qh_remove(_hcd, _qh);
13204+ if (!list_empty(&_qh->qtd_list)) {
13205+ /* Add back to inactive non-periodic schedule. */
13206+ dwc_otg_hcd_qh_add(_hcd, _qh);
13207+ }
13208+ } else {
13209+ uint16_t frame_number = dwc_otg_hcd_get_frame_number(dwc_otg_hcd_to_hcd(_hcd));
13210+
13211+ if (_qh->do_split) {
13212+ /* Schedule the next continuing periodic split transfer */
13213+ if (sched_next_periodic_split) {
13214+
13215+ _qh->sched_frame = frame_number;
13216+ if (dwc_frame_num_le(frame_number,
13217+ dwc_frame_num_inc(_qh->start_split_frame, 1))) {
13218+ /*
13219+ * Allow one frame to elapse after start
13220+ * split microframe before scheduling
13221+ * complete split, but DONT if we are
13222+ * doing the next start split in the
13223+ * same frame for an ISOC out.
13224+ */
13225+ if ((_qh->ep_type != USB_ENDPOINT_XFER_ISOC) || (_qh->ep_is_in != 0)) {
13226+ _qh->sched_frame = dwc_frame_num_inc(_qh->sched_frame, 1);
13227+ }
13228+ }
13229+ } else {
13230+ _qh->sched_frame = dwc_frame_num_inc(_qh->start_split_frame,
13231+ _qh->interval);
13232+ if (dwc_frame_num_le(_qh->sched_frame, frame_number)) {
13233+ _qh->sched_frame = frame_number;
13234+ }
13235+ _qh->sched_frame |= 0x7;
13236+ _qh->start_split_frame = _qh->sched_frame;
13237+ }
13238+ } else {
13239+ _qh->sched_frame = dwc_frame_num_inc(_qh->sched_frame, _qh->interval);
13240+ if (dwc_frame_num_le(_qh->sched_frame, frame_number)) {
13241+ _qh->sched_frame = frame_number;
13242+ }
13243+ }
13244+
13245+ if (list_empty(&_qh->qtd_list)) {
13246+ dwc_otg_hcd_qh_remove(_hcd, _qh);
13247+ } else {
13248+ /*
13249+ * Remove from periodic_sched_queued and move to
13250+ * appropriate queue.
13251+ */
13252+ if (dwc_frame_num_le(_qh->sched_frame, frame_number)) {
13253+ list_move(&_qh->qh_list_entry,
13254+ &_hcd->periodic_sched_ready);
13255+ } else {
13256+ list_move(&_qh->qh_list_entry,
13257+ &_hcd->periodic_sched_inactive);
13258+ }
13259+ }
13260+ }
13261+
13262+ local_irq_restore(flags);
13263+}
13264+
13265+/**
13266+ * This function allocates and initializes a QTD.
13267+ *
13268+ * @param[in] _urb The URB to create a QTD from. Each URB-QTD pair will end up
13269+ * pointing to each other so each pair should have a unique correlation.
13270+ *
13271+ * @return Returns pointer to the newly allocated QTD, or NULL on error. */
13272+dwc_otg_qtd_t *dwc_otg_hcd_qtd_create (struct urb *_urb)
13273+{
13274+ dwc_otg_qtd_t *qtd;
13275+
13276+ qtd = dwc_otg_hcd_qtd_alloc ();
13277+ if (qtd == NULL) {
13278+ return NULL;
13279+ }
13280+
13281+ dwc_otg_hcd_qtd_init (qtd, _urb);
13282+ return qtd;
13283+}
13284+
13285+/**
13286+ * Initializes a QTD structure.
13287+ *
13288+ * @param[in] _qtd The QTD to initialize.
13289+ * @param[in] _urb The URB to use for initialization. */
13290+void dwc_otg_hcd_qtd_init (dwc_otg_qtd_t *_qtd, struct urb *_urb)
13291+{
13292+ memset (_qtd, 0, sizeof (dwc_otg_qtd_t));
13293+ _qtd->urb = _urb;
13294+ if (usb_pipecontrol(_urb->pipe)) {
13295+ /*
13296+ * The only time the QTD data toggle is used is on the data
13297+ * phase of control transfers. This phase always starts with
13298+ * DATA1.
13299+ */
13300+ _qtd->data_toggle = DWC_OTG_HC_PID_DATA1;
13301+ _qtd->control_phase = DWC_OTG_CONTROL_SETUP;
13302+ }
13303+
13304+ /* start split */
13305+ _qtd->complete_split = 0;
13306+ _qtd->isoc_split_pos = DWC_HCSPLIT_XACTPOS_ALL;
13307+ _qtd->isoc_split_offset = 0;
13308+
13309+ /* Store the qtd ptr in the urb to reference what QTD. */
13310+ _urb->hcpriv = _qtd;
13311+ return;
13312+}
13313+
13314+/**
13315+ * This function adds a QTD to the QTD-list of a QH. It will find the correct
13316+ * QH to place the QTD into. If it does not find a QH, then it will create a
13317+ * new QH. If the QH to which the QTD is added is not currently scheduled, it
13318+ * is placed into the proper schedule based on its EP type.
13319+ *
13320+ * @param[in] _qtd The QTD to add
13321+ * @param[in] _dwc_otg_hcd The DWC HCD structure
13322+ *
13323+ * @return 0 if successful, negative error code otherwise.
13324+ */
13325+int dwc_otg_hcd_qtd_add(dwc_otg_qtd_t * _qtd, dwc_otg_hcd_t * _dwc_otg_hcd)
13326+{
13327+ struct usb_host_endpoint *ep;
13328+ dwc_otg_qh_t *qh;
13329+ unsigned long flags;
13330+ int retval = 0;
13331+ struct urb *urb = _qtd->urb;
13332+
13333+ local_irq_save(flags);
13334+
13335+ /*
13336+ * Get the QH which holds the QTD-list to insert to. Create QH if it
13337+ * doesn't exist.
13338+ */
13339+ ep = dwc_urb_to_endpoint(urb);
13340+ qh = (dwc_otg_qh_t *)ep->hcpriv;
13341+ if (qh == NULL) {
13342+ qh = dwc_otg_hcd_qh_create (_dwc_otg_hcd, urb);
13343+ if (qh == NULL) {
13344+ retval = -1;
13345+ goto done;
13346+ }
13347+ ep->hcpriv = qh;
13348+ }
13349+
13350+ _qtd->qtd_qh_ptr = qh;
13351+ retval = dwc_otg_hcd_qh_add(_dwc_otg_hcd, qh);
13352+ if (retval == 0) {
13353+ list_add_tail(&_qtd->qtd_list_entry, &qh->qtd_list);
13354+ }
13355+
13356+ done:
13357+ local_irq_restore(flags);
13358+ return retval;
13359+}
13360+
13361+#endif /* DWC_DEVICE_ONLY */
13362diff --git a/drivers/usb/dwc_otg/dwc_otg_ifx.c b/drivers/usb/dwc_otg/dwc_otg_ifx.c
13363new file mode 100644
13364index 0000000..0a4c209
13365--- /dev/null
13366+++ b/drivers/usb/dwc_otg/dwc_otg_ifx.c
13367@@ -0,0 +1,100 @@
13368+/******************************************************************************
13369+**
13370+** FILE NAME : dwc_otg_ifx.c
13371+** PROJECT : Twinpass/Danube
13372+** MODULES : DWC OTG USB
13373+**
13374+** DATE : 12 Auguest 2007
13375+** AUTHOR : Sung Winder
13376+** DESCRIPTION : Platform specific initialization.
13377+** COPYRIGHT : Copyright (c) 2007
13378+** Infineon Technologies AG
13379+** 2F, No.2, Li-Hsin Rd., Hsinchu Science Park,
13380+** Hsin-chu City, 300 Taiwan.
13381+**
13382+** This program is free software; you can redistribute it and/or modify
13383+** it under the terms of the GNU General Public License as published by
13384+** the Free Software Foundation; either version 2 of the License, or
13385+** (at your option) any later version.
13386+**
13387+** HISTORY
13388+** $Date $Author $Comment
13389+** 12 Auguest 2007 Sung Winder Initiate Version
13390+*******************************************************************************/
13391+#include "dwc_otg_ifx.h"
13392+
13393+#include <linux/platform_device.h>
13394+#include <linux/kernel.h>
13395+#include <linux/ioport.h>
13396+#include <linux/gpio.h>
13397+
13398+#include <asm/io.h>
13399+//#include <asm/mach-ifxmips/ifxmips.h>
13400+#include <lantiq_soc.h>
13401+
13402+#define IFXMIPS_GPIO_BASE_ADDR (0xBE100B00)
13403+
13404+#define IFXMIPS_GPIO_P0_OUT ((u32 *)(IFXMIPS_GPIO_BASE_ADDR + 0x0010))
13405+#define IFXMIPS_GPIO_P1_OUT ((u32 *)(IFXMIPS_GPIO_BASE_ADDR + 0x0040))
13406+#define IFXMIPS_GPIO_P0_IN ((u32 *)(IFXMIPS_GPIO_BASE_ADDR + 0x0014))
13407+#define IFXMIPS_GPIO_P1_IN ((u32 *)(IFXMIPS_GPIO_BASE_ADDR + 0x0044))
13408+#define IFXMIPS_GPIO_P0_DIR ((u32 *)(IFXMIPS_GPIO_BASE_ADDR + 0x0018))
13409+#define IFXMIPS_GPIO_P1_DIR ((u32 *)(IFXMIPS_GPIO_BASE_ADDR + 0x0048))
13410+#define IFXMIPS_GPIO_P0_ALTSEL0 ((u32 *)(IFXMIPS_GPIO_BASE_ADDR + 0x001C))
13411+#define IFXMIPS_GPIO_P1_ALTSEL0 ((u32 *)(IFXMIPS_GPIO_BASE_ADDR + 0x004C))
13412+#define IFXMIPS_GPIO_P0_ALTSEL1 ((u32 *)(IFXMIPS_GPIO_BASE_ADDR + 0x0020))
13413+#define IFXMIPS_GPIO_P1_ALTSEL1 ((u32 *)(IFXMIPS_GPIO_BASE_ADDR + 0x0050))
13414+#define IFXMIPS_GPIO_P0_OD ((u32 *)(IFXMIPS_GPIO_BASE_ADDR + 0x0024))
13415+#define IFXMIPS_GPIO_P1_OD ((u32 *)(IFXMIPS_GPIO_BASE_ADDR + 0x0054))
13416+#define IFXMIPS_GPIO_P0_STOFF ((u32 *)(IFXMIPS_GPIO_BASE_ADDR + 0x0028))
13417+#define IFXMIPS_GPIO_P1_STOFF ((u32 *)(IFXMIPS_GPIO_BASE_ADDR + 0x0058))
13418+#define IFXMIPS_GPIO_P0_PUDSEL ((u32 *)(IFXMIPS_GPIO_BASE_ADDR + 0x002C))
13419+#define IFXMIPS_GPIO_P1_PUDSEL ((u32 *)(IFXMIPS_GPIO_BASE_ADDR + 0x005C))
13420+#define IFXMIPS_GPIO_P0_PUDEN ((u32 *)(IFXMIPS_GPIO_BASE_ADDR + 0x0030))
13421+#define IFXMIPS_GPIO_P1_PUDEN ((u32 *)(IFXMIPS_GPIO_BASE_ADDR + 0x0060))
13422+
13423+
13424+#define writel ltq_w32
13425+#define readl ltq_r32
13426+void dwc_otg_power_on (void)
13427+{
13428+ // clear power
13429+ writel(readl(DANUBE_PMU_PWDCR) | 0x41, DANUBE_PMU_PWDCR);
13430+ // set clock gating
13431+ writel(readl(DANUBE_CGU_IFCCR) | 0x30, DANUBE_CGU_IFCCR);
13432+ // set power
13433+ writel(readl(DANUBE_PMU_PWDCR) & ~0x1, DANUBE_PMU_PWDCR);
13434+ writel(readl(DANUBE_PMU_PWDCR) & ~0x40, DANUBE_PMU_PWDCR);
13435+ writel(readl(DANUBE_PMU_PWDCR) & ~0x8000, DANUBE_PMU_PWDCR);
13436+
13437+#if 1//defined (DWC_HOST_ONLY)
13438+ // make the hardware be a host controller (default)
13439+ //clear_bit (DANUBE_USBCFG_HDSEL_BIT, (volatile unsigned long *)DANUBE_RCU_UBSCFG);
13440+ writel(readl(DANUBE_RCU_UBSCFG) & ~(1<<DANUBE_USBCFG_HDSEL_BIT), DANUBE_RCU_UBSCFG);
13441+
13442+ //#elif defined (DWC_DEVICE_ONLY)
13443+ /* set the controller to the device mode */
13444+ // set_bit (DANUBE_USBCFG_HDSEL_BIT, (volatile unsigned long *)DANUBE_RCU_UBSCFG);
13445+#else
13446+#error "For Danube/Twinpass, it should be HOST or Device Only."
13447+#endif
13448+
13449+ // set the HC's byte-order to big-endian
13450+ //set_bit (DANUBE_USBCFG_HOST_END_BIT, (volatile unsigned long *)DANUBE_RCU_UBSCFG);
13451+ writel(readl(DANUBE_RCU_UBSCFG) | (1<<DANUBE_USBCFG_HOST_END_BIT), DANUBE_RCU_UBSCFG);
13452+ //clear_bit (DANUBE_USBCFG_SLV_END_BIT, (volatile unsigned long *)DANUBE_RCU_UBSCFG);
13453+ writel(readl(DANUBE_RCU_UBSCFG) & ~(1<<DANUBE_USBCFG_SLV_END_BIT), DANUBE_RCU_UBSCFG);
13454+ //writel(0x400, DANUBE_RCU_UBSCFG);
13455+
13456+ // PHY configurations.
13457+ writel (0x14014, (volatile unsigned long *)0xbe10103c);
13458+}
13459+
13460+int ifx_usb_hc_init(unsigned long base_addr, int irq)
13461+{
13462+ return 0;
13463+}
13464+
13465+void ifx_usb_hc_remove(void)
13466+{
13467+}
13468diff --git a/drivers/usb/dwc_otg/dwc_otg_ifx.h b/drivers/usb/dwc_otg/dwc_otg_ifx.h
13469new file mode 100644
13470index 0000000..402d7a6
13471--- /dev/null
13472+++ b/drivers/usb/dwc_otg/dwc_otg_ifx.h
13473@@ -0,0 +1,85 @@
13474+/******************************************************************************
13475+**
13476+** FILE NAME : dwc_otg_ifx.h
13477+** PROJECT : Twinpass/Danube
13478+** MODULES : DWC OTG USB
13479+**
13480+** DATE : 12 April 2007
13481+** AUTHOR : Sung Winder
13482+** DESCRIPTION : Platform specific initialization.
13483+** COPYRIGHT : Copyright (c) 2007
13484+** Infineon Technologies AG
13485+** 2F, No.2, Li-Hsin Rd., Hsinchu Science Park,
13486+** Hsin-chu City, 300 Taiwan.
13487+**
13488+** This program is free software; you can redistribute it and/or modify
13489+** it under the terms of the GNU General Public License as published by
13490+** the Free Software Foundation; either version 2 of the License, or
13491+** (at your option) any later version.
13492+**
13493+** HISTORY
13494+** $Date $Author $Comment
13495+** 12 April 2007 Sung Winder Initiate Version
13496+*******************************************************************************/
13497+#if !defined(__DWC_OTG_IFX_H__)
13498+#define __DWC_OTG_IFX_H__
13499+
13500+#include <linux/irq.h>
13501+#include <irq.h>
13502+
13503+// 20070316, winder added.
13504+#ifndef SZ_256K
13505+#define SZ_256K 0x00040000
13506+#endif
13507+
13508+extern void dwc_otg_power_on (void);
13509+
13510+/* FIXME: The current Linux-2.6 do not have these header files, but anyway, we need these. */
13511+// #include <asm/danube/danube.h>
13512+// #include <asm/ifx/irq.h>
13513+
13514+/* winder, I used the Danube parameter as default. *
13515+ * We could change this through module param. */
13516+#define IFX_USB_IOMEM_BASE 0x1e101000
13517+#define IFX_USB_IOMEM_SIZE SZ_256K
13518+#define IFX_USB_IRQ LTQ_USB_INT
13519+
13520+/**
13521+ * This function is called to set correct clock gating and power.
13522+ * For Twinpass/Danube board.
13523+ */
13524+#ifndef DANUBE_RCU_BASE_ADDR
13525+#define DANUBE_RCU_BASE_ADDR (0xBF203000)
13526+#endif
13527+
13528+#ifndef DANUBE_CGU
13529+#define DANUBE_CGU (0xBF103000)
13530+#endif
13531+#ifndef DANUBE_CGU_IFCCR
13532+/***CGU Interface Clock Control Register***/
13533+#define DANUBE_CGU_IFCCR ((volatile u32*)(DANUBE_CGU+ 0x0018))
13534+#endif
13535+
13536+#ifndef DANUBE_PMU
13537+#define DANUBE_PMU (KSEG1+0x1F102000)
13538+#endif
13539+#ifndef DANUBE_PMU_PWDCR
13540+/* PMU Power down Control Register */
13541+#define DANUBE_PMU_PWDCR ((volatile u32*)(DANUBE_PMU+0x001C))
13542+#endif
13543+
13544+
13545+#define DANUBE_RCU_UBSCFG ((volatile u32*)(DANUBE_RCU_BASE_ADDR + 0x18))
13546+#define DANUBE_USBCFG_HDSEL_BIT 11 // 0:host, 1:device
13547+#define DANUBE_USBCFG_HOST_END_BIT 10 // 0:little_end, 1:big_end
13548+#define DANUBE_USBCFG_SLV_END_BIT 9 // 0:little_end, 1:big_end
13549+
13550+extern void ltq_mask_and_ack_irq(struct irq_data *d);
13551+
13552+static void inline mask_and_ack_ifx_irq(int x)
13553+{
13554+ struct irq_data d;
13555+ d.irq = x;
13556+ ltq_mask_and_ack_irq(&d);
13557+}
13558+#endif //__DWC_OTG_IFX_H__
13559diff --git a/drivers/usb/dwc_otg/dwc_otg_plat.h b/drivers/usb/dwc_otg/dwc_otg_plat.h
13560new file mode 100644
13561index 0000000..727d0c4
13562--- /dev/null
13563+++ b/drivers/usb/dwc_otg/dwc_otg_plat.h
13564@@ -0,0 +1,269 @@
13565+/* ==========================================================================
13566+ * $File: //dwh/usb_iip/dev/software/otg_ipmate/linux/platform/dwc_otg_plat.h $
13567+ * $Revision: 1.1.1.1 $
13568+ * $Date: 2009-04-17 06:15:34 $
13569+ * $Change: 510301 $
13570+ *
13571+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
13572+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
13573+ * otherwise expressly agreed to in writing between Synopsys and you.
13574+ *
13575+ * The Software IS NOT an item of Licensed Software or Licensed Product under
13576+ * any End User Software License Agreement or Agreement for Licensed Product
13577+ * with Synopsys or any supplement thereto. You are permitted to use and
13578+ * redistribute this Software in source and binary forms, with or without
13579+ * modification, provided that redistributions of source code must retain this
13580+ * notice. You may not view, use, disclose, copy or distribute this file or
13581+ * any information contained herein except pursuant to this license grant from
13582+ * Synopsys. If you do not agree with this notice, including the disclaimer
13583+ * below, then you are not authorized to use the Software.
13584+ *
13585+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
13586+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
13587+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
13588+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
13589+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
13590+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
13591+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
13592+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
13593+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
13594+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
13595+ * DAMAGE.
13596+ * ========================================================================== */
13597+
13598+#if !defined(__DWC_OTG_PLAT_H__)
13599+#define __DWC_OTG_PLAT_H__
13600+
13601+#include <linux/types.h>
13602+#include <linux/slab.h>
13603+#include <linux/list.h>
13604+#include <linux/delay.h>
13605+#include <asm/io.h>
13606+
13607+/**
13608+ * @file
13609+ *
13610+ * This file contains the Platform Specific constants, interfaces
13611+ * (functions and macros) for Linux.
13612+ *
13613+ */
13614+/*#if !defined(__LINUX__)
13615+#error "The contents of this file is Linux specific!!!"
13616+#endif
13617+*/
13618+#include <lantiq_soc.h>
13619+#define writel ltq_w32
13620+#define readl ltq_r32
13621+
13622+/**
13623+ * Reads the content of a register.
13624+ *
13625+ * @param _reg address of register to read.
13626+ * @return contents of the register.
13627+ *
13628+
13629+ * Usage:<br>
13630+ * <code>uint32_t dev_ctl = dwc_read_reg32(&dev_regs->dctl);</code>
13631+ */
13632+static __inline__ uint32_t dwc_read_reg32( volatile uint32_t *_reg)
13633+{
13634+ return readl(_reg);
13635+};
13636+
13637+/**
13638+ * Writes a register with a 32 bit value.
13639+ *
13640+ * @param _reg address of register to read.
13641+ * @param _value to write to _reg.
13642+ *
13643+ * Usage:<br>
13644+ * <code>dwc_write_reg32(&dev_regs->dctl, 0); </code>
13645+ */
13646+static __inline__ void dwc_write_reg32( volatile uint32_t *_reg, const uint32_t _value)
13647+{
13648+ writel( _value, _reg );
13649+};
13650+
13651+/**
13652+ * This function modifies bit values in a register. Using the
13653+ * algorithm: (reg_contents & ~clear_mask) | set_mask.
13654+ *
13655+ * @param _reg address of register to read.
13656+ * @param _clear_mask bit mask to be cleared.
13657+ * @param _set_mask bit mask to be set.
13658+ *
13659+ * Usage:<br>
13660+ * <code> // Clear the SOF Interrupt Mask bit and <br>
13661+ * // set the OTG Interrupt mask bit, leaving all others as they were.
13662+ * dwc_modify_reg32(&dev_regs->gintmsk, DWC_SOF_INT, DWC_OTG_INT);</code>
13663+ */
13664+static __inline__
13665+ void dwc_modify_reg32( volatile uint32_t *_reg, const uint32_t _clear_mask, const uint32_t _set_mask)
13666+{
13667+ writel( (readl(_reg) & ~_clear_mask) | _set_mask, _reg );
13668+};
13669+
13670+
13671+/**
13672+ * Wrapper for the OS micro-second delay function.
13673+ * @param[in] _usecs Microseconds of delay
13674+ */
13675+static __inline__ void UDELAY( const uint32_t _usecs )
13676+{
13677+ udelay( _usecs );
13678+}
13679+
13680+/**
13681+ * Wrapper for the OS milli-second delay function.
13682+ * @param[in] _msecs milliseconds of delay
13683+ */
13684+static __inline__ void MDELAY( const uint32_t _msecs )
13685+{
13686+ mdelay( _msecs );
13687+}
13688+
13689+/**
13690+ * Wrapper for the Linux spin_lock. On the ARM (Integrator)
13691+ * spin_lock() is a nop.
13692+ *
13693+ * @param _lock Pointer to the spinlock.
13694+ */
13695+static __inline__ void SPIN_LOCK( spinlock_t *_lock )
13696+{
13697+ spin_lock(_lock);
13698+}
13699+
13700+/**
13701+ * Wrapper for the Linux spin_unlock. On the ARM (Integrator)
13702+ * spin_lock() is a nop.
13703+ *
13704+ * @param _lock Pointer to the spinlock.
13705+ */
13706+static __inline__ void SPIN_UNLOCK( spinlock_t *_lock )
13707+{
13708+ spin_unlock(_lock);
13709+}
13710+
13711+/**
13712+ * Wrapper (macro) for the Linux spin_lock_irqsave. On the ARM
13713+ * (Integrator) spin_lock() is a nop.
13714+ *
13715+ * @param _l Pointer to the spinlock.
13716+ * @param _f unsigned long for irq flags storage.
13717+ */
13718+#define SPIN_LOCK_IRQSAVE( _l, _f ) { \
13719+ spin_lock_irqsave(_l,_f); \
13720+ }
13721+
13722+/**
13723+ * Wrapper (macro) for the Linux spin_unlock_irqrestore. On the ARM
13724+ * (Integrator) spin_lock() is a nop.
13725+ *
13726+ * @param _l Pointer to the spinlock.
13727+ * @param _f unsigned long for irq flags storage.
13728+ */
13729+#define SPIN_UNLOCK_IRQRESTORE( _l,_f ) {\
13730+ spin_unlock_irqrestore(_l,_f); \
13731+ }
13732+
13733+
13734+/*
13735+ * Debugging support vanishes in non-debug builds.
13736+ */
13737+
13738+
13739+/**
13740+ * The Debug Level bit-mask variable.
13741+ */
13742+extern uint32_t g_dbg_lvl;
13743+/**
13744+ * Set the Debug Level variable.
13745+ */
13746+static inline uint32_t SET_DEBUG_LEVEL( const uint32_t _new )
13747+{
13748+ uint32_t old = g_dbg_lvl;
13749+ g_dbg_lvl = _new;
13750+ return old;
13751+}
13752+
13753+/** When debug level has the DBG_CIL bit set, display CIL Debug messages. */
13754+#define DBG_CIL (0x2)
13755+/** When debug level has the DBG_CILV bit set, display CIL Verbose debug
13756+ * messages */
13757+#define DBG_CILV (0x20)
13758+/** When debug level has the DBG_PCD bit set, display PCD (Device) debug
13759+ * messages */
13760+#define DBG_PCD (0x4)
13761+/** When debug level has the DBG_PCDV set, display PCD (Device) Verbose debug
13762+ * messages */
13763+#define DBG_PCDV (0x40)
13764+/** When debug level has the DBG_HCD bit set, display Host debug messages */
13765+#define DBG_HCD (0x8)
13766+/** When debug level has the DBG_HCDV bit set, display Verbose Host debug
13767+ * messages */
13768+#define DBG_HCDV (0x80)
13769+/** When debug level has the DBG_HCD_URB bit set, display enqueued URBs in host
13770+ * mode. */
13771+#define DBG_HCD_URB (0x800)
13772+
13773+/** When debug level has any bit set, display debug messages */
13774+#define DBG_ANY (0xFF)
13775+
13776+/** All debug messages off */
13777+#define DBG_OFF 0
13778+
13779+/** Prefix string for DWC_DEBUG print macros. */
13780+#define USB_DWC "DWC_otg: "
13781+
13782+/**
13783+ * Print a debug message when the Global debug level variable contains
13784+ * the bit defined in <code>lvl</code>.
13785+ *
13786+ * @param[in] lvl - Debug level, use one of the DBG_ constants above.
13787+ * @param[in] x - like printf
13788+ *
13789+ * Example:<p>
13790+ * <code>
13791+ * DWC_DEBUGPL( DBG_ANY, "%s(%p)\n", __func__, _reg_base_addr);
13792+ * </code>
13793+ * <br>
13794+ * results in:<br>
13795+ * <code>
13796+ * usb-DWC_otg: dwc_otg_cil_init(ca867000)
13797+ * </code>
13798+ */
13799+#ifdef DEBUG
13800+
13801+# define DWC_DEBUGPL(lvl, x...) do{ if ((lvl)&g_dbg_lvl)printk( KERN_DEBUG USB_DWC x ); }while(0)
13802+# define DWC_DEBUGP(x...) DWC_DEBUGPL(DBG_ANY, x )
13803+
13804+# define CHK_DEBUG_LEVEL(level) ((level) & g_dbg_lvl)
13805+
13806+#else
13807+
13808+# define DWC_DEBUGPL(lvl, x...) do{}while(0)
13809+# define DWC_DEBUGP(x...)
13810+
13811+# define CHK_DEBUG_LEVEL(level) (0)
13812+
13813+#endif /*DEBUG*/
13814+
13815+/**
13816+ * Print an Error message.
13817+ */
13818+#define DWC_ERROR(x...) printk( KERN_ERR USB_DWC x )
13819+/**
13820+ * Print a Warning message.
13821+ */
13822+#define DWC_WARN(x...) printk( KERN_WARNING USB_DWC x )
13823+/**
13824+ * Print a notice (normal but significant message).
13825+ */
13826+#define DWC_NOTICE(x...) printk( KERN_NOTICE USB_DWC x )
13827+/**
13828+ * Basic message printing.
13829+ */
13830+#define DWC_PRINT(x...) printk( KERN_INFO USB_DWC x )
13831+
13832+#endif
13833+
13834diff --git a/drivers/usb/dwc_otg/dwc_otg_regs.h b/drivers/usb/dwc_otg/dwc_otg_regs.h
13835new file mode 100644
13836index 0000000..397a954
13837--- /dev/null
13838+++ b/drivers/usb/dwc_otg/dwc_otg_regs.h
13839@@ -0,0 +1,1797 @@
13840+/* ==========================================================================
13841+ * $File: //dwh/usb_iip/dev/software/otg_ipmate/linux/drivers/dwc_otg_regs.h $
13842+ * $Revision: 1.1.1.1 $
13843+ * $Date: 2009-04-17 06:15:34 $
13844+ * $Change: 631780 $
13845+ *
13846+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
13847+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
13848+ * otherwise expressly agreed to in writing between Synopsys and you.
13849+ *
13850+ * The Software IS NOT an item of Licensed Software or Licensed Product under
13851+ * any End User Software License Agreement or Agreement for Licensed Product
13852+ * with Synopsys or any supplement thereto. You are permitted to use and
13853+ * redistribute this Software in source and binary forms, with or without
13854+ * modification, provided that redistributions of source code must retain this
13855+ * notice. You may not view, use, disclose, copy or distribute this file or
13856+ * any information contained herein except pursuant to this license grant from
13857+ * Synopsys. If you do not agree with this notice, including the disclaimer
13858+ * below, then you are not authorized to use the Software.
13859+ *
13860+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
13861+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
13862+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
13863+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
13864+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
13865+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
13866+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
13867+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
13868+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
13869+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
13870+ * DAMAGE.
13871+ * ========================================================================== */
13872+
13873+#ifndef __DWC_OTG_REGS_H__
13874+#define __DWC_OTG_REGS_H__
13875+
13876+/**
13877+ * @file
13878+ *
13879+ * This file contains the data structures for accessing the DWC_otg core registers.
13880+ *
13881+ * The application interfaces with the HS OTG core by reading from and
13882+ * writing to the Control and Status Register (CSR) space through the
13883+ * AHB Slave interface. These registers are 32 bits wide, and the
13884+ * addresses are 32-bit-block aligned.
13885+ * CSRs are classified as follows:
13886+ * - Core Global Registers
13887+ * - Device Mode Registers
13888+ * - Device Global Registers
13889+ * - Device Endpoint Specific Registers
13890+ * - Host Mode Registers
13891+ * - Host Global Registers
13892+ * - Host Port CSRs
13893+ * - Host Channel Specific Registers
13894+ *
13895+ * Only the Core Global registers can be accessed in both Device and
13896+ * Host modes. When the HS OTG core is operating in one mode, either
13897+ * Device or Host, the application must not access registers from the
13898+ * other mode. When the core switches from one mode to another, the
13899+ * registers in the new mode of operation must be reprogrammed as they
13900+ * would be after a power-on reset.
13901+ */
13902+
13903+/****************************************************************************/
13904+/** DWC_otg Core registers .
13905+ * The dwc_otg_core_global_regs structure defines the size
13906+ * and relative field offsets for the Core Global registers.
13907+ */
13908+typedef struct dwc_otg_core_global_regs
13909+{
13910+ /** OTG Control and Status Register. <i>Offset: 000h</i> */
13911+ volatile uint32_t gotgctl;
13912+ /** OTG Interrupt Register. <i>Offset: 004h</i> */
13913+ volatile uint32_t gotgint;
13914+ /**Core AHB Configuration Register. <i>Offset: 008h</i> */
13915+ volatile uint32_t gahbcfg;
13916+#define DWC_GLBINTRMASK 0x0001
13917+#define DWC_DMAENABLE 0x0020
13918+#define DWC_NPTXEMPTYLVL_EMPTY 0x0080
13919+#define DWC_NPTXEMPTYLVL_HALFEMPTY 0x0000
13920+#define DWC_PTXEMPTYLVL_EMPTY 0x0100
13921+#define DWC_PTXEMPTYLVL_HALFEMPTY 0x0000
13922+
13923+
13924+ /**Core USB Configuration Register. <i>Offset: 00Ch</i> */
13925+ volatile uint32_t gusbcfg;
13926+ /**Core Reset Register. <i>Offset: 010h</i> */
13927+ volatile uint32_t grstctl;
13928+ /**Core Interrupt Register. <i>Offset: 014h</i> */
13929+ volatile uint32_t gintsts;
13930+ /**Core Interrupt Mask Register. <i>Offset: 018h</i> */
13931+ volatile uint32_t gintmsk;
13932+ /**Receive Status Queue Read Register (Read Only). <i>Offset: 01Ch</i> */
13933+ volatile uint32_t grxstsr;
13934+ /**Receive Status Queue Read & POP Register (Read Only). <i>Offset: 020h</i>*/
13935+ volatile uint32_t grxstsp;
13936+ /**Receive FIFO Size Register. <i>Offset: 024h</i> */
13937+ volatile uint32_t grxfsiz;
13938+ /**Non Periodic Transmit FIFO Size Register. <i>Offset: 028h</i> */
13939+ volatile uint32_t gnptxfsiz;
13940+ /**Non Periodic Transmit FIFO/Queue Status Register (Read
13941+ * Only). <i>Offset: 02Ch</i> */
13942+ volatile uint32_t gnptxsts;
13943+ /**I2C Access Register. <i>Offset: 030h</i> */
13944+ volatile uint32_t gi2cctl;
13945+ /**PHY Vendor Control Register. <i>Offset: 034h</i> */
13946+ volatile uint32_t gpvndctl;
13947+ /**General Purpose Input/Output Register. <i>Offset: 038h</i> */
13948+ volatile uint32_t ggpio;
13949+ /**User ID Register. <i>Offset: 03Ch</i> */
13950+ volatile uint32_t guid;
13951+ /**Synopsys ID Register (Read Only). <i>Offset: 040h</i> */
13952+ volatile uint32_t gsnpsid;
13953+ /**User HW Config1 Register (Read Only). <i>Offset: 044h</i> */
13954+ volatile uint32_t ghwcfg1;
13955+ /**User HW Config2 Register (Read Only). <i>Offset: 048h</i> */
13956+ volatile uint32_t ghwcfg2;
13957+#define DWC_SLAVE_ONLY_ARCH 0
13958+#define DWC_EXT_DMA_ARCH 1
13959+#define DWC_INT_DMA_ARCH 2
13960+
13961+#define DWC_MODE_HNP_SRP_CAPABLE 0
13962+#define DWC_MODE_SRP_ONLY_CAPABLE 1
13963+#define DWC_MODE_NO_HNP_SRP_CAPABLE 2
13964+#define DWC_MODE_SRP_CAPABLE_DEVICE 3
13965+#define DWC_MODE_NO_SRP_CAPABLE_DEVICE 4
13966+#define DWC_MODE_SRP_CAPABLE_HOST 5
13967+#define DWC_MODE_NO_SRP_CAPABLE_HOST 6
13968+
13969+ /**User HW Config3 Register (Read Only). <i>Offset: 04Ch</i> */
13970+ volatile uint32_t ghwcfg3;
13971+ /**User HW Config4 Register (Read Only). <i>Offset: 050h</i>*/
13972+ volatile uint32_t ghwcfg4;
13973+ /** Reserved <i>Offset: 054h-0FFh</i> */
13974+ uint32_t reserved[43];
13975+ /** Host Periodic Transmit FIFO Size Register. <i>Offset: 100h</i> */
13976+ volatile uint32_t hptxfsiz;
13977+ /** Device Periodic Transmit FIFO#n Register if dedicated fifos are disabled,
13978+ otherwise Device Transmit FIFO#n Register.
13979+ * <i>Offset: 104h + (FIFO_Number-1)*04h, 1 <= FIFO Number <= 15 (1<=n<=15).</i> */
13980+ //volatile uint32_t dptxfsiz[15];
13981+ volatile uint32_t dptxfsiz_dieptxf[15];
13982+} dwc_otg_core_global_regs_t;
13983+
13984+/**
13985+ * This union represents the bit fields of the Core OTG Control
13986+ * and Status Register (GOTGCTL). Set the bits using the bit
13987+ * fields then write the <i>d32</i> value to the register.
13988+ */
13989+typedef union gotgctl_data
13990+{
13991+ /** raw register data */
13992+ uint32_t d32;
13993+ /** register bits */
13994+ struct
13995+ {
13996+ unsigned reserved31_21 : 11;
13997+ unsigned currmod : 1;
13998+ unsigned bsesvld : 1;
13999+ unsigned asesvld : 1;
14000+ unsigned reserved17 : 1;
14001+ unsigned conidsts : 1;
14002+ unsigned reserved15_12 : 4;
14003+ unsigned devhnpen : 1;
14004+ unsigned hstsethnpen : 1;
14005+ unsigned hnpreq : 1;
14006+ unsigned hstnegscs : 1;
14007+ unsigned reserved7_2 : 6;
14008+ unsigned sesreq : 1;
14009+ unsigned sesreqscs : 1;
14010+ } b;
14011+} gotgctl_data_t;
14012+
14013+/**
14014+ * This union represents the bit fields of the Core OTG Interrupt Register
14015+ * (GOTGINT). Set/clear the bits using the bit fields then write the <i>d32</i>
14016+ * value to the register.
14017+ */
14018+typedef union gotgint_data
14019+{
14020+ /** raw register data */
14021+ uint32_t d32;
14022+ /** register bits */
14023+ struct
14024+ {
14025+ /** Current Mode */
14026+ unsigned reserved31_20 : 12;
14027+ /** Debounce Done */
14028+ unsigned debdone : 1;
14029+ /** A-Device Timeout Change */
14030+ unsigned adevtoutchng : 1;
14031+ /** Host Negotiation Detected */
14032+ unsigned hstnegdet : 1;
14033+ unsigned reserver16_10 : 7;
14034+ /** Host Negotiation Success Status Change */
14035+ unsigned hstnegsucstschng : 1;
14036+ /** Session Request Success Status Change */
14037+ unsigned sesreqsucstschng : 1;
14038+ unsigned reserved3_7 : 5;
14039+ /** Session End Detected */
14040+ unsigned sesenddet : 1;
14041+ /** Current Mode */
14042+ unsigned reserved1_0 : 2;
14043+ } b;
14044+} gotgint_data_t;
14045+
14046+
14047+/**
14048+ * This union represents the bit fields of the Core AHB Configuration
14049+ * Register (GAHBCFG). Set/clear the bits using the bit fields then
14050+ * write the <i>d32</i> value to the register.
14051+ */
14052+typedef union gahbcfg_data
14053+{
14054+ /** raw register data */
14055+ uint32_t d32;
14056+ /** register bits */
14057+ struct
14058+ {
14059+#define DWC_GAHBCFG_TXFEMPTYLVL_EMPTY 1
14060+#define DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY 0
14061+ unsigned reserved9_31 : 23;
14062+ unsigned ptxfemplvl : 1;
14063+ unsigned nptxfemplvl_txfemplvl : 1;
14064+#define DWC_GAHBCFG_DMAENABLE 1
14065+ unsigned reserved : 1;
14066+ unsigned dmaenable : 1;
14067+#define DWC_GAHBCFG_INT_DMA_BURST_SINGLE 0
14068+#define DWC_GAHBCFG_INT_DMA_BURST_INCR 1
14069+#define DWC_GAHBCFG_INT_DMA_BURST_INCR4 3
14070+#define DWC_GAHBCFG_INT_DMA_BURST_INCR8 5
14071+#define DWC_GAHBCFG_INT_DMA_BURST_INCR16 7
14072+ unsigned hburstlen : 4;
14073+ unsigned glblintrmsk : 1;
14074+#define DWC_GAHBCFG_GLBINT_ENABLE 1
14075+
14076+ } b;
14077+} gahbcfg_data_t;
14078+
14079+/**
14080+ * This union represents the bit fields of the Core USB Configuration
14081+ * Register (GUSBCFG). Set the bits using the bit fields then write
14082+ * the <i>d32</i> value to the register.
14083+ */
14084+typedef union gusbcfg_data
14085+{
14086+ /** raw register data */
14087+ uint32_t d32;
14088+ /** register bits */
14089+ struct
14090+ {
14091+ unsigned corrupt_tx_packet: 1; /*fscz*/
14092+ unsigned force_device_mode: 1;
14093+ unsigned force_host_mode: 1;
14094+ unsigned reserved23_28 : 6;
14095+ unsigned term_sel_dl_pulse : 1;
14096+ unsigned ulpi_int_vbus_indicator : 1;
14097+ unsigned ulpi_ext_vbus_drv : 1;
14098+ unsigned ulpi_clk_sus_m : 1;
14099+ unsigned ulpi_auto_res : 1;
14100+ unsigned ulpi_fsls : 1;
14101+ unsigned otgutmifssel : 1;
14102+ unsigned phylpwrclksel : 1;
14103+ unsigned nptxfrwnden : 1;
14104+ unsigned usbtrdtim : 4;
14105+ unsigned hnpcap : 1;
14106+ unsigned srpcap : 1;
14107+ unsigned ddrsel : 1;
14108+ unsigned physel : 1;
14109+ unsigned fsintf : 1;
14110+ unsigned ulpi_utmi_sel : 1;
14111+ unsigned phyif : 1;
14112+ unsigned toutcal : 3;
14113+ } b;
14114+} gusbcfg_data_t;
14115+
14116+/**
14117+ * This union represents the bit fields of the Core Reset Register
14118+ * (GRSTCTL). Set/clear the bits using the bit fields then write the
14119+ * <i>d32</i> value to the register.
14120+ */
14121+typedef union grstctl_data
14122+{
14123+ /** raw register data */
14124+ uint32_t d32;
14125+ /** register bits */
14126+ struct
14127+ {
14128+ /** AHB Master Idle. Indicates the AHB Master State
14129+ * Machine is in IDLE condition. */
14130+ unsigned ahbidle : 1;
14131+ /** DMA Request Signal. Indicated DMA request is in
14132+ * probress. Used for debug purpose. */
14133+ unsigned dmareq : 1;
14134+ /** Reserved */
14135+ unsigned reserved29_11 : 19;
14136+ /** TxFIFO Number (TxFNum) (Device and Host).
14137+ *
14138+ * This is the FIFO number which needs to be flushed,
14139+ * using the TxFIFO Flush bit. This field should not
14140+ * be changed until the TxFIFO Flush bit is cleared by
14141+ * the core.
14142+ * - 0x0 : Non Periodic TxFIFO Flush
14143+ * - 0x1 : Periodic TxFIFO #1 Flush in device mode
14144+ * or Periodic TxFIFO in host mode
14145+ * - 0x2 : Periodic TxFIFO #2 Flush in device mode.
14146+ * - ...
14147+ * - 0xF : Periodic TxFIFO #15 Flush in device mode
14148+ * - 0x10: Flush all the Transmit NonPeriodic and
14149+ * Transmit Periodic FIFOs in the core
14150+ */
14151+ unsigned txfnum : 5;
14152+ /** TxFIFO Flush (TxFFlsh) (Device and Host).
14153+ *
14154+ * This bit is used to selectively flush a single or
14155+ * all transmit FIFOs. The application must first
14156+ * ensure that the core is not in the middle of a
14157+ * transaction. <p>The application should write into
14158+ * this bit, only after making sure that neither the
14159+ * DMA engine is writing into the TxFIFO nor the MAC
14160+ * is reading the data out of the FIFO. <p>The
14161+ * application should wait until the core clears this
14162+ * bit, before performing any operations. This bit
14163+ * will takes 8 clocks (slowest of PHY or AHB clock)
14164+ * to clear.
14165+ */
14166+ unsigned txfflsh : 1;
14167+ /** RxFIFO Flush (RxFFlsh) (Device and Host)
14168+ *
14169+ * The application can flush the entire Receive FIFO
14170+ * using this bit. <p>The application must first
14171+ * ensure that the core is not in the middle of a
14172+ * transaction. <p>The application should write into
14173+ * this bit, only after making sure that neither the
14174+ * DMA engine is reading from the RxFIFO nor the MAC
14175+ * is writing the data in to the FIFO. <p>The
14176+ * application should wait until the bit is cleared
14177+ * before performing any other operations. This bit
14178+ * will takes 8 clocks (slowest of PHY or AHB clock)
14179+ * to clear.
14180+ */
14181+ unsigned rxfflsh : 1;
14182+ /** In Token Sequence Learning Queue Flush
14183+ * (INTknQFlsh) (Device Only)
14184+ */
14185+ unsigned intknqflsh : 1;
14186+ /** Host Frame Counter Reset (Host Only)<br>
14187+ *
14188+ * The application can reset the (micro)frame number
14189+ * counter inside the core, using this bit. When the
14190+ * (micro)frame counter is reset, the subsequent SOF
14191+ * sent out by the core, will have a (micro)frame
14192+ * number of 0.
14193+ */
14194+ unsigned hstfrm : 1;
14195+ /** Hclk Soft Reset
14196+ *
14197+ * The application uses this bit to reset the control logic in
14198+ * the AHB clock domain. Only AHB clock domain pipelines are
14199+ * reset.
14200+ */
14201+ unsigned hsftrst : 1;
14202+ /** Core Soft Reset (CSftRst) (Device and Host)
14203+ *
14204+ * The application can flush the control logic in the
14205+ * entire core using this bit. This bit resets the
14206+ * pipelines in the AHB Clock domain as well as the
14207+ * PHY Clock domain.
14208+ *
14209+ * The state machines are reset to an IDLE state, the
14210+ * control bits in the CSRs are cleared, all the
14211+ * transmit FIFOs and the receive FIFO are flushed.
14212+ *
14213+ * The status mask bits that control the generation of
14214+ * the interrupt, are cleared, to clear the
14215+ * interrupt. The interrupt status bits are not
14216+ * cleared, so the application can get the status of
14217+ * any events that occurred in the core after it has
14218+ * set this bit.
14219+ *
14220+ * Any transactions on the AHB are terminated as soon
14221+ * as possible following the protocol. Any
14222+ * transactions on the USB are terminated immediately.
14223+ *
14224+ * The configuration settings in the CSRs are
14225+ * unchanged, so the software doesn't have to
14226+ * reprogram these registers (Device
14227+ * Configuration/Host Configuration/Core System
14228+ * Configuration/Core PHY Configuration).
14229+ *
14230+ * The application can write to this bit, any time it
14231+ * wants to reset the core. This is a self clearing
14232+ * bit and the core clears this bit after all the
14233+ * necessary logic is reset in the core, which may
14234+ * take several clocks, depending on the current state
14235+ * of the core.
14236+ */
14237+ unsigned csftrst : 1;
14238+ } b;
14239+} grstctl_t;
14240+
14241+
14242+/**
14243+ * This union represents the bit fields of the Core Interrupt Mask
14244+ * Register (GINTMSK). Set/clear the bits using the bit fields then
14245+ * write the <i>d32</i> value to the register.
14246+ */
14247+typedef union gintmsk_data
14248+{
14249+ /** raw register data */
14250+ uint32_t d32;
14251+ /** register bits */
14252+ struct
14253+ {
14254+ unsigned wkupintr : 1;
14255+ unsigned sessreqintr : 1;
14256+ unsigned disconnect : 1;
14257+ unsigned conidstschng : 1;
14258+ unsigned reserved27 : 1;
14259+ unsigned ptxfempty : 1;
14260+ unsigned hcintr : 1;
14261+ unsigned portintr : 1;
14262+ unsigned reserved22_23 : 2;
14263+ unsigned incomplisoout : 1;
14264+ unsigned incomplisoin : 1;
14265+ unsigned outepintr : 1;
14266+ unsigned inepintr : 1;
14267+ unsigned epmismatch : 1;
14268+ unsigned reserved16 : 1;
14269+ unsigned eopframe : 1;
14270+ unsigned isooutdrop : 1;
14271+ unsigned enumdone : 1;
14272+ unsigned usbreset : 1;
14273+ unsigned usbsuspend : 1;
14274+ unsigned erlysuspend : 1;
14275+ unsigned i2cintr : 1;
14276+ unsigned reserved8 : 1;
14277+ unsigned goutnakeff : 1;
14278+ unsigned ginnakeff : 1;
14279+ unsigned nptxfempty : 1;
14280+ unsigned rxstsqlvl : 1;
14281+ unsigned sofintr : 1;
14282+ unsigned otgintr : 1;
14283+ unsigned modemismatch : 1;
14284+ unsigned reserved0 : 1;
14285+ } b;
14286+} gintmsk_data_t;
14287+/**
14288+ * This union represents the bit fields of the Core Interrupt Register
14289+ * (GINTSTS). Set/clear the bits using the bit fields then write the
14290+ * <i>d32</i> value to the register.
14291+ */
14292+typedef union gintsts_data
14293+{
14294+ /** raw register data */
14295+ uint32_t d32;
14296+#define DWC_SOF_INTR_MASK 0x0008
14297+ /** register bits */
14298+ struct
14299+ {
14300+#define DWC_HOST_MODE 1
14301+ unsigned wkupintr : 1;
14302+ unsigned sessreqintr : 1;
14303+ unsigned disconnect : 1;
14304+ unsigned conidstschng : 1;
14305+ unsigned reserved27 : 1;
14306+ unsigned ptxfempty : 1;
14307+ unsigned hcintr : 1;
14308+ unsigned portintr : 1;
14309+ unsigned reserved22_23 : 2;
14310+ unsigned incomplisoout : 1;
14311+ unsigned incomplisoin : 1;
14312+ unsigned outepintr : 1;
14313+ unsigned inepint: 1;
14314+ unsigned epmismatch : 1;
14315+ unsigned intokenrx : 1;
14316+ unsigned eopframe : 1;
14317+ unsigned isooutdrop : 1;
14318+ unsigned enumdone : 1;
14319+ unsigned usbreset : 1;
14320+ unsigned usbsuspend : 1;
14321+ unsigned erlysuspend : 1;
14322+ unsigned i2cintr : 1;
14323+ unsigned reserved8 : 1;
14324+ unsigned goutnakeff : 1;
14325+ unsigned ginnakeff : 1;
14326+ unsigned nptxfempty : 1;
14327+ unsigned rxstsqlvl : 1;
14328+ unsigned sofintr : 1;
14329+ unsigned otgintr : 1;
14330+ unsigned modemismatch : 1;
14331+ unsigned curmode : 1;
14332+ } b;
14333+} gintsts_data_t;
14334+
14335+
14336+/**
14337+ * This union represents the bit fields in the Device Receive Status Read and
14338+ * Pop Registers (GRXSTSR, GRXSTSP) Read the register into the <i>d32</i>
14339+ * element then read out the bits using the <i>b</i>it elements.
14340+ */
14341+typedef union device_grxsts_data {
14342+ /** raw register data */
14343+ uint32_t d32;
14344+ /** register bits */
14345+ struct {
14346+ unsigned reserved : 7;
14347+ unsigned fn : 4;
14348+#define DWC_STS_DATA_UPDT 0x2 // OUT Data Packet
14349+#define DWC_STS_XFER_COMP 0x3 // OUT Data Transfer Complete
14350+
14351+#define DWC_DSTS_GOUT_NAK 0x1 // Global OUT NAK
14352+#define DWC_DSTS_SETUP_COMP 0x4 // Setup Phase Complete
14353+#define DWC_DSTS_SETUP_UPDT 0x6 // SETUP Packet
14354+ unsigned pktsts : 4;
14355+ unsigned dpid : 2;
14356+ unsigned bcnt : 11;
14357+ unsigned epnum : 4;
14358+ } b;
14359+} device_grxsts_data_t;
14360+
14361+/**
14362+ * This union represents the bit fields in the Host Receive Status Read and
14363+ * Pop Registers (GRXSTSR, GRXSTSP) Read the register into the <i>d32</i>
14364+ * element then read out the bits using the <i>b</i>it elements.
14365+ */
14366+typedef union host_grxsts_data {
14367+ /** raw register data */
14368+ uint32_t d32;
14369+ /** register bits */
14370+ struct {
14371+ unsigned reserved31_21 : 11;
14372+#define DWC_GRXSTS_PKTSTS_IN 0x2
14373+#define DWC_GRXSTS_PKTSTS_IN_XFER_COMP 0x3
14374+#define DWC_GRXSTS_PKTSTS_DATA_TOGGLE_ERR 0x5
14375+#define DWC_GRXSTS_PKTSTS_CH_HALTED 0x7
14376+ unsigned pktsts : 4;
14377+ unsigned dpid : 2;
14378+ unsigned bcnt : 11;
14379+ unsigned chnum : 4;
14380+ } b;
14381+} host_grxsts_data_t;
14382+
14383+/**
14384+ * This union represents the bit fields in the FIFO Size Registers (HPTXFSIZ,
14385+ * GNPTXFSIZ, DPTXFSIZn). Read the register into the <i>d32</i> element then
14386+ * read out the bits using the <i>b</i>it elements.
14387+ */
14388+typedef union fifosize_data {
14389+ /** raw register data */
14390+ uint32_t d32;
14391+ /** register bits */
14392+ struct {
14393+ unsigned depth : 16;
14394+ unsigned startaddr : 16;
14395+ } b;
14396+} fifosize_data_t;
14397+
14398+/**
14399+ * This union represents the bit fields in the Non-Periodic Transmit
14400+ * FIFO/Queue Status Register (GNPTXSTS). Read the register into the
14401+ * <i>d32</i> element then read out the bits using the <i>b</i>it
14402+ * elements.
14403+ */
14404+typedef union gnptxsts_data {
14405+ /** raw register data */
14406+ uint32_t d32;
14407+ /** register bits */
14408+ struct {
14409+ unsigned reserved : 1;
14410+ /** Top of the Non-Periodic Transmit Request Queue
14411+ * - bits 30:27 - Channel/EP Number
14412+ * - bits 26:25 - Token Type
14413+ * - bit 24 - Terminate (Last entry for the selected
14414+ * channel/EP)
14415+ * - 2'b00 - IN/OUT
14416+ * - 2'b01 - Zero Length OUT
14417+ * - 2'b10 - PING/Complete Split
14418+ * - 2'b11 - Channel Halt
14419+
14420+ */
14421+ unsigned nptxqtop_chnep : 4;
14422+ unsigned nptxqtop_token : 2;
14423+ unsigned nptxqtop_terminate : 1;
14424+ unsigned nptxqspcavail : 8;
14425+ unsigned nptxfspcavail : 16;
14426+ } b;
14427+} gnptxsts_data_t;
14428+
14429+/**
14430+ * This union represents the bit fields in the Transmit
14431+ * FIFO Status Register (DTXFSTS). Read the register into the
14432+ * <i>d32</i> element then read out the bits using the <i>b</i>it
14433+ * elements.
14434+ */
14435+typedef union dtxfsts_data /* fscz */ //*
14436+{
14437+ /** raw register data */
14438+ uint32_t d32;
14439+ /** register bits */
14440+ struct {
14441+ unsigned reserved : 16;
14442+ unsigned txfspcavail : 16;
14443+ } b;
14444+} dtxfsts_data_t;
14445+
14446+/**
14447+ * This union represents the bit fields in the I2C Control Register
14448+ * (I2CCTL). Read the register into the <i>d32</i> element then read out the
14449+ * bits using the <i>b</i>it elements.
14450+ */
14451+typedef union gi2cctl_data {
14452+ /** raw register data */
14453+ uint32_t d32;
14454+ /** register bits */
14455+ struct {
14456+ unsigned bsydne : 1;
14457+ unsigned rw : 1;
14458+ unsigned reserved : 2;
14459+ unsigned i2cdevaddr : 2;
14460+ unsigned i2csuspctl : 1;
14461+ unsigned ack : 1;
14462+ unsigned i2cen : 1;
14463+ unsigned addr : 7;
14464+ unsigned regaddr : 8;
14465+ unsigned rwdata : 8;
14466+ } b;
14467+} gi2cctl_data_t;
14468+
14469+/**
14470+ * This union represents the bit fields in the User HW Config1
14471+ * Register. Read the register into the <i>d32</i> element then read
14472+ * out the bits using the <i>b</i>it elements.
14473+ */
14474+typedef union hwcfg1_data {
14475+ /** raw register data */
14476+ uint32_t d32;
14477+ /** register bits */
14478+ struct {
14479+ unsigned ep_dir15 : 2;
14480+ unsigned ep_dir14 : 2;
14481+ unsigned ep_dir13 : 2;
14482+ unsigned ep_dir12 : 2;
14483+ unsigned ep_dir11 : 2;
14484+ unsigned ep_dir10 : 2;
14485+ unsigned ep_dir9 : 2;
14486+ unsigned ep_dir8 : 2;
14487+ unsigned ep_dir7 : 2;
14488+ unsigned ep_dir6 : 2;
14489+ unsigned ep_dir5 : 2;
14490+ unsigned ep_dir4 : 2;
14491+ unsigned ep_dir3 : 2;
14492+ unsigned ep_dir2 : 2;
14493+ unsigned ep_dir1 : 2;
14494+ unsigned ep_dir0 : 2;
14495+ } b;
14496+} hwcfg1_data_t;
14497+
14498+/**
14499+ * This union represents the bit fields in the User HW Config2
14500+ * Register. Read the register into the <i>d32</i> element then read
14501+ * out the bits using the <i>b</i>it elements.
14502+ */
14503+typedef union hwcfg2_data
14504+{
14505+ /** raw register data */
14506+ uint32_t d32;
14507+ /** register bits */
14508+ struct {
14509+ /* GHWCFG2 */
14510+ unsigned reserved31 : 1;
14511+ unsigned dev_token_q_depth : 5;
14512+ unsigned host_perio_tx_q_depth : 2;
14513+ unsigned nonperio_tx_q_depth : 2;
14514+ unsigned rx_status_q_depth : 2;
14515+ unsigned dynamic_fifo : 1;
14516+ unsigned perio_ep_supported : 1;
14517+ unsigned num_host_chan : 4;
14518+ unsigned num_dev_ep : 4;
14519+ unsigned fs_phy_type : 2;
14520+#define DWC_HWCFG2_HS_PHY_TYPE_NOT_SUPPORTED 0
14521+#define DWC_HWCFG2_HS_PHY_TYPE_UTMI 1
14522+#define DWC_HWCFG2_HS_PHY_TYPE_ULPI 2
14523+#define DWC_HWCFG2_HS_PHY_TYPE_UTMI_ULPI 3
14524+ unsigned hs_phy_type : 2;
14525+ unsigned point2point : 1;
14526+ unsigned architecture : 2;
14527+#define DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG 0
14528+#define DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG 1
14529+#define DWC_HWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE_OTG 2
14530+#define DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE 3
14531+#define DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE 4
14532+#define DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST 5
14533+#define DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST 6
14534+ unsigned op_mode : 3;
14535+ } b;
14536+} hwcfg2_data_t;
14537+
14538+/**
14539+ * This union represents the bit fields in the User HW Config3
14540+ * Register. Read the register into the <i>d32</i> element then read
14541+ * out the bits using the <i>b</i>it elements.
14542+ */
14543+typedef union hwcfg3_data
14544+{
14545+ /** raw register data */
14546+ uint32_t d32;
14547+ /** register bits */
14548+ struct {
14549+ /* GHWCFG3 */
14550+ unsigned dfifo_depth : 16;
14551+ unsigned reserved15_13 : 3;
14552+ unsigned ahb_phy_clock_synch : 1;
14553+ unsigned synch_reset_type : 1;
14554+ unsigned optional_features : 1;
14555+ unsigned vendor_ctrl_if : 1;
14556+ unsigned i2c : 1;
14557+ unsigned otg_func : 1;
14558+ unsigned packet_size_cntr_width : 3;
14559+ unsigned xfer_size_cntr_width : 4;
14560+ } b;
14561+} hwcfg3_data_t;
14562+
14563+/**
14564+ * This union represents the bit fields in the User HW Config4
14565+ * Register. Read the register into the <i>d32</i> element then read
14566+ * out the bits using the <i>b</i>it elements.
14567+ */
14568+typedef union hwcfg4_data
14569+{
14570+ /** raw register data */
14571+ uint32_t d32;
14572+ /** register bits */
14573+ struct {
14574+unsigned reserved31_30 : 2; /* fscz */
14575+ unsigned num_in_eps : 4;
14576+ unsigned ded_fifo_en : 1;
14577+
14578+ unsigned session_end_filt_en : 1;
14579+ unsigned b_valid_filt_en : 1;
14580+ unsigned a_valid_filt_en : 1;
14581+ unsigned vbus_valid_filt_en : 1;
14582+ unsigned iddig_filt_en : 1;
14583+ unsigned num_dev_mode_ctrl_ep : 4;
14584+ unsigned utmi_phy_data_width : 2;
14585+ unsigned min_ahb_freq : 9;
14586+ unsigned power_optimiz : 1;
14587+ unsigned num_dev_perio_in_ep : 4;
14588+ } b;
14589+} hwcfg4_data_t;
14590+
14591+////////////////////////////////////////////
14592+// Device Registers
14593+/**
14594+ * Device Global Registers. <i>Offsets 800h-BFFh</i>
14595+ *
14596+ * The following structures define the size and relative field offsets
14597+ * for the Device Mode Registers.
14598+ *
14599+ * <i>These registers are visible only in Device mode and must not be
14600+ * accessed in Host mode, as the results are unknown.</i>
14601+ */
14602+typedef struct dwc_otg_dev_global_regs
14603+{
14604+ /** Device Configuration Register. <i>Offset 800h</i> */
14605+ volatile uint32_t dcfg;
14606+ /** Device Control Register. <i>Offset: 804h</i> */
14607+ volatile uint32_t dctl;
14608+ /** Device Status Register (Read Only). <i>Offset: 808h</i> */
14609+ volatile uint32_t dsts;
14610+ /** Reserved. <i>Offset: 80Ch</i> */
14611+ uint32_t unused;
14612+ /** Device IN Endpoint Common Interrupt Mask
14613+ * Register. <i>Offset: 810h</i> */
14614+ volatile uint32_t diepmsk;
14615+ /** Device OUT Endpoint Common Interrupt Mask
14616+ * Register. <i>Offset: 814h</i> */
14617+ volatile uint32_t doepmsk;
14618+ /** Device All Endpoints Interrupt Register. <i>Offset: 818h</i> */
14619+ volatile uint32_t daint;
14620+ /** Device All Endpoints Interrupt Mask Register. <i>Offset:
14621+ * 81Ch</i> */
14622+ volatile uint32_t daintmsk;
14623+ /** Device IN Token Queue Read Register-1 (Read Only).
14624+ * <i>Offset: 820h</i> */
14625+ volatile uint32_t dtknqr1;
14626+ /** Device IN Token Queue Read Register-2 (Read Only).
14627+ * <i>Offset: 824h</i> */
14628+ volatile uint32_t dtknqr2;
14629+ /** Device VBUS discharge Register. <i>Offset: 828h</i> */
14630+ volatile uint32_t dvbusdis;
14631+ /** Device VBUS Pulse Register. <i>Offset: 82Ch</i> */
14632+ volatile uint32_t dvbuspulse;
14633+ /** Device IN Token Queue Read Register-3 (Read Only).
14634+ * Device Thresholding control register (Read/Write)
14635+ * <i>Offset: 830h</i> */
14636+ volatile uint32_t dtknqr3_dthrctl;
14637+ /** Device IN Token Queue Read Register-4 (Read Only). /
14638+ * Device IN EPs empty Inr. Mask Register (Read/Write)
14639+ * <i>Offset: 834h</i> */
14640+ volatile uint32_t dtknqr4_fifoemptymsk;
14641+} dwc_otg_device_global_regs_t;
14642+
14643+/**
14644+ * This union represents the bit fields in the Device Configuration
14645+ * Register. Read the register into the <i>d32</i> member then
14646+ * set/clear the bits using the <i>b</i>it elements. Write the
14647+ * <i>d32</i> member to the dcfg register.
14648+ */
14649+typedef union dcfg_data
14650+{
14651+ /** raw register data */
14652+ uint32_t d32;
14653+ /** register bits */
14654+ struct {
14655+ unsigned reserved31_23 : 9;
14656+ /** In Endpoint Mis-match count */
14657+ unsigned epmscnt : 5;
14658+ unsigned reserved13_17 : 5;
14659+ /** Periodic Frame Interval */
14660+#define DWC_DCFG_FRAME_INTERVAL_80 0
14661+#define DWC_DCFG_FRAME_INTERVAL_85 1
14662+#define DWC_DCFG_FRAME_INTERVAL_90 2
14663+#define DWC_DCFG_FRAME_INTERVAL_95 3
14664+ unsigned perfrint : 2;
14665+ /** Device Addresses */
14666+ unsigned devaddr : 7;
14667+ unsigned reserved3 : 1;
14668+ /** Non Zero Length Status OUT Handshake */
14669+#define DWC_DCFG_SEND_STALL 1
14670+ unsigned nzstsouthshk : 1;
14671+ /** Device Speed */
14672+ unsigned devspd : 2;
14673+ } b;
14674+} dcfg_data_t;
14675+
14676+/**
14677+ * This union represents the bit fields in the Device Control
14678+ * Register. Read the register into the <i>d32</i> member then
14679+ * set/clear the bits using the <i>b</i>it elements.
14680+ */
14681+typedef union dctl_data
14682+{
14683+ /** raw register data */
14684+ uint32_t d32;
14685+ /** register bits */
14686+ struct {
14687+ unsigned reserved : 20;
14688+ /** Power-On Programming Done */
14689+ unsigned pwronprgdone : 1;
14690+ /** Clear Global OUT NAK */
14691+ unsigned cgoutnak : 1;
14692+ /** Set Global OUT NAK */
14693+ unsigned sgoutnak : 1;
14694+ /** Clear Global Non-Periodic IN NAK */
14695+ unsigned cgnpinnak : 1;
14696+ /** Set Global Non-Periodic IN NAK */
14697+ unsigned sgnpinnak : 1;
14698+ /** Test Control */
14699+ unsigned tstctl : 3;
14700+ /** Global OUT NAK Status */
14701+ unsigned goutnaksts : 1;
14702+ /** Global Non-Periodic IN NAK Status */
14703+ unsigned gnpinnaksts : 1;
14704+ /** Soft Disconnect */
14705+ unsigned sftdiscon : 1;
14706+ /** Remote Wakeup */
14707+ unsigned rmtwkupsig : 1;
14708+ } b;
14709+} dctl_data_t;
14710+
14711+/**
14712+ * This union represents the bit fields in the Device Status
14713+ * Register. Read the register into the <i>d32</i> member then
14714+ * set/clear the bits using the <i>b</i>it elements.
14715+ */
14716+typedef union dsts_data
14717+{
14718+ /** raw register data */
14719+ uint32_t d32;
14720+ /** register bits */
14721+ struct {
14722+ unsigned reserved22_31 : 10;
14723+ /** Frame or Microframe Number of the received SOF */
14724+ unsigned soffn : 14;
14725+ unsigned reserved4_7: 4;
14726+ /** Erratic Error */
14727+ unsigned errticerr : 1;
14728+ /** Enumerated Speed */
14729+#define DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ 0
14730+#define DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ 1
14731+#define DWC_DSTS_ENUMSPD_LS_PHY_6MHZ 2
14732+#define DWC_DSTS_ENUMSPD_FS_PHY_48MHZ 3
14733+ unsigned enumspd : 2;
14734+ /** Suspend Status */
14735+ unsigned suspsts : 1;
14736+ } b;
14737+} dsts_data_t;
14738+
14739+
14740+/**
14741+ * This union represents the bit fields in the Device IN EP Interrupt
14742+ * Register and the Device IN EP Common Mask Register.
14743+ *
14744+ * - Read the register into the <i>d32</i> member then set/clear the
14745+ * bits using the <i>b</i>it elements.
14746+ */
14747+typedef union diepint_data
14748+{
14749+ /** raw register data */
14750+ uint32_t d32;
14751+ /** register bits */
14752+ struct {
14753+ unsigned reserved07_31 : 23;
14754+ unsigned txfifoundrn : 1;
14755+ /** IN Endpoint HAK Effective mask */
14756+ unsigned emptyintr : 1;
14757+ /** IN Endpoint NAK Effective mask */
14758+ unsigned inepnakeff : 1;
14759+ /** IN Token Received with EP mismatch mask */
14760+ unsigned intknepmis : 1;
14761+ /** IN Token received with TxF Empty mask */
14762+ unsigned intktxfemp : 1;
14763+ /** TimeOUT Handshake mask (non-ISOC EPs) */
14764+ unsigned timeout : 1;
14765+ /** AHB Error mask */
14766+ unsigned ahberr : 1;
14767+ /** Endpoint disable mask */
14768+ unsigned epdisabled : 1;
14769+ /** Transfer complete mask */
14770+ unsigned xfercompl : 1;
14771+ } b;
14772+} diepint_data_t;
14773+/**
14774+ * This union represents the bit fields in the Device IN EP Common
14775+ * Interrupt Mask Register.
14776+ */
14777+typedef union diepint_data diepmsk_data_t;
14778+
14779+/**
14780+ * This union represents the bit fields in the Device OUT EP Interrupt
14781+ * Registerand Device OUT EP Common Interrupt Mask Register.
14782+ *
14783+ * - Read the register into the <i>d32</i> member then set/clear the
14784+ * bits using the <i>b</i>it elements.
14785+ */
14786+typedef union doepint_data
14787+{
14788+ /** raw register data */
14789+ uint32_t d32;
14790+ /** register bits */
14791+ struct {
14792+ unsigned reserved04_31 : 27;
14793+ /** OUT Token Received when Endpoint Disabled */
14794+ unsigned outtknepdis : 1;
14795+ /** Setup Phase Done (contorl EPs) */
14796+ unsigned setup : 1;
14797+ /** AHB Error */
14798+ unsigned ahberr : 1;
14799+ /** Endpoint disable */
14800+ unsigned epdisabled : 1;
14801+ /** Transfer complete */
14802+ unsigned xfercompl : 1;
14803+ } b;
14804+} doepint_data_t;
14805+/**
14806+ * This union represents the bit fields in the Device OUT EP Common
14807+ * Interrupt Mask Register.
14808+ */
14809+typedef union doepint_data doepmsk_data_t;
14810+
14811+
14812+/**
14813+ * This union represents the bit fields in the Device All EP Interrupt
14814+ * and Mask Registers.
14815+ * - Read the register into the <i>d32</i> member then set/clear the
14816+ * bits using the <i>b</i>it elements.
14817+ */
14818+typedef union daint_data
14819+{
14820+ /** raw register data */
14821+ uint32_t d32;
14822+ /** register bits */
14823+ struct {
14824+ /** OUT Endpoint bits */
14825+ unsigned out : 16;
14826+ /** IN Endpoint bits */
14827+ unsigned in : 16;
14828+ } ep;
14829+ struct {
14830+ /** OUT Endpoint bits */
14831+ unsigned outep15 : 1;
14832+ unsigned outep14 : 1;
14833+ unsigned outep13 : 1;
14834+ unsigned outep12 : 1;
14835+ unsigned outep11 : 1;
14836+ unsigned outep10 : 1;
14837+ unsigned outep9 : 1;
14838+ unsigned outep8 : 1;
14839+ unsigned outep7 : 1;
14840+ unsigned outep6 : 1;
14841+ unsigned outep5 : 1;
14842+ unsigned outep4 : 1;
14843+ unsigned outep3 : 1;
14844+ unsigned outep2 : 1;
14845+ unsigned outep1 : 1;
14846+ unsigned outep0 : 1;
14847+ /** IN Endpoint bits */
14848+ unsigned inep15 : 1;
14849+ unsigned inep14 : 1;
14850+ unsigned inep13 : 1;
14851+ unsigned inep12 : 1;
14852+ unsigned inep11 : 1;
14853+ unsigned inep10 : 1;
14854+ unsigned inep9 : 1;
14855+ unsigned inep8 : 1;
14856+ unsigned inep7 : 1;
14857+ unsigned inep6 : 1;
14858+ unsigned inep5 : 1;
14859+ unsigned inep4 : 1;
14860+ unsigned inep3 : 1;
14861+ unsigned inep2 : 1;
14862+ unsigned inep1 : 1;
14863+ unsigned inep0 : 1;
14864+ } b;
14865+} daint_data_t;
14866+
14867+/**
14868+ * This union represents the bit fields in the Device IN Token Queue
14869+ * Read Registers.
14870+ * - Read the register into the <i>d32</i> member.
14871+ * - READ-ONLY Register
14872+ */
14873+typedef union dtknq1_data
14874+{
14875+ /** raw register data */
14876+ uint32_t d32;
14877+ /** register bits */
14878+ struct {
14879+ /** EP Numbers of IN Tokens 0 ... 4 */
14880+ unsigned epnums0_5 : 24;
14881+ /** write pointer has wrapped. */
14882+ unsigned wrap_bit : 1;
14883+ /** Reserved */
14884+ unsigned reserved05_06 : 2;
14885+ /** In Token Queue Write Pointer */
14886+ unsigned intknwptr : 5;
14887+ }b;
14888+} dtknq1_data_t;
14889+
14890+/**
14891+ * This union represents Threshold control Register
14892+ * - Read and write the register into the <i>d32</i> member.
14893+ * - READ-WRITABLE Register
14894+ */
14895+typedef union dthrctl_data //* /*fscz */
14896+{
14897+ /** raw register data */
14898+ uint32_t d32;
14899+ /** register bits */
14900+ struct {
14901+ /** Reserved */
14902+ unsigned reserved26_31 : 6;
14903+ /** Rx Thr. Length */
14904+ unsigned rx_thr_len : 9;
14905+ /** Rx Thr. Enable */
14906+ unsigned rx_thr_en : 1;
14907+ /** Reserved */
14908+ unsigned reserved11_15 : 5;
14909+ /** Tx Thr. Length */
14910+ unsigned tx_thr_len : 9;
14911+ /** ISO Tx Thr. Enable */
14912+ unsigned iso_thr_en : 1;
14913+ /** non ISO Tx Thr. Enable */
14914+ unsigned non_iso_thr_en : 1;
14915+
14916+ }b;
14917+} dthrctl_data_t;
14918+
14919+/**
14920+ * Device Logical IN Endpoint-Specific Registers. <i>Offsets
14921+ * 900h-AFCh</i>
14922+ *
14923+ * There will be one set of endpoint registers per logical endpoint
14924+ * implemented.
14925+ *
14926+ * <i>These registers are visible only in Device mode and must not be
14927+ * accessed in Host mode, as the results are unknown.</i>
14928+ */
14929+typedef struct dwc_otg_dev_in_ep_regs
14930+{
14931+ /** Device IN Endpoint Control Register. <i>Offset:900h +
14932+ * (ep_num * 20h) + 00h</i> */
14933+ volatile uint32_t diepctl;
14934+ /** Reserved. <i>Offset:900h + (ep_num * 20h) + 04h</i> */
14935+ uint32_t reserved04;
14936+ /** Device IN Endpoint Interrupt Register. <i>Offset:900h +
14937+ * (ep_num * 20h) + 08h</i> */
14938+ volatile uint32_t diepint;
14939+ /** Reserved. <i>Offset:900h + (ep_num * 20h) + 0Ch</i> */
14940+ uint32_t reserved0C;
14941+ /** Device IN Endpoint Transfer Size
14942+ * Register. <i>Offset:900h + (ep_num * 20h) + 10h</i> */
14943+ volatile uint32_t dieptsiz;
14944+ /** Device IN Endpoint DMA Address Register. <i>Offset:900h +
14945+ * (ep_num * 20h) + 14h</i> */
14946+ volatile uint32_t diepdma;
14947+ /** Reserved. <i>Offset:900h + (ep_num * 20h) + 18h - 900h +
14948+ * (ep_num * 20h) + 1Ch</i>*/
14949+ volatile uint32_t dtxfsts;
14950+ /** Reserved. <i>Offset:900h + (ep_num * 20h) + 1Ch - 900h +
14951+ * (ep_num * 20h) + 1Ch</i>*/
14952+ uint32_t reserved18;
14953+} dwc_otg_dev_in_ep_regs_t;
14954+
14955+/**
14956+ * Device Logical OUT Endpoint-Specific Registers. <i>Offsets:
14957+ * B00h-CFCh</i>
14958+ *
14959+ * There will be one set of endpoint registers per logical endpoint
14960+ * implemented.
14961+ *
14962+ * <i>These registers are visible only in Device mode and must not be
14963+ * accessed in Host mode, as the results are unknown.</i>
14964+ */
14965+typedef struct dwc_otg_dev_out_ep_regs
14966+{
14967+ /** Device OUT Endpoint Control Register. <i>Offset:B00h +
14968+ * (ep_num * 20h) + 00h</i> */
14969+ volatile uint32_t doepctl;
14970+ /** Device OUT Endpoint Frame number Register. <i>Offset:
14971+ * B00h + (ep_num * 20h) + 04h</i> */
14972+ volatile uint32_t doepfn;
14973+ /** Device OUT Endpoint Interrupt Register. <i>Offset:B00h +
14974+ * (ep_num * 20h) + 08h</i> */
14975+ volatile uint32_t doepint;
14976+ /** Reserved. <i>Offset:B00h + (ep_num * 20h) + 0Ch</i> */
14977+ uint32_t reserved0C;
14978+ /** Device OUT Endpoint Transfer Size Register. <i>Offset:
14979+ * B00h + (ep_num * 20h) + 10h</i> */
14980+ volatile uint32_t doeptsiz;
14981+ /** Device OUT Endpoint DMA Address Register. <i>Offset:B00h
14982+ * + (ep_num * 20h) + 14h</i> */
14983+ volatile uint32_t doepdma;
14984+ /** Reserved. <i>Offset:B00h + (ep_num * 20h) + 18h - B00h +
14985+ * (ep_num * 20h) + 1Ch</i> */
14986+ uint32_t unused[2];
14987+} dwc_otg_dev_out_ep_regs_t;
14988+
14989+/**
14990+ * This union represents the bit fields in the Device EP Control
14991+ * Register. Read the register into the <i>d32</i> member then
14992+ * set/clear the bits using the <i>b</i>it elements.
14993+ */
14994+typedef union depctl_data
14995+{
14996+ /** raw register data */
14997+ uint32_t d32;
14998+ /** register bits */
14999+ struct {
15000+ /** Endpoint Enable */
15001+ unsigned epena : 1;
15002+ /** Endpoint Disable */
15003+ unsigned epdis : 1;
15004+ /** Set DATA1 PID (INTR/Bulk IN and OUT endpoints)
15005+ * Writing to this field sets the Endpoint DPID (DPID)
15006+ * field in this register to DATA1 Set Odd
15007+ * (micro)frame (SetOddFr) (ISO IN and OUT Endpoints)
15008+ * Writing to this field sets the Even/Odd
15009+ * (micro)frame (EO_FrNum) field to odd (micro) frame.
15010+ */
15011+ unsigned setd1pid : 1;
15012+ /** Set DATA0 PID (INTR/Bulk IN and OUT endpoints)
15013+ * Writing to this field sets the Endpoint DPID (DPID)
15014+ * field in this register to DATA0. Set Even
15015+ * (micro)frame (SetEvenFr) (ISO IN and OUT Endpoints)
15016+ * Writing to this field sets the Even/Odd
15017+ * (micro)frame (EO_FrNum) field to even (micro)
15018+ * frame.
15019+ */
15020+ unsigned setd0pid : 1;
15021+ /** Set NAK */
15022+ unsigned snak : 1;
15023+ /** Clear NAK */
15024+ unsigned cnak : 1;
15025+ /** Tx Fifo Number
15026+ * IN EPn/IN EP0
15027+ * OUT EPn/OUT EP0 - reserved */
15028+ unsigned txfnum : 4;
15029+ /** Stall Handshake */
15030+ unsigned stall : 1;
15031+ /** Snoop Mode
15032+ * OUT EPn/OUT EP0
15033+ * IN EPn/IN EP0 - reserved */
15034+ unsigned snp : 1;
15035+ /** Endpoint Type
15036+ * 2'b00: Control
15037+ * 2'b01: Isochronous
15038+ * 2'b10: Bulk
15039+ * 2'b11: Interrupt */
15040+ unsigned eptype : 2;
15041+ /** NAK Status */
15042+ unsigned naksts : 1;
15043+ /** Endpoint DPID (INTR/Bulk IN and OUT endpoints)
15044+ * This field contains the PID of the packet going to
15045+ * be received or transmitted on this endpoint. The
15046+ * application should program the PID of the first
15047+ * packet going to be received or transmitted on this
15048+ * endpoint , after the endpoint is
15049+ * activated. Application use the SetD1PID and
15050+ * SetD0PID fields of this register to program either
15051+ * D0 or D1 PID.
15052+ *
15053+ * The encoding for this field is
15054+ * - 0: D0
15055+ * - 1: D1
15056+ */
15057+ unsigned dpid : 1;
15058+ /** USB Active Endpoint */
15059+ unsigned usbactep : 1;
15060+ /** Next Endpoint
15061+ * IN EPn/IN EP0
15062+ * OUT EPn/OUT EP0 - reserved */
15063+ unsigned nextep : 4;
15064+ /** Maximum Packet Size
15065+ * IN/OUT EPn
15066+ * IN/OUT EP0 - 2 bits
15067+ * 2'b00: 64 Bytes
15068+ * 2'b01: 32
15069+ * 2'b10: 16
15070+ * 2'b11: 8 */
15071+#define DWC_DEP0CTL_MPS_64 0
15072+#define DWC_DEP0CTL_MPS_32 1
15073+#define DWC_DEP0CTL_MPS_16 2
15074+#define DWC_DEP0CTL_MPS_8 3
15075+ unsigned mps : 11;
15076+ } b;
15077+} depctl_data_t;
15078+
15079+/**
15080+ * This union represents the bit fields in the Device EP Transfer
15081+ * Size Register. Read the register into the <i>d32</i> member then
15082+ * set/clear the bits using the <i>b</i>it elements.
15083+ */
15084+typedef union deptsiz_data
15085+{
15086+ /** raw register data */
15087+ uint32_t d32;
15088+ /** register bits */
15089+ struct {
15090+ unsigned reserved : 1;
15091+ /** Multi Count - Periodic IN endpoints */
15092+ unsigned mc : 2;
15093+ /** Packet Count */
15094+ unsigned pktcnt : 10;
15095+ /** Transfer size */
15096+ unsigned xfersize : 19;
15097+ } b;
15098+} deptsiz_data_t;
15099+
15100+/**
15101+ * This union represents the bit fields in the Device EP 0 Transfer
15102+ * Size Register. Read the register into the <i>d32</i> member then
15103+ * set/clear the bits using the <i>b</i>it elements.
15104+ */
15105+typedef union deptsiz0_data
15106+{
15107+ /** raw register data */
15108+ uint32_t d32;
15109+ /** register bits */
15110+ struct {
15111+ unsigned reserved31 : 1;
15112+ /**Setup Packet Count (DOEPTSIZ0 Only) */
15113+ unsigned supcnt : 2;
15114+ /** Reserved */
15115+ unsigned reserved28_20 : 9;
15116+ /** Packet Count */
15117+ unsigned pktcnt : 1;
15118+ /** Reserved */
15119+ unsigned reserved18_7 : 12;
15120+ /** Transfer size */
15121+ unsigned xfersize : 7;
15122+ } b;
15123+} deptsiz0_data_t;
15124+
15125+
15126+/** Maximum number of Periodic FIFOs */
15127+#define MAX_PERIO_FIFOS 15
15128+/** Maximum number of TX FIFOs */
15129+#define MAX_TX_FIFOS 15
15130+/** Maximum number of Endpoints/HostChannels */
15131+#define MAX_EPS_CHANNELS 16
15132+//#define MAX_EPS_CHANNELS 4
15133+
15134+/**
15135+ * The dwc_otg_dev_if structure contains information needed to manage
15136+ * the DWC_otg controller acting in device mode. It represents the
15137+ * programming view of the device-specific aspects of the controller.
15138+ */
15139+typedef struct dwc_otg_dev_if {
15140+ /** Pointer to device Global registers.
15141+ * Device Global Registers starting at offset 800h
15142+ */
15143+ dwc_otg_device_global_regs_t *dev_global_regs;
15144+#define DWC_DEV_GLOBAL_REG_OFFSET 0x800
15145+
15146+ /**
15147+ * Device Logical IN Endpoint-Specific Registers 900h-AFCh
15148+ */
15149+ dwc_otg_dev_in_ep_regs_t *in_ep_regs[MAX_EPS_CHANNELS];
15150+#define DWC_DEV_IN_EP_REG_OFFSET 0x900
15151+#define DWC_EP_REG_OFFSET 0x20
15152+
15153+ /** Device Logical OUT Endpoint-Specific Registers B00h-CFCh */
15154+ dwc_otg_dev_out_ep_regs_t *out_ep_regs[MAX_EPS_CHANNELS];
15155+#define DWC_DEV_OUT_EP_REG_OFFSET 0xB00
15156+
15157+ /* Device configuration information*/
15158+ uint8_t speed; /**< Device Speed 0: Unknown, 1: LS, 2:FS, 3: HS */
15159+ //uint8_t num_eps; /**< Number of EPs range: 0-16 (includes EP0) */
15160+ //uint8_t num_perio_eps; /**< # of Periodic EP range: 0-15 */
15161+ /*fscz */
15162+ uint8_t num_in_eps; /**< Number # of Tx EP range: 0-15 exept ep0 */
15163+ uint8_t num_out_eps; /**< Number # of Rx EP range: 0-15 exept ep 0*/
15164+
15165+ /** Size of periodic FIFOs (Bytes) */
15166+ uint16_t perio_tx_fifo_size[MAX_PERIO_FIFOS];
15167+
15168+ /** Size of Tx FIFOs (Bytes) */
15169+ uint16_t tx_fifo_size[MAX_TX_FIFOS];
15170+
15171+ /** Thresholding enable flags and length varaiables **/
15172+ uint16_t rx_thr_en;
15173+ uint16_t iso_tx_thr_en;
15174+ uint16_t non_iso_tx_thr_en;
15175+
15176+ uint16_t rx_thr_length;
15177+ uint16_t tx_thr_length;
15178+} dwc_otg_dev_if_t;
15179+
15180+/**
15181+ * This union represents the bit fields in the Power and Clock Gating Control
15182+ * Register. Read the register into the <i>d32</i> member then set/clear the
15183+ * bits using the <i>b</i>it elements.
15184+ */
15185+typedef union pcgcctl_data
15186+{
15187+ /** raw register data */
15188+ uint32_t d32;
15189+
15190+ /** register bits */
15191+ struct {
15192+ unsigned reserved31_05 : 27;
15193+ /** PHY Suspended */
15194+ unsigned physuspended : 1;
15195+ /** Reset Power Down Modules */
15196+ unsigned rstpdwnmodule : 1;
15197+ /** Power Clamp */
15198+ unsigned pwrclmp : 1;
15199+ /** Gate Hclk */
15200+ unsigned gatehclk : 1;
15201+ /** Stop Pclk */
15202+ unsigned stoppclk : 1;
15203+ } b;
15204+} pcgcctl_data_t;
15205+
15206+/////////////////////////////////////////////////
15207+// Host Mode Register Structures
15208+//
15209+/**
15210+ * The Host Global Registers structure defines the size and relative
15211+ * field offsets for the Host Mode Global Registers. Host Global
15212+ * Registers offsets 400h-7FFh.
15213+*/
15214+typedef struct dwc_otg_host_global_regs
15215+{
15216+ /** Host Configuration Register. <i>Offset: 400h</i> */
15217+ volatile uint32_t hcfg;
15218+ /** Host Frame Interval Register. <i>Offset: 404h</i> */
15219+ volatile uint32_t hfir;
15220+ /** Host Frame Number / Frame Remaining Register. <i>Offset: 408h</i> */
15221+ volatile uint32_t hfnum;
15222+ /** Reserved. <i>Offset: 40Ch</i> */
15223+ uint32_t reserved40C;
15224+ /** Host Periodic Transmit FIFO/ Queue Status Register. <i>Offset: 410h</i> */
15225+ volatile uint32_t hptxsts;
15226+ /** Host All Channels Interrupt Register. <i>Offset: 414h</i> */
15227+ volatile uint32_t haint;
15228+ /** Host All Channels Interrupt Mask Register. <i>Offset: 418h</i> */
15229+ volatile uint32_t haintmsk;
15230+} dwc_otg_host_global_regs_t;
15231+
15232+/**
15233+ * This union represents the bit fields in the Host Configuration Register.
15234+ * Read the register into the <i>d32</i> member then set/clear the bits using
15235+ * the <i>b</i>it elements. Write the <i>d32</i> member to the hcfg register.
15236+ */
15237+typedef union hcfg_data
15238+{
15239+ /** raw register data */
15240+ uint32_t d32;
15241+
15242+ /** register bits */
15243+ struct {
15244+ /** Reserved */
15245+ //unsigned reserved31_03 : 29;
15246+ /** FS/LS Only Support */
15247+ unsigned fslssupp : 1;
15248+ /** FS/LS Phy Clock Select */
15249+#define DWC_HCFG_30_60_MHZ 0
15250+#define DWC_HCFG_48_MHZ 1
15251+#define DWC_HCFG_6_MHZ 2
15252+ unsigned fslspclksel : 2;
15253+ } b;
15254+} hcfg_data_t;
15255+
15256+/**
15257+ * This union represents the bit fields in the Host Frame Remaing/Number
15258+ * Register.
15259+ */
15260+typedef union hfir_data
15261+{
15262+ /** raw register data */
15263+ uint32_t d32;
15264+
15265+ /** register bits */
15266+ struct {
15267+ unsigned reserved : 16;
15268+ unsigned frint : 16;
15269+ } b;
15270+} hfir_data_t;
15271+
15272+/**
15273+ * This union represents the bit fields in the Host Frame Remaing/Number
15274+ * Register.
15275+ */
15276+typedef union hfnum_data
15277+{
15278+ /** raw register data */
15279+ uint32_t d32;
15280+
15281+ /** register bits */
15282+ struct {
15283+ unsigned frrem : 16;
15284+#define DWC_HFNUM_MAX_FRNUM 0x3FFF
15285+ unsigned frnum : 16;
15286+ } b;
15287+} hfnum_data_t;
15288+
15289+typedef union hptxsts_data
15290+{
15291+ /** raw register data */
15292+ uint32_t d32;
15293+
15294+ /** register bits */
15295+ struct {
15296+ /** Top of the Periodic Transmit Request Queue
15297+ * - bit 24 - Terminate (last entry for the selected channel)
15298+ * - bits 26:25 - Token Type
15299+ * - 2'b00 - Zero length
15300+ * - 2'b01 - Ping
15301+ * - 2'b10 - Disable
15302+ * - bits 30:27 - Channel Number
15303+ * - bit 31 - Odd/even microframe
15304+ */
15305+ unsigned ptxqtop_odd : 1;
15306+ unsigned ptxqtop_chnum : 4;
15307+ unsigned ptxqtop_token : 2;
15308+ unsigned ptxqtop_terminate : 1;
15309+ unsigned ptxqspcavail : 8;
15310+ unsigned ptxfspcavail : 16;
15311+ } b;
15312+} hptxsts_data_t;
15313+
15314+/**
15315+ * This union represents the bit fields in the Host Port Control and Status
15316+ * Register. Read the register into the <i>d32</i> member then set/clear the
15317+ * bits using the <i>b</i>it elements. Write the <i>d32</i> member to the
15318+ * hprt0 register.
15319+ */
15320+typedef union hprt0_data
15321+{
15322+ /** raw register data */
15323+ uint32_t d32;
15324+ /** register bits */
15325+ struct {
15326+ unsigned reserved19_31 : 13;
15327+#define DWC_HPRT0_PRTSPD_HIGH_SPEED 0
15328+#define DWC_HPRT0_PRTSPD_FULL_SPEED 1
15329+#define DWC_HPRT0_PRTSPD_LOW_SPEED 2
15330+ unsigned prtspd : 2;
15331+ unsigned prttstctl : 4;
15332+ unsigned prtpwr : 1;
15333+ unsigned prtlnsts : 2;
15334+ unsigned reserved9 : 1;
15335+ unsigned prtrst : 1;
15336+ unsigned prtsusp : 1;
15337+ unsigned prtres : 1;
15338+ unsigned prtovrcurrchng : 1;
15339+ unsigned prtovrcurract : 1;
15340+ unsigned prtenchng : 1;
15341+ unsigned prtena : 1;
15342+ unsigned prtconndet : 1;
15343+ unsigned prtconnsts : 1;
15344+ } b;
15345+} hprt0_data_t;
15346+
15347+/**
15348+ * This union represents the bit fields in the Host All Interrupt
15349+ * Register.
15350+ */
15351+typedef union haint_data
15352+{
15353+ /** raw register data */
15354+ uint32_t d32;
15355+ /** register bits */
15356+ struct {
15357+ unsigned reserved : 16;
15358+ unsigned ch15 : 1;
15359+ unsigned ch14 : 1;
15360+ unsigned ch13 : 1;
15361+ unsigned ch12 : 1;
15362+ unsigned ch11 : 1;
15363+ unsigned ch10 : 1;
15364+ unsigned ch9 : 1;
15365+ unsigned ch8 : 1;
15366+ unsigned ch7 : 1;
15367+ unsigned ch6 : 1;
15368+ unsigned ch5 : 1;
15369+ unsigned ch4 : 1;
15370+ unsigned ch3 : 1;
15371+ unsigned ch2 : 1;
15372+ unsigned ch1 : 1;
15373+ unsigned ch0 : 1;
15374+ } b;
15375+ struct {
15376+ unsigned reserved : 16;
15377+ unsigned chint : 16;
15378+ } b2;
15379+} haint_data_t;
15380+
15381+/**
15382+ * This union represents the bit fields in the Host All Interrupt
15383+ * Register.
15384+ */
15385+typedef union haintmsk_data
15386+{
15387+ /** raw register data */
15388+ uint32_t d32;
15389+ /** register bits */
15390+ struct {
15391+ unsigned reserved : 16;
15392+ unsigned ch15 : 1;
15393+ unsigned ch14 : 1;
15394+ unsigned ch13 : 1;
15395+ unsigned ch12 : 1;
15396+ unsigned ch11 : 1;
15397+ unsigned ch10 : 1;
15398+ unsigned ch9 : 1;
15399+ unsigned ch8 : 1;
15400+ unsigned ch7 : 1;
15401+ unsigned ch6 : 1;
15402+ unsigned ch5 : 1;
15403+ unsigned ch4 : 1;
15404+ unsigned ch3 : 1;
15405+ unsigned ch2 : 1;
15406+ unsigned ch1 : 1;
15407+ unsigned ch0 : 1;
15408+ } b;
15409+ struct {
15410+ unsigned reserved : 16;
15411+ unsigned chint : 16;
15412+ } b2;
15413+} haintmsk_data_t;
15414+
15415+/**
15416+ * Host Channel Specific Registers. <i>500h-5FCh</i>
15417+ */
15418+typedef struct dwc_otg_hc_regs
15419+{
15420+ /** Host Channel 0 Characteristic Register. <i>Offset: 500h + (chan_num * 20h) + 00h</i> */
15421+ volatile uint32_t hcchar;
15422+ /** Host Channel 0 Split Control Register. <i>Offset: 500h + (chan_num * 20h) + 04h</i> */
15423+ volatile uint32_t hcsplt;
15424+ /** Host Channel 0 Interrupt Register. <i>Offset: 500h + (chan_num * 20h) + 08h</i> */
15425+ volatile uint32_t hcint;
15426+ /** Host Channel 0 Interrupt Mask Register. <i>Offset: 500h + (chan_num * 20h) + 0Ch</i> */
15427+ volatile uint32_t hcintmsk;
15428+ /** Host Channel 0 Transfer Size Register. <i>Offset: 500h + (chan_num * 20h) + 10h</i> */
15429+ volatile uint32_t hctsiz;
15430+ /** Host Channel 0 DMA Address Register. <i>Offset: 500h + (chan_num * 20h) + 14h</i> */
15431+ volatile uint32_t hcdma;
15432+ /** Reserved. <i>Offset: 500h + (chan_num * 20h) + 18h - 500h + (chan_num * 20h) + 1Ch</i> */
15433+ uint32_t reserved[2];
15434+} dwc_otg_hc_regs_t;
15435+
15436+/**
15437+ * This union represents the bit fields in the Host Channel Characteristics
15438+ * Register. Read the register into the <i>d32</i> member then set/clear the
15439+ * bits using the <i>b</i>it elements. Write the <i>d32</i> member to the
15440+ * hcchar register.
15441+ */
15442+typedef union hcchar_data
15443+{
15444+ /** raw register data */
15445+ uint32_t d32;
15446+
15447+ /** register bits */
15448+ struct {
15449+ /** Channel enable */
15450+ unsigned chen : 1;
15451+ /** Channel disable */
15452+ unsigned chdis : 1;
15453+ /**
15454+ * Frame to transmit periodic transaction.
15455+ * 0: even, 1: odd
15456+ */
15457+ unsigned oddfrm : 1;
15458+ /** Device address */
15459+ unsigned devaddr : 7;
15460+ /** Packets per frame for periodic transfers. 0 is reserved. */
15461+ unsigned multicnt : 2;
15462+ /** 0: Control, 1: Isoc, 2: Bulk, 3: Intr */
15463+ unsigned eptype : 2;
15464+ /** 0: Full/high speed device, 1: Low speed device */
15465+ unsigned lspddev : 1;
15466+ unsigned reserved : 1;
15467+ /** 0: OUT, 1: IN */
15468+ unsigned epdir : 1;
15469+ /** Endpoint number */
15470+ unsigned epnum : 4;
15471+ /** Maximum packet size in bytes */
15472+ unsigned mps : 11;
15473+ } b;
15474+} hcchar_data_t;
15475+
15476+typedef union hcsplt_data
15477+{
15478+ /** raw register data */
15479+ uint32_t d32;
15480+
15481+ /** register bits */
15482+ struct {
15483+ /** Split Enble */
15484+ unsigned spltena : 1;
15485+ /** Reserved */
15486+ unsigned reserved : 14;
15487+ /** Do Complete Split */
15488+ unsigned compsplt : 1;
15489+ /** Transaction Position */
15490+#define DWC_HCSPLIT_XACTPOS_MID 0
15491+#define DWC_HCSPLIT_XACTPOS_END 1
15492+#define DWC_HCSPLIT_XACTPOS_BEGIN 2
15493+#define DWC_HCSPLIT_XACTPOS_ALL 3
15494+ unsigned xactpos : 2;
15495+ /** Hub Address */
15496+ unsigned hubaddr : 7;
15497+ /** Port Address */
15498+ unsigned prtaddr : 7;
15499+ } b;
15500+} hcsplt_data_t;
15501+
15502+
15503+/**
15504+ * This union represents the bit fields in the Host All Interrupt
15505+ * Register.
15506+ */
15507+typedef union hcint_data
15508+{
15509+ /** raw register data */
15510+ uint32_t d32;
15511+ /** register bits */
15512+ struct {
15513+ /** Reserved */
15514+ unsigned reserved : 21;
15515+ /** Data Toggle Error */
15516+ unsigned datatglerr : 1;
15517+ /** Frame Overrun */
15518+ unsigned frmovrun : 1;
15519+ /** Babble Error */
15520+ unsigned bblerr : 1;
15521+ /** Transaction Err */
15522+ unsigned xacterr : 1;
15523+ /** NYET Response Received */
15524+ unsigned nyet : 1;
15525+ /** ACK Response Received */
15526+ unsigned ack : 1;
15527+ /** NAK Response Received */
15528+ unsigned nak : 1;
15529+ /** STALL Response Received */
15530+ unsigned stall : 1;
15531+ /** AHB Error */
15532+ unsigned ahberr : 1;
15533+ /** Channel Halted */
15534+ unsigned chhltd : 1;
15535+ /** Transfer Complete */
15536+ unsigned xfercomp : 1;
15537+ } b;
15538+} hcint_data_t;
15539+
15540+/**
15541+ * This union represents the bit fields in the Host Channel Transfer Size
15542+ * Register. Read the register into the <i>d32</i> member then set/clear the
15543+ * bits using the <i>b</i>it elements. Write the <i>d32</i> member to the
15544+ * hcchar register.
15545+ */
15546+typedef union hctsiz_data
15547+{
15548+ /** raw register data */
15549+ uint32_t d32;
15550+
15551+ /** register bits */
15552+ struct {
15553+ /** Do PING protocol when 1 */
15554+ unsigned dopng : 1;
15555+ /**
15556+ * Packet ID for next data packet
15557+ * 0: DATA0
15558+ * 1: DATA2
15559+ * 2: DATA1
15560+ * 3: MDATA (non-Control), SETUP (Control)
15561+ */
15562+#define DWC_HCTSIZ_DATA0 0
15563+#define DWC_HCTSIZ_DATA1 2
15564+#define DWC_HCTSIZ_DATA2 1
15565+#define DWC_HCTSIZ_MDATA 3
15566+#define DWC_HCTSIZ_SETUP 3
15567+ unsigned pid : 2;
15568+ /** Data packets to transfer */
15569+ unsigned pktcnt : 10;
15570+ /** Total transfer size in bytes */
15571+ unsigned xfersize : 19;
15572+ } b;
15573+} hctsiz_data_t;
15574+
15575+/**
15576+ * This union represents the bit fields in the Host Channel Interrupt Mask
15577+ * Register. Read the register into the <i>d32</i> member then set/clear the
15578+ * bits using the <i>b</i>it elements. Write the <i>d32</i> member to the
15579+ * hcintmsk register.
15580+ */
15581+typedef union hcintmsk_data
15582+{
15583+ /** raw register data */
15584+ uint32_t d32;
15585+
15586+ /** register bits */
15587+ struct {
15588+ unsigned reserved : 21;
15589+ unsigned datatglerr : 1;
15590+ unsigned frmovrun : 1;
15591+ unsigned bblerr : 1;
15592+ unsigned xacterr : 1;
15593+ unsigned nyet : 1;
15594+ unsigned ack : 1;
15595+ unsigned nak : 1;
15596+ unsigned stall : 1;
15597+ unsigned ahberr : 1;
15598+ unsigned chhltd : 1;
15599+ unsigned xfercompl : 1;
15600+ } b;
15601+} hcintmsk_data_t;
15602+
15603+/** OTG Host Interface Structure.
15604+ *
15605+ * The OTG Host Interface Structure structure contains information
15606+ * needed to manage the DWC_otg controller acting in host mode. It
15607+ * represents the programming view of the host-specific aspects of the
15608+ * controller.
15609+ */
15610+typedef struct dwc_otg_host_if {
15611+ /** Host Global Registers starting at offset 400h.*/
15612+ dwc_otg_host_global_regs_t *host_global_regs;
15613+#define DWC_OTG_HOST_GLOBAL_REG_OFFSET 0x400
15614+
15615+ /** Host Port 0 Control and Status Register */
15616+ volatile uint32_t *hprt0;
15617+#define DWC_OTG_HOST_PORT_REGS_OFFSET 0x440
15618+
15619+
15620+ /** Host Channel Specific Registers at offsets 500h-5FCh. */
15621+ dwc_otg_hc_regs_t *hc_regs[MAX_EPS_CHANNELS];
15622+#define DWC_OTG_HOST_CHAN_REGS_OFFSET 0x500
15623+#define DWC_OTG_CHAN_REGS_OFFSET 0x20
15624+
15625+
15626+ /* Host configuration information */
15627+ /** Number of Host Channels (range: 1-16) */
15628+ uint8_t num_host_channels;
15629+ /** Periodic EPs supported (0: no, 1: yes) */
15630+ uint8_t perio_eps_supported;
15631+ /** Periodic Tx FIFO Size (Only 1 host periodic Tx FIFO) */
15632+ uint16_t perio_tx_fifo_size;
15633+
15634+} dwc_otg_host_if_t;
15635+
15636+#endif
15637--
156381.7.5.4
15639
15640

Archive Download this file



interactive