Root/target/linux/cns3xxx/patches-2.6.39/200-dwc_otg.patch

1--- a/drivers/Makefile
2+++ b/drivers/Makefile
3@@ -65,6 +65,7 @@ obj-$(CONFIG_PARIDE) += block/paride/
4 obj-$(CONFIG_TC) += tc/
5 obj-$(CONFIG_UWB) += uwb/
6 obj-$(CONFIG_USB_OTG_UTILS) += usb/otg/
7+obj-$(CONFIG_USB_DWC_OTG) += usb/dwc/
8 obj-$(CONFIG_USB) += usb/
9 obj-$(CONFIG_USB_MUSB_HDRC) += usb/musb/
10 obj-$(CONFIG_PCI) += usb/
11--- a/drivers/usb/Kconfig
12+++ b/drivers/usb/Kconfig
13@@ -116,6 +116,8 @@ source "drivers/usb/host/Kconfig"
14 
15 source "drivers/usb/musb/Kconfig"
16 
17+source "drivers/usb/dwc/Kconfig"
18+
19 source "drivers/usb/class/Kconfig"
20 
21 source "drivers/usb/storage/Kconfig"
22--- /dev/null
23+++ b/drivers/usb/dwc/Kconfig
24@@ -0,0 +1,44 @@
25+#
26+# USB Dual Role (OTG-ready) Controller Drivers
27+# for silicon based on Synopsys DesignWare IP
28+#
29+
30+comment "Enable Host or Gadget support for DesignWare OTG controller"
31+depends on !USB && USB_GADGET=n
32+
33+config USB_DWC_OTG
34+ tristate "Synopsys DWC OTG Controller"
35+ depends on USB
36+ help
37+ This driver provides USB Device Controller support for the
38+ Synopsys DesignWare USB OTG Core used on the Cavium CNS34xx SOC.
39+
40+config DWC_DEBUG
41+ bool "Enable DWC Debugging"
42+ depends on USB_DWC_OTG
43+ default n
44+ help
45+ Enable DWC driver debugging
46+
47+choice
48+ prompt "DWC Mode Selection"
49+ depends on USB_DWC_OTG
50+ default DWC_HOST_ONLY
51+ help
52+ Select the DWC Core in OTG, Host only, or Device only mode.
53+
54+config DWC_HOST_ONLY
55+ bool "DWC Host Only Mode"
56+
57+config DWC_OTG_MODE
58+ bool "DWC OTG Mode"
59+ select USB_GADGET
60+ select USB_GADGET_SELECTED
61+
62+config DWC_DEVICE_ONLY
63+ bool "DWC Device Only Mode"
64+ select USB_GADGET
65+ select USB_GADGET_SELECTED
66+
67+endchoice
68+
69--- /dev/null
70+++ b/drivers/usb/dwc/Makefile
71@@ -0,0 +1,26 @@
72+#
73+# Makefile for DWC_otg Highspeed USB controller driver
74+#
75+
76+EXTRA_CFLAGS += -DDWC_HS_ELECT_TST
77+#EXTRA_CFLAGS += -Dlinux -DDWC_HS_ELECT_TST
78+#EXTRA_CFLAGS += -DDWC_EN_ISOC
79+
80+ifneq ($(CONFIG_DWC_HOST_ONLY),)
81+EXTRA_CFLAGS += -DDWC_HOST_ONLY
82+endif
83+
84+ifneq ($(CONFIG_DWC_DEVICE_ONLY),)
85+EXTRA_CFLAGS += -DDWC_DEVICE_ONLY
86+endif
87+
88+ifneq ($(CONFIG_DWC_DEBUG),)
89+EXTRA_CFLAGS += -DDEBUG
90+endif
91+
92+obj-$(CONFIG_USB_DWC_OTG) := dwc_otg.o
93+
94+dwc_otg-objs := otg_driver.o otg_attr.o
95+dwc_otg-objs += otg_cil.o otg_cil_intr.o
96+dwc_otg-objs += otg_pcd.o otg_pcd_intr.o
97+dwc_otg-objs += otg_hcd.o otg_hcd_intr.o otg_hcd_queue.o
98--- /dev/null
99+++ b/drivers/usb/dwc/otg_attr.c
100@@ -0,0 +1,886 @@
101+/* ==========================================================================
102+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_attr.c $
103+ * $Revision: #31 $
104+ * $Date: 2008/07/15 $
105+ * $Change: 1064918 $
106+ *
107+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
108+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
109+ * otherwise expressly agreed to in writing between Synopsys and you.
110+ *
111+ * The Software IS NOT an item of Licensed Software or Licensed Product under
112+ * any End User Software License Agreement or Agreement for Licensed Product
113+ * with Synopsys or any supplement thereto. You are permitted to use and
114+ * redistribute this Software in source and binary forms, with or without
115+ * modification, provided that redistributions of source code must retain this
116+ * notice. You may not view, use, disclose, copy or distribute this file or
117+ * any information contained herein except pursuant to this license grant from
118+ * Synopsys. If you do not agree with this notice, including the disclaimer
119+ * below, then you are not authorized to use the Software.
120+ *
121+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
122+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
123+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
124+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
125+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
126+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
127+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
128+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
129+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
130+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
131+ * DAMAGE.
132+ * ========================================================================== */
133+
134+/** @file
135+ *
136+ * The diagnostic interface will provide access to the controller for
137+ * bringing up the hardware and testing. The Linux driver attributes
138+ * feature will be used to provide the Linux Diagnostic
139+ * Interface. These attributes are accessed through sysfs.
140+ */
141+
142+/** @page "Linux Module Attributes"
143+ *
144+ * The Linux module attributes feature is used to provide the Linux
145+ * Diagnostic Interface. These attributes are accessed through sysfs.
146+ * The diagnostic interface will provide access to the controller for
147+ * bringing up the hardware and testing.
148+
149+
150+ The following table shows the attributes.
151+ <table>
152+ <tr>
153+ <td><b> Name</b></td>
154+ <td><b> Description</b></td>
155+ <td><b> Access</b></td>
156+ </tr>
157+
158+ <tr>
159+ <td> mode </td>
160+ <td> Returns the current mode: 0 for device mode, 1 for host mode</td>
161+ <td> Read</td>
162+ </tr>
163+
164+ <tr>
165+ <td> hnpcapable </td>
166+ <td> Gets or sets the "HNP-capable" bit in the Core USB Configuraton Register.
167+ Read returns the current value.</td>
168+ <td> Read/Write</td>
169+ </tr>
170+
171+ <tr>
172+ <td> srpcapable </td>
173+ <td> Gets or sets the "SRP-capable" bit in the Core USB Configuraton Register.
174+ Read returns the current value.</td>
175+ <td> Read/Write</td>
176+ </tr>
177+
178+ <tr>
179+ <td> hnp </td>
180+ <td> Initiates the Host Negotiation Protocol. Read returns the status.</td>
181+ <td> Read/Write</td>
182+ </tr>
183+
184+ <tr>
185+ <td> srp </td>
186+ <td> Initiates the Session Request Protocol. Read returns the status.</td>
187+ <td> Read/Write</td>
188+ </tr>
189+
190+ <tr>
191+ <td> buspower </td>
192+ <td> Gets or sets the Power State of the bus (0 - Off or 1 - On)</td>
193+ <td> Read/Write</td>
194+ </tr>
195+
196+ <tr>
197+ <td> bussuspend </td>
198+ <td> Suspends the USB bus.</td>
199+ <td> Read/Write</td>
200+ </tr>
201+
202+ <tr>
203+ <td> busconnected </td>
204+ <td> Gets the connection status of the bus</td>
205+ <td> Read</td>
206+ </tr>
207+
208+ <tr>
209+ <td> gotgctl </td>
210+ <td> Gets or sets the Core Control Status Register.</td>
211+ <td> Read/Write</td>
212+ </tr>
213+
214+ <tr>
215+ <td> gusbcfg </td>
216+ <td> Gets or sets the Core USB Configuration Register</td>
217+ <td> Read/Write</td>
218+ </tr>
219+
220+ <tr>
221+ <td> grxfsiz </td>
222+ <td> Gets or sets the Receive FIFO Size Register</td>
223+ <td> Read/Write</td>
224+ </tr>
225+
226+ <tr>
227+ <td> gnptxfsiz </td>
228+ <td> Gets or sets the non-periodic Transmit Size Register</td>
229+ <td> Read/Write</td>
230+ </tr>
231+
232+ <tr>
233+ <td> gpvndctl </td>
234+ <td> Gets or sets the PHY Vendor Control Register</td>
235+ <td> Read/Write</td>
236+ </tr>
237+
238+ <tr>
239+ <td> ggpio </td>
240+ <td> Gets the value in the lower 16-bits of the General Purpose IO Register
241+ or sets the upper 16 bits.</td>
242+ <td> Read/Write</td>
243+ </tr>
244+
245+ <tr>
246+ <td> guid </td>
247+ <td> Gets or sets the value of the User ID Register</td>
248+ <td> Read/Write</td>
249+ </tr>
250+
251+ <tr>
252+ <td> gsnpsid </td>
253+ <td> Gets the value of the Synopsys ID Regester</td>
254+ <td> Read</td>
255+ </tr>
256+
257+ <tr>
258+ <td> devspeed </td>
259+ <td> Gets or sets the device speed setting in the DCFG register</td>
260+ <td> Read/Write</td>
261+ </tr>
262+
263+ <tr>
264+ <td> enumspeed </td>
265+ <td> Gets the device enumeration Speed.</td>
266+ <td> Read</td>
267+ </tr>
268+
269+ <tr>
270+ <td> hptxfsiz </td>
271+ <td> Gets the value of the Host Periodic Transmit FIFO</td>
272+ <td> Read</td>
273+ </tr>
274+
275+ <tr>
276+ <td> hprt0 </td>
277+ <td> Gets or sets the value in the Host Port Control and Status Register</td>
278+ <td> Read/Write</td>
279+ </tr>
280+
281+ <tr>
282+ <td> regoffset </td>
283+ <td> Sets the register offset for the next Register Access</td>
284+ <td> Read/Write</td>
285+ </tr>
286+
287+ <tr>
288+ <td> regvalue </td>
289+ <td> Gets or sets the value of the register at the offset in the regoffset attribute.</td>
290+ <td> Read/Write</td>
291+ </tr>
292+
293+ <tr>
294+ <td> remote_wakeup </td>
295+ <td> On read, shows the status of Remote Wakeup. On write, initiates a remote
296+ wakeup of the host. When bit 0 is 1 and Remote Wakeup is enabled, the Remote
297+ Wakeup signalling bit in the Device Control Register is set for 1
298+ milli-second.</td>
299+ <td> Read/Write</td>
300+ </tr>
301+
302+ <tr>
303+ <td> regdump </td>
304+ <td> Dumps the contents of core registers.</td>
305+ <td> Read</td>
306+ </tr>
307+
308+ <tr>
309+ <td> spramdump </td>
310+ <td> Dumps the contents of core registers.</td>
311+ <td> Read</td>
312+ </tr>
313+
314+ <tr>
315+ <td> hcddump </td>
316+ <td> Dumps the current HCD state.</td>
317+ <td> Read</td>
318+ </tr>
319+
320+ <tr>
321+ <td> hcd_frrem </td>
322+ <td> Shows the average value of the Frame Remaining
323+ field in the Host Frame Number/Frame Remaining register when an SOF interrupt
324+ occurs. This can be used to determine the average interrupt latency. Also
325+ shows the average Frame Remaining value for start_transfer and the "a" and
326+ "b" sample points. The "a" and "b" sample points may be used during debugging
327+ bto determine how long it takes to execute a section of the HCD code.</td>
328+ <td> Read</td>
329+ </tr>
330+
331+ <tr>
332+ <td> rd_reg_test </td>
333+ <td> Displays the time required to read the GNPTXFSIZ register many times
334+ (the output shows the number of times the register is read).
335+ <td> Read</td>
336+ </tr>
337+
338+ <tr>
339+ <td> wr_reg_test </td>
340+ <td> Displays the time required to write the GNPTXFSIZ register many times
341+ (the output shows the number of times the register is written).
342+ <td> Read</td>
343+ </tr>
344+
345+ </table>
346+
347+ Example usage:
348+ To get the current mode:
349+ cat /sys/devices/lm0/mode
350+
351+ To power down the USB:
352+ echo 0 > /sys/devices/lm0/buspower
353+ */
354+
355+#include <linux/kernel.h>
356+#include <linux/module.h>
357+#include <linux/moduleparam.h>
358+#include <linux/init.h>
359+#include <linux/device.h>
360+#include <linux/platform_device.h>
361+#include <linux/errno.h>
362+#include <linux/types.h>
363+#include <linux/stat.h> /* permission constants */
364+#include <linux/version.h>
365+
366+#include <asm/sizes.h>
367+#include <asm/io.h>
368+#include <asm/sizes.h>
369+
370+#include "otg_plat.h"
371+#include "otg_attr.h"
372+#include "otg_driver.h"
373+#include "otg_pcd.h"
374+#include "otg_hcd.h"
375+
376+/*
377+ * MACROs for defining sysfs attribute
378+ */
379+#define DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
380+static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
381+{ \
382+ struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
383+ dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
384+ uint32_t val; \
385+ val = dwc_read_reg32 (_addr_); \
386+ val = (val & (_mask_)) >> _shift_; \
387+ return sprintf (buf, "%s = 0x%x\n", _string_, val); \
388+}
389+#define DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
390+static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \
391+ const char *buf, size_t count) \
392+{ \
393+ struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
394+ dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
395+ uint32_t set = simple_strtoul(buf, NULL, 16); \
396+ uint32_t clear = set; \
397+ clear = ((~clear) << _shift_) & _mask_; \
398+ set = (set << _shift_) & _mask_; \
399+ dev_dbg(_dev, "Storing Address=0x%08x Set=0x%08x Clear=0x%08x\n", (uint32_t)_addr_, set, clear); \
400+ dwc_modify_reg32(_addr_, clear, set); \
401+ return count; \
402+}
403+
404+/*
405+ * MACROs for defining sysfs attribute for 32-bit registers
406+ */
407+#define DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_addr_,_string_) \
408+static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
409+{ \
410+ struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
411+ dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
412+ uint32_t val; \
413+ val = dwc_read_reg32 (_addr_); \
414+ return sprintf (buf, "%s = 0x%08x\n", _string_, val); \
415+}
416+#define DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_addr_,_string_) \
417+static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \
418+ const char *buf, size_t count) \
419+{ \
420+ struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
421+ dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
422+ uint32_t val = simple_strtoul(buf, NULL, 16); \
423+ dev_dbg(_dev, "Storing Address=0x%08x Val=0x%08x\n", (uint32_t)_addr_, val); \
424+ dwc_write_reg32(_addr_, val); \
425+ return count; \
426+}
427+
428+#define DWC_OTG_DEVICE_ATTR_BITFIELD_RW(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
429+DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
430+DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
431+DEVICE_ATTR(_otg_attr_name_,0644,_otg_attr_name_##_show,_otg_attr_name_##_store);
432+
433+#define DWC_OTG_DEVICE_ATTR_BITFIELD_RO(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
434+DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
435+DEVICE_ATTR(_otg_attr_name_,0444,_otg_attr_name_##_show,NULL);
436+
437+#define DWC_OTG_DEVICE_ATTR_REG32_RW(_otg_attr_name_,_addr_,_string_) \
438+DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_addr_,_string_) \
439+DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_addr_,_string_) \
440+DEVICE_ATTR(_otg_attr_name_,0644,_otg_attr_name_##_show,_otg_attr_name_##_store);
441+
442+#define DWC_OTG_DEVICE_ATTR_REG32_RO(_otg_attr_name_,_addr_,_string_) \
443+DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_addr_,_string_) \
444+DEVICE_ATTR(_otg_attr_name_,0444,_otg_attr_name_##_show,NULL);
445+
446+
447+/** @name Functions for Show/Store of Attributes */
448+/**@{*/
449+
450+/**
451+ * Show the register offset of the Register Access.
452+ */
453+static ssize_t regoffset_show( struct device *_dev,
454+ struct device_attribute *attr,
455+ char *buf)
456+{
457+ struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
458+ dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
459+ return snprintf(buf, sizeof("0xFFFFFFFF\n")+1,"0x%08x\n", otg_dev->reg_offset);
460+}
461+
462+/**
463+ * Set the register offset for the next Register Access Read/Write
464+ */
465+static ssize_t regoffset_store( struct device *_dev,
466+ struct device_attribute *attr,
467+ const char *buf,
468+ size_t count )
469+{
470+ struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
471+ dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
472+ uint32_t offset = simple_strtoul(buf, NULL, 16);
473+ //dev_dbg(_dev, "Offset=0x%08x\n", offset);
474+ if (offset < SZ_256K ) {
475+ otg_dev->reg_offset = offset;
476+ }
477+ else {
478+ dev_err( _dev, "invalid offset\n" );
479+ }
480+
481+ return count;
482+}
483+DEVICE_ATTR(regoffset, S_IRUGO|S_IWUSR, (void *)regoffset_show, regoffset_store);
484+
485+
486+/**
487+ * Show the value of the register at the offset in the reg_offset
488+ * attribute.
489+ */
490+static ssize_t regvalue_show( struct device *_dev,
491+ struct device_attribute *attr,
492+ char *buf)
493+{
494+ struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
495+ dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
496+ uint32_t val;
497+ volatile uint32_t *addr;
498+
499+ if (otg_dev->reg_offset != 0xFFFFFFFF &&
500+ 0 != otg_dev->base) {
501+ /* Calculate the address */
502+ addr = (uint32_t*)(otg_dev->reg_offset +
503+ (uint8_t*)otg_dev->base);
504+ //dev_dbg(_dev, "@0x%08x\n", (unsigned)addr);
505+ val = dwc_read_reg32( addr );
506+ return snprintf(buf, sizeof("Reg@0xFFFFFFFF = 0xFFFFFFFF\n")+1,
507+ "Reg@0x%06x = 0x%08x\n",
508+ otg_dev->reg_offset, val);
509+ }
510+ else {
511+ dev_err(_dev, "Invalid offset (0x%0x)\n",
512+ otg_dev->reg_offset);
513+ return sprintf(buf, "invalid offset\n" );
514+ }
515+}
516+
517+/**
518+ * Store the value in the register at the offset in the reg_offset
519+ * attribute.
520+ *
521+ */
522+static ssize_t regvalue_store( struct device *_dev,
523+ struct device_attribute *attr,
524+ const char *buf,
525+ size_t count )
526+{
527+ struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
528+ dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
529+ volatile uint32_t * addr;
530+ uint32_t val = simple_strtoul(buf, NULL, 16);
531+ //dev_dbg(_dev, "Offset=0x%08x Val=0x%08x\n", otg_dev->reg_offset, val);
532+ if (otg_dev->reg_offset != 0xFFFFFFFF && 0 != otg_dev->base) {
533+ /* Calculate the address */
534+ addr = (uint32_t*)(otg_dev->reg_offset +
535+ (uint8_t*)otg_dev->base);
536+ //dev_dbg(_dev, "@0x%08x\n", (unsigned)addr);
537+ dwc_write_reg32( addr, val );
538+ }
539+ else {
540+ dev_err(_dev, "Invalid Register Offset (0x%08x)\n",
541+ otg_dev->reg_offset);
542+ }
543+ return count;
544+}
545+DEVICE_ATTR(regvalue, S_IRUGO|S_IWUSR, regvalue_show, regvalue_store);
546+
547+/*
548+ * Attributes
549+ */
550+DWC_OTG_DEVICE_ATTR_BITFIELD_RO(mode,&(otg_dev->core_if->core_global_regs->gotgctl),(1<<20),20,"Mode");
551+DWC_OTG_DEVICE_ATTR_BITFIELD_RW(hnpcapable,&(otg_dev->core_if->core_global_regs->gusbcfg),(1<<9),9,"Mode");
552+DWC_OTG_DEVICE_ATTR_BITFIELD_RW(srpcapable,&(otg_dev->core_if->core_global_regs->gusbcfg),(1<<8),8,"Mode");
553+
554+//DWC_OTG_DEVICE_ATTR_BITFIELD_RW(buspower,&(otg_dev->core_if->core_global_regs->gotgctl),(1<<8),8,"Mode");
555+//DWC_OTG_DEVICE_ATTR_BITFIELD_RW(bussuspend,&(otg_dev->core_if->core_global_regs->gotgctl),(1<<8),8,"Mode");
556+DWC_OTG_DEVICE_ATTR_BITFIELD_RO(busconnected,otg_dev->core_if->host_if->hprt0,0x01,0,"Bus Connected");
557+
558+DWC_OTG_DEVICE_ATTR_REG32_RW(gotgctl,&(otg_dev->core_if->core_global_regs->gotgctl),"GOTGCTL");
559+DWC_OTG_DEVICE_ATTR_REG32_RW(gusbcfg,&(otg_dev->core_if->core_global_regs->gusbcfg),"GUSBCFG");
560+DWC_OTG_DEVICE_ATTR_REG32_RW(grxfsiz,&(otg_dev->core_if->core_global_regs->grxfsiz),"GRXFSIZ");
561+DWC_OTG_DEVICE_ATTR_REG32_RW(gnptxfsiz,&(otg_dev->core_if->core_global_regs->gnptxfsiz),"GNPTXFSIZ");
562+DWC_OTG_DEVICE_ATTR_REG32_RW(gpvndctl,&(otg_dev->core_if->core_global_regs->gpvndctl),"GPVNDCTL");
563+DWC_OTG_DEVICE_ATTR_REG32_RW(ggpio,&(otg_dev->core_if->core_global_regs->ggpio),"GGPIO");
564+DWC_OTG_DEVICE_ATTR_REG32_RW(guid,&(otg_dev->core_if->core_global_regs->guid),"GUID");
565+DWC_OTG_DEVICE_ATTR_REG32_RO(gsnpsid,&(otg_dev->core_if->core_global_regs->gsnpsid),"GSNPSID");
566+DWC_OTG_DEVICE_ATTR_BITFIELD_RW(devspeed,&(otg_dev->core_if->dev_if->dev_global_regs->dcfg),0x3,0,"Device Speed");
567+DWC_OTG_DEVICE_ATTR_BITFIELD_RO(enumspeed,&(otg_dev->core_if->dev_if->dev_global_regs->dsts),0x6,1,"Device Enumeration Speed");
568+
569+DWC_OTG_DEVICE_ATTR_REG32_RO(hptxfsiz,&(otg_dev->core_if->core_global_regs->hptxfsiz),"HPTXFSIZ");
570+DWC_OTG_DEVICE_ATTR_REG32_RW(hprt0,otg_dev->core_if->host_if->hprt0,"HPRT0");
571+
572+
573+/**
574+ * @todo Add code to initiate the HNP.
575+ */
576+/**
577+ * Show the HNP status bit
578+ */
579+static ssize_t hnp_show( struct device *_dev,
580+ struct device_attribute *attr,
581+ char *buf)
582+{
583+ struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
584+ dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
585+ gotgctl_data_t val;
586+ val.d32 = dwc_read_reg32 (&(otg_dev->core_if->core_global_regs->gotgctl));
587+ return sprintf (buf, "HstNegScs = 0x%x\n", val.b.hstnegscs);
588+}
589+
590+/**
591+ * Set the HNP Request bit
592+ */
593+static ssize_t hnp_store( struct device *_dev,
594+ struct device_attribute *attr,
595+ const char *buf,
596+ size_t count )
597+{
598+ struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
599+ dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
600+ uint32_t in = simple_strtoul(buf, NULL, 16);
601+ uint32_t *addr = (uint32_t *)&(otg_dev->core_if->core_global_regs->gotgctl);
602+ gotgctl_data_t mem;
603+ mem.d32 = dwc_read_reg32(addr);
604+ mem.b.hnpreq = in;
605+ dev_dbg(_dev, "Storing Address=0x%08x Data=0x%08x\n", (uint32_t)addr, mem.d32);
606+ dwc_write_reg32(addr, mem.d32);
607+ return count;
608+}
609+DEVICE_ATTR(hnp, 0644, hnp_show, hnp_store);
610+
611+/**
612+ * @todo Add code to initiate the SRP.
613+ */
614+/**
615+ * Show the SRP status bit
616+ */
617+static ssize_t srp_show( struct device *_dev,
618+ struct device_attribute *attr,
619+ char *buf)
620+{
621+#ifndef DWC_HOST_ONLY
622+ struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
623+ dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
624+ gotgctl_data_t val;
625+ val.d32 = dwc_read_reg32 (&(otg_dev->core_if->core_global_regs->gotgctl));
626+ return sprintf (buf, "SesReqScs = 0x%x\n", val.b.sesreqscs);
627+#else
628+ return sprintf(buf, "Host Only Mode!\n");
629+#endif
630+}
631+
632+
633+
634+/**
635+ * Set the SRP Request bit
636+ */
637+static ssize_t srp_store( struct device *_dev,
638+ struct device_attribute *attr,
639+ const char *buf,
640+ size_t count )
641+{
642+#ifndef DWC_HOST_ONLY
643+ struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
644+ dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
645+ dwc_otg_pcd_initiate_srp(otg_dev->pcd);
646+#endif
647+ return count;
648+}
649+DEVICE_ATTR(srp, 0644, srp_show, srp_store);
650+
651+/**
652+ * @todo Need to do more for power on/off?
653+ */
654+/**
655+ * Show the Bus Power status
656+ */
657+static ssize_t buspower_show( struct device *_dev,
658+ struct device_attribute *attr,
659+ char *buf)
660+{
661+ struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
662+ dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
663+ hprt0_data_t val;
664+ val.d32 = dwc_read_reg32 (otg_dev->core_if->host_if->hprt0);
665+ return sprintf (buf, "Bus Power = 0x%x\n", val.b.prtpwr);
666+}
667+
668+
669+/**
670+ * Set the Bus Power status
671+ */
672+static ssize_t buspower_store( struct device *_dev,
673+ struct device_attribute *attr,
674+ const char *buf,
675+ size_t count )
676+{
677+ struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
678+ dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
679+ uint32_t on = simple_strtoul(buf, NULL, 16);
680+ uint32_t *addr = (uint32_t *)otg_dev->core_if->host_if->hprt0;
681+ hprt0_data_t mem;
682+
683+ mem.d32 = dwc_read_reg32(addr);
684+ mem.b.prtpwr = on;
685+
686+ //dev_dbg(_dev, "Storing Address=0x%08x Data=0x%08x\n", (uint32_t)addr, mem.d32);
687+ dwc_write_reg32(addr, mem.d32);
688+
689+ return count;
690+}
691+DEVICE_ATTR(buspower, 0644, buspower_show, buspower_store);
692+
693+/**
694+ * @todo Need to do more for suspend?
695+ */
696+/**
697+ * Show the Bus Suspend status
698+ */
699+static ssize_t bussuspend_show( struct device *_dev,
700+ struct device_attribute *attr,
701+ char *buf)
702+{
703+ struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
704+ dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
705+ hprt0_data_t val;
706+ val.d32 = dwc_read_reg32 (otg_dev->core_if->host_if->hprt0);
707+ return sprintf (buf, "Bus Suspend = 0x%x\n", val.b.prtsusp);
708+}
709+
710+/**
711+ * Set the Bus Suspend status
712+ */
713+static ssize_t bussuspend_store( struct device *_dev,
714+ struct device_attribute *attr,
715+ const char *buf,
716+ size_t count )
717+{
718+ struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
719+ dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
720+ uint32_t in = simple_strtoul(buf, NULL, 16);
721+ uint32_t *addr = (uint32_t *)otg_dev->core_if->host_if->hprt0;
722+ hprt0_data_t mem;
723+ mem.d32 = dwc_read_reg32(addr);
724+ mem.b.prtsusp = in;
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+ return count;
728+}
729+DEVICE_ATTR(bussuspend, 0644, bussuspend_show, bussuspend_store);
730+
731+/**
732+ * Show the status of Remote Wakeup.
733+ */
734+static ssize_t remote_wakeup_show( struct device *_dev,
735+ struct device_attribute *attr,
736+ char *buf)
737+{
738+#ifndef DWC_HOST_ONLY
739+ struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
740+ dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
741+ dctl_data_t val;
742+ val.d32 =
743+ dwc_read_reg32( &otg_dev->core_if->dev_if->dev_global_regs->dctl);
744+ return sprintf( buf, "Remote Wakeup = %d Enabled = %d\n",
745+ val.b.rmtwkupsig, otg_dev->pcd->remote_wakeup_enable);
746+#else
747+ return sprintf(buf, "Host Only Mode!\n");
748+#endif
749+}
750+/**
751+ * Initiate a remote wakeup of the host. The Device control register
752+ * Remote Wakeup Signal bit is written if the PCD Remote wakeup enable
753+ * flag is set.
754+ *
755+ */
756+static ssize_t remote_wakeup_store( struct device *_dev,
757+ struct device_attribute *attr,
758+ const char *buf,
759+ size_t count )
760+{
761+#ifndef DWC_HOST_ONLY
762+ struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
763+ dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
764+ uint32_t val = simple_strtoul(buf, NULL, 16);
765+ if (val&1) {
766+ dwc_otg_pcd_remote_wakeup(otg_dev->pcd, 1);
767+ }
768+ else {
769+ dwc_otg_pcd_remote_wakeup(otg_dev->pcd, 0);
770+ }
771+#endif
772+ return count;
773+}
774+DEVICE_ATTR(remote_wakeup, S_IRUGO|S_IWUSR, remote_wakeup_show,
775+ remote_wakeup_store);
776+
777+/**
778+ * Dump global registers and either host or device registers (depending on the
779+ * current mode of the core).
780+ */
781+static ssize_t regdump_show( struct device *_dev,
782+ struct device_attribute *attr,
783+ char *buf)
784+{
785+ struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
786+ dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
787+ dwc_otg_dump_global_registers( otg_dev->core_if);
788+ if (dwc_otg_is_host_mode(otg_dev->core_if)) {
789+ dwc_otg_dump_host_registers( otg_dev->core_if);
790+ } else {
791+ dwc_otg_dump_dev_registers( otg_dev->core_if);
792+
793+ }
794+ return sprintf( buf, "Register Dump\n" );
795+}
796+
797+DEVICE_ATTR(regdump, S_IRUGO|S_IWUSR, regdump_show, 0);
798+
799+/**
800+ * Dump global registers and either host or device registers (depending on the
801+ * current mode of the core).
802+ */
803+static ssize_t spramdump_show( struct device *_dev,
804+ struct device_attribute *attr,
805+ char *buf)
806+{
807+ struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
808+ dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
809+ dwc_otg_dump_spram( otg_dev->core_if);
810+
811+ return sprintf( buf, "SPRAM Dump\n" );
812+}
813+
814+DEVICE_ATTR(spramdump, S_IRUGO|S_IWUSR, spramdump_show, 0);
815+
816+/**
817+ * Dump the current hcd state.
818+ */
819+static ssize_t hcddump_show( struct device *_dev,
820+ struct device_attribute *attr,
821+ char *buf)
822+{
823+#ifndef DWC_DEVICE_ONLY
824+ struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
825+ dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
826+ dwc_otg_hcd_dump_state(otg_dev->hcd);
827+#endif
828+ return sprintf( buf, "HCD Dump\n" );
829+}
830+
831+DEVICE_ATTR(hcddump, S_IRUGO|S_IWUSR, hcddump_show, 0);
832+
833+/**
834+ * Dump the average frame remaining at SOF. This can be used to
835+ * determine average interrupt latency. Frame remaining is also shown for
836+ * start transfer and two additional sample points.
837+ */
838+static ssize_t hcd_frrem_show( struct device *_dev,
839+ struct device_attribute *attr,
840+ char *buf)
841+{
842+#ifndef DWC_DEVICE_ONLY
843+ struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
844+ dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
845+ dwc_otg_hcd_dump_frrem(otg_dev->hcd);
846+#endif
847+ return sprintf( buf, "HCD Dump Frame Remaining\n" );
848+}
849+
850+DEVICE_ATTR(hcd_frrem, S_IRUGO|S_IWUSR, hcd_frrem_show, 0);
851+
852+/**
853+ * Displays the time required to read the GNPTXFSIZ register many times (the
854+ * output shows the number of times the register is read).
855+ */
856+#define RW_REG_COUNT 10000000
857+#define MSEC_PER_JIFFIE 1000/HZ
858+static ssize_t rd_reg_test_show( struct device *_dev,
859+ struct device_attribute *attr,
860+ char *buf)
861+{
862+ struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
863+ dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
864+ int i;
865+ int time;
866+ int start_jiffies;
867+
868+ printk("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n",
869+ HZ, MSEC_PER_JIFFIE, loops_per_jiffy);
870+ start_jiffies = jiffies;
871+ for (i = 0; i < RW_REG_COUNT; i++) {
872+ dwc_read_reg32(&otg_dev->core_if->core_global_regs->gnptxfsiz);
873+ }
874+ time = jiffies - start_jiffies;
875+ return sprintf( buf, "Time to read GNPTXFSIZ reg %d times: %d msecs (%d jiffies)\n",
876+ RW_REG_COUNT, time * MSEC_PER_JIFFIE, time );
877+}
878+
879+DEVICE_ATTR(rd_reg_test, S_IRUGO|S_IWUSR, rd_reg_test_show, 0);
880+
881+/**
882+ * Displays the time required to write the GNPTXFSIZ register many times (the
883+ * output shows the number of times the register is written).
884+ */
885+static ssize_t wr_reg_test_show( struct device *_dev,
886+ struct device_attribute *attr,
887+ char *buf)
888+{
889+ struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
890+ dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
891+ uint32_t reg_val;
892+ int i;
893+ int time;
894+ int start_jiffies;
895+
896+ printk("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n",
897+ HZ, MSEC_PER_JIFFIE, loops_per_jiffy);
898+ reg_val = dwc_read_reg32(&otg_dev->core_if->core_global_regs->gnptxfsiz);
899+ start_jiffies = jiffies;
900+ for (i = 0; i < RW_REG_COUNT; i++) {
901+ dwc_write_reg32(&otg_dev->core_if->core_global_regs->gnptxfsiz, reg_val);
902+ }
903+ time = jiffies - start_jiffies;
904+ return sprintf( buf, "Time to write GNPTXFSIZ reg %d times: %d msecs (%d jiffies)\n",
905+ RW_REG_COUNT, time * MSEC_PER_JIFFIE, time);
906+}
907+
908+DEVICE_ATTR(wr_reg_test, S_IRUGO|S_IWUSR, wr_reg_test_show, 0);
909+/**@}*/
910+
911+/**
912+ * Create the device files
913+ */
914+void dwc_otg_attr_create (struct platform_device *pdev)
915+{
916+ struct device *dev = &pdev->dev;
917+ int error;
918+
919+ error = device_create_file(dev, &dev_attr_regoffset);
920+ error = device_create_file(dev, &dev_attr_regvalue);
921+ error = device_create_file(dev, &dev_attr_mode);
922+ error = device_create_file(dev, &dev_attr_hnpcapable);
923+ error = device_create_file(dev, &dev_attr_srpcapable);
924+ error = device_create_file(dev, &dev_attr_hnp);
925+ error = device_create_file(dev, &dev_attr_srp);
926+ error = device_create_file(dev, &dev_attr_buspower);
927+ error = device_create_file(dev, &dev_attr_bussuspend);
928+ error = device_create_file(dev, &dev_attr_busconnected);
929+ error = device_create_file(dev, &dev_attr_gotgctl);
930+ error = device_create_file(dev, &dev_attr_gusbcfg);
931+ error = device_create_file(dev, &dev_attr_grxfsiz);
932+ error = device_create_file(dev, &dev_attr_gnptxfsiz);
933+ error = device_create_file(dev, &dev_attr_gpvndctl);
934+ error = device_create_file(dev, &dev_attr_ggpio);
935+ error = device_create_file(dev, &dev_attr_guid);
936+ error = device_create_file(dev, &dev_attr_gsnpsid);
937+ error = device_create_file(dev, &dev_attr_devspeed);
938+ error = device_create_file(dev, &dev_attr_enumspeed);
939+ error = device_create_file(dev, &dev_attr_hptxfsiz);
940+ error = device_create_file(dev, &dev_attr_hprt0);
941+ error = device_create_file(dev, &dev_attr_remote_wakeup);
942+ error = device_create_file(dev, &dev_attr_regdump);
943+ error = device_create_file(dev, &dev_attr_spramdump);
944+ error = device_create_file(dev, &dev_attr_hcddump);
945+ error = device_create_file(dev, &dev_attr_hcd_frrem);
946+ error = device_create_file(dev, &dev_attr_rd_reg_test);
947+ error = device_create_file(dev, &dev_attr_wr_reg_test);
948+}
949+
950+/**
951+ * Remove the device files
952+ */
953+void dwc_otg_attr_remove (struct platform_device *pdev)
954+{
955+ struct device *dev = &pdev->dev;
956+
957+ device_remove_file(dev, &dev_attr_regoffset);
958+ device_remove_file(dev, &dev_attr_regvalue);
959+ device_remove_file(dev, &dev_attr_mode);
960+ device_remove_file(dev, &dev_attr_hnpcapable);
961+ device_remove_file(dev, &dev_attr_srpcapable);
962+ device_remove_file(dev, &dev_attr_hnp);
963+ device_remove_file(dev, &dev_attr_srp);
964+ device_remove_file(dev, &dev_attr_buspower);
965+ device_remove_file(dev, &dev_attr_bussuspend);
966+ device_remove_file(dev, &dev_attr_busconnected);
967+ device_remove_file(dev, &dev_attr_gotgctl);
968+ device_remove_file(dev, &dev_attr_gusbcfg);
969+ device_remove_file(dev, &dev_attr_grxfsiz);
970+ device_remove_file(dev, &dev_attr_gnptxfsiz);
971+ device_remove_file(dev, &dev_attr_gpvndctl);
972+ device_remove_file(dev, &dev_attr_ggpio);
973+ device_remove_file(dev, &dev_attr_guid);
974+ device_remove_file(dev, &dev_attr_gsnpsid);
975+ device_remove_file(dev, &dev_attr_devspeed);
976+ device_remove_file(dev, &dev_attr_enumspeed);
977+ device_remove_file(dev, &dev_attr_hptxfsiz);
978+ device_remove_file(dev, &dev_attr_hprt0);
979+ device_remove_file(dev, &dev_attr_remote_wakeup);
980+ device_remove_file(dev, &dev_attr_regdump);
981+ device_remove_file(dev, &dev_attr_spramdump);
982+ device_remove_file(dev, &dev_attr_hcddump);
983+ device_remove_file(dev, &dev_attr_hcd_frrem);
984+ device_remove_file(dev, &dev_attr_rd_reg_test);
985+ device_remove_file(dev, &dev_attr_wr_reg_test);
986+}
987--- /dev/null
988+++ b/drivers/usb/dwc/otg_attr.h
989@@ -0,0 +1,67 @@
990+/* ==========================================================================
991+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_attr.h $
992+ * $Revision: #7 $
993+ * $Date: 2005/03/28 $
994+ * $Change: 477051 $
995+ *
996+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
997+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
998+ * otherwise expressly agreed to in writing between Synopsys and you.
999+ *
1000+ * The Software IS NOT an item of Licensed Software or Licensed Product under
1001+ * any End User Software License Agreement or Agreement for Licensed Product
1002+ * with Synopsys or any supplement thereto. You are permitted to use and
1003+ * redistribute this Software in source and binary forms, with or without
1004+ * modification, provided that redistributions of source code must retain this
1005+ * notice. You may not view, use, disclose, copy or distribute this file or
1006+ * any information contained herein except pursuant to this license grant from
1007+ * Synopsys. If you do not agree with this notice, including the disclaimer
1008+ * below, then you are not authorized to use the Software.
1009+ *
1010+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
1011+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1012+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1013+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
1014+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1015+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
1016+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
1017+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1018+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1019+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
1020+ * DAMAGE.
1021+ * ========================================================================== */
1022+
1023+#if !defined(__DWC_OTG_ATTR_H__)
1024+#define __DWC_OTG_ATTR_H__
1025+
1026+/** @file
1027+ * This file contains the interface to the Linux device attributes.
1028+ */
1029+extern struct device_attribute dev_attr_regoffset;
1030+extern struct device_attribute dev_attr_regvalue;
1031+
1032+extern struct device_attribute dev_attr_mode;
1033+extern struct device_attribute dev_attr_hnpcapable;
1034+extern struct device_attribute dev_attr_srpcapable;
1035+extern struct device_attribute dev_attr_hnp;
1036+extern struct device_attribute dev_attr_srp;
1037+extern struct device_attribute dev_attr_buspower;
1038+extern struct device_attribute dev_attr_bussuspend;
1039+extern struct device_attribute dev_attr_busconnected;
1040+extern struct device_attribute dev_attr_gotgctl;
1041+extern struct device_attribute dev_attr_gusbcfg;
1042+extern struct device_attribute dev_attr_grxfsiz;
1043+extern struct device_attribute dev_attr_gnptxfsiz;
1044+extern struct device_attribute dev_attr_gpvndctl;
1045+extern struct device_attribute dev_attr_ggpio;
1046+extern struct device_attribute dev_attr_guid;
1047+extern struct device_attribute dev_attr_gsnpsid;
1048+extern struct device_attribute dev_attr_devspeed;
1049+extern struct device_attribute dev_attr_enumspeed;
1050+extern struct device_attribute dev_attr_hptxfsiz;
1051+extern struct device_attribute dev_attr_hprt0;
1052+
1053+void dwc_otg_attr_create (struct platform_device *pdev);
1054+void dwc_otg_attr_remove (struct platform_device *pdev);
1055+
1056+#endif
1057--- /dev/null
1058+++ b/drivers/usb/dwc/otg_cil.c
1059@@ -0,0 +1,3831 @@
1060+/* ==========================================================================
1061+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_cil.c $
1062+ * $Revision: #147 $
1063+ * $Date: 2008/10/16 $
1064+ * $Change: 1117667 $
1065+ *
1066+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
1067+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
1068+ * otherwise expressly agreed to in writing between Synopsys and you.
1069+ *
1070+ * The Software IS NOT an item of Licensed Software or Licensed Product under
1071+ * any End User Software License Agreement or Agreement for Licensed Product
1072+ * with Synopsys or any supplement thereto. You are permitted to use and
1073+ * redistribute this Software in source and binary forms, with or without
1074+ * modification, provided that redistributions of source code must retain this
1075+ * notice. You may not view, use, disclose, copy or distribute this file or
1076+ * any information contained herein except pursuant to this license grant from
1077+ * Synopsys. If you do not agree with this notice, including the disclaimer
1078+ * below, then you are not authorized to use the Software.
1079+ *
1080+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
1081+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1082+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1083+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
1084+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1085+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
1086+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
1087+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1088+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1089+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
1090+ * DAMAGE.
1091+ * ========================================================================== */
1092+
1093+/** @file
1094+ *
1095+ * The Core Interface Layer provides basic services for accessing and
1096+ * managing the DWC_otg hardware. These services are used by both the
1097+ * Host Controller Driver and the Peripheral Controller Driver.
1098+ *
1099+ * The CIL manages the memory map for the core so that the HCD and PCD
1100+ * don't have to do this separately. It also handles basic tasks like
1101+ * reading/writing the registers and data FIFOs in the controller.
1102+ * Some of the data access functions provide encapsulation of several
1103+ * operations required to perform a task, such as writing multiple
1104+ * registers to start a transfer. Finally, the CIL performs basic
1105+ * services that are not specific to either the host or device modes
1106+ * of operation. These services include management of the OTG Host
1107+ * Negotiation Protocol (HNP) and Session Request Protocol (SRP). A
1108+ * Diagnostic API is also provided to allow testing of the controller
1109+ * hardware.
1110+ *
1111+ * The Core Interface Layer has the following requirements:
1112+ * - Provides basic controller operations.
1113+ * - Minimal use of OS services.
1114+ * - The OS services used will be abstracted by using inline functions
1115+ * or macros.
1116+ *
1117+ */
1118+#include <asm/unaligned.h>
1119+#include <linux/dma-mapping.h>
1120+#ifdef DEBUG
1121+#include <linux/jiffies.h>
1122+#endif
1123+
1124+#include "otg_plat.h"
1125+#include "otg_regs.h"
1126+#include "otg_cil.h"
1127+#include "otg_pcd.h"
1128+
1129+
1130+/**
1131+ * This function is called to initialize the DWC_otg CSR data
1132+ * structures. The register addresses in the device and host
1133+ * structures are initialized from the base address supplied by the
1134+ * caller. The calling function must make the OS calls to get the
1135+ * base address of the DWC_otg controller registers. The core_params
1136+ * argument holds the parameters that specify how the core should be
1137+ * configured.
1138+ *
1139+ * @param[in] reg_base_addr Base address of DWC_otg core registers
1140+ * @param[in] core_params Pointer to the core configuration parameters
1141+ *
1142+ */
1143+dwc_otg_core_if_t *dwc_otg_cil_init(const uint32_t *reg_base_addr,
1144+ dwc_otg_core_params_t *core_params)
1145+{
1146+ dwc_otg_core_if_t *core_if = 0;
1147+ dwc_otg_dev_if_t *dev_if = 0;
1148+ dwc_otg_host_if_t *host_if = 0;
1149+ uint8_t *reg_base = (uint8_t *)reg_base_addr;
1150+ int i = 0;
1151+
1152+ DWC_DEBUGPL(DBG_CILV, "%s(%p,%p)\n", __func__, reg_base_addr, core_params);
1153+
1154+ core_if = kmalloc(sizeof(dwc_otg_core_if_t), GFP_KERNEL);
1155+
1156+ if (core_if == 0) {
1157+ DWC_DEBUGPL(DBG_CIL, "Allocation of dwc_otg_core_if_t failed\n");
1158+ return 0;
1159+ }
1160+
1161+ memset(core_if, 0, sizeof(dwc_otg_core_if_t));
1162+
1163+ core_if->core_params = core_params;
1164+ core_if->core_global_regs = (dwc_otg_core_global_regs_t *)reg_base;
1165+
1166+ /*
1167+ * Allocate the Device Mode structures.
1168+ */
1169+ dev_if = kmalloc(sizeof(dwc_otg_dev_if_t), GFP_KERNEL);
1170+
1171+ if (dev_if == 0) {
1172+ DWC_DEBUGPL(DBG_CIL, "Allocation of dwc_otg_dev_if_t failed\n");
1173+ kfree(core_if);
1174+ return 0;
1175+ }
1176+
1177+ dev_if->dev_global_regs =
1178+ (dwc_otg_device_global_regs_t *)(reg_base + DWC_DEV_GLOBAL_REG_OFFSET);
1179+
1180+ for (i=0; i<MAX_EPS_CHANNELS; i++)
1181+ {
1182+ dev_if->in_ep_regs[i] = (dwc_otg_dev_in_ep_regs_t *)
1183+ (reg_base + DWC_DEV_IN_EP_REG_OFFSET +
1184+ (i * DWC_EP_REG_OFFSET));
1185+
1186+ dev_if->out_ep_regs[i] = (dwc_otg_dev_out_ep_regs_t *)
1187+ (reg_base + DWC_DEV_OUT_EP_REG_OFFSET +
1188+ (i * DWC_EP_REG_OFFSET));
1189+ DWC_DEBUGPL(DBG_CILV, "in_ep_regs[%d]->diepctl=%p\n",
1190+ i, &dev_if->in_ep_regs[i]->diepctl);
1191+ DWC_DEBUGPL(DBG_CILV, "out_ep_regs[%d]->doepctl=%p\n",
1192+ i, &dev_if->out_ep_regs[i]->doepctl);
1193+ }
1194+
1195+ dev_if->speed = 0; // unknown
1196+
1197+ core_if->dev_if = dev_if;
1198+
1199+ /*
1200+ * Allocate the Host Mode structures.
1201+ */
1202+ host_if = kmalloc(sizeof(dwc_otg_host_if_t), GFP_KERNEL);
1203+
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+
1214+ host_if->hprt0 = (uint32_t*)(reg_base + DWC_OTG_HOST_PORT_REGS_OFFSET);
1215+
1216+ for (i=0; i<MAX_EPS_CHANNELS; i++)
1217+ {
1218+ host_if->hc_regs[i] = (dwc_otg_hc_regs_t *)
1219+ (reg_base + DWC_OTG_HOST_CHAN_REGS_OFFSET +
1220+ (i * DWC_OTG_CHAN_REGS_OFFSET));
1221+ DWC_DEBUGPL(DBG_CILV, "hc_reg[%d]->hcchar=%p\n",
1222+ i, &host_if->hc_regs[i]->hcchar);
1223+ }
1224+
1225+ host_if->num_host_channels = MAX_EPS_CHANNELS;
1226+ core_if->host_if = host_if;
1227+
1228+ for (i=0; i<MAX_EPS_CHANNELS; i++)
1229+ {
1230+ core_if->data_fifo[i] =
1231+ (uint32_t *)(reg_base + DWC_OTG_DATA_FIFO_OFFSET +
1232+ (i * DWC_OTG_DATA_FIFO_SIZE));
1233+ DWC_DEBUGPL(DBG_CILV, "data_fifo[%d]=0x%08x\n",
1234+ i, (unsigned)core_if->data_fifo[i]);
1235+ }
1236+
1237+ core_if->pcgcctl = (uint32_t*)(reg_base + DWC_OTG_PCGCCTL_OFFSET);
1238+
1239+ /*
1240+ * Store the contents of the hardware configuration registers here for
1241+ * easy access later.
1242+ */
1243+ core_if->hwcfg1.d32 = dwc_read_reg32(&core_if->core_global_regs->ghwcfg1);
1244+ core_if->hwcfg2.d32 = dwc_read_reg32(&core_if->core_global_regs->ghwcfg2);
1245+ core_if->hwcfg3.d32 = dwc_read_reg32(&core_if->core_global_regs->ghwcfg3);
1246+ core_if->hwcfg4.d32 = dwc_read_reg32(&core_if->core_global_regs->ghwcfg4);
1247+
1248+ DWC_DEBUGPL(DBG_CILV,"hwcfg1=%08x\n",core_if->hwcfg1.d32);
1249+ DWC_DEBUGPL(DBG_CILV,"hwcfg2=%08x\n",core_if->hwcfg2.d32);
1250+ DWC_DEBUGPL(DBG_CILV,"hwcfg3=%08x\n",core_if->hwcfg3.d32);
1251+ DWC_DEBUGPL(DBG_CILV,"hwcfg4=%08x\n",core_if->hwcfg4.d32);
1252+
1253+ core_if->hcfg.d32 = dwc_read_reg32(&core_if->host_if->host_global_regs->hcfg);
1254+ core_if->dcfg.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dcfg);
1255+
1256+ DWC_DEBUGPL(DBG_CILV,"hcfg=%08x\n",core_if->hcfg.d32);
1257+ DWC_DEBUGPL(DBG_CILV,"dcfg=%08x\n",core_if->dcfg.d32);
1258+
1259+ DWC_DEBUGPL(DBG_CILV,"op_mode=%0x\n",core_if->hwcfg2.b.op_mode);
1260+ DWC_DEBUGPL(DBG_CILV,"arch=%0x\n",core_if->hwcfg2.b.architecture);
1261+ DWC_DEBUGPL(DBG_CILV,"num_dev_ep=%d\n",core_if->hwcfg2.b.num_dev_ep);
1262+ DWC_DEBUGPL(DBG_CILV,"num_host_chan=%d\n",core_if->hwcfg2.b.num_host_chan);
1263+ DWC_DEBUGPL(DBG_CILV,"nonperio_tx_q_depth=0x%0x\n",core_if->hwcfg2.b.nonperio_tx_q_depth);
1264+ DWC_DEBUGPL(DBG_CILV,"host_perio_tx_q_depth=0x%0x\n",core_if->hwcfg2.b.host_perio_tx_q_depth);
1265+ DWC_DEBUGPL(DBG_CILV,"dev_token_q_depth=0x%0x\n",core_if->hwcfg2.b.dev_token_q_depth);
1266+
1267+ DWC_DEBUGPL(DBG_CILV,"Total FIFO SZ=%d\n", core_if->hwcfg3.b.dfifo_depth);
1268+ DWC_DEBUGPL(DBG_CILV,"xfer_size_cntr_width=%0x\n", core_if->hwcfg3.b.xfer_size_cntr_width);
1269+
1270+ /*
1271+ * Set the SRP sucess bit for FS-I2c
1272+ */
1273+ core_if->srp_success = 0;
1274+ core_if->srp_timer_started = 0;
1275+
1276+
1277+ /*
1278+ * Create new workqueue and init works
1279+ */
1280+ core_if->wq_otg = create_singlethread_workqueue("dwc_otg");
1281+ if(core_if->wq_otg == 0) {
1282+ DWC_DEBUGPL(DBG_CIL, "Creation of wq_otg failed\n");
1283+ kfree(host_if);
1284+ kfree(dev_if);
1285+ kfree(core_if);
1286+ return 0 * HZ;
1287+ }
1288+ INIT_WORK(&core_if->w_conn_id, w_conn_id_status_change);
1289+ INIT_DELAYED_WORK(&core_if->w_wkp, w_wakeup_detected);
1290+
1291+ return core_if;
1292+}
1293+
1294+/**
1295+ * This function frees the structures allocated by dwc_otg_cil_init().
1296+ *
1297+ * @param[in] core_if The core interface pointer returned from
1298+ * dwc_otg_cil_init().
1299+ *
1300+ */
1301+void dwc_otg_cil_remove(dwc_otg_core_if_t *core_if)
1302+{
1303+ /* Disable all interrupts */
1304+ dwc_modify_reg32(&core_if->core_global_regs->gahbcfg, 1, 0);
1305+ dwc_write_reg32(&core_if->core_global_regs->gintmsk, 0);
1306+
1307+ if (core_if->wq_otg) {
1308+ destroy_workqueue(core_if->wq_otg);
1309+ }
1310+ if (core_if->dev_if) {
1311+ kfree(core_if->dev_if);
1312+ }
1313+ if (core_if->host_if) {
1314+ kfree(core_if->host_if);
1315+ }
1316+ kfree(core_if);
1317+}
1318+
1319+/**
1320+ * This function enables the controller's Global Interrupt in the AHB Config
1321+ * register.
1322+ *
1323+ * @param[in] core_if Programming view of DWC_otg controller.
1324+ */
1325+void dwc_otg_enable_global_interrupts(dwc_otg_core_if_t *core_if)
1326+{
1327+ gahbcfg_data_t ahbcfg = { .d32 = 0};
1328+ ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */
1329+ dwc_modify_reg32(&core_if->core_global_regs->gahbcfg, 0, ahbcfg.d32);
1330+}
1331+
1332+/**
1333+ * This function disables the controller's Global Interrupt in the AHB Config
1334+ * register.
1335+ *
1336+ * @param[in] core_if Programming view of DWC_otg controller.
1337+ */
1338+void dwc_otg_disable_global_interrupts(dwc_otg_core_if_t *core_if)
1339+{
1340+ gahbcfg_data_t ahbcfg = { .d32 = 0};
1341+ ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */
1342+ dwc_modify_reg32(&core_if->core_global_regs->gahbcfg, ahbcfg.d32, 0);
1343+}
1344+
1345+/**
1346+ * This function initializes the commmon interrupts, used in both
1347+ * device and host modes.
1348+ *
1349+ * @param[in] core_if Programming view of the DWC_otg controller
1350+ *
1351+ */
1352+static void dwc_otg_enable_common_interrupts(dwc_otg_core_if_t *core_if)
1353+{
1354+ dwc_otg_core_global_regs_t *global_regs =
1355+ core_if->core_global_regs;
1356+ gintmsk_data_t intr_mask = { .d32 = 0};
1357+
1358+ /* Clear any pending OTG Interrupts */
1359+ dwc_write_reg32(&global_regs->gotgint, 0xFFFFFFFF);
1360+
1361+ /* Clear any pending interrupts */
1362+ dwc_write_reg32(&global_regs->gintsts, 0xFFFFFFFF);
1363+
1364+ /*
1365+ * Enable the interrupts in the GINTMSK.
1366+ */
1367+ intr_mask.b.modemismatch = 1;
1368+ intr_mask.b.otgintr = 1;
1369+
1370+ if (!core_if->dma_enable) {
1371+ intr_mask.b.rxstsqlvl = 1;
1372+ }
1373+
1374+ intr_mask.b.conidstschng = 1;
1375+ intr_mask.b.wkupintr = 1;
1376+ intr_mask.b.disconnect = 1;
1377+ intr_mask.b.usbsuspend = 1;
1378+ intr_mask.b.sessreqintr = 1;
1379+ dwc_write_reg32(&global_regs->gintmsk, intr_mask.d32);
1380+}
1381+
1382+/**
1383+ * Initializes the FSLSPClkSel field of the HCFG register depending on the PHY
1384+ * type.
1385+ */
1386+static void init_fslspclksel(dwc_otg_core_if_t *core_if)
1387+{
1388+ uint32_t val;
1389+ hcfg_data_t hcfg;
1390+
1391+ if (((core_if->hwcfg2.b.hs_phy_type == 2) &&
1392+ (core_if->hwcfg2.b.fs_phy_type == 1) &&
1393+ (core_if->core_params->ulpi_fs_ls)) ||
1394+ (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
1395+ /* Full speed PHY */
1396+ val = DWC_HCFG_48_MHZ;
1397+ }
1398+ else {
1399+ /* High speed PHY running at full speed or high speed */
1400+ val = DWC_HCFG_30_60_MHZ;
1401+ }
1402+
1403+ DWC_DEBUGPL(DBG_CIL, "Initializing HCFG.FSLSPClkSel to 0x%1x\n", val);
1404+ hcfg.d32 = dwc_read_reg32(&core_if->host_if->host_global_regs->hcfg);
1405+ hcfg.b.fslspclksel = val;
1406+ dwc_write_reg32(&core_if->host_if->host_global_regs->hcfg, hcfg.d32);
1407+}
1408+
1409+/**
1410+ * Initializes the DevSpd field of the DCFG register depending on the PHY type
1411+ * and the enumeration speed of the device.
1412+ */
1413+static void init_devspd(dwc_otg_core_if_t *core_if)
1414+{
1415+ uint32_t val;
1416+ dcfg_data_t dcfg;
1417+
1418+ if (((core_if->hwcfg2.b.hs_phy_type == 2) &&
1419+ (core_if->hwcfg2.b.fs_phy_type == 1) &&
1420+ (core_if->core_params->ulpi_fs_ls)) ||
1421+ (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
1422+ /* Full speed PHY */
1423+ val = 0x3;
1424+ }
1425+ else if (core_if->core_params->speed == DWC_SPEED_PARAM_FULL) {
1426+ /* High speed PHY running at full speed */
1427+ val = 0x1;
1428+ }
1429+ else {
1430+ /* High speed PHY running at high speed */
1431+ val = 0x0;
1432+ }
1433+
1434+ DWC_DEBUGPL(DBG_CIL, "Initializing DCFG.DevSpd to 0x%1x\n", val);
1435+
1436+ dcfg.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dcfg);
1437+ dcfg.b.devspd = val;
1438+ dwc_write_reg32(&core_if->dev_if->dev_global_regs->dcfg, dcfg.d32);
1439+}
1440+
1441+/**
1442+ * This function calculates the number of IN EPS
1443+ * using GHWCFG1 and GHWCFG2 registers values
1444+ *
1445+ * @param core_if Programming view of the DWC_otg controller
1446+ */
1447+static uint32_t calc_num_in_eps(dwc_otg_core_if_t *core_if)
1448+{
1449+ uint32_t num_in_eps = 0;
1450+ uint32_t num_eps = core_if->hwcfg2.b.num_dev_ep;
1451+ uint32_t hwcfg1 = core_if->hwcfg1.d32 >> 3;
1452+ uint32_t num_tx_fifos = core_if->hwcfg4.b.num_in_eps;
1453+ int i;
1454+
1455+
1456+ for(i = 0; i < num_eps; ++i)
1457+ {
1458+ if(!(hwcfg1 & 0x1))
1459+ num_in_eps++;
1460+
1461+ hwcfg1 >>= 2;
1462+ }
1463+
1464+ if(core_if->hwcfg4.b.ded_fifo_en) {
1465+ num_in_eps = (num_in_eps > num_tx_fifos) ? num_tx_fifos : num_in_eps;
1466+ }
1467+
1468+ return num_in_eps;
1469+}
1470+
1471+
1472+/**
1473+ * This function calculates the number of OUT EPS
1474+ * using GHWCFG1 and GHWCFG2 registers values
1475+ *
1476+ * @param core_if Programming view of the DWC_otg controller
1477+ */
1478+static uint32_t calc_num_out_eps(dwc_otg_core_if_t *core_if)
1479+{
1480+ uint32_t num_out_eps = 0;
1481+ uint32_t num_eps = core_if->hwcfg2.b.num_dev_ep;
1482+ uint32_t hwcfg1 = core_if->hwcfg1.d32 >> 2;
1483+ int i;
1484+
1485+ for(i = 0; i < num_eps; ++i)
1486+ {
1487+ if(!(hwcfg1 & 0x2))
1488+ num_out_eps++;
1489+
1490+ hwcfg1 >>= 2;
1491+ }
1492+ return num_out_eps;
1493+}
1494+/**
1495+ * This function initializes the DWC_otg controller registers and
1496+ * prepares the core for device mode or host mode operation.
1497+ *
1498+ * @param core_if Programming view of the DWC_otg controller
1499+ *
1500+ */
1501+void dwc_otg_core_init(dwc_otg_core_if_t *core_if)
1502+{
1503+ int i = 0;
1504+ dwc_otg_core_global_regs_t *global_regs =
1505+ core_if->core_global_regs;
1506+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
1507+ gahbcfg_data_t ahbcfg = { .d32 = 0 };
1508+ gusbcfg_data_t usbcfg = { .d32 = 0 };
1509+ gi2cctl_data_t i2cctl = { .d32 = 0 };
1510+
1511+ DWC_DEBUGPL(DBG_CILV, "dwc_otg_core_init(%p)\n", core_if);
1512+
1513+ /* Common Initialization */
1514+
1515+ usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
1516+
1517+// usbcfg.b.tx_end_delay = 1;
1518+ /* Program the ULPI External VBUS bit if needed */
1519+ usbcfg.b.ulpi_ext_vbus_drv =
1520+ (core_if->core_params->phy_ulpi_ext_vbus == DWC_PHY_ULPI_EXTERNAL_VBUS) ? 1 : 0;
1521+
1522+ /* Set external TS Dline pulsing */
1523+ usbcfg.b.term_sel_dl_pulse = (core_if->core_params->ts_dline == 1) ? 1 : 0;
1524+ dwc_write_reg32 (&global_regs->gusbcfg, usbcfg.d32);
1525+
1526+
1527+ /* Reset the Controller */
1528+ dwc_otg_core_reset(core_if);
1529+
1530+ /* Initialize parameters from Hardware configuration registers. */
1531+ dev_if->num_in_eps = calc_num_in_eps(core_if);
1532+ dev_if->num_out_eps = calc_num_out_eps(core_if);
1533+
1534+
1535+ DWC_DEBUGPL(DBG_CIL, "num_dev_perio_in_ep=%d\n", core_if->hwcfg4.b.num_dev_perio_in_ep);
1536+
1537+ for (i=0; i < core_if->hwcfg4.b.num_dev_perio_in_ep; i++)
1538+ {
1539+ dev_if->perio_tx_fifo_size[i] =
1540+ dwc_read_reg32(&global_regs->dptxfsiz_dieptxf[i]) >> 16;
1541+ DWC_DEBUGPL(DBG_CIL, "Periodic Tx FIFO SZ #%d=0x%0x\n",
1542+ i, dev_if->perio_tx_fifo_size[i]);
1543+ }
1544+
1545+ for (i=0; i < core_if->hwcfg4.b.num_in_eps; i++)
1546+ {
1547+ dev_if->tx_fifo_size[i] =
1548+ dwc_read_reg32(&global_regs->dptxfsiz_dieptxf[i]) >> 16;
1549+ DWC_DEBUGPL(DBG_CIL, "Tx FIFO SZ #%d=0x%0x\n",
1550+ i, dev_if->perio_tx_fifo_size[i]);
1551+ }
1552+
1553+ core_if->total_fifo_size = core_if->hwcfg3.b.dfifo_depth;
1554+ core_if->rx_fifo_size =
1555+ dwc_read_reg32(&global_regs->grxfsiz);
1556+ core_if->nperio_tx_fifo_size =
1557+ dwc_read_reg32(&global_regs->gnptxfsiz) >> 16;
1558+
1559+ DWC_DEBUGPL(DBG_CIL, "Total FIFO SZ=%d\n", core_if->total_fifo_size);
1560+ DWC_DEBUGPL(DBG_CIL, "Rx FIFO SZ=%d\n", core_if->rx_fifo_size);
1561+ DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO SZ=%d\n", core_if->nperio_tx_fifo_size);
1562+
1563+ /* This programming sequence needs to happen in FS mode before any other
1564+ * programming occurs */
1565+ if ((core_if->core_params->speed == DWC_SPEED_PARAM_FULL) &&
1566+ (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
1567+ /* If FS mode with FS PHY */
1568+
1569+ /* core_init() is now called on every switch so only call the
1570+ * following for the first time through. */
1571+ if (!core_if->phy_init_done) {
1572+ core_if->phy_init_done = 1;
1573+ DWC_DEBUGPL(DBG_CIL, "FS_PHY detected\n");
1574+ usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
1575+ usbcfg.b.physel = 1;
1576+ dwc_write_reg32 (&global_regs->gusbcfg, usbcfg.d32);
1577+
1578+ /* Reset after a PHY select */
1579+ dwc_otg_core_reset(core_if);
1580+ }
1581+
1582+ /* Program DCFG.DevSpd or HCFG.FSLSPclkSel to 48Mhz in FS. Also
1583+ * do this on HNP Dev/Host mode switches (done in dev_init and
1584+ * host_init). */
1585+ if (dwc_otg_is_host_mode(core_if)) {
1586+ init_fslspclksel(core_if);
1587+ }
1588+ else {
1589+ init_devspd(core_if);
1590+ }
1591+
1592+ if (core_if->core_params->i2c_enable) {
1593+ DWC_DEBUGPL(DBG_CIL, "FS_PHY Enabling I2c\n");
1594+ /* Program GUSBCFG.OtgUtmifsSel to I2C */
1595+ usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
1596+ usbcfg.b.otgutmifssel = 1;
1597+ dwc_write_reg32 (&global_regs->gusbcfg, usbcfg.d32);
1598+
1599+ /* Program GI2CCTL.I2CEn */
1600+ i2cctl.d32 = dwc_read_reg32(&global_regs->gi2cctl);
1601+ i2cctl.b.i2cdevaddr = 1;
1602+ i2cctl.b.i2cen = 0;
1603+ dwc_write_reg32 (&global_regs->gi2cctl, i2cctl.d32);
1604+ i2cctl.b.i2cen = 1;
1605+ dwc_write_reg32 (&global_regs->gi2cctl, i2cctl.d32);
1606+ }
1607+
1608+ } /* endif speed == DWC_SPEED_PARAM_FULL */
1609+
1610+ else {
1611+ /* High speed PHY. */
1612+ if (!core_if->phy_init_done) {
1613+ core_if->phy_init_done = 1;
1614+ /* HS PHY parameters. These parameters are preserved
1615+ * during soft reset so only program the first time. Do
1616+ * a soft reset immediately after setting phyif. */
1617+ usbcfg.b.ulpi_utmi_sel = core_if->core_params->phy_type;
1618+ if (usbcfg.b.ulpi_utmi_sel == 1) {
1619+ /* ULPI interface */
1620+ usbcfg.b.phyif = 0;
1621+ usbcfg.b.ddrsel = core_if->core_params->phy_ulpi_ddr;
1622+ }
1623+ else {
1624+ /* UTMI+ interface */
1625+ if (core_if->core_params->phy_utmi_width == 16) {
1626+ usbcfg.b.phyif = 1;
1627+ }
1628+ else {
1629+ usbcfg.b.phyif = 0;
1630+ }
1631+ }
1632+
1633+ dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
1634+
1635+ /* Reset after setting the PHY parameters */
1636+ dwc_otg_core_reset(core_if);
1637+ }
1638+ }
1639+
1640+ if ((core_if->hwcfg2.b.hs_phy_type == 2) &&
1641+ (core_if->hwcfg2.b.fs_phy_type == 1) &&
1642+ (core_if->core_params->ulpi_fs_ls)) {
1643+ DWC_DEBUGPL(DBG_CIL, "Setting ULPI FSLS\n");
1644+ usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
1645+ usbcfg.b.ulpi_fsls = 1;
1646+ usbcfg.b.ulpi_clk_sus_m = 1;
1647+ dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
1648+ }
1649+ else {
1650+ usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
1651+ usbcfg.b.ulpi_fsls = 0;
1652+ usbcfg.b.ulpi_clk_sus_m = 0;
1653+ dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
1654+ }
1655+
1656+ /* Program the GAHBCFG Register.*/
1657+ switch (core_if->hwcfg2.b.architecture) {
1658+
1659+ case DWC_SLAVE_ONLY_ARCH:
1660+ DWC_DEBUGPL(DBG_CIL, "Slave Only Mode\n");
1661+ ahbcfg.b.nptxfemplvl_txfemplvl = DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
1662+ ahbcfg.b.ptxfemplvl = DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
1663+ core_if->dma_enable = 0;
1664+ core_if->dma_desc_enable = 0;
1665+ break;
1666+
1667+ case DWC_EXT_DMA_ARCH:
1668+ DWC_DEBUGPL(DBG_CIL, "External DMA Mode\n");
1669+ ahbcfg.b.hburstlen = core_if->core_params->dma_burst_size;
1670+ core_if->dma_enable = (core_if->core_params->dma_enable != 0);
1671+ core_if->dma_desc_enable = (core_if->core_params->dma_desc_enable != 0);
1672+ break;
1673+
1674+ case DWC_INT_DMA_ARCH:
1675+ DWC_DEBUGPL(DBG_CIL, "Internal DMA Mode\n");
1676+ ahbcfg.b.hburstlen = DWC_GAHBCFG_INT_DMA_BURST_INCR;
1677+ core_if->dma_enable = (core_if->core_params->dma_enable != 0);
1678+ core_if->dma_desc_enable = (core_if->core_params->dma_desc_enable != 0);
1679+ break;
1680+
1681+ }
1682+ ahbcfg.b.dmaenable = core_if->dma_enable;
1683+ dwc_write_reg32(&global_regs->gahbcfg, ahbcfg.d32);
1684+
1685+ core_if->en_multiple_tx_fifo = core_if->hwcfg4.b.ded_fifo_en;
1686+
1687+ core_if->pti_enh_enable = core_if->core_params->pti_enable != 0;
1688+ core_if->multiproc_int_enable = core_if->core_params->mpi_enable;
1689+ DWC_PRINT("Periodic Transfer Interrupt Enhancement - %s\n", ((core_if->pti_enh_enable) ? "enabled": "disabled"));
1690+ DWC_PRINT("Multiprocessor Interrupt Enhancement - %s\n", ((core_if->multiproc_int_enable) ? "enabled": "disabled"));
1691+
1692+ /*
1693+ * Program the GUSBCFG register.
1694+ */
1695+ usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
1696+
1697+ switch (core_if->hwcfg2.b.op_mode) {
1698+ case DWC_MODE_HNP_SRP_CAPABLE:
1699+ usbcfg.b.hnpcap = (core_if->core_params->otg_cap ==
1700+ DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE);
1701+ usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
1702+ DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
1703+ break;
1704+
1705+ case DWC_MODE_SRP_ONLY_CAPABLE:
1706+ usbcfg.b.hnpcap = 0;
1707+ usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
1708+ DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
1709+ break;
1710+
1711+ case DWC_MODE_NO_HNP_SRP_CAPABLE:
1712+ usbcfg.b.hnpcap = 0;
1713+ usbcfg.b.srpcap = 0;
1714+ break;
1715+
1716+ case DWC_MODE_SRP_CAPABLE_DEVICE:
1717+ usbcfg.b.hnpcap = 0;
1718+ usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
1719+ DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
1720+ break;
1721+
1722+ case DWC_MODE_NO_SRP_CAPABLE_DEVICE:
1723+ usbcfg.b.hnpcap = 0;
1724+ usbcfg.b.srpcap = 0;
1725+ break;
1726+
1727+ case DWC_MODE_SRP_CAPABLE_HOST:
1728+ usbcfg.b.hnpcap = 0;
1729+ usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
1730+ DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
1731+ break;
1732+
1733+ case DWC_MODE_NO_SRP_CAPABLE_HOST:
1734+ usbcfg.b.hnpcap = 0;
1735+ usbcfg.b.srpcap = 0;
1736+ break;
1737+ }
1738+
1739+ dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
1740+
1741+ /* Enable common interrupts */
1742+ dwc_otg_enable_common_interrupts(core_if);
1743+
1744+ /* Do device or host intialization based on mode during PCD
1745+ * and HCD initialization */
1746+ if (dwc_otg_is_host_mode(core_if)) {
1747+ DWC_DEBUGPL(DBG_ANY, "Host Mode\n");
1748+ core_if->op_state = A_HOST;
1749+ }
1750+ else {
1751+ DWC_DEBUGPL(DBG_ANY, "Device Mode\n");
1752+ core_if->op_state = B_PERIPHERAL;
1753+#ifdef DWC_DEVICE_ONLY
1754+ dwc_otg_core_dev_init(core_if);
1755+#endif
1756+ }
1757+}
1758+
1759+
1760+/**
1761+ * This function enables the Device mode interrupts.
1762+ *
1763+ * @param core_if Programming view of DWC_otg controller
1764+ */
1765+void dwc_otg_enable_device_interrupts(dwc_otg_core_if_t *core_if)
1766+{
1767+ gintmsk_data_t intr_mask = { .d32 = 0};
1768+ dwc_otg_core_global_regs_t *global_regs =
1769+ core_if->core_global_regs;
1770+
1771+ DWC_DEBUGPL(DBG_CIL, "%s()\n", __func__);
1772+
1773+ /* Disable all interrupts. */
1774+ dwc_write_reg32(&global_regs->gintmsk, 0);
1775+
1776+ /* Clear any pending interrupts */
1777+ dwc_write_reg32(&global_regs->gintsts, 0xFFFFFFFF);
1778+
1779+ /* Enable the common interrupts */
1780+ dwc_otg_enable_common_interrupts(core_if);
1781+
1782+ /* Enable interrupts */
1783+ intr_mask.b.usbreset = 1;
1784+ intr_mask.b.enumdone = 1;
1785+
1786+ if(!core_if->multiproc_int_enable) {
1787+ intr_mask.b.inepintr = 1;
1788+ intr_mask.b.outepintr = 1;
1789+ }
1790+
1791+ intr_mask.b.erlysuspend = 1;
1792+
1793+ if(core_if->en_multiple_tx_fifo == 0) {
1794+ intr_mask.b.epmismatch = 1;
1795+ }
1796+
1797+
1798+#ifdef DWC_EN_ISOC
1799+ if(core_if->dma_enable) {
1800+ if(core_if->dma_desc_enable == 0) {
1801+ if(core_if->pti_enh_enable) {
1802+ dctl_data_t dctl = { .d32 = 0 };
1803+ dctl.b.ifrmnum = 1;
1804+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->dctl, 0, dctl.d32);
1805+ } else {
1806+ intr_mask.b.incomplisoin = 1;
1807+ intr_mask.b.incomplisoout = 1;
1808+ }
1809+ }
1810+ } else {
1811+ intr_mask.b.incomplisoin = 1;
1812+ intr_mask.b.incomplisoout = 1;
1813+ }
1814+#endif // DWC_EN_ISOC
1815+
1816+/** @todo NGS: Should this be a module parameter? */
1817+#ifdef USE_PERIODIC_EP
1818+ intr_mask.b.isooutdrop = 1;
1819+ intr_mask.b.eopframe = 1;
1820+ intr_mask.b.incomplisoin = 1;
1821+ intr_mask.b.incomplisoout = 1;
1822+#endif
1823+
1824+ dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
1825+
1826+ DWC_DEBUGPL(DBG_CIL, "%s() gintmsk=%0x\n", __func__,
1827+ dwc_read_reg32(&global_regs->gintmsk));
1828+}
1829+
1830+/**
1831+ * This function initializes the DWC_otg controller registers for
1832+ * device mode.
1833+ *
1834+ * @param core_if Programming view of DWC_otg controller
1835+ *
1836+ */
1837+void dwc_otg_core_dev_init(dwc_otg_core_if_t *core_if)
1838+{
1839+ int i,size;
1840+ u_int32_t *default_value_array;
1841+
1842+ dwc_otg_core_global_regs_t *global_regs =
1843+ core_if->core_global_regs;
1844+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
1845+ dwc_otg_core_params_t *params = core_if->core_params;
1846+ dcfg_data_t dcfg = { .d32 = 0};
1847+ grstctl_t resetctl = { .d32 = 0 };
1848+ uint32_t rx_fifo_size;
1849+ fifosize_data_t nptxfifosize;
1850+ fifosize_data_t txfifosize;
1851+ dthrctl_data_t dthrctl;
1852+
1853+ /* Restart the Phy Clock */
1854+ dwc_write_reg32(core_if->pcgcctl, 0);
1855+
1856+ /* Device configuration register */
1857+ init_devspd(core_if);
1858+ dcfg.d32 = dwc_read_reg32(&dev_if->dev_global_regs->dcfg);
1859+ dcfg.b.descdma = (core_if->dma_desc_enable) ? 1 : 0;
1860+ dcfg.b.perfrint = DWC_DCFG_FRAME_INTERVAL_80;
1861+
1862+ dwc_write_reg32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
1863+
1864+ /* Configure data FIFO sizes */
1865+ if (core_if->hwcfg2.b.dynamic_fifo && params->enable_dynamic_fifo) {
1866+ DWC_DEBUGPL(DBG_CIL, "Total FIFO Size=%d\n", core_if->total_fifo_size);
1867+ DWC_DEBUGPL(DBG_CIL, "Rx FIFO Size=%d\n", params->dev_rx_fifo_size);
1868+ DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO Size=%d\n", params->dev_nperio_tx_fifo_size);
1869+
1870+ /* Rx FIFO */
1871+ DWC_DEBUGPL(DBG_CIL, "initial grxfsiz=%08x\n",
1872+ dwc_read_reg32(&global_regs->grxfsiz));
1873+
1874+ rx_fifo_size = params->dev_rx_fifo_size;
1875+ dwc_write_reg32(&global_regs->grxfsiz, rx_fifo_size);
1876+
1877+ DWC_DEBUGPL(DBG_CIL, "new grxfsiz=%08x\n",
1878+ dwc_read_reg32(&global_regs->grxfsiz));
1879+
1880+ /** Set Periodic Tx FIFO Mask all bits 0 */
1881+ core_if->p_tx_msk = 0;
1882+
1883+ /** Set Tx FIFO Mask all bits 0 */
1884+ core_if->tx_msk = 0;
1885+
1886+ /* Non-periodic Tx FIFO */
1887+ DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n",
1888+ dwc_read_reg32(&global_regs->gnptxfsiz));
1889+
1890+ nptxfifosize.b.depth = params->dev_nperio_tx_fifo_size;
1891+ nptxfifosize.b.startaddr = params->dev_rx_fifo_size;
1892+
1893+ dwc_write_reg32(&global_regs->gnptxfsiz, nptxfifosize.d32);
1894+
1895+ DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",
1896+ dwc_read_reg32(&global_regs->gnptxfsiz));
1897+
1898+ txfifosize.b.startaddr = nptxfifosize.b.startaddr + nptxfifosize.b.depth;
1899+ if(core_if->en_multiple_tx_fifo == 0) {
1900+ //core_if->hwcfg4.b.ded_fifo_en==0
1901+
1902+ /**@todo NGS: Fix Periodic FIFO Sizing! */
1903+ /*
1904+ * Periodic Tx FIFOs These FIFOs are numbered from 1 to 15.
1905+ * Indexes of the FIFO size module parameters in the
1906+ * dev_perio_tx_fifo_size array and the FIFO size registers in
1907+ * the dptxfsiz array run from 0 to 14.
1908+ */
1909+ /** @todo Finish debug of this */
1910+ size=core_if->hwcfg4.b.num_dev_perio_in_ep;
1911+ default_value_array=params->dev_perio_tx_fifo_size;
1912+
1913+ }
1914+ else {
1915+ //core_if->hwcfg4.b.ded_fifo_en==1
1916+ /*
1917+ * Tx FIFOs These FIFOs are numbered from 1 to 15.
1918+ * Indexes of the FIFO size module parameters in the
1919+ * dev_tx_fifo_size array and the FIFO size registers in
1920+ * the dptxfsiz_dieptxf array run from 0 to 14.
1921+ */
1922+
1923+ size=core_if->hwcfg4.b.num_in_eps;
1924+ default_value_array=params->dev_tx_fifo_size;
1925+
1926+ }
1927+ for (i=0; i < size; i++)
1928+ {
1929+
1930+ txfifosize.b.depth = default_value_array[i];
1931+ DWC_DEBUGPL(DBG_CIL, "initial dptxfsiz_dieptxf[%d]=%08x\n", i,
1932+ dwc_read_reg32(&global_regs->dptxfsiz_dieptxf[i]));
1933+ dwc_write_reg32(&global_regs->dptxfsiz_dieptxf[i],
1934+ txfifosize.d32);
1935+ DWC_DEBUGPL(DBG_CIL, "new dptxfsiz_dieptxf[%d]=%08x\n", i,
1936+ dwc_read_reg32(&global_regs->dptxfsiz_dieptxf[i]));
1937+ txfifosize.b.startaddr += txfifosize.b.depth;
1938+ }
1939+ }
1940+ /* Flush the FIFOs */
1941+ dwc_otg_flush_tx_fifo(core_if, 0x10); /* all Tx FIFOs */
1942+ dwc_otg_flush_rx_fifo(core_if);
1943+
1944+ /* Flush the Learning Queue. */
1945+ resetctl.b.intknqflsh = 1;
1946+ dwc_write_reg32(&core_if->core_global_regs->grstctl, resetctl.d32);
1947+
1948+ /* Clear all pending Device Interrupts */
1949+
1950+ if(core_if->multiproc_int_enable) {
1951+ }
1952+
1953+ /** @todo - if the condition needed to be checked
1954+ * or in any case all pending interrutps should be cleared?
1955+ */
1956+ if(core_if->multiproc_int_enable) {
1957+ for(i = 0; i < core_if->dev_if->num_in_eps; ++i) {
1958+ dwc_write_reg32(&dev_if->dev_global_regs->diepeachintmsk[i], 0);
1959+ }
1960+
1961+ for(i = 0; i < core_if->dev_if->num_out_eps; ++i) {
1962+ dwc_write_reg32(&dev_if->dev_global_regs->doepeachintmsk[i], 0);
1963+ }
1964+
1965+ dwc_write_reg32(&dev_if->dev_global_regs->deachint, 0xFFFFFFFF);
1966+ dwc_write_reg32(&dev_if->dev_global_regs->deachintmsk, 0);
1967+ } else {
1968+ dwc_write_reg32(&dev_if->dev_global_regs->diepmsk, 0);
1969+ dwc_write_reg32(&dev_if->dev_global_regs->doepmsk, 0);
1970+ dwc_write_reg32(&dev_if->dev_global_regs->daint, 0xFFFFFFFF);
1971+ dwc_write_reg32(&dev_if->dev_global_regs->daintmsk, 0);
1972+ }
1973+
1974+ for (i=0; i <= dev_if->num_in_eps; i++)
1975+ {
1976+ depctl_data_t depctl;
1977+ depctl.d32 = dwc_read_reg32(&dev_if->in_ep_regs[i]->diepctl);
1978+ if (depctl.b.epena) {
1979+ depctl.d32 = 0;
1980+ depctl.b.epdis = 1;
1981+ depctl.b.snak = 1;
1982+ }
1983+ else {
1984+ depctl.d32 = 0;
1985+ }
1986+
1987+ dwc_write_reg32(&dev_if->in_ep_regs[i]->diepctl, depctl.d32);
1988+
1989+
1990+ dwc_write_reg32(&dev_if->in_ep_regs[i]->dieptsiz, 0);
1991+ dwc_write_reg32(&dev_if->in_ep_regs[i]->diepdma, 0);
1992+ dwc_write_reg32(&dev_if->in_ep_regs[i]->diepint, 0xFF);
1993+ }
1994+
1995+ for (i=0; i <= dev_if->num_out_eps; i++)
1996+ {
1997+ depctl_data_t depctl;
1998+ depctl.d32 = dwc_read_reg32(&dev_if->out_ep_regs[i]->doepctl);
1999+ if (depctl.b.epena) {
2000+ depctl.d32 = 0;
2001+ depctl.b.epdis = 1;
2002+ depctl.b.snak = 1;
2003+ }
2004+ else {
2005+ depctl.d32 = 0;
2006+ }
2007+
2008+ dwc_write_reg32(&dev_if->out_ep_regs[i]->doepctl, depctl.d32);
2009+
2010+ dwc_write_reg32(&dev_if->out_ep_regs[i]->doeptsiz, 0);
2011+ dwc_write_reg32(&dev_if->out_ep_regs[i]->doepdma, 0);
2012+ dwc_write_reg32(&dev_if->out_ep_regs[i]->doepint, 0xFF);
2013+ }
2014+
2015+ if(core_if->en_multiple_tx_fifo && core_if->dma_enable) {
2016+ dev_if->non_iso_tx_thr_en = params->thr_ctl & 0x1;
2017+ dev_if->iso_tx_thr_en = (params->thr_ctl >> 1) & 0x1;
2018+ dev_if->rx_thr_en = (params->thr_ctl >> 2) & 0x1;
2019+
2020+ dev_if->rx_thr_length = params->rx_thr_length;
2021+ dev_if->tx_thr_length = params->tx_thr_length;
2022+
2023+ dev_if->setup_desc_index = 0;
2024+
2025+ dthrctl.d32 = 0;
2026+ dthrctl.b.non_iso_thr_en = dev_if->non_iso_tx_thr_en;
2027+ dthrctl.b.iso_thr_en = dev_if->iso_tx_thr_en;
2028+ dthrctl.b.tx_thr_len = dev_if->tx_thr_length;
2029+ dthrctl.b.rx_thr_en = dev_if->rx_thr_en;
2030+ dthrctl.b.rx_thr_len = dev_if->rx_thr_length;
2031+
2032+ dwc_write_reg32(&dev_if->dev_global_regs->dtknqr3_dthrctl, dthrctl.d32);
2033+
2034+ DWC_DEBUGPL(DBG_CIL, "Non ISO Tx Thr - %d\nISO Tx Thr - %d\nRx Thr - %d\nTx Thr Len - %d\nRx Thr Len - %d\n",
2035+ dthrctl.b.non_iso_thr_en, dthrctl.b.iso_thr_en, dthrctl.b.rx_thr_en, dthrctl.b.tx_thr_len, dthrctl.b.rx_thr_len);
2036+
2037+ }
2038+
2039+ dwc_otg_enable_device_interrupts(core_if);
2040+
2041+ {
2042+ diepmsk_data_t msk = { .d32 = 0 };
2043+ msk.b.txfifoundrn = 1;
2044+ if(core_if->multiproc_int_enable) {
2045+ dwc_modify_reg32(&dev_if->dev_global_regs->diepeachintmsk[0], msk.d32, msk.d32);
2046+ } else {
2047+ dwc_modify_reg32(&dev_if->dev_global_regs->diepmsk, msk.d32, msk.d32);
2048+ }
2049+ }
2050+
2051+
2052+ if(core_if->multiproc_int_enable) {
2053+ /* Set NAK on Babble */
2054+ dctl_data_t dctl = { .d32 = 0};
2055+ dctl.b.nakonbble = 1;
2056+ dwc_modify_reg32(&dev_if->dev_global_regs->dctl, 0, dctl.d32);
2057+ }
2058+}
2059+
2060+/**
2061+ * This function enables the Host mode interrupts.
2062+ *
2063+ * @param core_if Programming view of DWC_otg controller
2064+ */
2065+void dwc_otg_enable_host_interrupts(dwc_otg_core_if_t *core_if)
2066+{
2067+ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
2068+ gintmsk_data_t intr_mask = { .d32 = 0 };
2069+
2070+ DWC_DEBUGPL(DBG_CIL, "%s()\n", __func__);
2071+
2072+ /* Disable all interrupts. */
2073+ dwc_write_reg32(&global_regs->gintmsk, 0);
2074+
2075+ /* Clear any pending interrupts. */
2076+ dwc_write_reg32(&global_regs->gintsts, 0xFFFFFFFF);
2077+
2078+ /* Enable the common interrupts */
2079+ dwc_otg_enable_common_interrupts(core_if);
2080+
2081+ /*
2082+ * Enable host mode interrupts without disturbing common
2083+ * interrupts.
2084+ */
2085+ intr_mask.b.sofintr = 1;
2086+ intr_mask.b.portintr = 1;
2087+ intr_mask.b.hcintr = 1;
2088+
2089+ dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
2090+}
2091+
2092+/**
2093+ * This function disables the Host Mode interrupts.
2094+ *
2095+ * @param core_if Programming view of DWC_otg controller
2096+ */
2097+void dwc_otg_disable_host_interrupts(dwc_otg_core_if_t *core_if)
2098+{
2099+ dwc_otg_core_global_regs_t *global_regs =
2100+ core_if->core_global_regs;
2101+ gintmsk_data_t intr_mask = { .d32 = 0 };
2102+
2103+ DWC_DEBUGPL(DBG_CILV, "%s()\n", __func__);
2104+
2105+ /*
2106+ * Disable host mode interrupts without disturbing common
2107+ * interrupts.
2108+ */
2109+ intr_mask.b.sofintr = 1;
2110+ intr_mask.b.portintr = 1;
2111+ intr_mask.b.hcintr = 1;
2112+ intr_mask.b.ptxfempty = 1;
2113+ intr_mask.b.nptxfempty = 1;
2114+
2115+ dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, 0);
2116+}
2117+
2118+/**
2119+ * This function initializes the DWC_otg controller registers for
2120+ * host mode.
2121+ *
2122+ * This function flushes the Tx and Rx FIFOs and it flushes any entries in the
2123+ * request queues. Host channels are reset to ensure that they are ready for
2124+ * performing transfers.
2125+ *
2126+ * @param core_if Programming view of DWC_otg controller
2127+ *
2128+ */
2129+void dwc_otg_core_host_init(dwc_otg_core_if_t *core_if)
2130+{
2131+ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
2132+ dwc_otg_host_if_t *host_if = core_if->host_if;
2133+ dwc_otg_core_params_t *params = core_if->core_params;
2134+ hprt0_data_t hprt0 = { .d32 = 0 };
2135+ fifosize_data_t nptxfifosize;
2136+ fifosize_data_t ptxfifosize;
2137+ int i;
2138+ hcchar_data_t hcchar;
2139+ hcfg_data_t hcfg;
2140+ dwc_otg_hc_regs_t *hc_regs;
2141+ int num_channels;
2142+ gotgctl_data_t gotgctl = { .d32 = 0 };
2143+
2144+ DWC_DEBUGPL(DBG_CILV,"%s(%p)\n", __func__, core_if);
2145+
2146+ /* Restart the Phy Clock */
2147+ dwc_write_reg32(core_if->pcgcctl, 0);
2148+
2149+ /* Initialize Host Configuration Register */
2150+ init_fslspclksel(core_if);
2151+ if (core_if->core_params->speed == DWC_SPEED_PARAM_FULL)
2152+ {
2153+ hcfg.d32 = dwc_read_reg32(&host_if->host_global_regs->hcfg);
2154+ hcfg.b.fslssupp = 1;
2155+ dwc_write_reg32(&host_if->host_global_regs->hcfg, hcfg.d32);
2156+ }
2157+
2158+ /* Configure data FIFO sizes */
2159+ if (core_if->hwcfg2.b.dynamic_fifo && params->enable_dynamic_fifo) {
2160+ DWC_DEBUGPL(DBG_CIL,"Total FIFO Size=%d\n", core_if->total_fifo_size);
2161+ DWC_DEBUGPL(DBG_CIL,"Rx FIFO Size=%d\n", params->host_rx_fifo_size);
2162+ DWC_DEBUGPL(DBG_CIL,"NP Tx FIFO Size=%d\n", params->host_nperio_tx_fifo_size);
2163+ DWC_DEBUGPL(DBG_CIL,"P Tx FIFO Size=%d\n", params->host_perio_tx_fifo_size);
2164+
2165+ /* Rx FIFO */
2166+ DWC_DEBUGPL(DBG_CIL,"initial grxfsiz=%08x\n", dwc_read_reg32(&global_regs->grxfsiz));
2167+ dwc_write_reg32(&global_regs->grxfsiz, params->host_rx_fifo_size);
2168+ DWC_DEBUGPL(DBG_CIL,"new grxfsiz=%08x\n", dwc_read_reg32(&global_regs->grxfsiz));
2169+
2170+ /* Non-periodic Tx FIFO */
2171+ DWC_DEBUGPL(DBG_CIL,"initial gnptxfsiz=%08x\n", dwc_read_reg32(&global_regs->gnptxfsiz));
2172+ nptxfifosize.b.depth = params->host_nperio_tx_fifo_size;
2173+ nptxfifosize.b.startaddr = params->host_rx_fifo_size;
2174+ dwc_write_reg32(&global_regs->gnptxfsiz, nptxfifosize.d32);
2175+ DWC_DEBUGPL(DBG_CIL,"new gnptxfsiz=%08x\n", dwc_read_reg32(&global_regs->gnptxfsiz));
2176+
2177+ /* Periodic Tx FIFO */
2178+ DWC_DEBUGPL(DBG_CIL,"initial hptxfsiz=%08x\n", dwc_read_reg32(&global_regs->hptxfsiz));
2179+ ptxfifosize.b.depth = params->host_perio_tx_fifo_size;
2180+ ptxfifosize.b.startaddr = nptxfifosize.b.startaddr + nptxfifosize.b.depth;
2181+ dwc_write_reg32(&global_regs->hptxfsiz, ptxfifosize.d32);
2182+ DWC_DEBUGPL(DBG_CIL,"new hptxfsiz=%08x\n", dwc_read_reg32(&global_regs->hptxfsiz));
2183+ }
2184+
2185+ /* Clear Host Set HNP Enable in the OTG Control Register */
2186+ gotgctl.b.hstsethnpen = 1;
2187+ dwc_modify_reg32(&global_regs->gotgctl, gotgctl.d32, 0);
2188+
2189+ /* Make sure the FIFOs are flushed. */
2190+ dwc_otg_flush_tx_fifo(core_if, 0x10 /* all Tx FIFOs */);
2191+ dwc_otg_flush_rx_fifo(core_if);
2192+
2193+ /* Flush out any leftover queued requests. */
2194+ num_channels = core_if->core_params->host_channels;
2195+ for (i = 0; i < num_channels; i++)
2196+ {
2197+ hc_regs = core_if->host_if->hc_regs[i];
2198+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
2199+ hcchar.b.chen = 0;
2200+ hcchar.b.chdis = 1;
2201+ hcchar.b.epdir = 0;
2202+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
2203+ }
2204+
2205+ /* Halt all channels to put them into a known state. */
2206+ for (i = 0; i < num_channels; i++)
2207+ {
2208+ int count = 0;
2209+ hc_regs = core_if->host_if->hc_regs[i];
2210+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
2211+ hcchar.b.chen = 1;
2212+ hcchar.b.chdis = 1;
2213+ hcchar.b.epdir = 0;
2214+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
2215+ DWC_DEBUGPL(DBG_HCDV, "%s: Halt channel %d\n", __func__, i);
2216+ do {
2217+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
2218+ if (++count > 1000)
2219+ {
2220+ DWC_ERROR("%s: Unable to clear halt on channel %d\n",
2221+ __func__, i);
2222+ break;
2223+ }
2224+ }
2225+ while (hcchar.b.chen);
2226+ }
2227+
2228+ /* Turn on the vbus power. */
2229+ DWC_PRINT("Init: Port Power? op_state=%d\n", core_if->op_state);
2230+ if (core_if->op_state == A_HOST) {
2231+ hprt0.d32 = dwc_otg_read_hprt0(core_if);
2232+ DWC_PRINT("Init: Power Port (%d)\n", hprt0.b.prtpwr);
2233+ if (hprt0.b.prtpwr == 0) {
2234+ hprt0.b.prtpwr = 1;
2235+ dwc_write_reg32(host_if->hprt0, hprt0.d32);
2236+ }
2237+ }
2238+
2239+ dwc_otg_enable_host_interrupts(core_if);
2240+}
2241+
2242+/**
2243+ * Prepares a host channel for transferring packets to/from a specific
2244+ * endpoint. The HCCHARn register is set up with the characteristics specified
2245+ * in _hc. Host channel interrupts that may need to be serviced while this
2246+ * transfer is in progress are enabled.
2247+ *
2248+ * @param core_if Programming view of DWC_otg controller
2249+ * @param hc Information needed to initialize the host channel
2250+ */
2251+void dwc_otg_hc_init(dwc_otg_core_if_t *core_if, dwc_hc_t *hc)
2252+{
2253+ uint32_t intr_enable;
2254+ hcintmsk_data_t hc_intr_mask;
2255+ gintmsk_data_t gintmsk = { .d32 = 0 };
2256+ hcchar_data_t hcchar;
2257+ hcsplt_data_t hcsplt;
2258+
2259+ uint8_t hc_num = hc->hc_num;
2260+ dwc_otg_host_if_t *host_if = core_if->host_if;
2261+ dwc_otg_hc_regs_t *hc_regs = host_if->hc_regs[hc_num];
2262+
2263+ /* Clear old interrupt conditions for this host channel. */
2264+ hc_intr_mask.d32 = 0xFFFFFFFF;
2265+ hc_intr_mask.b.reserved = 0;
2266+ dwc_write_reg32(&hc_regs->hcint, hc_intr_mask.d32);
2267+
2268+ /* Enable channel interrupts required for this transfer. */
2269+ hc_intr_mask.d32 = 0;
2270+ hc_intr_mask.b.chhltd = 1;
2271+ if (core_if->dma_enable) {
2272+ hc_intr_mask.b.ahberr = 1;
2273+ if (hc->error_state && !hc->do_split &&
2274+ hc->ep_type != DWC_OTG_EP_TYPE_ISOC) {
2275+ hc_intr_mask.b.ack = 1;
2276+ if (hc->ep_is_in) {
2277+ hc_intr_mask.b.datatglerr = 1;
2278+ if (hc->ep_type != DWC_OTG_EP_TYPE_INTR) {
2279+ hc_intr_mask.b.nak = 1;
2280+ }
2281+ }
2282+ }
2283+ }
2284+ else {
2285+ switch (hc->ep_type) {
2286+ case DWC_OTG_EP_TYPE_CONTROL:
2287+ case DWC_OTG_EP_TYPE_BULK:
2288+ hc_intr_mask.b.xfercompl = 1;
2289+ hc_intr_mask.b.stall = 1;
2290+ hc_intr_mask.b.xacterr = 1;
2291+ hc_intr_mask.b.datatglerr = 1;
2292+ if (hc->ep_is_in) {
2293+ hc_intr_mask.b.bblerr = 1;
2294+ }
2295+ else {
2296+ hc_intr_mask.b.nak = 1;
2297+ hc_intr_mask.b.nyet = 1;
2298+ if (hc->do_ping) {
2299+ hc_intr_mask.b.ack = 1;
2300+ }
2301+ }
2302+
2303+ if (hc->do_split) {
2304+ hc_intr_mask.b.nak = 1;
2305+ if (hc->complete_split) {
2306+ hc_intr_mask.b.nyet = 1;
2307+ }
2308+ else {
2309+ hc_intr_mask.b.ack = 1;
2310+ }
2311+ }
2312+
2313+ if (hc->error_state) {
2314+ hc_intr_mask.b.ack = 1;
2315+ }
2316+ break;
2317+ case DWC_OTG_EP_TYPE_INTR:
2318+ hc_intr_mask.b.xfercompl = 1;
2319+ hc_intr_mask.b.nak = 1;
2320+ hc_intr_mask.b.stall = 1;
2321+ hc_intr_mask.b.xacterr = 1;
2322+ hc_intr_mask.b.datatglerr = 1;
2323+ hc_intr_mask.b.frmovrun = 1;
2324+
2325+ if (hc->ep_is_in) {
2326+ hc_intr_mask.b.bblerr = 1;
2327+ }
2328+ if (hc->error_state) {
2329+ hc_intr_mask.b.ack = 1;
2330+ }
2331+ if (hc->do_split) {
2332+ if (hc->complete_split) {
2333+ hc_intr_mask.b.nyet = 1;
2334+ }
2335+ else {
2336+ hc_intr_mask.b.ack = 1;
2337+ }
2338+ }
2339+ break;
2340+ case DWC_OTG_EP_TYPE_ISOC:
2341+ hc_intr_mask.b.xfercompl = 1;
2342+ hc_intr_mask.b.frmovrun = 1;
2343+ hc_intr_mask.b.ack = 1;
2344+
2345+ if (hc->ep_is_in) {
2346+ hc_intr_mask.b.xacterr = 1;
2347+ hc_intr_mask.b.bblerr = 1;
2348+ }
2349+ break;
2350+ }
2351+ }
2352+ dwc_write_reg32(&hc_regs->hcintmsk, hc_intr_mask.d32);
2353+
2354+// if(hc->ep_type == DWC_OTG_EP_TYPE_BULK && !hc->ep_is_in)
2355+// hc->max_packet = 512;
2356+ /* Enable the top level host channel interrupt. */
2357+ intr_enable = (1 << hc_num);
2358+ dwc_modify_reg32(&host_if->host_global_regs->haintmsk, 0, intr_enable);
2359+
2360+ /* Make sure host channel interrupts are enabled. */
2361+ gintmsk.b.hcintr = 1;
2362+ dwc_modify_reg32(&core_if->core_global_regs->gintmsk, 0, gintmsk.d32);
2363+
2364+ /*
2365+ * Program the HCCHARn register with the endpoint characteristics for
2366+ * the current transfer.
2367+ */
2368+ hcchar.d32 = 0;
2369+ hcchar.b.devaddr = hc->dev_addr;
2370+ hcchar.b.epnum = hc->ep_num;
2371+ hcchar.b.epdir = hc->ep_is_in;
2372+ hcchar.b.lspddev = (hc->speed == DWC_OTG_EP_SPEED_LOW);
2373+ hcchar.b.eptype = hc->ep_type;
2374+ hcchar.b.mps = hc->max_packet;
2375+
2376+ dwc_write_reg32(&host_if->hc_regs[hc_num]->hcchar, hcchar.d32);
2377+
2378+ DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
2379+ DWC_DEBUGPL(DBG_HCDV, " Dev Addr: %d\n", hcchar.b.devaddr);
2380+ DWC_DEBUGPL(DBG_HCDV, " Ep Num: %d\n", hcchar.b.epnum);
2381+ DWC_DEBUGPL(DBG_HCDV, " Is In: %d\n", hcchar.b.epdir);
2382+ DWC_DEBUGPL(DBG_HCDV, " Is Low Speed: %d\n", hcchar.b.lspddev);
2383+ DWC_DEBUGPL(DBG_HCDV, " Ep Type: %d\n", hcchar.b.eptype);
2384+ DWC_DEBUGPL(DBG_HCDV, " Max Pkt: %d\n", hcchar.b.mps);
2385+ DWC_DEBUGPL(DBG_HCDV, " Multi Cnt: %d\n", hcchar.b.multicnt);
2386+
2387+ /*
2388+ * Program the HCSPLIT register for SPLITs
2389+ */
2390+ hcsplt.d32 = 0;
2391+ if (hc->do_split) {
2392+ DWC_DEBUGPL(DBG_HCDV, "Programming HC %d with split --> %s\n", hc->hc_num,
2393+ hc->complete_split ? "CSPLIT" : "SSPLIT");
2394+ hcsplt.b.compsplt = hc->complete_split;
2395+ hcsplt.b.xactpos = hc->xact_pos;
2396+ hcsplt.b.hubaddr = hc->hub_addr;
2397+ hcsplt.b.prtaddr = hc->port_addr;
2398+ DWC_DEBUGPL(DBG_HCDV, " comp split %d\n", hc->complete_split);
2399+ DWC_DEBUGPL(DBG_HCDV, " xact pos %d\n", hc->xact_pos);
2400+ DWC_DEBUGPL(DBG_HCDV, " hub addr %d\n", hc->hub_addr);
2401+ DWC_DEBUGPL(DBG_HCDV, " port addr %d\n", hc->port_addr);
2402+ DWC_DEBUGPL(DBG_HCDV, " is_in %d\n", hc->ep_is_in);
2403+ DWC_DEBUGPL(DBG_HCDV, " Max Pkt: %d\n", hcchar.b.mps);
2404+ DWC_DEBUGPL(DBG_HCDV, " xferlen: %d\n", hc->xfer_len);
2405+ }
2406+ dwc_write_reg32(&host_if->hc_regs[hc_num]->hcsplt, hcsplt.d32);
2407+
2408+}
2409+
2410+/**
2411+ * Attempts to halt a host channel. This function should only be called in
2412+ * Slave mode or to abort a transfer in either Slave mode or DMA mode. Under
2413+ * normal circumstances in DMA mode, the controller halts the channel when the
2414+ * transfer is complete or a condition occurs that requires application
2415+ * intervention.
2416+ *
2417+ * In slave mode, checks for a free request queue entry, then sets the Channel
2418+ * Enable and Channel Disable bits of the Host Channel Characteristics
2419+ * register of the specified channel to intiate the halt. If there is no free
2420+ * request queue entry, sets only the Channel Disable bit of the HCCHARn
2421+ * register to flush requests for this channel. In the latter case, sets a
2422+ * flag to indicate that the host channel needs to be halted when a request
2423+ * queue slot is open.
2424+ *
2425+ * In DMA mode, always sets the Channel Enable and Channel Disable bits of the
2426+ * HCCHARn register. The controller ensures there is space in the request
2427+ * queue before submitting the halt request.
2428+ *
2429+ * Some time may elapse before the core flushes any posted requests for this
2430+ * host channel and halts. The Channel Halted interrupt handler completes the
2431+ * deactivation of the host channel.
2432+ *
2433+ * @param core_if Controller register interface.
2434+ * @param hc Host channel to halt.
2435+ * @param halt_status Reason for halting the channel.
2436+ */
2437+void dwc_otg_hc_halt(dwc_otg_core_if_t *core_if,
2438+ dwc_hc_t *hc,
2439+ dwc_otg_halt_status_e halt_status)
2440+{
2441+ gnptxsts_data_t nptxsts;
2442+ hptxsts_data_t hptxsts;
2443+ hcchar_data_t hcchar;
2444+ dwc_otg_hc_regs_t *hc_regs;
2445+ dwc_otg_core_global_regs_t *global_regs;
2446+ dwc_otg_host_global_regs_t *host_global_regs;
2447+
2448+ hc_regs = core_if->host_if->hc_regs[hc->hc_num];
2449+ global_regs = core_if->core_global_regs;
2450+ host_global_regs = core_if->host_if->host_global_regs;
2451+
2452+ WARN_ON(halt_status == DWC_OTG_HC_XFER_NO_HALT_STATUS);
2453+
2454+ if (halt_status == DWC_OTG_HC_XFER_URB_DEQUEUE ||
2455+ halt_status == DWC_OTG_HC_XFER_AHB_ERR) {
2456+ /*
2457+ * Disable all channel interrupts except Ch Halted. The QTD
2458+ * and QH state associated with this transfer has been cleared
2459+ * (in the case of URB_DEQUEUE), so the channel needs to be
2460+ * shut down carefully to prevent crashes.
2461+ */
2462+ hcintmsk_data_t hcintmsk;
2463+ hcintmsk.d32 = 0;
2464+ hcintmsk.b.chhltd = 1;
2465+ dwc_write_reg32(&hc_regs->hcintmsk, hcintmsk.d32);
2466+
2467+ /*
2468+ * Make sure no other interrupts besides halt are currently
2469+ * pending. Handling another interrupt could cause a crash due
2470+ * to the QTD and QH state.
2471+ */
2472+ dwc_write_reg32(&hc_regs->hcint, ~hcintmsk.d32);
2473+
2474+ /*
2475+ * Make sure the halt status is set to URB_DEQUEUE or AHB_ERR
2476+ * even if the channel was already halted for some other
2477+ * reason.
2478+ */
2479+ hc->halt_status = halt_status;
2480+
2481+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
2482+ if (hcchar.b.chen == 0) {
2483+ /*
2484+ * The channel is either already halted or it hasn't
2485+ * started yet. In DMA mode, the transfer may halt if
2486+ * it finishes normally or a condition occurs that
2487+ * requires driver intervention. Don't want to halt
2488+ * the channel again. In either Slave or DMA mode,
2489+ * it's possible that the transfer has been assigned
2490+ * to a channel, but not started yet when an URB is
2491+ * dequeued. Don't want to halt a channel that hasn't
2492+ * started yet.
2493+ */
2494+ return;
2495+ }
2496+ }
2497+
2498+ if (hc->halt_pending) {
2499+ /*
2500+ * A halt has already been issued for this channel. This might
2501+ * happen when a transfer is aborted by a higher level in
2502+ * the stack.
2503+ */
2504+#ifdef DEBUG
2505+ DWC_PRINT("*** %s: Channel %d, _hc->halt_pending already set ***\n",
2506+ __func__, hc->hc_num);
2507+
2508+/* dwc_otg_dump_global_registers(core_if); */
2509+/* dwc_otg_dump_host_registers(core_if); */
2510+#endif
2511+ return;
2512+ }
2513+
2514+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
2515+ hcchar.b.chen = 1;
2516+ hcchar.b.chdis = 1;
2517+
2518+ if (!core_if->dma_enable) {
2519+ /* Check for space in the request queue to issue the halt. */
2520+ if (hc->ep_type == DWC_OTG_EP_TYPE_CONTROL ||
2521+ hc->ep_type == DWC_OTG_EP_TYPE_BULK) {
2522+ nptxsts.d32 = dwc_read_reg32(&global_regs->gnptxsts);
2523+ if (nptxsts.b.nptxqspcavail == 0) {
2524+ hcchar.b.chen = 0;
2525+ }
2526+ }
2527+ else {
2528+ hptxsts.d32 = dwc_read_reg32(&host_global_regs->hptxsts);
2529+ if ((hptxsts.b.ptxqspcavail == 0) || (core_if->queuing_high_bandwidth)) {
2530+ hcchar.b.chen = 0;
2531+ }
2532+ }
2533+ }
2534+
2535+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
2536+
2537+ hc->halt_status = halt_status;
2538+
2539+ if (hcchar.b.chen) {
2540+ hc->halt_pending = 1;
2541+ hc->halt_on_queue = 0;
2542+ }
2543+ else {
2544+ hc->halt_on_queue = 1;
2545+ }
2546+
2547+ DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
2548+ DWC_DEBUGPL(DBG_HCDV, " hcchar: 0x%08x\n", hcchar.d32);
2549+ DWC_DEBUGPL(DBG_HCDV, " halt_pending: %d\n", hc->halt_pending);
2550+ DWC_DEBUGPL(DBG_HCDV, " halt_on_queue: %d\n", hc->halt_on_queue);
2551+ DWC_DEBUGPL(DBG_HCDV, " halt_status: %d\n", hc->halt_status);
2552+
2553+ return;
2554+}
2555+
2556+/**
2557+ * Clears the transfer state for a host channel. This function is normally
2558+ * called after a transfer is done and the host channel is being released.
2559+ *
2560+ * @param core_if Programming view of DWC_otg controller.
2561+ * @param hc Identifies the host channel to clean up.
2562+ */
2563+void dwc_otg_hc_cleanup(dwc_otg_core_if_t *core_if, dwc_hc_t *hc)
2564+{
2565+ dwc_otg_hc_regs_t *hc_regs;
2566+
2567+ hc->xfer_started = 0;
2568+
2569+ /*
2570+ * Clear channel interrupt enables and any unhandled channel interrupt
2571+ * conditions.
2572+ */
2573+ hc_regs = core_if->host_if->hc_regs[hc->hc_num];
2574+ dwc_write_reg32(&hc_regs->hcintmsk, 0);
2575+ dwc_write_reg32(&hc_regs->hcint, 0xFFFFFFFF);
2576+
2577+#ifdef DEBUG
2578+ del_timer(&core_if->hc_xfer_timer[hc->hc_num]);
2579+ {
2580+ hcchar_data_t hcchar;
2581+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
2582+ if (hcchar.b.chdis) {
2583+ DWC_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n",
2584+ __func__, hc->hc_num, hcchar.d32);
2585+ }
2586+ }
2587+#endif
2588+}
2589+
2590+/**
2591+ * Sets the channel property that indicates in which frame a periodic transfer
2592+ * should occur. This is always set to the _next_ frame. This function has no
2593+ * effect on non-periodic transfers.
2594+ *
2595+ * @param core_if Programming view of DWC_otg controller.
2596+ * @param hc Identifies the host channel to set up and its properties.
2597+ * @param hcchar Current value of the HCCHAR register for the specified host
2598+ * channel.
2599+ */
2600+static inline void hc_set_even_odd_frame(dwc_otg_core_if_t *core_if,
2601+ dwc_hc_t *hc,
2602+ hcchar_data_t *hcchar)
2603+{
2604+ if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
2605+ hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
2606+ hfnum_data_t hfnum;
2607+ hfnum.d32 = dwc_read_reg32(&core_if->host_if->host_global_regs->hfnum);
2608+
2609+ /* 1 if _next_ frame is odd, 0 if it's even */
2610+ hcchar->b.oddfrm = (hfnum.b.frnum & 0x1) ? 0 : 1;
2611+#ifdef DEBUG
2612+ if (hc->ep_type == DWC_OTG_EP_TYPE_INTR && hc->do_split && !hc->complete_split) {
2613+ switch (hfnum.b.frnum & 0x7) {
2614+ case 7:
2615+ core_if->hfnum_7_samples++;
2616+ core_if->hfnum_7_frrem_accum += hfnum.b.frrem;
2617+ break;
2618+ case 0:
2619+ core_if->hfnum_0_samples++;
2620+ core_if->hfnum_0_frrem_accum += hfnum.b.frrem;
2621+ break;
2622+ default:
2623+ core_if->hfnum_other_samples++;
2624+ core_if->hfnum_other_frrem_accum += hfnum.b.frrem;
2625+ break;
2626+ }
2627+ }
2628+#endif
2629+ }
2630+}
2631+
2632+#ifdef DEBUG
2633+static void hc_xfer_timeout(unsigned long ptr)
2634+{
2635+ hc_xfer_info_t *xfer_info = (hc_xfer_info_t *)ptr;
2636+ int hc_num = xfer_info->hc->hc_num;
2637+ DWC_WARN("%s: timeout on channel %d\n", __func__, hc_num);
2638+ DWC_WARN(" start_hcchar_val 0x%08x\n", xfer_info->core_if->start_hcchar_val[hc_num]);
2639+}
2640+#endif
2641+
2642+/*
2643+ * This function does the setup for a data transfer for a host channel and
2644+ * starts the transfer. May be called in either Slave mode or DMA mode. In
2645+ * Slave mode, the caller must ensure that there is sufficient space in the
2646+ * request queue and Tx Data FIFO.
2647+ *
2648+ * For an OUT transfer in Slave mode, it loads a data packet into the
2649+ * appropriate FIFO. If necessary, additional data packets will be loaded in
2650+ * the Host ISR.
2651+ *
2652+ * For an IN transfer in Slave mode, a data packet is requested. The data
2653+ * packets are unloaded from the Rx FIFO in the Host ISR. If necessary,
2654+ * additional data packets are requested in the Host ISR.
2655+ *
2656+ * For a PING transfer in Slave mode, the Do Ping bit is set in the HCTSIZ
2657+ * register along with a packet count of 1 and the channel is enabled. This
2658+ * causes a single PING transaction to occur. Other fields in HCTSIZ are
2659+ * simply set to 0 since no data transfer occurs in this case.
2660+ *
2661+ * For a PING transfer in DMA mode, the HCTSIZ register is initialized with
2662+ * all the information required to perform the subsequent data transfer. In
2663+ * addition, the Do Ping bit is set in the HCTSIZ register. In this case, the
2664+ * controller performs the entire PING protocol, then starts the data
2665+ * transfer.
2666+ *
2667+ * @param core_if Programming view of DWC_otg controller.
2668+ * @param hc Information needed to initialize the host channel. The xfer_len
2669+ * value may be reduced to accommodate the max widths of the XferSize and
2670+ * PktCnt fields in the HCTSIZn register. The multi_count value may be changed
2671+ * to reflect the final xfer_len value.
2672+ */
2673+void dwc_otg_hc_start_transfer(dwc_otg_core_if_t *core_if, dwc_hc_t *hc)
2674+{
2675+ hcchar_data_t hcchar;
2676+ hctsiz_data_t hctsiz;
2677+ uint16_t num_packets;
2678+ uint32_t max_hc_xfer_size = core_if->core_params->max_transfer_size;
2679+ uint16_t max_hc_pkt_count = core_if->core_params->max_packet_count;
2680+ dwc_otg_hc_regs_t *hc_regs = core_if->host_if->hc_regs[hc->hc_num];
2681+
2682+ hctsiz.d32 = 0;
2683+
2684+ if (hc->do_ping) {
2685+ if (!core_if->dma_enable) {
2686+ dwc_otg_hc_do_ping(core_if, hc);
2687+ hc->xfer_started = 1;
2688+ return;
2689+ }
2690+ else {
2691+ hctsiz.b.dopng = 1;
2692+ }
2693+ }
2694+
2695+ if (hc->do_split) {
2696+ num_packets = 1;
2697+
2698+ if (hc->complete_split && !hc->ep_is_in) {
2699+ /* For CSPLIT OUT Transfer, set the size to 0 so the
2700+ * core doesn't expect any data written to the FIFO */
2701+ hc->xfer_len = 0;
2702+ }
2703+ else if (hc->ep_is_in || (hc->xfer_len > hc->max_packet)) {
2704+ hc->xfer_len = hc->max_packet;
2705+ }
2706+ else if (!hc->ep_is_in && (hc->xfer_len > 188)) {
2707+ hc->xfer_len = 188;
2708+ }
2709+
2710+ hctsiz.b.xfersize = hc->xfer_len;
2711+ }
2712+ else {
2713+ /*
2714+ * Ensure that the transfer length and packet count will fit
2715+ * in the widths allocated for them in the HCTSIZn register.
2716+ */
2717+ if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
2718+ hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
2719+ /*
2720+ * Make sure the transfer size is no larger than one
2721+ * (micro)frame's worth of data. (A check was done
2722+ * when the periodic transfer was accepted to ensure
2723+ * that a (micro)frame's worth of data can be
2724+ * programmed into a channel.)
2725+ */
2726+ uint32_t max_periodic_len = hc->multi_count * hc->max_packet;
2727+ if (hc->xfer_len > max_periodic_len) {
2728+ hc->xfer_len = max_periodic_len;
2729+ }
2730+ else {
2731+ }
2732+ }
2733+ else if (hc->xfer_len > max_hc_xfer_size) {
2734+ /* Make sure that xfer_len is a multiple of max packet size. */
2735+ hc->xfer_len = max_hc_xfer_size - hc->max_packet + 1;
2736+ }
2737+
2738+ if (hc->xfer_len > 0) {
2739+ num_packets = (hc->xfer_len + hc->max_packet - 1) / hc->max_packet;
2740+ if (num_packets > max_hc_pkt_count) {
2741+ num_packets = max_hc_pkt_count;
2742+ hc->xfer_len = num_packets * hc->max_packet;
2743+ }
2744+ }
2745+ else {
2746+ /* Need 1 packet for transfer length of 0. */
2747+ num_packets = 1;
2748+ }
2749+
2750+#if 0
2751+//host testusb item 10, would do series of Control transfer
2752+//with URB_SHORT_NOT_OK set in transfer_flags ,
2753+//changing the xfer_len would cause the test fail
2754+ if (hc->ep_is_in) {
2755+ /* Always program an integral # of max packets for IN transfers. */
2756+ hc->xfer_len = num_packets * hc->max_packet;
2757+ }
2758+#endif
2759+
2760+ if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
2761+ hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
2762+ /*
2763+ * Make sure that the multi_count field matches the
2764+ * actual transfer length.
2765+ */
2766+ hc->multi_count = num_packets;
2767+ }
2768+
2769+ if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
2770+ /* Set up the initial PID for the transfer. */
2771+ if (hc->speed == DWC_OTG_EP_SPEED_HIGH) {
2772+ if (hc->ep_is_in) {
2773+ if (hc->multi_count == 1) {
2774+ hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
2775+ }
2776+ else if (hc->multi_count == 2) {
2777+ hc->data_pid_start = DWC_OTG_HC_PID_DATA1;
2778+ }
2779+ else {
2780+ hc->data_pid_start = DWC_OTG_HC_PID_DATA2;
2781+ }
2782+ }
2783+ else {
2784+ if (hc->multi_count == 1) {
2785+ hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
2786+ }
2787+ else {
2788+ hc->data_pid_start = DWC_OTG_HC_PID_MDATA;
2789+ }
2790+ }
2791+ }
2792+ else {
2793+ hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
2794+ }
2795+ }
2796+
2797+ hctsiz.b.xfersize = hc->xfer_len;
2798+ }
2799+
2800+ hc->start_pkt_count = num_packets;
2801+ hctsiz.b.pktcnt = num_packets;
2802+ hctsiz.b.pid = hc->data_pid_start;
2803+ dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
2804+
2805+ DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
2806+ DWC_DEBUGPL(DBG_HCDV, " Xfer Size: %d\n", hctsiz.b.xfersize);
2807+ DWC_DEBUGPL(DBG_HCDV, " Num Pkts: %d\n", hctsiz.b.pktcnt);
2808+ DWC_DEBUGPL(DBG_HCDV, " Start PID: %d\n", hctsiz.b.pid);
2809+
2810+ if (core_if->dma_enable) {
2811+ dwc_write_reg32(&hc_regs->hcdma, (uint32_t)hc->xfer_buff);
2812+ }
2813+
2814+ /* Start the split */
2815+ if (hc->do_split) {
2816+ hcsplt_data_t hcsplt;
2817+ hcsplt.d32 = dwc_read_reg32 (&hc_regs->hcsplt);
2818+ hcsplt.b.spltena = 1;
2819+ dwc_write_reg32(&hc_regs->hcsplt, hcsplt.d32);
2820+ }
2821+
2822+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
2823+ hcchar.b.multicnt = hc->multi_count;
2824+ hc_set_even_odd_frame(core_if, hc, &hcchar);
2825+#ifdef DEBUG
2826+ core_if->start_hcchar_val[hc->hc_num] = hcchar.d32;
2827+ if (hcchar.b.chdis) {
2828+ DWC_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n",
2829+ __func__, hc->hc_num, hcchar.d32);
2830+ }
2831+#endif
2832+
2833+ /* Set host channel enable after all other setup is complete. */
2834+ hcchar.b.chen = 1;
2835+ hcchar.b.chdis = 0;
2836+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
2837+
2838+ hc->xfer_started = 1;
2839+ hc->requests++;
2840+
2841+ if (!core_if->dma_enable &&
2842+ !hc->ep_is_in && hc->xfer_len > 0) {
2843+ /* Load OUT packet into the appropriate Tx FIFO. */
2844+ dwc_otg_hc_write_packet(core_if, hc);
2845+ }
2846+
2847+#ifdef DEBUG
2848+ /* Start a timer for this transfer. */
2849+ core_if->hc_xfer_timer[hc->hc_num].function = hc_xfer_timeout;
2850+ core_if->hc_xfer_info[hc->hc_num].core_if = core_if;
2851+ core_if->hc_xfer_info[hc->hc_num].hc = hc;
2852+ core_if->hc_xfer_timer[hc->hc_num].data = (unsigned long)(&core_if->hc_xfer_info[hc->hc_num]);
2853+ core_if->hc_xfer_timer[hc->hc_num].expires = jiffies + (HZ*10);
2854+ add_timer(&core_if->hc_xfer_timer[hc->hc_num]);
2855+#endif
2856+}
2857+
2858+/**
2859+ * This function continues a data transfer that was started by previous call
2860+ * to <code>dwc_otg_hc_start_transfer</code>. The caller must ensure there is
2861+ * sufficient space in the request queue and Tx Data FIFO. This function
2862+ * should only be called in Slave mode. In DMA mode, the controller acts
2863+ * autonomously to complete transfers programmed to a host channel.
2864+ *
2865+ * For an OUT transfer, a new data packet is loaded into the appropriate FIFO
2866+ * if there is any data remaining to be queued. For an IN transfer, another
2867+ * data packet is always requested. For the SETUP phase of a control transfer,
2868+ * this function does nothing.
2869+ *
2870+ * @return 1 if a new request is queued, 0 if no more requests are required
2871+ * for this transfer.
2872+ */
2873+int dwc_otg_hc_continue_transfer(dwc_otg_core_if_t *core_if, dwc_hc_t *hc)
2874+{
2875+ DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
2876+
2877+ if (hc->do_split) {
2878+ /* SPLITs always queue just once per channel */
2879+ return 0;
2880+ }
2881+ else if (hc->data_pid_start == DWC_OTG_HC_PID_SETUP) {
2882+ /* SETUPs are queued only once since they can't be NAKed. */
2883+ return 0;
2884+ }
2885+ else if (hc->ep_is_in) {
2886+ /*
2887+ * Always queue another request for other IN transfers. If
2888+ * back-to-back INs are issued and NAKs are received for both,
2889+ * the driver may still be processing the first NAK when the
2890+ * second NAK is received. When the interrupt handler clears
2891+ * the NAK interrupt for the first NAK, the second NAK will
2892+ * not be seen. So we can't depend on the NAK interrupt
2893+ * handler to requeue a NAKed request. Instead, IN requests
2894+ * are issued each time this function is called. When the
2895+ * transfer completes, the extra requests for the channel will
2896+ * be flushed.
2897+ */
2898+ hcchar_data_t hcchar;
2899+ dwc_otg_hc_regs_t *hc_regs = core_if->host_if->hc_regs[hc->hc_num];
2900+
2901+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
2902+ hc_set_even_odd_frame(core_if, hc, &hcchar);
2903+ hcchar.b.chen = 1;
2904+ hcchar.b.chdis = 0;
2905+ DWC_DEBUGPL(DBG_HCDV, " IN xfer: hcchar = 0x%08x\n", hcchar.d32);
2906+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
2907+ hc->requests++;
2908+ return 1;
2909+ }
2910+ else {
2911+ /* OUT transfers. */
2912+ if (hc->xfer_count < hc->xfer_len) {
2913+ if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
2914+ hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
2915+ hcchar_data_t hcchar;
2916+ dwc_otg_hc_regs_t *hc_regs;
2917+ hc_regs = core_if->host_if->hc_regs[hc->hc_num];
2918+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
2919+ hc_set_even_odd_frame(core_if, hc, &hcchar);
2920+ }
2921+
2922+ /* Load OUT packet into the appropriate Tx FIFO. */
2923+ dwc_otg_hc_write_packet(core_if, hc);
2924+ hc->requests++;
2925+ return 1;
2926+ }
2927+ else {
2928+ return 0;
2929+ }
2930+ }
2931+}
2932+
2933+/**
2934+ * Starts a PING transfer. This function should only be called in Slave mode.
2935+ * The Do Ping bit is set in the HCTSIZ register, then the channel is enabled.
2936+ */
2937+void dwc_otg_hc_do_ping(dwc_otg_core_if_t *core_if, dwc_hc_t *hc)
2938+{
2939+ hcchar_data_t hcchar;
2940+ hctsiz_data_t hctsiz;
2941+ dwc_otg_hc_regs_t *hc_regs = core_if->host_if->hc_regs[hc->hc_num];
2942+
2943+ DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
2944+
2945+ hctsiz.d32 = 0;
2946+ hctsiz.b.dopng = 1;
2947+ hctsiz.b.pktcnt = 1;
2948+ dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
2949+
2950+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
2951+ hcchar.b.chen = 1;
2952+ hcchar.b.chdis = 0;
2953+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
2954+}
2955+
2956+/*
2957+ * This function writes a packet into the Tx FIFO associated with the Host
2958+ * Channel. For a channel associated with a non-periodic EP, the non-periodic
2959+ * Tx FIFO is written. For a channel associated with a periodic EP, the
2960+ * periodic Tx FIFO is written. This function should only be called in Slave
2961+ * mode.
2962+ *
2963+ * Upon return the xfer_buff and xfer_count fields in _hc are incremented by
2964+ * then number of bytes written to the Tx FIFO.
2965+ */
2966+void dwc_otg_hc_write_packet(dwc_otg_core_if_t *core_if, dwc_hc_t *hc)
2967+{
2968+ uint32_t i;
2969+ uint32_t remaining_count;
2970+ uint32_t byte_count;
2971+ uint32_t dword_count;
2972+
2973+ uint32_t *data_buff = (uint32_t *)(hc->xfer_buff);
2974+ uint32_t *data_fifo = core_if->data_fifo[hc->hc_num];
2975+
2976+ remaining_count = hc->xfer_len - hc->xfer_count;
2977+ if (remaining_count > hc->max_packet) {
2978+ byte_count = hc->max_packet;
2979+ }
2980+ else {
2981+ byte_count = remaining_count;
2982+ }
2983+
2984+ dword_count = (byte_count + 3) / 4;
2985+
2986+ if ((((unsigned long)data_buff) & 0x3) == 0) {
2987+ /* xfer_buff is DWORD aligned. */
2988+ for (i = 0; i < dword_count; i++, data_buff++)
2989+ {
2990+ dwc_write_reg32(data_fifo, *data_buff);
2991+ }
2992+ }
2993+ else {
2994+ /* xfer_buff is not DWORD aligned. */
2995+ for (i = 0; i < dword_count; i++, data_buff++)
2996+ {
2997+ dwc_write_reg32(data_fifo, get_unaligned(data_buff));
2998+ }
2999+ }
3000+
3001+ hc->xfer_count += byte_count;
3002+ hc->xfer_buff += byte_count;
3003+}
3004+
3005+/**
3006+ * Gets the current USB frame number. This is the frame number from the last
3007+ * SOF packet.
3008+ */
3009+uint32_t dwc_otg_get_frame_number(dwc_otg_core_if_t *core_if)
3010+{
3011+ dsts_data_t dsts;
3012+ dsts.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts);
3013+
3014+ /* read current frame/microframe number from DSTS register */
3015+ return dsts.b.soffn;
3016+}
3017+
3018+/**
3019+ * This function reads a setup packet from the Rx FIFO into the destination
3020+ * buffer. This function is called from the Rx Status Queue Level (RxStsQLvl)
3021+ * Interrupt routine when a SETUP packet has been received in Slave mode.
3022+ *
3023+ * @param core_if Programming view of DWC_otg controller.
3024+ * @param dest Destination buffer for packet data.
3025+ */
3026+void dwc_otg_read_setup_packet(dwc_otg_core_if_t *core_if, uint32_t *dest)
3027+{
3028+ /* Get the 8 bytes of a setup transaction data */
3029+
3030+ /* Pop 2 DWORDS off the receive data FIFO into memory */
3031+ dest[0] = dwc_read_reg32(core_if->data_fifo[0]);
3032+ dest[1] = dwc_read_reg32(core_if->data_fifo[0]);
3033+}
3034+
3035+
3036+/**
3037+ * This function enables EP0 OUT to receive SETUP packets and configures EP0
3038+ * IN for transmitting packets. It is normally called when the
3039+ * "Enumeration Done" interrupt occurs.
3040+ *
3041+ * @param core_if Programming view of DWC_otg controller.
3042+ * @param ep The EP0 data.
3043+ */
3044+void dwc_otg_ep0_activate(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
3045+{
3046+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
3047+ dsts_data_t dsts;
3048+ depctl_data_t diepctl;
3049+ depctl_data_t doepctl;
3050+ dctl_data_t dctl = { .d32 = 0 };
3051+
3052+ /* Read the Device Status and Endpoint 0 Control registers */
3053+ dsts.d32 = dwc_read_reg32(&dev_if->dev_global_regs->dsts);
3054+ diepctl.d32 = dwc_read_reg32(&dev_if->in_ep_regs[0]->diepctl);
3055+ doepctl.d32 = dwc_read_reg32(&dev_if->out_ep_regs[0]->doepctl);
3056+
3057+ /* Set the MPS of the IN EP based on the enumeration speed */
3058+ switch (dsts.b.enumspd) {
3059+ case DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
3060+ case DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
3061+ case DWC_DSTS_ENUMSPD_FS_PHY_48MHZ:
3062+ diepctl.b.mps = DWC_DEP0CTL_MPS_64;
3063+ break;
3064+ case DWC_DSTS_ENUMSPD_LS_PHY_6MHZ:
3065+ diepctl.b.mps = DWC_DEP0CTL_MPS_8;
3066+ break;
3067+ }
3068+
3069+ dwc_write_reg32(&dev_if->in_ep_regs[0]->diepctl, diepctl.d32);
3070+
3071+ /* Enable OUT EP for receive */
3072+ doepctl.b.epena = 1;
3073+ dwc_write_reg32(&dev_if->out_ep_regs[0]->doepctl, doepctl.d32);
3074+
3075+#ifdef VERBOSE
3076+ DWC_DEBUGPL(DBG_PCDV,"doepctl0=%0x\n",
3077+ dwc_read_reg32(&dev_if->out_ep_regs[0]->doepctl));
3078+ DWC_DEBUGPL(DBG_PCDV,"diepctl0=%0x\n",
3079+ dwc_read_reg32(&dev_if->in_ep_regs[0]->diepctl));
3080+#endif
3081+ dctl.b.cgnpinnak = 1;
3082+
3083+ dwc_modify_reg32(&dev_if->dev_global_regs->dctl, dctl.d32, dctl.d32);
3084+ DWC_DEBUGPL(DBG_PCDV,"dctl=%0x\n",
3085+ dwc_read_reg32(&dev_if->dev_global_regs->dctl));
3086+}
3087+
3088+/**
3089+ * This function activates an EP. The Device EP control register for
3090+ * the EP is configured as defined in the ep structure. Note: This
3091+ * function is not used for EP0.
3092+ *
3093+ * @param core_if Programming view of DWC_otg controller.
3094+ * @param ep The EP to activate.
3095+ */
3096+void dwc_otg_ep_activate(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
3097+{
3098+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
3099+ depctl_data_t depctl;
3100+ volatile uint32_t *addr;
3101+ daint_data_t daintmsk = { .d32 = 0 };
3102+
3103+ DWC_DEBUGPL(DBG_PCDV, "%s() EP%d-%s\n", __func__, ep->num,
3104+ (ep->is_in?"IN":"OUT"));
3105+
3106+ /* Read DEPCTLn register */
3107+ if (ep->is_in == 1) {
3108+ addr = &dev_if->in_ep_regs[ep->num]->diepctl;
3109+ daintmsk.ep.in = 1<<ep->num;
3110+ }
3111+ else {
3112+ addr = &dev_if->out_ep_regs[ep->num]->doepctl;
3113+ daintmsk.ep.out = 1<<ep->num;
3114+ }
3115+
3116+ /* If the EP is already active don't change the EP Control
3117+ * register. */
3118+ depctl.d32 = dwc_read_reg32(addr);
3119+ if (!depctl.b.usbactep) {
3120+ depctl.b.mps = ep->maxpacket;
3121+ depctl.b.eptype = ep->type;
3122+ depctl.b.txfnum = ep->tx_fifo_num;
3123+
3124+ if (ep->type == DWC_OTG_EP_TYPE_ISOC) {
3125+ depctl.b.setd0pid = 1; // ???
3126+ }
3127+ else {
3128+ depctl.b.setd0pid = 1;
3129+ }
3130+ depctl.b.usbactep = 1;
3131+
3132+ dwc_write_reg32(addr, depctl.d32);
3133+ DWC_DEBUGPL(DBG_PCDV,"DEPCTL(%.8x)=%08x\n",(u32)addr, dwc_read_reg32(addr));
3134+ }
3135+
3136+ /* Enable the Interrupt for this EP */
3137+ if(core_if->multiproc_int_enable) {
3138+ if (ep->is_in == 1) {
3139+ diepmsk_data_t diepmsk = { .d32 = 0};
3140+ diepmsk.b.xfercompl = 1;
3141+ diepmsk.b.timeout = 1;
3142+ diepmsk.b.epdisabled = 1;
3143+ diepmsk.b.ahberr = 1;
3144+ diepmsk.b.intknepmis = 1;
3145+ diepmsk.b.txfifoundrn = 1; //?????
3146+
3147+
3148+ if(core_if->dma_desc_enable) {
3149+ diepmsk.b.bna = 1;
3150+ }
3151+/*
3152+ if(core_if->dma_enable) {
3153+ doepmsk.b.nak = 1;
3154+ }
3155+*/
3156+ dwc_write_reg32(&dev_if->dev_global_regs->diepeachintmsk[ep->num], diepmsk.d32);
3157+
3158+ } else {
3159+ doepmsk_data_t doepmsk = { .d32 = 0};
3160+ doepmsk.b.xfercompl = 1;
3161+ doepmsk.b.ahberr = 1;
3162+ doepmsk.b.epdisabled = 1;
3163+
3164+
3165+ if(core_if->dma_desc_enable) {
3166+ doepmsk.b.bna = 1;
3167+ }
3168+/*
3169+ doepmsk.b.babble = 1;
3170+ doepmsk.b.nyet = 1;
3171+ doepmsk.b.nak = 1;
3172+*/
3173+ dwc_write_reg32(&dev_if->dev_global_regs->doepeachintmsk[ep->num], doepmsk.d32);
3174+ }
3175+ dwc_modify_reg32(&dev_if->dev_global_regs->deachintmsk,
3176+ 0, daintmsk.d32);
3177+ } else {
3178+ dwc_modify_reg32(&dev_if->dev_global_regs->daintmsk,
3179+ 0, daintmsk.d32);
3180+ }
3181+
3182+ DWC_DEBUGPL(DBG_PCDV,"DAINTMSK=%0x\n",
3183+ dwc_read_reg32(&dev_if->dev_global_regs->daintmsk));
3184+
3185+ ep->stall_clear_flag = 0;
3186+ return;
3187+}
3188+
3189+/**
3190+ * This function deactivates an EP. This is done by clearing the USB Active
3191+ * EP bit in the Device EP control register. Note: This function is not used
3192+ * for EP0. EP0 cannot be deactivated.
3193+ *
3194+ * @param core_if Programming view of DWC_otg controller.
3195+ * @param ep The EP to deactivate.
3196+ */
3197+void dwc_otg_ep_deactivate(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
3198+{
3199+ depctl_data_t depctl = { .d32 = 0 };
3200+ volatile uint32_t *addr;
3201+ daint_data_t daintmsk = { .d32 = 0};
3202+
3203+ /* Read DEPCTLn register */
3204+ if (ep->is_in == 1) {
3205+ addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl;
3206+ daintmsk.ep.in = 1<<ep->num;
3207+ }
3208+ else {
3209+ addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl;
3210+ daintmsk.ep.out = 1<<ep->num;
3211+ }
3212+
3213+ //disabled ep only when ep is enabled
3214+ //or got halt in the loop in test in cv9
3215+ depctl.d32=dwc_read_reg32(addr);
3216+ if(depctl.b.epena){
3217+ if (ep->is_in == 1) {
3218+ diepint_data_t diepint;
3219+ dwc_otg_dev_in_ep_regs_t *in_reg=core_if->dev_if->in_ep_regs[ep->num];
3220+
3221+ //Set ep nak
3222+ depctl.d32=dwc_read_reg32(&in_reg->diepctl);
3223+ depctl.b.snak=1;
3224+ dwc_write_reg32(&in_reg->diepctl,depctl.d32);
3225+
3226+ //wait for diepint.b.inepnakeff
3227+ diepint.d32=dwc_read_reg32(&in_reg->diepint);
3228+ while(!diepint.b.inepnakeff){
3229+ udelay(1);
3230+ diepint.d32=dwc_read_reg32(&in_reg->diepint);
3231+ }
3232+ diepint.d32=0;
3233+ diepint.b.inepnakeff=1;
3234+ dwc_write_reg32(&in_reg->diepint,diepint.d32);
3235+
3236+ //set ep disable and snak
3237+ depctl.d32=dwc_read_reg32(&in_reg->diepctl);
3238+ depctl.b.snak=1;
3239+ depctl.b.epdis=1;
3240+ dwc_write_reg32(&in_reg->diepctl,depctl.d32);
3241+
3242+ //wait for diepint.b.epdisabled
3243+ diepint.d32=dwc_read_reg32(&in_reg->diepint);
3244+ while(!diepint.b.epdisabled){
3245+ udelay(1);
3246+ diepint.d32=dwc_read_reg32(&in_reg->diepint);
3247+ }
3248+ diepint.d32=0;
3249+ diepint.b.epdisabled=1;
3250+ dwc_write_reg32(&in_reg->diepint,diepint.d32);
3251+
3252+ //clear ep enable and disable bit
3253+ depctl.d32=dwc_read_reg32(&in_reg->diepctl);
3254+ depctl.b.epena=0;
3255+ depctl.b.epdis=0;
3256+ dwc_write_reg32(&in_reg->diepctl,depctl.d32);
3257+
3258+ }
3259+#if 0
3260+//following DWC OTG DataBook v2.72a, 6.4.2.1.3 Disabling an OUT Endpoint,
3261+//but this doesn't work, the old code do.
3262+ else {
3263+ doepint_data_t doepint;
3264+ dwc_otg_dev_out_ep_regs_t *out_reg=core_if->dev_if->out_ep_regs[ep->num];
3265+ dctl_data_t dctl;
3266+ gintsts_data_t gintsts;
3267+
3268+ //set dctl global out nak
3269+ dctl.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dctl);
3270+ dctl.b.sgoutnak=1;
3271+ dwc_write_reg32(&core_if->dev_if->dev_global_regs->dctl,dctl.d32);
3272+
3273+ //wait for gintsts.goutnakeff
3274+ gintsts.d32=dwc_read_reg32(&core_if->core_global_regs->gintsts);
3275+ while(!gintsts.b.goutnakeff){
3276+ udelay(1);
3277+ gintsts.d32=dwc_read_reg32(&core_if->core_global_regs->gintsts);
3278+ }
3279+ gintsts.d32=0;
3280+ gintsts.b.goutnakeff=1;
3281+ dwc_write_reg32 (&core_if->core_global_regs->gintsts, gintsts.d32);
3282+
3283+ //set ep disable and snak
3284+ depctl.d32=dwc_read_reg32(&out_reg->doepctl);
3285+ depctl.b.snak=1;
3286+ depctl.b.epdis=1;
3287+ dwc_write_reg32(&out_reg->doepctl,depctl.d32);
3288+
3289+ //wait for diepint.b.epdisabled
3290+ doepint.d32=dwc_read_reg32(&out_reg->doepint);
3291+ while(!doepint.b.epdisabled){
3292+ udelay(1);
3293+ doepint.d32=dwc_read_reg32(&out_reg->doepint);
3294+ }
3295+ doepint.d32=0;
3296+ doepint.b.epdisabled=1;
3297+ dwc_write_reg32(&out_reg->doepint,doepint.d32);
3298+
3299+ //clear ep enable and disable bit
3300+ depctl.d32=dwc_read_reg32(&out_reg->doepctl);
3301+ depctl.b.epena=0;
3302+ depctl.b.epdis=0;
3303+ dwc_write_reg32(&out_reg->doepctl,depctl.d32);
3304+ }
3305+#endif
3306+
3307+ depctl.d32=0;
3308+ depctl.b.usbactep = 0;
3309+
3310+ if (ep->is_in == 0) {
3311+ if(core_if->dma_enable||core_if->dma_desc_enable)
3312+ depctl.b.epdis = 1;
3313+ }
3314+
3315+ dwc_write_reg32(addr, depctl.d32);
3316+ }
3317+
3318+ /* Disable the Interrupt for this EP */
3319+ if(core_if->multiproc_int_enable) {
3320+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->deachintmsk,
3321+ daintmsk.d32, 0);
3322+
3323+ if (ep->is_in == 1) {
3324+ dwc_write_reg32(&core_if->dev_if->dev_global_regs->diepeachintmsk[ep->num], 0);
3325+ } else {
3326+ dwc_write_reg32(&core_if->dev_if->dev_global_regs->doepeachintmsk[ep->num], 0);
3327+ }
3328+ } else {
3329+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->daintmsk,
3330+ daintmsk.d32, 0);
3331+ }
3332+
3333+ if (ep->is_in == 1) {
3334+ DWC_DEBUGPL(DBG_PCD, "DIEPCTL(%.8x)=%08x DIEPTSIZ=%08x, DIEPINT=%.8x, DIEPDMA=%.8x, DTXFSTS=%.8x\n",
3335+ (u32)&core_if->dev_if->in_ep_regs[ep->num]->diepctl,
3336+ dwc_read_reg32(&core_if->dev_if->in_ep_regs[ep->num]->diepctl),
3337+ dwc_read_reg32(&core_if->dev_if->in_ep_regs[ep->num]->dieptsiz),
3338+ dwc_read_reg32(&core_if->dev_if->in_ep_regs[ep->num]->diepint),
3339+ dwc_read_reg32(&core_if->dev_if->in_ep_regs[ep->num]->diepdma),
3340+ dwc_read_reg32(&core_if->dev_if->in_ep_regs[ep->num]->dtxfsts));
3341+ DWC_DEBUGPL(DBG_PCD, "DAINTMSK=%08x GINTMSK=%08x\n",
3342+ dwc_read_reg32(&core_if->dev_if->dev_global_regs->daintmsk),
3343+ dwc_read_reg32(&core_if->core_global_regs->gintmsk));
3344+ }
3345+ else {
3346+ DWC_DEBUGPL(DBG_PCD, "DOEPCTL(%.8x)=%08x DOEPTSIZ=%08x, DOEPINT=%.8x, DOEPDMA=%.8x\n",
3347+ (u32)&core_if->dev_if->out_ep_regs[ep->num]->doepctl,
3348+ dwc_read_reg32(&core_if->dev_if->out_ep_regs[ep->num]->doepctl),
3349+ dwc_read_reg32(&core_if->dev_if->out_ep_regs[ep->num]->doeptsiz),
3350+ dwc_read_reg32(&core_if->dev_if->out_ep_regs[ep->num]->doepint),
3351+ dwc_read_reg32(&core_if->dev_if->out_ep_regs[ep->num]->doepdma));
3352+
3353+ DWC_DEBUGPL(DBG_PCD, "DAINTMSK=%08x GINTMSK=%08x\n",
3354+ dwc_read_reg32(&core_if->dev_if->dev_global_regs->daintmsk),
3355+ dwc_read_reg32(&core_if->core_global_regs->gintmsk));
3356+ }
3357+
3358+}
3359+
3360+/**
3361+ * This function does the setup for a data transfer for an EP and
3362+ * starts the transfer. For an IN transfer, the packets will be
3363+ * loaded into the appropriate Tx FIFO in the ISR. For OUT transfers,
3364+ * the packets are unloaded from the Rx FIFO in the ISR. the ISR.
3365+ *
3366+ * @param core_if Programming view of DWC_otg controller.
3367+ * @param ep The EP to start the transfer on.
3368+ */
3369+static void init_dma_desc_chain(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
3370+{
3371+ dwc_otg_dma_desc_t* dma_desc;
3372+ uint32_t offset;
3373+ uint32_t xfer_est;
3374+ int i;
3375+
3376+ ep->desc_cnt = ( ep->total_len / ep->maxxfer) +
3377+ ((ep->total_len % ep->maxxfer) ? 1 : 0);
3378+ if(!ep->desc_cnt)
3379+ ep->desc_cnt = 1;
3380+
3381+ dma_desc = ep->desc_addr;
3382+ xfer_est = ep->total_len;
3383+ offset = 0;
3384+ for( i = 0; i < ep->desc_cnt; ++i) {
3385+ /** DMA Descriptor Setup */
3386+ if(xfer_est > ep->maxxfer) {
3387+ dma_desc->status.b.bs = BS_HOST_BUSY;
3388+ dma_desc->status.b.l = 0;
3389+ dma_desc->status.b.ioc = 0;
3390+ dma_desc->status.b.sp = 0;
3391+ dma_desc->status.b.bytes = ep->maxxfer;
3392+ dma_desc->buf = ep->dma_addr + offset;
3393+ dma_desc->status.b.bs = BS_HOST_READY;
3394+
3395+ xfer_est -= ep->maxxfer;
3396+ offset += ep->maxxfer;
3397+ } else {
3398+ dma_desc->status.b.bs = BS_HOST_BUSY;
3399+ dma_desc->status.b.l = 1;
3400+ dma_desc->status.b.ioc = 1;
3401+ if(ep->is_in) {
3402+ dma_desc->status.b.sp = (xfer_est % ep->maxpacket) ?
3403+ 1 : ((ep->sent_zlp) ? 1 : 0);
3404+ dma_desc->status.b.bytes = xfer_est;
3405+ } else {
3406+ dma_desc->status.b.bytes = xfer_est + ((4 - (xfer_est & 0x3)) & 0x3) ;
3407+ }
3408+
3409+ dma_desc->buf = ep->dma_addr + offset;
3410+ dma_desc->status.b.bs = BS_HOST_READY;
3411+ }
3412+ dma_desc ++;
3413+ }
3414+}
3415+
3416+/**
3417+ * This function does the setup for a data transfer for an EP and
3418+ * starts the transfer. For an IN transfer, the packets will be
3419+ * loaded into the appropriate Tx FIFO in the ISR. For OUT transfers,
3420+ * the packets are unloaded from the Rx FIFO in the ISR. the ISR.
3421+ *
3422+ * @param core_if Programming view of DWC_otg controller.
3423+ * @param ep The EP to start the transfer on.
3424+ */
3425+
3426+void dwc_otg_ep_start_transfer(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
3427+{
3428+ depctl_data_t depctl;
3429+ deptsiz_data_t deptsiz;
3430+ gintmsk_data_t intr_mask = { .d32 = 0};
3431+
3432+ DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s()\n", __func__);
3433+
3434+ DWC_DEBUGPL(DBG_PCD, "ep%d-%s xfer_len=%d xfer_cnt=%d "
3435+ "xfer_buff=%p start_xfer_buff=%p\n",
3436+ ep->num, (ep->is_in?"IN":"OUT"), ep->xfer_len,
3437+ ep->xfer_count, ep->xfer_buff, ep->start_xfer_buff);
3438+
3439+ /* IN endpoint */
3440+ if (ep->is_in == 1) {
3441+ dwc_otg_dev_in_ep_regs_t *in_regs =
3442+ core_if->dev_if->in_ep_regs[ep->num];
3443+
3444+ gnptxsts_data_t gtxstatus;
3445+
3446+ gtxstatus.d32 =
3447+ dwc_read_reg32(&core_if->core_global_regs->gnptxsts);
3448+
3449+ if(core_if->en_multiple_tx_fifo == 0 && gtxstatus.b.nptxqspcavail == 0) {
3450+#ifdef DEBUG
3451+ DWC_PRINT("TX Queue Full (0x%0x)\n", gtxstatus.d32);
3452+#endif
3453+ return;
3454+ }
3455+
3456+ depctl.d32 = dwc_read_reg32(&(in_regs->diepctl));
3457+ deptsiz.d32 = dwc_read_reg32(&(in_regs->dieptsiz));
3458+
3459+ ep->xfer_len += (ep->maxxfer < (ep->total_len - ep->xfer_len)) ?
3460+ ep->maxxfer : (ep->total_len - ep->xfer_len);
3461+
3462+ /* Zero Length Packet? */
3463+ if ((ep->xfer_len - ep->xfer_count) == 0) {
3464+ deptsiz.b.xfersize = 0;
3465+ deptsiz.b.pktcnt = 1;
3466+ }
3467+ else {
3468+ /* Program the transfer size and packet count
3469+ * as follows: xfersize = N * maxpacket +
3470+ * short_packet pktcnt = N + (short_packet
3471+ * exist ? 1 : 0)
3472+ */
3473+ deptsiz.b.xfersize = ep->xfer_len - ep->xfer_count;
3474+ deptsiz.b.pktcnt =
3475+ (ep->xfer_len - ep->xfer_count - 1 + ep->maxpacket) /
3476+ ep->maxpacket;
3477+ }
3478+
3479+
3480+ /* Write the DMA register */
3481+ if (core_if->dma_enable) {
3482+ if (/*(core_if->dma_enable)&&*/(ep->dma_addr==DMA_ADDR_INVALID)) {
3483+ ep->dma_addr=dma_map_single(NULL,(void *)(ep->xfer_buff),(ep->xfer_len),DMA_TO_DEVICE);
3484+ }
3485+ DWC_DEBUGPL(DBG_PCDV, "ep%d dma_addr=%.8x\n", ep->num, ep->dma_addr);
3486+
3487+ if (core_if->dma_desc_enable == 0) {
3488+ dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
3489+
3490+ VERIFY_PCD_DMA_ADDR(ep->dma_addr);
3491+ dwc_write_reg32 (&(in_regs->diepdma),
3492+ (uint32_t)ep->dma_addr);
3493+ }
3494+ else {
3495+ init_dma_desc_chain(core_if, ep);
3496+ /** DIEPDMAn Register write */
3497+
3498+ VERIFY_PCD_DMA_ADDR(ep->dma_desc_addr);
3499+ dwc_write_reg32(&in_regs->diepdma, ep->dma_desc_addr);
3500+ }
3501+ }
3502+ else
3503+ {
3504+ dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
3505+ if(ep->type != DWC_OTG_EP_TYPE_ISOC) {
3506+ /**
3507+ * Enable the Non-Periodic Tx FIFO empty interrupt,
3508+ * or the Tx FIFO epmty interrupt in dedicated Tx FIFO mode,
3509+ * the data will be written into the fifo by the ISR.
3510+ */
3511+ if(core_if->en_multiple_tx_fifo == 0) {
3512+ intr_mask.b.nptxfempty = 1;
3513+ dwc_modify_reg32(&core_if->core_global_regs->gintmsk,
3514+ intr_mask.d32, intr_mask.d32);
3515+ }
3516+ else {
3517+ /* Enable the Tx FIFO Empty Interrupt for this EP */
3518+ if(ep->xfer_len > 0) {
3519+ uint32_t fifoemptymsk = 0;
3520+ fifoemptymsk = 1 << ep->num;
3521+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
3522+ 0, fifoemptymsk);
3523+
3524+ }
3525+ }
3526+ }
3527+ }
3528+
3529+ /* EP enable, IN data in FIFO */
3530+ depctl.b.cnak = 1;
3531+ depctl.b.epena = 1;
3532+ dwc_write_reg32(&in_regs->diepctl, depctl.d32);
3533+
3534+ depctl.d32 = dwc_read_reg32 (&core_if->dev_if->in_ep_regs[0]->diepctl);
3535+ depctl.b.nextep = ep->num;
3536+ dwc_write_reg32 (&core_if->dev_if->in_ep_regs[0]->diepctl, depctl.d32);
3537+
3538+ DWC_DEBUGPL(DBG_PCD, "DIEPCTL(%.8x)=%08x DIEPTSIZ=%08x, DIEPINT=%.8x, DIEPDMA=%.8x, DTXFSTS=%.8x\n",
3539+ (u32)&in_regs->diepctl,
3540+ dwc_read_reg32(&in_regs->diepctl),
3541+ dwc_read_reg32(&in_regs->dieptsiz),
3542+ dwc_read_reg32(&in_regs->diepint),
3543+ dwc_read_reg32(&in_regs->diepdma),
3544+ dwc_read_reg32(&in_regs->dtxfsts));
3545+ DWC_DEBUGPL(DBG_PCD, "DAINTMSK=%08x GINTMSK=%08x\n",
3546+ dwc_read_reg32(&core_if->dev_if->dev_global_regs->daintmsk),
3547+ dwc_read_reg32(&core_if->core_global_regs->gintmsk));
3548+
3549+ }
3550+ else {
3551+ /* OUT endpoint */
3552+ dwc_otg_dev_out_ep_regs_t *out_regs =
3553+ core_if->dev_if->out_ep_regs[ep->num];
3554+
3555+ depctl.d32 = dwc_read_reg32(&(out_regs->doepctl));
3556+ deptsiz.d32 = dwc_read_reg32(&(out_regs->doeptsiz));
3557+
3558+ ep->xfer_len += (ep->maxxfer < (ep->total_len - ep->xfer_len)) ?
3559+ ep->maxxfer : (ep->total_len - ep->xfer_len);
3560+
3561+ /* Program the transfer size and packet count as follows:
3562+ *
3563+ * pktcnt = N
3564+ * xfersize = N * maxpacket
3565+ */
3566+ if ((ep->xfer_len - ep->xfer_count) == 0) {
3567+ /* Zero Length Packet */
3568+ deptsiz.b.xfersize = ep->maxpacket;
3569+ deptsiz.b.pktcnt = 1;
3570+ }
3571+ else {
3572+ deptsiz.b.pktcnt =
3573+ (ep->xfer_len - ep->xfer_count + (ep->maxpacket - 1)) /
3574+ ep->maxpacket;
3575+ ep->xfer_len = deptsiz.b.pktcnt * ep->maxpacket + ep->xfer_count;
3576+ deptsiz.b.xfersize = ep->xfer_len - ep->xfer_count;
3577+ }
3578+
3579+ DWC_DEBUGPL(DBG_PCDV, "ep%d xfersize=%d pktcnt=%d\n",
3580+ ep->num,
3581+ deptsiz.b.xfersize, deptsiz.b.pktcnt);
3582+
3583+ if (core_if->dma_enable) {
3584+ if (/*(core_if->dma_enable)&&*/(ep->dma_addr==DMA_ADDR_INVALID)) {
3585+ ep->dma_addr=dma_map_single(NULL,(void *)(ep->xfer_buff),(ep->xfer_len),DMA_TO_DEVICE);
3586+ }
3587+ DWC_DEBUGPL(DBG_PCDV, "ep%d dma_addr=%.8x\n",
3588+ ep->num,
3589+ ep->dma_addr);
3590+ if (!core_if->dma_desc_enable) {
3591+ dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32);
3592+
3593+ VERIFY_PCD_DMA_ADDR(ep->dma_addr);
3594+ dwc_write_reg32 (&(out_regs->doepdma),
3595+ (uint32_t)ep->dma_addr);
3596+ }
3597+ else {
3598+ init_dma_desc_chain(core_if, ep);
3599+
3600+ /** DOEPDMAn Register write */
3601+
3602+ VERIFY_PCD_DMA_ADDR(ep->dma_desc_addr);
3603+ dwc_write_reg32(&out_regs->doepdma, ep->dma_desc_addr);
3604+ }
3605+ }
3606+ else {
3607+ dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32);
3608+ }
3609+
3610+ /* EP enable */
3611+ depctl.b.cnak = 1;
3612+ depctl.b.epena = 1;
3613+
3614+ dwc_write_reg32(&out_regs->doepctl, depctl.d32);
3615+
3616+ DWC_DEBUGPL(DBG_PCD, "DOEPCTL(%.8x)=%08x DOEPTSIZ=%08x, DOEPINT=%.8x, DOEPDMA=%.8x\n",
3617+ (u32)&out_regs->doepctl,
3618+ dwc_read_reg32(&out_regs->doepctl),
3619+ dwc_read_reg32(&out_regs->doeptsiz),
3620+ dwc_read_reg32(&out_regs->doepint),
3621+ dwc_read_reg32(&out_regs->doepdma));
3622+
3623+ DWC_DEBUGPL(DBG_PCD, "DAINTMSK=%08x GINTMSK=%08x\n",
3624+ dwc_read_reg32(&core_if->dev_if->dev_global_regs->daintmsk),
3625+ dwc_read_reg32(&core_if->core_global_regs->gintmsk));
3626+ }
3627+}
3628+
3629+/**
3630+ * This function setup a zero length transfer in Buffer DMA and
3631+ * Slave modes for usb requests with zero field set
3632+ *
3633+ * @param core_if Programming view of DWC_otg controller.
3634+ * @param ep The EP to start the transfer on.
3635+ *
3636+ */
3637+void dwc_otg_ep_start_zl_transfer(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
3638+{
3639+
3640+ depctl_data_t depctl;
3641+ deptsiz_data_t deptsiz;
3642+ gintmsk_data_t intr_mask = { .d32 = 0};
3643+
3644+ DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s()\n", __func__);
3645+
3646+ /* IN endpoint */
3647+ if (ep->is_in == 1) {
3648+ dwc_otg_dev_in_ep_regs_t *in_regs =
3649+ core_if->dev_if->in_ep_regs[ep->num];
3650+
3651+ depctl.d32 = dwc_read_reg32(&(in_regs->diepctl));
3652+ deptsiz.d32 = dwc_read_reg32(&(in_regs->dieptsiz));
3653+
3654+ deptsiz.b.xfersize = 0;
3655+ deptsiz.b.pktcnt = 1;
3656+
3657+
3658+ /* Write the DMA register */
3659+ if (core_if->dma_enable) {
3660+ if (/*(core_if->dma_enable)&&*/(ep->dma_addr==DMA_ADDR_INVALID)) {
3661+ ep->dma_addr=dma_map_single(NULL,(void *)(ep->xfer_buff),(ep->xfer_len),DMA_TO_DEVICE);
3662+ }
3663+ if (core_if->dma_desc_enable == 0) {
3664+ dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
3665+
3666+ VERIFY_PCD_DMA_ADDR(ep->dma_addr);
3667+ dwc_write_reg32 (&(in_regs->diepdma),
3668+ (uint32_t)ep->dma_addr);
3669+ }
3670+ }
3671+ else {
3672+ dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
3673+ /**
3674+ * Enable the Non-Periodic Tx FIFO empty interrupt,
3675+ * or the Tx FIFO epmty interrupt in dedicated Tx FIFO mode,
3676+ * the data will be written into the fifo by the ISR.
3677+ */
3678+ if(core_if->en_multiple_tx_fifo == 0) {
3679+ intr_mask.b.nptxfempty = 1;
3680+ dwc_modify_reg32(&core_if->core_global_regs->gintmsk,
3681+ intr_mask.d32, intr_mask.d32);
3682+ }
3683+ else {
3684+ /* Enable the Tx FIFO Empty Interrupt for this EP */
3685+ if(ep->xfer_len > 0) {
3686+ uint32_t fifoemptymsk = 0;
3687+ fifoemptymsk = 1 << ep->num;
3688+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
3689+ 0, fifoemptymsk);
3690+ }
3691+ }
3692+ }
3693+
3694+ /* EP enable, IN data in FIFO */
3695+ depctl.b.cnak = 1;
3696+ depctl.b.epena = 1;
3697+ dwc_write_reg32(&in_regs->diepctl, depctl.d32);
3698+
3699+ depctl.d32 = dwc_read_reg32 (&core_if->dev_if->in_ep_regs[0]->diepctl);
3700+ depctl.b.nextep = ep->num;
3701+ dwc_write_reg32 (&core_if->dev_if->in_ep_regs[0]->diepctl, depctl.d32);
3702+
3703+ }
3704+ else {
3705+ /* OUT endpoint */
3706+ dwc_otg_dev_out_ep_regs_t *out_regs =
3707+ core_if->dev_if->out_ep_regs[ep->num];
3708+
3709+ depctl.d32 = dwc_read_reg32(&(out_regs->doepctl));
3710+ deptsiz.d32 = dwc_read_reg32(&(out_regs->doeptsiz));
3711+
3712+ /* Zero Length Packet */
3713+ deptsiz.b.xfersize = ep->maxpacket;
3714+ deptsiz.b.pktcnt = 1;
3715+
3716+ if (core_if->dma_enable) {
3717+ if (/*(core_if->dma_enable)&&*/(ep->dma_addr==DMA_ADDR_INVALID)) {
3718+ ep->dma_addr=dma_map_single(NULL,(void *)(ep->xfer_buff),(ep->xfer_len),DMA_TO_DEVICE);
3719+ }
3720+ if (!core_if->dma_desc_enable) {
3721+ dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32);
3722+
3723+
3724+ VERIFY_PCD_DMA_ADDR(ep->dma_addr);
3725+ dwc_write_reg32 (&(out_regs->doepdma),
3726+ (uint32_t)ep->dma_addr);
3727+ }
3728+ }
3729+ else {
3730+ dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32);
3731+ }
3732+
3733+ /* EP enable */
3734+ depctl.b.cnak = 1;
3735+ depctl.b.epena = 1;
3736+
3737+ dwc_write_reg32(&out_regs->doepctl, depctl.d32);
3738+
3739+ }
3740+}
3741+
3742+/**
3743+ * This function does the setup for a data transfer for EP0 and starts
3744+ * the transfer. For an IN transfer, the packets will be loaded into
3745+ * the appropriate Tx FIFO in the ISR. For OUT transfers, the packets are
3746+ * unloaded from the Rx FIFO in the ISR.
3747+ *
3748+ * @param core_if Programming view of DWC_otg controller.
3749+ * @param ep The EP0 data.
3750+ */
3751+void dwc_otg_ep0_start_transfer(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
3752+{
3753+ depctl_data_t depctl;
3754+ deptsiz0_data_t deptsiz;
3755+ gintmsk_data_t intr_mask = { .d32 = 0};
3756+ dwc_otg_dma_desc_t* dma_desc;
3757+
3758+ DWC_DEBUGPL(DBG_PCD, "ep%d-%s xfer_len=%d xfer_cnt=%d "
3759+ "xfer_buff=%p start_xfer_buff=%p, dma_addr=%.8x\n",
3760+ ep->num, (ep->is_in?"IN":"OUT"), ep->xfer_len,
3761+ ep->xfer_count, ep->xfer_buff, ep->start_xfer_buff,ep->dma_addr);
3762+
3763+ ep->total_len = ep->xfer_len;
3764+
3765+ /* IN endpoint */
3766+ if (ep->is_in == 1) {
3767+ dwc_otg_dev_in_ep_regs_t *in_regs =
3768+ core_if->dev_if->in_ep_regs[0];
3769+
3770+ gnptxsts_data_t gtxstatus;
3771+
3772+ gtxstatus.d32 =
3773+ dwc_read_reg32(&core_if->core_global_regs->gnptxsts);
3774+
3775+ if(core_if->en_multiple_tx_fifo == 0 && gtxstatus.b.nptxqspcavail == 0) {
3776+#ifdef DEBUG
3777+ deptsiz.d32 = dwc_read_reg32(&in_regs->dieptsiz);
3778+ DWC_DEBUGPL(DBG_PCD,"DIEPCTL0=%0x\n",
3779+ dwc_read_reg32(&in_regs->diepctl));
3780+ DWC_DEBUGPL(DBG_PCD, "DIEPTSIZ0=%0x (sz=%d, pcnt=%d)\n",
3781+ deptsiz.d32,
3782+ deptsiz.b.xfersize, deptsiz.b.pktcnt);
3783+ DWC_PRINT("TX Queue or FIFO Full (0x%0x)\n",
3784+ gtxstatus.d32);
3785+#endif
3786+ return;
3787+ }
3788+
3789+
3790+ depctl.d32 = dwc_read_reg32(&in_regs->diepctl);
3791+ deptsiz.d32 = dwc_read_reg32(&in_regs->dieptsiz);
3792+
3793+ /* Zero Length Packet? */
3794+ if (ep->xfer_len == 0) {
3795+ deptsiz.b.xfersize = 0;
3796+ deptsiz.b.pktcnt = 1;
3797+ }
3798+ else {
3799+ /* Program the transfer size and packet count
3800+ * as follows: xfersize = N * maxpacket +
3801+ * short_packet pktcnt = N + (short_packet
3802+ * exist ? 1 : 0)
3803+ */
3804+ if (ep->xfer_len > ep->maxpacket) {
3805+ ep->xfer_len = ep->maxpacket;
3806+ deptsiz.b.xfersize = ep->maxpacket;
3807+ }
3808+ else {
3809+ deptsiz.b.xfersize = ep->xfer_len;
3810+ }
3811+ deptsiz.b.pktcnt = 1;
3812+
3813+ }
3814+ DWC_DEBUGPL(DBG_PCDV, "IN len=%d xfersize=%d pktcnt=%d [%08x]\n",
3815+ ep->xfer_len,
3816+ deptsiz.b.xfersize, deptsiz.b.pktcnt, deptsiz.d32);
3817+ /* Write the DMA register */
3818+ if (core_if->dma_enable) {
3819+ if (/*(core_if->dma_enable)&&*/(ep->dma_addr==DMA_ADDR_INVALID)) {
3820+ ep->dma_addr=dma_map_single(NULL,(void *)(ep->xfer_buff),(ep->xfer_len),DMA_TO_DEVICE);
3821+ }
3822+ if(core_if->dma_desc_enable == 0) {
3823+ dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
3824+
3825+ VERIFY_PCD_DMA_ADDR(ep->dma_addr);
3826+ dwc_write_reg32 (&(in_regs->diepdma),
3827+ (uint32_t)ep->dma_addr);
3828+ }
3829+ else {
3830+ dma_desc = core_if->dev_if->in_desc_addr;
3831+
3832+ /** DMA Descriptor Setup */
3833+ dma_desc->status.b.bs = BS_HOST_BUSY;
3834+ dma_desc->status.b.l = 1;
3835+ dma_desc->status.b.ioc = 1;
3836+ dma_desc->status.b.sp = (ep->xfer_len == ep->maxpacket) ? 0 : 1;
3837+ dma_desc->status.b.bytes = ep->xfer_len;
3838+ dma_desc->buf = ep->dma_addr;
3839+ dma_desc->status.b.bs = BS_HOST_READY;
3840+
3841+ /** DIEPDMA0 Register write */
3842+
3843+ VERIFY_PCD_DMA_ADDR(core_if->dev_if->dma_in_desc_addr);
3844+ dwc_write_reg32(&in_regs->diepdma, core_if->dev_if->dma_in_desc_addr);
3845+ }
3846+ }
3847+ else {
3848+ dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
3849+ }
3850+
3851+ /* EP enable, IN data in FIFO */
3852+ depctl.b.cnak = 1;
3853+ depctl.b.epena = 1;
3854+ dwc_write_reg32(&in_regs->diepctl, depctl.d32);
3855+
3856+ /**
3857+ * Enable the Non-Periodic Tx FIFO empty interrupt, the
3858+ * data will be written into the fifo by the ISR.
3859+ */
3860+ if (!core_if->dma_enable) {
3861+ if(core_if->en_multiple_tx_fifo == 0) {
3862+ intr_mask.b.nptxfempty = 1;
3863+ dwc_modify_reg32(&core_if->core_global_regs->gintmsk,
3864+ intr_mask.d32, intr_mask.d32);
3865+ }
3866+ else {
3867+ /* Enable the Tx FIFO Empty Interrupt for this EP */
3868+ if(ep->xfer_len > 0) {
3869+ uint32_t fifoemptymsk = 0;
3870+ fifoemptymsk |= 1 << ep->num;
3871+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
3872+ 0, fifoemptymsk);
3873+ }
3874+ }
3875+ }
3876+ }
3877+ else {
3878+ /* OUT endpoint */
3879+ dwc_otg_dev_out_ep_regs_t *out_regs =
3880+ core_if->dev_if->out_ep_regs[0];
3881+
3882+ depctl.d32 = dwc_read_reg32(&out_regs->doepctl);
3883+ deptsiz.d32 = dwc_read_reg32(&out_regs->doeptsiz);
3884+
3885+ /* Program the transfer size and packet count as follows:
3886+ * xfersize = N * (maxpacket + 4 - (maxpacket % 4))
3887+ * pktcnt = N */
3888+ /* Zero Length Packet */
3889+ deptsiz.b.xfersize = ep->maxpacket;
3890+ deptsiz.b.pktcnt = 1;
3891+
3892+ DWC_DEBUGPL(DBG_PCDV, "len=%d xfersize=%d pktcnt=%d\n",
3893+ ep->xfer_len,
3894+ deptsiz.b.xfersize, deptsiz.b.pktcnt);
3895+
3896+ if (core_if->dma_enable) {
3897+ if (/*(core_if->dma_enable)&&*/(ep->dma_addr==DMA_ADDR_INVALID)) {
3898+ ep->dma_addr=dma_map_single(NULL,(void *)(ep->xfer_buff),(ep->xfer_len),DMA_TO_DEVICE);
3899+ }
3900+ if(!core_if->dma_desc_enable) {
3901+ dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32);
3902+
3903+
3904+ VERIFY_PCD_DMA_ADDR(ep->dma_addr);
3905+ dwc_write_reg32 (&(out_regs->doepdma),
3906+ (uint32_t)ep->dma_addr);
3907+ }
3908+ else {
3909+ dma_desc = core_if->dev_if->out_desc_addr;
3910+
3911+ /** DMA Descriptor Setup */
3912+ dma_desc->status.b.bs = BS_HOST_BUSY;
3913+ dma_desc->status.b.l = 1;
3914+ dma_desc->status.b.ioc = 1;
3915+ dma_desc->status.b.bytes = ep->maxpacket;
3916+ dma_desc->buf = ep->dma_addr;
3917+ dma_desc->status.b.bs = BS_HOST_READY;
3918+
3919+ /** DOEPDMA0 Register write */
3920+ VERIFY_PCD_DMA_ADDR(core_if->dev_if->dma_out_desc_addr);
3921+ dwc_write_reg32(&out_regs->doepdma, core_if->dev_if->dma_out_desc_addr);
3922+ }
3923+ }
3924+ else {
3925+ dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32);
3926+ }
3927+
3928+ /* EP enable */
3929+ depctl.b.cnak = 1;
3930+ depctl.b.epena = 1;
3931+ dwc_write_reg32 (&(out_regs->doepctl), depctl.d32);
3932+ }
3933+}
3934+
3935+/**
3936+ * This function continues control IN transfers started by
3937+ * dwc_otg_ep0_start_transfer, when the transfer does not fit in a
3938+ * single packet. NOTE: The DIEPCTL0/DOEPCTL0 registers only have one
3939+ * bit for the packet count.
3940+ *
3941+ * @param core_if Programming view of DWC_otg controller.
3942+ * @param ep The EP0 data.
3943+ */
3944+void dwc_otg_ep0_continue_transfer(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
3945+{
3946+ depctl_data_t depctl;
3947+ deptsiz0_data_t deptsiz;
3948+ gintmsk_data_t intr_mask = { .d32 = 0};
3949+ dwc_otg_dma_desc_t* dma_desc;
3950+
3951+ if (ep->is_in == 1) {
3952+ dwc_otg_dev_in_ep_regs_t *in_regs =
3953+ core_if->dev_if->in_ep_regs[0];
3954+ gnptxsts_data_t tx_status = { .d32 = 0 };
3955+
3956+ tx_status.d32 = dwc_read_reg32(&core_if->core_global_regs->gnptxsts);
3957+ /** @todo Should there be check for room in the Tx
3958+ * Status Queue. If not remove the code above this comment. */
3959+
3960+ depctl.d32 = dwc_read_reg32(&in_regs->diepctl);
3961+ deptsiz.d32 = dwc_read_reg32(&in_regs->dieptsiz);
3962+
3963+ /* Program the transfer size and packet count
3964+ * as follows: xfersize = N * maxpacket +
3965+ * short_packet pktcnt = N + (short_packet
3966+ * exist ? 1 : 0)
3967+ */
3968+
3969+
3970+ if(core_if->dma_desc_enable == 0) {
3971+ deptsiz.b.xfersize = (ep->total_len - ep->xfer_count) > ep->maxpacket ? ep->maxpacket :
3972+ (ep->total_len - ep->xfer_count);
3973+ deptsiz.b.pktcnt = 1;
3974+ if(core_if->dma_enable == 0) {
3975+ ep->xfer_len += deptsiz.b.xfersize;
3976+ } else {
3977+ ep->xfer_len = deptsiz.b.xfersize;
3978+ }
3979+ dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
3980+ }
3981+ else {
3982+ ep->xfer_len = (ep->total_len - ep->xfer_count) > ep->maxpacket ? ep->maxpacket :
3983+ (ep->total_len - ep->xfer_count);
3984+
3985+ dma_desc = core_if->dev_if->in_desc_addr;
3986+
3987+ /** DMA Descriptor Setup */
3988+ dma_desc->status.b.bs = BS_HOST_BUSY;
3989+ dma_desc->status.b.l = 1;
3990+ dma_desc->status.b.ioc = 1;
3991+ dma_desc->status.b.sp = (ep->xfer_len == ep->maxpacket) ? 0 : 1;
3992+ dma_desc->status.b.bytes = ep->xfer_len;
3993+ dma_desc->buf = ep->dma_addr;
3994+ dma_desc->status.b.bs = BS_HOST_READY;
3995+
3996+
3997+ /** DIEPDMA0 Register write */
3998+ VERIFY_PCD_DMA_ADDR(core_if->dev_if->dma_in_desc_addr);
3999+ dwc_write_reg32(&in_regs->diepdma, core_if->dev_if->dma_in_desc_addr);
4000+ }
4001+
4002+
4003+ DWC_DEBUGPL(DBG_PCDV, "IN len=%d xfersize=%d pktcnt=%d [%08x]\n",
4004+ ep->xfer_len,
4005+ deptsiz.b.xfersize, deptsiz.b.pktcnt, deptsiz.d32);
4006+
4007+ /* Write the DMA register */
4008+ if (core_if->hwcfg2.b.architecture == DWC_INT_DMA_ARCH) {
4009+ if(core_if->dma_desc_enable == 0){
4010+
4011+ VERIFY_PCD_DMA_ADDR(ep->dma_addr);
4012+ dwc_write_reg32 (&(in_regs->diepdma), (uint32_t)ep->dma_addr);
4013+ }
4014+ }
4015+
4016+ /* EP enable, IN data in FIFO */
4017+ depctl.b.cnak = 1;
4018+ depctl.b.epena = 1;
4019+ dwc_write_reg32(&in_regs->diepctl, depctl.d32);
4020+
4021+ /**
4022+ * Enable the Non-Periodic Tx FIFO empty interrupt, the
4023+ * data will be written into the fifo by the ISR.
4024+ */
4025+ if (!core_if->dma_enable) {
4026+ if(core_if->en_multiple_tx_fifo == 0) {
4027+ /* First clear it from GINTSTS */
4028+ intr_mask.b.nptxfempty = 1;
4029+ dwc_modify_reg32(&core_if->core_global_regs->gintmsk,
4030+ intr_mask.d32, intr_mask.d32);
4031+
4032+ }
4033+ else {
4034+ /* Enable the Tx FIFO Empty Interrupt for this EP */
4035+ if(ep->xfer_len > 0) {
4036+ uint32_t fifoemptymsk = 0;
4037+ fifoemptymsk |= 1 << ep->num;
4038+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
4039+ 0, fifoemptymsk);
4040+ }
4041+ }
4042+ }
4043+ }
4044+ else {
4045+ dwc_otg_dev_out_ep_regs_t *out_regs =
4046+ core_if->dev_if->out_ep_regs[0];
4047+
4048+
4049+ depctl.d32 = dwc_read_reg32(&out_regs->doepctl);
4050+ deptsiz.d32 = dwc_read_reg32(&out_regs->doeptsiz);
4051+
4052+ /* Program the transfer size and packet count
4053+ * as follows: xfersize = N * maxpacket +
4054+ * short_packet pktcnt = N + (short_packet
4055+ * exist ? 1 : 0)
4056+ */
4057+ deptsiz.b.xfersize = ep->maxpacket;
4058+ deptsiz.b.pktcnt = 1;
4059+
4060+
4061+ if(core_if->dma_desc_enable == 0) {
4062+ dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32);
4063+ }
4064+ else {
4065+ dma_desc = core_if->dev_if->out_desc_addr;
4066+
4067+ /** DMA Descriptor Setup */
4068+ dma_desc->status.b.bs = BS_HOST_BUSY;
4069+ dma_desc->status.b.l = 1;
4070+ dma_desc->status.b.ioc = 1;
4071+ dma_desc->status.b.bytes = ep->maxpacket;
4072+ dma_desc->buf = ep->dma_addr;
4073+ dma_desc->status.b.bs = BS_HOST_READY;
4074+
4075+ /** DOEPDMA0 Register write */
4076+ VERIFY_PCD_DMA_ADDR(core_if->dev_if->dma_out_desc_addr);
4077+ dwc_write_reg32(&out_regs->doepdma, core_if->dev_if->dma_out_desc_addr);
4078+ }
4079+
4080+
4081+ DWC_DEBUGPL(DBG_PCDV, "IN len=%d xfersize=%d pktcnt=%d [%08x]\n",
4082+ ep->xfer_len,
4083+ deptsiz.b.xfersize, deptsiz.b.pktcnt, deptsiz.d32);
4084+
4085+ /* Write the DMA register */
4086+ if (core_if->hwcfg2.b.architecture == DWC_INT_DMA_ARCH) {
4087+ if(core_if->dma_desc_enable == 0){
4088+
4089+ VERIFY_PCD_DMA_ADDR(ep->dma_addr);
4090+ dwc_write_reg32 (&(out_regs->doepdma), (uint32_t)ep->dma_addr);
4091+ }
4092+ }
4093+
4094+ /* EP enable, IN data in FIFO */
4095+ depctl.b.cnak = 1;
4096+ depctl.b.epena = 1;
4097+ dwc_write_reg32(&out_regs->doepctl, depctl.d32);
4098+
4099+ }
4100+}
4101+
4102+#ifdef DEBUG
4103+void dump_msg(const u8 *buf, unsigned int length)
4104+{
4105+ unsigned int start, num, i;
4106+ char line[52], *p;
4107+
4108+ if (length >= 512)
4109+ return;
4110+ start = 0;
4111+ while (length > 0) {
4112+ num = min(length, 16u);
4113+ p = line;
4114+ for (i = 0; i < num; ++i)
4115+ {
4116+ if (i == 8)
4117+ *p++ = ' ';
4118+ sprintf(p, " %02x", buf[i]);
4119+ p += 3;
4120+ }
4121+ *p = 0;
4122+ DWC_PRINT("%6x: %s\n", start, line);
4123+ buf += num;
4124+ start += num;
4125+ length -= num;
4126+ }
4127+}
4128+#else
4129+static inline void dump_msg(const u8 *buf, unsigned int length)
4130+{
4131+}
4132+#endif
4133+
4134+/**
4135+ * This function writes a packet into the Tx FIFO associated with the
4136+ * EP. For non-periodic EPs the non-periodic Tx FIFO is written. For
4137+ * periodic EPs the periodic Tx FIFO associated with the EP is written
4138+ * with all packets for the next micro-frame.
4139+ *
4140+ * @param core_if Programming view of DWC_otg controller.
4141+ * @param ep The EP to write packet for.
4142+ * @param dma Indicates if DMA is being used.
4143+ */
4144+void dwc_otg_ep_write_packet(dwc_otg_core_if_t *core_if, dwc_ep_t *ep, int dma)
4145+{
4146+ /**
4147+ * The buffer is padded to DWORD on a per packet basis in
4148+ * slave/dma mode if the MPS is not DWORD aligned. The last
4149+ * packet, if short, is also padded to a multiple of DWORD.
4150+ *
4151+ * ep->xfer_buff always starts DWORD aligned in memory and is a
4152+ * multiple of DWORD in length
4153+ *
4154+ * ep->xfer_len can be any number of bytes
4155+ *
4156+ * ep->xfer_count is a multiple of ep->maxpacket until the last
4157+ * packet
4158+ *
4159+ * FIFO access is DWORD */
4160+
4161+ uint32_t i;
4162+ uint32_t byte_count;
4163+ uint32_t dword_count;
4164+ uint32_t *fifo;
4165+ uint32_t *data_buff = (uint32_t *)ep->xfer_buff;
4166+
4167+ DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s(%p,%p)\n", __func__, core_if, ep);
4168+ if (ep->xfer_count >= ep->xfer_len) {
4169+ DWC_WARN("%s() No data for EP%d!!!\n", __func__, ep->num);
4170+ return;
4171+ }
4172+
4173+ /* Find the byte length of the packet either short packet or MPS */
4174+ if ((ep->xfer_len - ep->xfer_count) < ep->maxpacket) {
4175+ byte_count = ep->xfer_len - ep->xfer_count;
4176+ }
4177+ else {
4178+ byte_count = ep->maxpacket;
4179+ }
4180+
4181+ /* Find the DWORD length, padded by extra bytes as neccessary if MPS
4182+ * is not a multiple of DWORD */
4183+ dword_count = (byte_count + 3) / 4;
4184+
4185+#ifdef VERBOSE
4186+ dump_msg(ep->xfer_buff, byte_count);
4187+#endif
4188+
4189+ /**@todo NGS Where are the Periodic Tx FIFO addresses
4190+ * intialized? What should this be? */
4191+
4192+ fifo = core_if->data_fifo[ep->num];
4193+
4194+
4195+ DWC_DEBUGPL((DBG_PCDV|DBG_CILV), "fifo=%p buff=%p *p=%08x bc=%d\n", fifo, data_buff, *data_buff, byte_count);
4196+
4197+ if (!dma) {
4198+ for (i=0; i<dword_count; i++, data_buff++) {
4199+ dwc_write_reg32(fifo, *data_buff);
4200+ }
4201+ }
4202+
4203+ ep->xfer_count += byte_count;
4204+ ep->xfer_buff += byte_count;
4205+ ep->dma_addr += byte_count;
4206+}
4207+
4208+/**
4209+ * Set the EP STALL.
4210+ *
4211+ * @param core_if Programming view of DWC_otg controller.
4212+ * @param ep The EP to set the stall on.
4213+ */
4214+void dwc_otg_ep_set_stall(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
4215+{
4216+ depctl_data_t depctl;
4217+ volatile uint32_t *depctl_addr;
4218+
4219+ DWC_DEBUGPL(DBG_PCDV, "%s ep%d-%s1\n", __func__, ep->num,
4220+ (ep->is_in?"IN":"OUT"));
4221+
4222+ DWC_PRINT("%s ep%d-%s\n", __func__, ep->num,
4223+ (ep->is_in?"in":"out"));
4224+
4225+ if (ep->is_in == 1) {
4226+ depctl_addr = &(core_if->dev_if->in_ep_regs[ep->num]->diepctl);
4227+ depctl.d32 = dwc_read_reg32(depctl_addr);
4228+
4229+ /* set the disable and stall bits */
4230+#if 0
4231+//epdis is set here but not cleared at latter dwc_otg_ep_clear_stall,
4232+//which cause the testusb item 13 failed(Host:pc, device: otg device)
4233+ if (depctl.b.epena) {
4234+ depctl.b.epdis = 1;
4235+ }
4236+#endif
4237+ depctl.b.stall = 1;
4238+ dwc_write_reg32(depctl_addr, depctl.d32);
4239+ }
4240+ else {
4241+ depctl_addr = &(core_if->dev_if->out_ep_regs[ep->num]->doepctl);
4242+ depctl.d32 = dwc_read_reg32(depctl_addr);
4243+
4244+ /* set the stall bit */
4245+ depctl.b.stall = 1;
4246+ dwc_write_reg32(depctl_addr, depctl.d32);
4247+ }
4248+
4249+ DWC_DEBUGPL(DBG_PCDV,"%s: DEPCTL(%.8x)=%0x\n",__func__,(u32)depctl_addr,dwc_read_reg32(depctl_addr));
4250+
4251+ return;
4252+}
4253+
4254+/**
4255+ * Clear the EP STALL.
4256+ *
4257+ * @param core_if Programming view of DWC_otg controller.
4258+ * @param ep The EP to clear stall from.
4259+ */
4260+void dwc_otg_ep_clear_stall(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
4261+{
4262+ depctl_data_t depctl;
4263+ volatile uint32_t *depctl_addr;
4264+
4265+ DWC_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, ep->num,
4266+ (ep->is_in?"IN":"OUT"));
4267+
4268+ if (ep->is_in == 1) {
4269+ depctl_addr = &(core_if->dev_if->in_ep_regs[ep->num]->diepctl);
4270+ }
4271+ else {
4272+ depctl_addr = &(core_if->dev_if->out_ep_regs[ep->num]->doepctl);
4273+ }
4274+
4275+ depctl.d32 = dwc_read_reg32(depctl_addr);
4276+
4277+ /* clear the stall bits */
4278+ depctl.b.stall = 0;
4279+
4280+ /*
4281+ * USB Spec 9.4.5: For endpoints using data toggle, regardless
4282+ * of whether an endpoint has the Halt feature set, a
4283+ * ClearFeature(ENDPOINT_HALT) request always results in the
4284+ * data toggle being reinitialized to DATA0.
4285+ */
4286+ if (ep->type == DWC_OTG_EP_TYPE_INTR ||
4287+ ep->type == DWC_OTG_EP_TYPE_BULK) {
4288+ depctl.b.setd0pid = 1; /* DATA0 */
4289+ }
4290+
4291+ dwc_write_reg32(depctl_addr, depctl.d32);
4292+ DWC_DEBUGPL(DBG_PCD,"DEPCTL=%0x\n",dwc_read_reg32(depctl_addr));
4293+ return;
4294+}
4295+
4296+/**
4297+ * This function reads a packet from the Rx FIFO into the destination
4298+ * buffer. To read SETUP data use dwc_otg_read_setup_packet.
4299+ *
4300+ * @param core_if Programming view of DWC_otg controller.
4301+ * @param dest Destination buffer for the packet.
4302+ * @param bytes Number of bytes to copy to the destination.
4303+ */
4304+void dwc_otg_read_packet(dwc_otg_core_if_t *core_if,
4305+ uint8_t *dest,
4306+ uint16_t bytes)
4307+{
4308+ int i;
4309+ int word_count = (bytes + 3) / 4;
4310+
4311+ volatile uint32_t *fifo = core_if->data_fifo[0];
4312+ uint32_t *data_buff = (uint32_t *)dest;
4313+
4314+ /**
4315+ * @todo Account for the case where _dest is not dword aligned. This
4316+ * requires reading data from the FIFO into a uint32_t temp buffer,
4317+ * then moving it into the data buffer.
4318+ */
4319+
4320+ DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s(%p,%p,%d)\n", __func__,
4321+ core_if, dest, bytes);
4322+
4323+ for (i=0; i<word_count; i++, data_buff++)
4324+ {
4325+ *data_buff = dwc_read_reg32(fifo);
4326+ }
4327+
4328+ return;
4329+}
4330+
4331+
4332+
4333+/**
4334+ * This functions reads the device registers and prints them
4335+ *
4336+ * @param core_if Programming view of DWC_otg controller.
4337+ */
4338+void dwc_otg_dump_dev_registers(dwc_otg_core_if_t *core_if)
4339+{
4340+ int i;
4341+ volatile uint32_t *addr;
4342+
4343+ DWC_PRINT("Device Global Registers\n");
4344+ addr=&core_if->dev_if->dev_global_regs->dcfg;
4345+ DWC_PRINT("DCFG @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4346+ addr=&core_if->dev_if->dev_global_regs->dctl;
4347+ DWC_PRINT("DCTL @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4348+ addr=&core_if->dev_if->dev_global_regs->dsts;
4349+ DWC_PRINT("DSTS @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4350+ addr=&core_if->dev_if->dev_global_regs->diepmsk;
4351+ DWC_PRINT("DIEPMSK @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4352+ addr=&core_if->dev_if->dev_global_regs->doepmsk;
4353+ DWC_PRINT("DOEPMSK @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4354+ addr=&core_if->dev_if->dev_global_regs->daint;
4355+ DWC_PRINT("DAINT @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4356+ addr=&core_if->dev_if->dev_global_regs->daintmsk;
4357+ DWC_PRINT("DAINTMSK @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4358+ addr=&core_if->dev_if->dev_global_regs->dtknqr1;
4359+ DWC_PRINT("DTKNQR1 @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4360+ if (core_if->hwcfg2.b.dev_token_q_depth > 6) {
4361+ addr=&core_if->dev_if->dev_global_regs->dtknqr2;
4362+ DWC_PRINT("DTKNQR2 @0x%08X : 0x%08X\n",
4363+ (uint32_t)addr,dwc_read_reg32(addr));
4364+ }
4365+
4366+ addr=&core_if->dev_if->dev_global_regs->dvbusdis;
4367+ DWC_PRINT("DVBUSID @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4368+
4369+ addr=&core_if->dev_if->dev_global_regs->dvbuspulse;
4370+ DWC_PRINT("DVBUSPULSE @0x%08X : 0x%08X\n",
4371+ (uint32_t)addr,dwc_read_reg32(addr));
4372+
4373+ if (core_if->hwcfg2.b.dev_token_q_depth > 14) {
4374+ addr=&core_if->dev_if->dev_global_regs->dtknqr3_dthrctl;
4375+ DWC_PRINT("DTKNQR3_DTHRCTL @0x%08X : 0x%08X\n",
4376+ (uint32_t)addr, dwc_read_reg32(addr));
4377+ }
4378+/*
4379+ if (core_if->hwcfg2.b.dev_token_q_depth > 22) {
4380+ addr=&core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk;
4381+ DWC_PRINT("DTKNQR4 @0x%08X : 0x%08X\n",
4382+ (uint32_t)addr, dwc_read_reg32(addr));
4383+ }
4384+*/
4385+ addr=&core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk;
4386+ DWC_PRINT("FIFOEMPMSK @0x%08X : 0x%08X\n", (uint32_t)addr, dwc_read_reg32(addr));
4387+
4388+ addr=&core_if->dev_if->dev_global_regs->deachint;
4389+ DWC_PRINT("DEACHINT @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4390+ addr=&core_if->dev_if->dev_global_regs->deachintmsk;
4391+ DWC_PRINT("DEACHINTMSK @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4392+
4393+ for (i=0; i<= core_if->dev_if->num_in_eps; i++) {
4394+ addr=&core_if->dev_if->dev_global_regs->diepeachintmsk[i];
4395+ DWC_PRINT("DIEPEACHINTMSK[%d] @0x%08X : 0x%08X\n", i, (uint32_t)addr, dwc_read_reg32(addr));
4396+ }
4397+
4398+
4399+ for (i=0; i<= core_if->dev_if->num_out_eps; i++) {
4400+ addr=&core_if->dev_if->dev_global_regs->doepeachintmsk[i];
4401+ DWC_PRINT("DOEPEACHINTMSK[%d] @0x%08X : 0x%08X\n", i, (uint32_t)addr, dwc_read_reg32(addr));
4402+ }
4403+
4404+ for (i=0; i<= core_if->dev_if->num_in_eps; i++) {
4405+ DWC_PRINT("Device IN EP %d Registers\n", i);
4406+ addr=&core_if->dev_if->in_ep_regs[i]->diepctl;
4407+ DWC_PRINT("DIEPCTL @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4408+ addr=&core_if->dev_if->in_ep_regs[i]->diepint;
4409+ DWC_PRINT("DIEPINT @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4410+ addr=&core_if->dev_if->in_ep_regs[i]->dieptsiz;
4411+ DWC_PRINT("DIETSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4412+ addr=&core_if->dev_if->in_ep_regs[i]->diepdma;
4413+ DWC_PRINT("DIEPDMA @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4414+ addr=&core_if->dev_if->in_ep_regs[i]->dtxfsts;
4415+ DWC_PRINT("DTXFSTS @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4416+ //reading depdmab in non desc dma mode would halt the ahb bus...
4417+ if(core_if->dma_desc_enable){
4418+ addr=&core_if->dev_if->in_ep_regs[i]->diepdmab;
4419+ DWC_PRINT("DIEPDMAB @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4420+ }
4421+ }
4422+
4423+
4424+ for (i=0; i<= core_if->dev_if->num_out_eps; i++) {
4425+ DWC_PRINT("Device OUT EP %d Registers\n", i);
4426+ addr=&core_if->dev_if->out_ep_regs[i]->doepctl;
4427+ DWC_PRINT("DOEPCTL @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4428+ addr=&core_if->dev_if->out_ep_regs[i]->doepfn;
4429+ DWC_PRINT("DOEPFN @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4430+ addr=&core_if->dev_if->out_ep_regs[i]->doepint;
4431+ DWC_PRINT("DOEPINT @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4432+ addr=&core_if->dev_if->out_ep_regs[i]->doeptsiz;
4433+ DWC_PRINT("DOETSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4434+ addr=&core_if->dev_if->out_ep_regs[i]->doepdma;
4435+ DWC_PRINT("DOEPDMA @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4436+
4437+ //reading depdmab in non desc dma mode would halt the ahb bus...
4438+ if(core_if->dma_desc_enable){
4439+ addr=&core_if->dev_if->out_ep_regs[i]->doepdmab;
4440+ DWC_PRINT("DOEPDMAB @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4441+ }
4442+
4443+ }
4444+
4445+
4446+
4447+ return;
4448+}
4449+
4450+/**
4451+ * This functions reads the SPRAM and prints its content
4452+ *
4453+ * @param core_if Programming view of DWC_otg controller.
4454+ */
4455+void dwc_otg_dump_spram(dwc_otg_core_if_t *core_if)
4456+{
4457+ volatile uint8_t *addr, *start_addr, *end_addr;
4458+
4459+ DWC_PRINT("SPRAM Data:\n");
4460+ start_addr = (void*)core_if->core_global_regs;
4461+ DWC_PRINT("Base Address: 0x%8X\n", (uint32_t)start_addr);
4462+ start_addr += 0x00028000;
4463+ end_addr=(void*)core_if->core_global_regs;
4464+ end_addr += 0x000280e0;
4465+
4466+ for(addr = start_addr; addr < end_addr; addr+=16)
4467+ {
4468+ DWC_PRINT("0x%8X:\t%2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X\n", (uint32_t)addr,
4469+ addr[0],
4470+ addr[1],
4471+ addr[2],
4472+ addr[3],
4473+ addr[4],
4474+ addr[5],
4475+ addr[6],
4476+ addr[7],
4477+ addr[8],
4478+ addr[9],
4479+ addr[10],
4480+ addr[11],
4481+ addr[12],
4482+ addr[13],
4483+ addr[14],
4484+ addr[15]
4485+ );
4486+ }
4487+
4488+ return;
4489+}
4490+/**
4491+ * This function reads the host registers and prints them
4492+ *
4493+ * @param core_if Programming view of DWC_otg controller.
4494+ */
4495+void dwc_otg_dump_host_registers(dwc_otg_core_if_t *core_if)
4496+{
4497+ int i;
4498+ volatile uint32_t *addr;
4499+
4500+ DWC_PRINT("Host Global Registers\n");
4501+ addr=&core_if->host_if->host_global_regs->hcfg;
4502+ DWC_PRINT("HCFG @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4503+ addr=&core_if->host_if->host_global_regs->hfir;
4504+ DWC_PRINT("HFIR @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4505+ addr=&core_if->host_if->host_global_regs->hfnum;
4506+ DWC_PRINT("HFNUM @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4507+ addr=&core_if->host_if->host_global_regs->hptxsts;
4508+ DWC_PRINT("HPTXSTS @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4509+ addr=&core_if->host_if->host_global_regs->haint;
4510+ DWC_PRINT("HAINT @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4511+ addr=&core_if->host_if->host_global_regs->haintmsk;
4512+ DWC_PRINT("HAINTMSK @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4513+ addr=core_if->host_if->hprt0;
4514+ DWC_PRINT("HPRT0 @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4515+
4516+ for (i=0; i<core_if->core_params->host_channels; i++)
4517+ {
4518+ DWC_PRINT("Host Channel %d Specific Registers\n", i);
4519+ addr=&core_if->host_if->hc_regs[i]->hcchar;
4520+ DWC_PRINT("HCCHAR @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4521+ addr=&core_if->host_if->hc_regs[i]->hcsplt;
4522+ DWC_PRINT("HCSPLT @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4523+ addr=&core_if->host_if->hc_regs[i]->hcint;
4524+ DWC_PRINT("HCINT @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4525+ addr=&core_if->host_if->hc_regs[i]->hcintmsk;
4526+ DWC_PRINT("HCINTMSK @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4527+ addr=&core_if->host_if->hc_regs[i]->hctsiz;
4528+ DWC_PRINT("HCTSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4529+ addr=&core_if->host_if->hc_regs[i]->hcdma;
4530+ DWC_PRINT("HCDMA @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4531+ }
4532+ return;
4533+}
4534+
4535+/**
4536+ * This function reads the core global registers and prints them
4537+ *
4538+ * @param core_if Programming view of DWC_otg controller.
4539+ */
4540+void dwc_otg_dump_global_registers(dwc_otg_core_if_t *core_if)
4541+{
4542+ int i,size;
4543+ char* str;
4544+ volatile uint32_t *addr;
4545+
4546+ DWC_PRINT("Core Global Registers\n");
4547+ addr=&core_if->core_global_regs->gotgctl;
4548+ DWC_PRINT("GOTGCTL @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4549+ addr=&core_if->core_global_regs->gotgint;
4550+ DWC_PRINT("GOTGINT @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4551+ addr=&core_if->core_global_regs->gahbcfg;
4552+ DWC_PRINT("GAHBCFG @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4553+ addr=&core_if->core_global_regs->gusbcfg;
4554+ DWC_PRINT("GUSBCFG @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4555+ addr=&core_if->core_global_regs->grstctl;
4556+ DWC_PRINT("GRSTCTL @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4557+ addr=&core_if->core_global_regs->gintsts;
4558+ DWC_PRINT("GINTSTS @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4559+ addr=&core_if->core_global_regs->gintmsk;
4560+ DWC_PRINT("GINTMSK @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4561+ addr=&core_if->core_global_regs->grxstsr;
4562+ DWC_PRINT("GRXSTSR @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4563+ //addr=&core_if->core_global_regs->grxstsp;
4564+ //DWC_PRINT("GRXSTSP @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4565+ addr=&core_if->core_global_regs->grxfsiz;
4566+ DWC_PRINT("GRXFSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4567+ addr=&core_if->core_global_regs->gnptxfsiz;
4568+ DWC_PRINT("GNPTXFSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4569+ addr=&core_if->core_global_regs->gnptxsts;
4570+ DWC_PRINT("GNPTXSTS @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4571+ addr=&core_if->core_global_regs->gi2cctl;
4572+ DWC_PRINT("GI2CCTL @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4573+ addr=&core_if->core_global_regs->gpvndctl;
4574+ DWC_PRINT("GPVNDCTL @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4575+ addr=&core_if->core_global_regs->ggpio;
4576+ DWC_PRINT("GGPIO @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4577+ addr=&core_if->core_global_regs->guid;
4578+ DWC_PRINT("GUID @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4579+ addr=&core_if->core_global_regs->gsnpsid;
4580+ DWC_PRINT("GSNPSID @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4581+ addr=&core_if->core_global_regs->ghwcfg1;
4582+ DWC_PRINT("GHWCFG1 @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4583+ addr=&core_if->core_global_regs->ghwcfg2;
4584+ DWC_PRINT("GHWCFG2 @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4585+ addr=&core_if->core_global_regs->ghwcfg3;
4586+ DWC_PRINT("GHWCFG3 @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4587+ addr=&core_if->core_global_regs->ghwcfg4;
4588+ DWC_PRINT("GHWCFG4 @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4589+ addr=&core_if->core_global_regs->hptxfsiz;
4590+ DWC_PRINT("HPTXFSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
4591+
4592+ size=(core_if->hwcfg4.b.ded_fifo_en)?
4593+ core_if->hwcfg4.b.num_in_eps:core_if->hwcfg4.b.num_dev_perio_in_ep;
4594+ str=(core_if->hwcfg4.b.ded_fifo_en)?"DIEPTXF":"DPTXFSIZ";
4595+ for (i=0; i<size; i++)
4596+ {
4597+ addr=&core_if->core_global_regs->dptxfsiz_dieptxf[i];
4598+ DWC_PRINT("%s[%d] @0x%08X : 0x%08X\n",str,i,(uint32_t)addr,dwc_read_reg32(addr));
4599+ }
4600+}
4601+
4602+/**
4603+ * Flush a Tx FIFO.
4604+ *
4605+ * @param core_if Programming view of DWC_otg controller.
4606+ * @param num Tx FIFO to flush.
4607+ */
4608+void dwc_otg_flush_tx_fifo(dwc_otg_core_if_t *core_if,
4609+ const int num)
4610+{
4611+ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
4612+ volatile grstctl_t greset = { .d32 = 0};
4613+ int count = 0;
4614+
4615+ DWC_DEBUGPL((DBG_CIL|DBG_PCDV), "Flush Tx FIFO %d\n", num);
4616+
4617+ greset.b.txfflsh = 1;
4618+ greset.b.txfnum = num;
4619+ dwc_write_reg32(&global_regs->grstctl, greset.d32);
4620+
4621+ do {
4622+ greset.d32 = dwc_read_reg32(&global_regs->grstctl);
4623+ if (++count > 10000) {
4624+ DWC_WARN("%s() HANG! GRSTCTL=%0x GNPTXSTS=0x%08x\n",
4625+ __func__, greset.d32,
4626+ dwc_read_reg32(&global_regs->gnptxsts));
4627+ break;
4628+ }
4629+ }
4630+ while (greset.b.txfflsh == 1);
4631+
4632+ /* Wait for 3 PHY Clocks*/
4633+ UDELAY(1);
4634+}
4635+
4636+/**
4637+ * Flush Rx FIFO.
4638+ *
4639+ * @param core_if Programming view of DWC_otg controller.
4640+ */
4641+void dwc_otg_flush_rx_fifo(dwc_otg_core_if_t *core_if)
4642+{
4643+ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
4644+ volatile grstctl_t greset = { .d32 = 0};
4645+ int count = 0;
4646+
4647+ DWC_DEBUGPL((DBG_CIL|DBG_PCDV), "%s\n", __func__);
4648+ /*
4649+ *
4650+ */
4651+ greset.b.rxfflsh = 1;
4652+ dwc_write_reg32(&global_regs->grstctl, greset.d32);
4653+
4654+ do {
4655+ greset.d32 = dwc_read_reg32(&global_regs->grstctl);
4656+ if (++count > 10000) {
4657+ DWC_WARN("%s() HANG! GRSTCTL=%0x\n", __func__,
4658+ greset.d32);
4659+ break;
4660+ }
4661+ }
4662+ while (greset.b.rxfflsh == 1);
4663+
4664+ /* Wait for 3 PHY Clocks*/
4665+ UDELAY(1);
4666+}
4667+
4668+/**
4669+ * Do core a soft reset of the core. Be careful with this because it
4670+ * resets all the internal state machines of the core.
4671+ */
4672+void dwc_otg_core_reset(dwc_otg_core_if_t *core_if)
4673+{
4674+ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
4675+ volatile grstctl_t greset = { .d32 = 0};
4676+ int count = 0;
4677+
4678+ DWC_DEBUGPL(DBG_CILV, "%s\n", __func__);
4679+ /* Wait for AHB master IDLE state. */
4680+ do {
4681+ UDELAY(10);
4682+ greset.d32 = dwc_read_reg32(&global_regs->grstctl);
4683+ if (++count > 100000) {
4684+ DWC_WARN("%s() HANG! AHB Idle GRSTCTL=%0x\n", __func__,
4685+ greset.d32);
4686+ return;
4687+ }
4688+ }
4689+ while (greset.b.ahbidle == 0);
4690+
4691+ /* Core Soft Reset */
4692+ count = 0;
4693+ greset.b.csftrst = 1;
4694+ dwc_write_reg32(&global_regs->grstctl, greset.d32);
4695+ do {
4696+ greset.d32 = dwc_read_reg32(&global_regs->grstctl);
4697+ if (++count > 10000) {
4698+ DWC_WARN("%s() HANG! Soft Reset GRSTCTL=%0x\n", __func__,
4699+ greset.d32);
4700+ break;
4701+ }
4702+ }
4703+ while (greset.b.csftrst == 1);
4704+
4705+ /* Wait for 3 PHY Clocks*/
4706+ MDELAY(100);
4707+
4708+ DWC_DEBUGPL(DBG_CILV, "GINTSTS=%.8x\n", dwc_read_reg32(&global_regs->gintsts));
4709+ DWC_DEBUGPL(DBG_CILV, "GINTSTS=%.8x\n", dwc_read_reg32(&global_regs->gintsts));
4710+ DWC_DEBUGPL(DBG_CILV, "GINTSTS=%.8x\n", dwc_read_reg32(&global_regs->gintsts));
4711+
4712+}
4713+
4714+
4715+
4716+/**
4717+ * Register HCD callbacks. The callbacks are used to start and stop
4718+ * the HCD for interrupt processing.
4719+ *
4720+ * @param core_if Programming view of DWC_otg controller.
4721+ * @param cb the HCD callback structure.
4722+ * @param p pointer to be passed to callback function (usb_hcd*).
4723+ */
4724+void dwc_otg_cil_register_hcd_callbacks(dwc_otg_core_if_t *core_if,
4725+ dwc_otg_cil_callbacks_t *cb,
4726+ void *p)
4727+{
4728+ core_if->hcd_cb = cb;
4729+ cb->p = p;
4730+}
4731+
4732+/**
4733+ * Register PCD callbacks. The callbacks are used to start and stop
4734+ * the PCD for interrupt processing.
4735+ *
4736+ * @param core_if Programming view of DWC_otg controller.
4737+ * @param cb the PCD callback structure.
4738+ * @param p pointer to be passed to callback function (pcd*).
4739+ */
4740+void dwc_otg_cil_register_pcd_callbacks(dwc_otg_core_if_t *core_if,
4741+ dwc_otg_cil_callbacks_t *cb,
4742+ void *p)
4743+{
4744+ core_if->pcd_cb = cb;
4745+ cb->p = p;
4746+}
4747+
4748+#ifdef DWC_EN_ISOC
4749+
4750+/**
4751+ * This function writes isoc data per 1 (micro)frame into tx fifo
4752+ *
4753+ * @param core_if Programming view of DWC_otg controller.
4754+ * @param ep The EP to start the transfer on.
4755+ *
4756+ */
4757+void write_isoc_frame_data(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
4758+{
4759+ dwc_otg_dev_in_ep_regs_t *ep_regs;
4760+ dtxfsts_data_t txstatus = {.d32 = 0};
4761+ uint32_t len = 0;
4762+ uint32_t dwords;
4763+
4764+ ep->xfer_len = ep->data_per_frame;
4765+ ep->xfer_count = 0;
4766+
4767+ ep_regs = core_if->dev_if->in_ep_regs[ep->num];
4768+
4769+ len = ep->xfer_len - ep->xfer_count;
4770+
4771+ if (len > ep->maxpacket) {
4772+ len = ep->maxpacket;
4773+ }
4774+
4775+ dwords = (len + 3)/4;
4776+
4777+ /* While there is space in the queue and space in the FIFO and
4778+ * More data to tranfer, Write packets to the Tx FIFO */
4779+ txstatus.d32 = dwc_read_reg32(&core_if->dev_if->in_ep_regs[ep->num]->dtxfsts);
4780+ DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n",ep->num,txstatus.d32);
4781+
4782+ while (txstatus.b.txfspcavail > dwords &&
4783+ ep->xfer_count < ep->xfer_len &&
4784+ ep->xfer_len != 0) {
4785+ /* Write the FIFO */
4786+ dwc_otg_ep_write_packet(core_if, ep, 0);
4787+
4788+ len = ep->xfer_len - ep->xfer_count;
4789+ if (len > ep->maxpacket) {
4790+ len = ep->maxpacket;
4791+ }
4792+
4793+ dwords = (len + 3)/4;
4794+ txstatus.d32 = dwc_read_reg32(&core_if->dev_if->in_ep_regs[ep->num]->dtxfsts);
4795+ DWC_DEBUGPL(DBG_PCDV,"dtxfsts[%d]=0x%08x\n", ep->num, txstatus.d32);
4796+ }
4797+}
4798+
4799+
4800+/**
4801+ * This function initializes a descriptor chain for Isochronous transfer
4802+ *
4803+ * @param core_if Programming view of DWC_otg controller.
4804+ * @param ep The EP to start the transfer on.
4805+ *
4806+ */
4807+void dwc_otg_iso_ep_start_frm_transfer(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
4808+{
4809+ deptsiz_data_t deptsiz = { .d32 = 0 };
4810+ depctl_data_t depctl = { .d32 = 0 };
4811+ dsts_data_t dsts = { .d32 = 0 };
4812+ volatile uint32_t *addr;
4813+
4814+ if(ep->is_in) {
4815+ addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl;
4816+ } else {
4817+ addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl;
4818+ }
4819+
4820+ ep->xfer_len = ep->data_per_frame;
4821+ ep->xfer_count = 0;
4822+ ep->xfer_buff = ep->cur_pkt_addr;
4823+ ep->dma_addr = ep->cur_pkt_dma_addr;
4824+
4825+ if(ep->is_in) {
4826+ /* Program the transfer size and packet count
4827+ * as follows: xfersize = N * maxpacket +
4828+ * short_packet pktcnt = N + (short_packet
4829+ * exist ? 1 : 0)
4830+ */
4831+ deptsiz.b.xfersize = ep->xfer_len;
4832+ deptsiz.b.pktcnt =
4833+ (ep->xfer_len - 1 + ep->maxpacket) /
4834+ ep->maxpacket;
4835+ deptsiz.b.mc = deptsiz.b.pktcnt;
4836+ dwc_write_reg32(&core_if->dev_if->in_ep_regs[ep->num]->dieptsiz, deptsiz.d32);
4837+
4838+ /* Write the DMA register */
4839+ if (core_if->dma_enable) {
4840+ dwc_write_reg32 (&(core_if->dev_if->in_ep_regs[ep->num]->diepdma), (uint32_t)ep->dma_addr);
4841+ }
4842+ } else {
4843+ deptsiz.b.pktcnt =
4844+ (ep->xfer_len + (ep->maxpacket - 1)) /
4845+ ep->maxpacket;
4846+ deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket;
4847+
4848+ dwc_write_reg32(&core_if->dev_if->out_ep_regs[ep->num]->doeptsiz, deptsiz.d32);
4849+
4850+ if (core_if->dma_enable) {
4851+ dwc_write_reg32 (&(core_if->dev_if->out_ep_regs[ep->num]->doepdma),
4852+ (uint32_t)ep->dma_addr);
4853+ }
4854+ }
4855+
4856+
4857+ /** Enable endpoint, clear nak */
4858+
4859+ depctl.d32 = 0;
4860+ if(ep->bInterval == 1) {
4861+ dsts.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts);
4862+ ep->next_frame = dsts.b.soffn + ep->bInterval;
4863+
4864+ if(ep->next_frame & 0x1) {
4865+ depctl.b.setd1pid = 1;
4866+ } else {
4867+ depctl.b.setd0pid = 1;
4868+ }
4869+ } else {
4870+ ep->next_frame += ep->bInterval;
4871+
4872+ if(ep->next_frame & 0x1) {
4873+ depctl.b.setd1pid = 1;
4874+ } else {
4875+ depctl.b.setd0pid = 1;
4876+ }
4877+ }
4878+ depctl.b.epena = 1;
4879+ depctl.b.cnak = 1;
4880+
4881+ dwc_modify_reg32(addr, 0, depctl.d32);
4882+ depctl.d32 = dwc_read_reg32(addr);
4883+
4884+ if(ep->is_in && core_if->dma_enable == 0) {
4885+ write_isoc_frame_data(core_if, ep);
4886+ }
4887+
4888+}
4889+
4890+#endif //DWC_EN_ISOC
4891--- /dev/null
4892+++ b/drivers/usb/dwc/otg_cil.h
4893@@ -0,0 +1,1106 @@
4894+/* ==========================================================================
4895+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_cil.h $
4896+ * $Revision: #91 $
4897+ * $Date: 2008/09/19 $
4898+ * $Change: 1099526 $
4899+ *
4900+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
4901+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
4902+ * otherwise expressly agreed to in writing between Synopsys and you.
4903+ *
4904+ * The Software IS NOT an item of Licensed Software or Licensed Product under
4905+ * any End User Software License Agreement or Agreement for Licensed Product
4906+ * with Synopsys or any supplement thereto. You are permitted to use and
4907+ * redistribute this Software in source and binary forms, with or without
4908+ * modification, provided that redistributions of source code must retain this
4909+ * notice. You may not view, use, disclose, copy or distribute this file or
4910+ * any information contained herein except pursuant to this license grant from
4911+ * Synopsys. If you do not agree with this notice, including the disclaimer
4912+ * below, then you are not authorized to use the Software.
4913+ *
4914+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
4915+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4916+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4917+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
4918+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
4919+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
4920+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
4921+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4922+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
4923+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
4924+ * DAMAGE.
4925+ * ========================================================================== */
4926+
4927+#if !defined(__DWC_CIL_H__)
4928+#define __DWC_CIL_H__
4929+
4930+#include <linux/workqueue.h>
4931+#include <linux/version.h>
4932+#include <asm/param.h>
4933+//#include <asm/arch/regs-irq.h>
4934+
4935+#include "otg_plat.h"
4936+#include "otg_regs.h"
4937+#ifdef DEBUG
4938+#include "linux/timer.h"
4939+#endif
4940+
4941+/**
4942+ * @file
4943+ * This file contains the interface to the Core Interface Layer.
4944+ */
4945+
4946+
4947+/** Macros defined for DWC OTG HW Release verison */
4948+#define OTG_CORE_REV_2_00 0x4F542000
4949+#define OTG_CORE_REV_2_60a 0x4F54260A
4950+#define OTG_CORE_REV_2_71a 0x4F54271A
4951+#define OTG_CORE_REV_2_72a 0x4F54272A
4952+
4953+/**
4954+*/
4955+typedef struct iso_pkt_info
4956+{
4957+ uint32_t offset;
4958+ uint32_t length;
4959+ int32_t status;
4960+} iso_pkt_info_t;
4961+/**
4962+ * The <code>dwc_ep</code> structure represents the state of a single
4963+ * endpoint when acting in device mode. It contains the data items
4964+ * needed for an endpoint to be activated and transfer packets.
4965+ */
4966+typedef struct dwc_ep
4967+{
4968+ /** EP number used for register address lookup */
4969+ uint8_t num;
4970+ /** EP direction 0 = OUT */
4971+ unsigned is_in : 1;
4972+ /** EP active. */
4973+ unsigned active : 1;
4974+
4975+ /** Periodic Tx FIFO # for IN EPs For INTR EP set to 0 to use non-periodic Tx FIFO
4976+ If dedicated Tx FIFOs are enabled for all IN Eps - Tx FIFO # FOR IN EPs*/
4977+ unsigned tx_fifo_num : 4;
4978+ /** EP type: 0 - Control, 1 - ISOC, 2 - BULK, 3 - INTR */
4979+ unsigned type : 2;
4980+#define DWC_OTG_EP_TYPE_CONTROL 0
4981+#define DWC_OTG_EP_TYPE_ISOC 1
4982+#define DWC_OTG_EP_TYPE_BULK 2
4983+#define DWC_OTG_EP_TYPE_INTR 3
4984+
4985+ /** DATA start PID for INTR and BULK EP */
4986+ unsigned data_pid_start : 1;
4987+ /** Frame (even/odd) for ISOC EP */
4988+ unsigned even_odd_frame : 1;
4989+ /** Max Packet bytes */
4990+ unsigned maxpacket : 11;
4991+
4992+ /** Max Transfer size */
4993+ unsigned maxxfer : 16;
4994+
4995+ /** @name Transfer state */
4996+ /** @{ */
4997+
4998+ /**
4999+ * Pointer to the beginning of the transfer buffer -- do not modify
5000+ * during transfer.
5001+ */
5002+
5003+ uint32_t dma_addr;
5004+
5005+ uint32_t dma_desc_addr;
5006+ dwc_otg_dma_desc_t* desc_addr;
5007+
5008+
5009+ uint8_t *start_xfer_buff;
5010+ /** pointer to the transfer buffer */
5011+ uint8_t *xfer_buff;
5012+ /** Number of bytes to transfer */
5013+ unsigned xfer_len : 19;
5014+ /** Number of bytes transferred. */
5015+ unsigned xfer_count : 19;
5016+ /** Sent ZLP */
5017+ unsigned sent_zlp : 1;
5018+ /** Total len for control transfer */
5019+ unsigned total_len : 19;
5020+
5021+ /** stall clear flag */
5022+ unsigned stall_clear_flag : 1;
5023+
5024+ /** Allocated DMA Desc count */
5025+ uint32_t desc_cnt;
5026+
5027+ uint32_t aligned_dma_addr;
5028+ uint32_t aligned_buf_size;
5029+ uint8_t *aligned_buf;
5030+
5031+
5032+#ifdef DWC_EN_ISOC
5033+ /**
5034+ * Variables specific for ISOC EPs
5035+ *
5036+ */
5037+ /** DMA addresses of ISOC buffers */
5038+ uint32_t dma_addr0;
5039+ uint32_t dma_addr1;
5040+
5041+ uint32_t iso_dma_desc_addr;
5042+ dwc_otg_dma_desc_t* iso_desc_addr;
5043+
5044+ /** pointer to the transfer buffers */
5045+ uint8_t *xfer_buff0;
5046+ uint8_t *xfer_buff1;
5047+
5048+ /** number of ISOC Buffer is processing */
5049+ uint32_t proc_buf_num;
5050+ /** Interval of ISOC Buffer processing */
5051+ uint32_t buf_proc_intrvl;
5052+ /** Data size for regular frame */
5053+ uint32_t data_per_frame;
5054+
5055+ /* todo - pattern data support is to be implemented in the future */
5056+ /** Data size for pattern frame */
5057+ uint32_t data_pattern_frame;
5058+ /** Frame number of pattern data */
5059+ uint32_t sync_frame;
5060+
5061+ /** bInterval */
5062+ uint32_t bInterval;
5063+ /** ISO Packet number per frame */
5064+ uint32_t pkt_per_frm;
5065+ /** Next frame num for which will be setup DMA Desc */
5066+ uint32_t next_frame;
5067+ /** Number of packets per buffer processing */
5068+ uint32_t pkt_cnt;
5069+ /** Info for all isoc packets */
5070+ iso_pkt_info_t *pkt_info;
5071+ /** current pkt number */
5072+ uint32_t cur_pkt;
5073+ /** current pkt number */
5074+ uint8_t *cur_pkt_addr;
5075+ /** current pkt number */
5076+ uint32_t cur_pkt_dma_addr;
5077+#endif //DWC_EN_ISOC
5078+/** @} */
5079+} dwc_ep_t;
5080+
5081+/*
5082+ * Reasons for halting a host channel.
5083+ */
5084+typedef enum dwc_otg_halt_status
5085+{
5086+ DWC_OTG_HC_XFER_NO_HALT_STATUS,
5087+ DWC_OTG_HC_XFER_COMPLETE,
5088+ DWC_OTG_HC_XFER_URB_COMPLETE,
5089+ DWC_OTG_HC_XFER_ACK,
5090+ DWC_OTG_HC_XFER_NAK,
5091+ DWC_OTG_HC_XFER_NYET,
5092+ DWC_OTG_HC_XFER_STALL,
5093+ DWC_OTG_HC_XFER_XACT_ERR,
5094+ DWC_OTG_HC_XFER_FRAME_OVERRUN,
5095+ DWC_OTG_HC_XFER_BABBLE_ERR,
5096+ DWC_OTG_HC_XFER_DATA_TOGGLE_ERR,
5097+ DWC_OTG_HC_XFER_AHB_ERR,
5098+ DWC_OTG_HC_XFER_PERIODIC_INCOMPLETE,
5099+ DWC_OTG_HC_XFER_URB_DEQUEUE
5100+} dwc_otg_halt_status_e;
5101+
5102+/**
5103+ * Host channel descriptor. This structure represents the state of a single
5104+ * host channel when acting in host mode. It contains the data items needed to
5105+ * transfer packets to an endpoint via a host channel.
5106+ */
5107+typedef struct dwc_hc
5108+{
5109+ /** Host channel number used for register address lookup */
5110+ uint8_t hc_num;
5111+
5112+ /** Device to access */
5113+ unsigned dev_addr : 7;
5114+
5115+ /** EP to access */
5116+ unsigned ep_num : 4;
5117+
5118+ /** EP direction. 0: OUT, 1: IN */
5119+ unsigned ep_is_in : 1;
5120+
5121+ /**
5122+ * EP speed.
5123+ * One of the following values:
5124+ * - DWC_OTG_EP_SPEED_LOW
5125+ * - DWC_OTG_EP_SPEED_FULL
5126+ * - DWC_OTG_EP_SPEED_HIGH
5127+ */
5128+ unsigned speed : 2;
5129+#define DWC_OTG_EP_SPEED_LOW 0
5130+#define DWC_OTG_EP_SPEED_FULL 1
5131+#define DWC_OTG_EP_SPEED_HIGH 2
5132+
5133+ /**
5134+ * Endpoint type.
5135+ * One of the following values:
5136+ * - DWC_OTG_EP_TYPE_CONTROL: 0
5137+ * - DWC_OTG_EP_TYPE_ISOC: 1
5138+ * - DWC_OTG_EP_TYPE_BULK: 2
5139+ * - DWC_OTG_EP_TYPE_INTR: 3
5140+ */
5141+ unsigned ep_type : 2;
5142+
5143+ /** Max packet size in bytes */
5144+ unsigned max_packet : 11;
5145+
5146+ /**
5147+ * PID for initial transaction.
5148+ * 0: DATA0,<br>
5149+ * 1: DATA2,<br>
5150+ * 2: DATA1,<br>
5151+ * 3: MDATA (non-Control EP),
5152+ * SETUP (Control EP)
5153+ */
5154+ unsigned data_pid_start : 2;
5155+#define DWC_OTG_HC_PID_DATA0 0
5156+#define DWC_OTG_HC_PID_DATA2 1
5157+#define DWC_OTG_HC_PID_DATA1 2
5158+#define DWC_OTG_HC_PID_MDATA 3
5159+#define DWC_OTG_HC_PID_SETUP 3
5160+
5161+ /** Number of periodic transactions per (micro)frame */
5162+ unsigned multi_count: 2;
5163+
5164+ /** @name Transfer State */
5165+ /** @{ */
5166+
5167+ /** Pointer to the current transfer buffer position. */
5168+ uint8_t *xfer_buff;
5169+ /** Total number of bytes to transfer. */
5170+ uint32_t xfer_len;
5171+ /** Number of bytes transferred so far. */
5172+ uint32_t xfer_count;
5173+ /** Packet count at start of transfer.*/
5174+ uint16_t start_pkt_count;
5175+
5176+ /**
5177+ * Flag to indicate whether the transfer has been started. Set to 1 if
5178+ * it has been started, 0 otherwise.
5179+ */
5180+ uint8_t xfer_started;
5181+
5182+ /**
5183+ * Set to 1 to indicate that a PING request should be issued on this
5184+ * channel. If 0, process normally.
5185+ */
5186+ uint8_t do_ping;
5187+
5188+ /**
5189+ * Set to 1 to indicate that the error count for this transaction is
5190+ * non-zero. Set to 0 if the error count is 0.
5191+ */
5192+ uint8_t error_state;
5193+
5194+ /**
5195+ * Set to 1 to indicate that this channel should be halted the next
5196+ * time a request is queued for the channel. This is necessary in
5197+ * slave mode if no request queue space is available when an attempt
5198+ * is made to halt the channel.
5199+ */
5200+ uint8_t halt_on_queue;
5201+
5202+ /**
5203+ * Set to 1 if the host channel has been halted, but the core is not
5204+ * finished flushing queued requests. Otherwise 0.
5205+ */
5206+ uint8_t halt_pending;
5207+
5208+ /**
5209+ * Reason for halting the host channel.
5210+ */
5211+ dwc_otg_halt_status_e halt_status;
5212+
5213+ /*
5214+ * Split settings for the host channel
5215+ */
5216+ uint8_t do_split; /**< Enable split for the channel */
5217+ uint8_t complete_split; /**< Enable complete split */
5218+ uint8_t hub_addr; /**< Address of high speed hub */
5219+
5220+ uint8_t port_addr; /**< Port of the low/full speed device */
5221+ /** Split transaction position
5222+ * One of the following values:
5223+ * - DWC_HCSPLIT_XACTPOS_MID
5224+ * - DWC_HCSPLIT_XACTPOS_BEGIN
5225+ * - DWC_HCSPLIT_XACTPOS_END
5226+ * - DWC_HCSPLIT_XACTPOS_ALL */
5227+ uint8_t xact_pos;
5228+
5229+ /** Set when the host channel does a short read. */
5230+ uint8_t short_read;
5231+
5232+ /**
5233+ * Number of requests issued for this channel since it was assigned to
5234+ * the current transfer (not counting PINGs).
5235+ */
5236+ uint8_t requests;
5237+
5238+ /**
5239+ * Queue Head for the transfer being processed by this channel.
5240+ */
5241+ struct dwc_otg_qh *qh;
5242+
5243+ /** @} */
5244+
5245+ /** Entry in list of host channels. */
5246+ struct list_head hc_list_entry;
5247+} dwc_hc_t;
5248+
5249+/**
5250+ * The following parameters may be specified when starting the module. These
5251+ * parameters define how the DWC_otg controller should be configured.
5252+ * Parameter values are passed to the CIL initialization function
5253+ * dwc_otg_cil_init.
5254+ */
5255+typedef struct dwc_otg_core_params
5256+{
5257+ int32_t opt;
5258+#define dwc_param_opt_default 1
5259+
5260+ /**
5261+ * Specifies the OTG capabilities. The driver will automatically
5262+ * detect the value for this parameter if none is specified.
5263+ * 0 - HNP and SRP capable (default)
5264+ * 1 - SRP Only capable
5265+ * 2 - No HNP/SRP capable
5266+ */
5267+ int32_t otg_cap;
5268+#define DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE 0
5269+#define DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE 1
5270+#define DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE 2
5271+//#define dwc_param_otg_cap_default DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE
5272+#define dwc_param_otg_cap_default DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE
5273+
5274+ /**
5275+ * Specifies whether to use slave or DMA mode for accessing the data
5276+ * FIFOs. The driver will automatically detect the value for this
5277+ * parameter if none is specified.
5278+ * 0 - Slave
5279+ * 1 - DMA (default, if available)
5280+ */
5281+ int32_t dma_enable;
5282+#define dwc_param_dma_enable_default 1
5283+
5284+ /**
5285+ * When DMA mode is enabled specifies whether to use address DMA or DMA Descritor mode for accessing the data
5286+ * FIFOs in device mode. The driver will automatically detect the value for this
5287+ * parameter if none is specified.
5288+ * 0 - address DMA
5289+ * 1 - DMA Descriptor(default, if available)
5290+ */
5291+ int32_t dma_desc_enable;
5292+#define dwc_param_dma_desc_enable_default 0
5293+ /** The DMA Burst size (applicable only for External DMA
5294+ * Mode). 1, 4, 8 16, 32, 64, 128, 256 (default 32)
5295+ */
5296+ int32_t dma_burst_size; /* Translate this to GAHBCFG values */
5297+//#define dwc_param_dma_burst_size_default 32
5298+#define dwc_param_dma_burst_size_default 1
5299+
5300+ /**
5301+ * Specifies the maximum speed of operation in host and device mode.
5302+ * The actual speed depends on the speed of the attached device and
5303+ * the value of phy_type. The actual speed depends on the speed of the
5304+ * attached device.
5305+ * 0 - High Speed (default)
5306+ * 1 - Full Speed
5307+ */
5308+ int32_t speed;
5309+#define dwc_param_speed_default 0
5310+#define DWC_SPEED_PARAM_HIGH 0
5311+#define DWC_SPEED_PARAM_FULL 1
5312+
5313+ /** Specifies whether low power mode is supported when attached
5314+ * to a Full Speed or Low Speed device in host mode.
5315+ * 0 - Don't support low power mode (default)
5316+ * 1 - Support low power mode
5317+ */
5318+ int32_t host_support_fs_ls_low_power;
5319+#define dwc_param_host_support_fs_ls_low_power_default 0
5320+
5321+ /** Specifies the PHY clock rate in low power mode when connected to a
5322+ * Low Speed device in host mode. This parameter is applicable only if
5323+ * HOST_SUPPORT_FS_LS_LOW_POWER is enabled. If PHY_TYPE is set to FS
5324+ * then defaults to 6 MHZ otherwise 48 MHZ.
5325+ *
5326+ * 0 - 48 MHz
5327+ * 1 - 6 MHz
5328+ */
5329+ int32_t host_ls_low_power_phy_clk;
5330+#define dwc_param_host_ls_low_power_phy_clk_default 0
5331+#define DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ 0
5332+#define DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ 1
5333+
5334+ /**
5335+ * 0 - Use cC FIFO size parameters
5336+ * 1 - Allow dynamic FIFO sizing (default)
5337+ */
5338+ int32_t enable_dynamic_fifo;
5339+#define dwc_param_enable_dynamic_fifo_default 1
5340+
5341+ /** Total number of 4-byte words in the data FIFO memory. This
5342+ * memory includes the Rx FIFO, non-periodic Tx FIFO, and periodic
5343+ * Tx FIFOs.
5344+ * 32 to 32768 (default 8192)
5345+ * Note: The total FIFO memory depth in the FPGA configuration is 8192.
5346+ */
5347+ int32_t data_fifo_size;
5348+#define dwc_param_data_fifo_size_default 8192
5349+
5350+ /** Number of 4-byte words in the Rx FIFO in device mode when dynamic
5351+ * FIFO sizing is enabled.
5352+ * 16 to 32768 (default 1064)
5353+ */
5354+ int32_t dev_rx_fifo_size;
5355+//#define dwc_param_dev_rx_fifo_size_default 1064
5356+#define dwc_param_dev_rx_fifo_size_default 0x100
5357+
5358+ /**
5359+ * Specifies whether dedicated transmit FIFOs are
5360+ * enabled for non periodic IN endpoints in device mode
5361+ * 0 - No
5362+ * 1 - Yes
5363+ */
5364+ int32_t en_multiple_tx_fifo;
5365+#define dwc_param_en_multiple_tx_fifo_default 1
5366+
5367+ /** Number of 4-byte words in each of the Tx FIFOs in device
5368+ * mode when dynamic FIFO sizing is enabled.
5369+ * 4 to 768 (default 256)
5370+ */
5371+ uint32_t dev_tx_fifo_size[MAX_TX_FIFOS];
5372+//#define dwc_param_dev_tx_fifo_size_default 256
5373+#define dwc_param_dev_tx_fifo_size_default 0x80
5374+
5375+ /** Number of 4-byte words in the non-periodic Tx FIFO in device mode
5376+ * when dynamic FIFO sizing is enabled.
5377+ * 16 to 32768 (default 1024)
5378+ */
5379+ int32_t dev_nperio_tx_fifo_size;
5380+//#define dwc_param_dev_nperio_tx_fifo_size_default 1024
5381+#define dwc_param_dev_nperio_tx_fifo_size_default 0x80
5382+
5383+ /** Number of 4-byte words in each of the periodic Tx FIFOs in device
5384+ * mode when dynamic FIFO sizing is enabled.
5385+ * 4 to 768 (default 256)
5386+ */
5387+ uint32_t dev_perio_tx_fifo_size[MAX_PERIO_FIFOS];
5388+//#define dwc_param_dev_perio_tx_fifo_size_default 256
5389+#define dwc_param_dev_perio_tx_fifo_size_default 0x80
5390+
5391+ /** Number of 4-byte words in the Rx FIFO in host mode when dynamic
5392+ * FIFO sizing is enabled.
5393+ * 16 to 32768 (default 1024)
5394+ */
5395+ int32_t host_rx_fifo_size;
5396+//#define dwc_param_host_rx_fifo_size_default 1024
5397+#define dwc_param_host_rx_fifo_size_default 0x292
5398+
5399+ /** Number of 4-byte words in the non-periodic Tx FIFO in host mode
5400+ * when Dynamic FIFO sizing is enabled in the core.
5401+ * 16 to 32768 (default 1024)
5402+ */
5403+ int32_t host_nperio_tx_fifo_size;
5404+//#define dwc_param_host_nperio_tx_fifo_size_default 1024
5405+//#define dwc_param_host_nperio_tx_fifo_size_default 0x292
5406+#define dwc_param_host_nperio_tx_fifo_size_default 0x80
5407+
5408+ /** Number of 4-byte words in the host periodic Tx FIFO when dynamic
5409+ * FIFO sizing is enabled.
5410+ * 16 to 32768 (default 1024)
5411+ */
5412+ int32_t host_perio_tx_fifo_size;
5413+//#define dwc_param_host_perio_tx_fifo_size_default 1024
5414+#define dwc_param_host_perio_tx_fifo_size_default 0x292
5415+
5416+ /** The maximum transfer size supported in bytes.
5417+ * 2047 to 65,535 (default 65,535)
5418+ */
5419+ int32_t max_transfer_size;
5420+#define dwc_param_max_transfer_size_default 65535
5421+
5422+ /** The maximum number of packets in a transfer.
5423+ * 15 to 511 (default 511)
5424+ */
5425+ int32_t max_packet_count;
5426+#define dwc_param_max_packet_count_default 511
5427+
5428+ /** The number of host channel registers to use.
5429+ * 1 to 16 (default 12)
5430+ * Note: The FPGA configuration supports a maximum of 12 host channels.
5431+ */
5432+ int32_t host_channels;
5433+//#define dwc_param_host_channels_default 12
5434+#define dwc_param_host_channels_default 16
5435+
5436+ /** The number of endpoints in addition to EP0 available for device
5437+ * mode operations.
5438+ * 1 to 15 (default 6 IN and OUT)
5439+ * Note: The FPGA configuration supports a maximum of 6 IN and OUT
5440+ * endpoints in addition to EP0.
5441+ */
5442+ int32_t dev_endpoints;
5443+//#define dwc_param_dev_endpoints_default 6
5444+#define dwc_param_dev_endpoints_default 8
5445+
5446+ /**
5447+ * Specifies the type of PHY interface to use. By default, the driver
5448+ * will automatically detect the phy_type.
5449+ *
5450+ * 0 - Full Speed PHY
5451+ * 1 - UTMI+ (default)
5452+ * 2 - ULPI
5453+ */
5454+ int32_t phy_type;
5455+#define DWC_PHY_TYPE_PARAM_FS 0
5456+#define DWC_PHY_TYPE_PARAM_UTMI 1
5457+#define DWC_PHY_TYPE_PARAM_ULPI 2
5458+#define dwc_param_phy_type_default DWC_PHY_TYPE_PARAM_UTMI
5459+
5460+ /**
5461+ * Specifies the UTMI+ Data Width. This parameter is
5462+ * applicable for a PHY_TYPE of UTMI+ or ULPI. (For a ULPI
5463+ * PHY_TYPE, this parameter indicates the data width between
5464+ * the MAC and the ULPI Wrapper.) Also, this parameter is
5465+ * applicable only if the OTG_HSPHY_WIDTH cC parameter was set
5466+ * to "8 and 16 bits", meaning that the core has been
5467+ * configured to work at either data path width.
5468+ *
5469+ * 8 or 16 bits (default 16)
5470+ */
5471+ int32_t phy_utmi_width;
5472+#define dwc_param_phy_utmi_width_default 16
5473+
5474+ /**
5475+ * Specifies whether the ULPI operates at double or single
5476+ * data rate. This parameter is only applicable if PHY_TYPE is
5477+ * ULPI.
5478+ *
5479+ * 0 - single data rate ULPI interface with 8 bit wide data
5480+ * bus (default)
5481+ * 1 - double data rate ULPI interface with 4 bit wide data
5482+ * bus
5483+ */
5484+ int32_t phy_ulpi_ddr;
5485+#define dwc_param_phy_ulpi_ddr_default 0
5486+
5487+ /**
5488+ * Specifies whether to use the internal or external supply to
5489+ * drive the vbus with a ULPI phy.
5490+ */
5491+ int32_t phy_ulpi_ext_vbus;
5492+#define DWC_PHY_ULPI_INTERNAL_VBUS 0
5493+#define DWC_PHY_ULPI_EXTERNAL_VBUS 1
5494+#define dwc_param_phy_ulpi_ext_vbus_default DWC_PHY_ULPI_INTERNAL_VBUS
5495+
5496+ /**
5497+ * Specifies whether to use the I2Cinterface for full speed PHY. This
5498+ * parameter is only applicable if PHY_TYPE is FS.
5499+ * 0 - No (default)
5500+ * 1 - Yes
5501+ */
5502+ int32_t i2c_enable;
5503+#define dwc_param_i2c_enable_default 0
5504+
5505+ int32_t ulpi_fs_ls;
5506+#define dwc_param_ulpi_fs_ls_default 0
5507+
5508+ int32_t ts_dline;
5509+#define dwc_param_ts_dline_default 0
5510+
5511+ /** Thresholding enable flag-
5512+ * bit 0 - enable non-ISO Tx thresholding
5513+ * bit 1 - enable ISO Tx thresholding
5514+ * bit 2 - enable Rx thresholding
5515+ */
5516+ uint32_t thr_ctl;
5517+#define dwc_param_thr_ctl_default 0
5518+
5519+ /** Thresholding length for Tx
5520+ * FIFOs in 32 bit DWORDs
5521+ */
5522+ uint32_t tx_thr_length;
5523+#define dwc_param_tx_thr_length_default 64
5524+
5525+ /** Thresholding length for Rx
5526+ * FIFOs in 32 bit DWORDs
5527+ */
5528+ uint32_t rx_thr_length;
5529+#define dwc_param_rx_thr_length_default 64
5530+
5531+ /** Per Transfer Interrupt
5532+ * mode enable flag
5533+ * 1 - Enabled
5534+ * 0 - Disabled
5535+ */
5536+ uint32_t pti_enable;
5537+#define dwc_param_pti_enable_default 0
5538+
5539+ /** Molti Processor Interrupt
5540+ * mode enable flag
5541+ * 1 - Enabled
5542+ * 0 - Disabled
5543+ */
5544+ uint32_t mpi_enable;
5545+#define dwc_param_mpi_enable_default 0
5546+
5547+} dwc_otg_core_params_t;
5548+
5549+#ifdef DEBUG
5550+struct dwc_otg_core_if;
5551+typedef struct hc_xfer_info
5552+{
5553+ struct dwc_otg_core_if *core_if;
5554+ dwc_hc_t *hc;
5555+} hc_xfer_info_t;
5556+#endif
5557+
5558+/**
5559+ * The <code>dwc_otg_core_if</code> structure contains information needed to manage
5560+ * the DWC_otg controller acting in either host or device mode. It
5561+ * represents the programming view of the controller as a whole.
5562+ */
5563+typedef struct dwc_otg_core_if
5564+{
5565+ /** Parameters that define how the core should be configured.*/
5566+ dwc_otg_core_params_t *core_params;
5567+
5568+ /** Core Global registers starting at offset 000h. */
5569+ dwc_otg_core_global_regs_t *core_global_regs;
5570+
5571+ /** Device-specific information */
5572+ dwc_otg_dev_if_t *dev_if;
5573+ /** Host-specific information */
5574+ dwc_otg_host_if_t *host_if;
5575+
5576+ /** Value from SNPSID register */
5577+ uint32_t snpsid;
5578+
5579+ /*
5580+ * Set to 1 if the core PHY interface bits in USBCFG have been
5581+ * initialized.
5582+ */
5583+ uint8_t phy_init_done;
5584+
5585+ /*
5586+ * SRP Success flag, set by srp success interrupt in FS I2C mode
5587+ */
5588+ uint8_t srp_success;
5589+ uint8_t srp_timer_started;
5590+
5591+ /* Common configuration information */
5592+ /** Power and Clock Gating Control Register */
5593+ volatile uint32_t *pcgcctl;
5594+#define DWC_OTG_PCGCCTL_OFFSET 0xE00
5595+
5596+ /** Push/pop addresses for endpoints or host channels.*/
5597+ uint32_t *data_fifo[MAX_EPS_CHANNELS];
5598+#define DWC_OTG_DATA_FIFO_OFFSET 0x1000
5599+#define DWC_OTG_DATA_FIFO_SIZE 0x1000
5600+
5601+ /** Total RAM for FIFOs (Bytes) */
5602+ uint16_t total_fifo_size;
5603+ /** Size of Rx FIFO (Bytes) */
5604+ uint16_t rx_fifo_size;
5605+ /** Size of Non-periodic Tx FIFO (Bytes) */
5606+ uint16_t nperio_tx_fifo_size;
5607+
5608+
5609+ /** 1 if DMA is enabled, 0 otherwise. */
5610+ uint8_t dma_enable;
5611+
5612+ /** 1 if Descriptor DMA mode is enabled, 0 otherwise. */
5613+ uint8_t dma_desc_enable;
5614+
5615+ /** 1 if PTI Enhancement mode is enabled, 0 otherwise. */
5616+ uint8_t pti_enh_enable;
5617+
5618+ /** 1 if MPI Enhancement mode is enabled, 0 otherwise. */
5619+ uint8_t multiproc_int_enable;
5620+
5621+ /** 1 if dedicated Tx FIFOs are enabled, 0 otherwise. */
5622+ uint8_t en_multiple_tx_fifo;
5623+
5624+ /** Set to 1 if multiple packets of a high-bandwidth transfer is in
5625+ * process of being queued */
5626+ uint8_t queuing_high_bandwidth;
5627+
5628+ /** Hardware Configuration -- stored here for convenience.*/
5629+ hwcfg1_data_t hwcfg1;
5630+ hwcfg2_data_t hwcfg2;
5631+ hwcfg3_data_t hwcfg3;
5632+ hwcfg4_data_t hwcfg4;
5633+
5634+ /** Host and Device Configuration -- stored here for convenience.*/
5635+ hcfg_data_t hcfg;
5636+ dcfg_data_t dcfg;
5637+
5638+ /** The operational State, during transations
5639+ * (a_host>>a_peripherial and b_device=>b_host) this may not
5640+ * match the core but allows the software to determine
5641+ * transitions.
5642+ */
5643+ uint8_t op_state;
5644+
5645+ /**
5646+ * Set to 1 if the HCD needs to be restarted on a session request
5647+ * interrupt. This is required if no connector ID status change has
5648+ * occurred since the HCD was last disconnected.
5649+ */
5650+ uint8_t restart_hcd_on_session_req;
5651+
5652+ /** HCD callbacks */
5653+ /** A-Device is a_host */
5654+#define A_HOST (1)
5655+ /** A-Device is a_suspend */
5656+#define A_SUSPEND (2)
5657+ /** A-Device is a_peripherial */
5658+#define A_PERIPHERAL (3)
5659+ /** B-Device is operating as a Peripheral. */
5660+#define B_PERIPHERAL (4)
5661+ /** B-Device is operating as a Host. */
5662+#define B_HOST (5)
5663+
5664+ /** HCD callbacks */
5665+ struct dwc_otg_cil_callbacks *hcd_cb;
5666+ /** PCD callbacks */
5667+ struct dwc_otg_cil_callbacks *pcd_cb;
5668+
5669+ /** Device mode Periodic Tx FIFO Mask */
5670+ uint32_t p_tx_msk;
5671+ /** Device mode Periodic Tx FIFO Mask */
5672+ uint32_t tx_msk;
5673+
5674+ /** Workqueue object used for handling several interrupts */
5675+ struct workqueue_struct *wq_otg;
5676+
5677+ /** Work object used for handling "Connector ID Status Change" Interrupt */
5678+ struct work_struct w_conn_id;
5679+
5680+ /** Work object used for handling "Wakeup Detected" Interrupt */
5681+ struct delayed_work w_wkp;
5682+
5683+#ifdef DEBUG
5684+ uint32_t start_hcchar_val[MAX_EPS_CHANNELS];
5685+
5686+ hc_xfer_info_t hc_xfer_info[MAX_EPS_CHANNELS];
5687+ struct timer_list hc_xfer_timer[MAX_EPS_CHANNELS];
5688+
5689+ uint32_t hfnum_7_samples;
5690+ uint64_t hfnum_7_frrem_accum;
5691+ uint32_t hfnum_0_samples;
5692+ uint64_t hfnum_0_frrem_accum;
5693+ uint32_t hfnum_other_samples;
5694+ uint64_t hfnum_other_frrem_accum;
5695+#endif
5696+
5697+
5698+} dwc_otg_core_if_t;
5699+
5700+/*We must clear S3C24XX_EINTPEND external interrupt register
5701+ * because after clearing in this register trigerred IRQ from
5702+ * H/W core in kernel interrupt can be occured again before OTG
5703+ * handlers clear all IRQ sources of Core registers because of
5704+ * timing latencies and Low Level IRQ Type.
5705+ */
5706+
5707+#ifdef CONFIG_MACH_IPMATE
5708+#define S3C2410X_CLEAR_EINTPEND() \
5709+do { \
5710+ if (!dwc_otg_read_core_intr(core_if)) { \
5711+ __raw_writel(1UL << 11,S3C24XX_EINTPEND); \
5712+ } \
5713+} while (0)
5714+#else
5715+#define S3C2410X_CLEAR_EINTPEND() do { } while (0)
5716+#endif
5717+
5718+/*
5719+ * The following functions are functions for works
5720+ * using during handling some interrupts
5721+ */
5722+extern void w_conn_id_status_change(struct work_struct *p);
5723+extern void w_wakeup_detected(struct work_struct *p);
5724+
5725+
5726+/*
5727+ * The following functions support initialization of the CIL driver component
5728+ * and the DWC_otg controller.
5729+ */
5730+extern dwc_otg_core_if_t *dwc_otg_cil_init(const uint32_t *_reg_base_addr,
5731+ dwc_otg_core_params_t *_core_params);
5732+extern void dwc_otg_cil_remove(dwc_otg_core_if_t *_core_if);
5733+extern void dwc_otg_core_init(dwc_otg_core_if_t *_core_if);
5734+extern void dwc_otg_core_host_init(dwc_otg_core_if_t *_core_if);
5735+extern void dwc_otg_core_dev_init(dwc_otg_core_if_t *_core_if);
5736+extern void dwc_otg_enable_global_interrupts( dwc_otg_core_if_t *_core_if );
5737+extern void dwc_otg_disable_global_interrupts( dwc_otg_core_if_t *_core_if );
5738+
5739+/** @name Device CIL Functions
5740+ * The following functions support managing the DWC_otg controller in device
5741+ * mode.
5742+ */
5743+/**@{*/
5744+extern void dwc_otg_wakeup(dwc_otg_core_if_t *_core_if);
5745+extern void dwc_otg_read_setup_packet (dwc_otg_core_if_t *_core_if, uint32_t *_dest);
5746+extern uint32_t dwc_otg_get_frame_number(dwc_otg_core_if_t *_core_if);
5747+extern void dwc_otg_ep0_activate(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep);
5748+extern void dwc_otg_ep_activate(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep);
5749+extern void dwc_otg_ep_deactivate(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep);
5750+extern void dwc_otg_ep_start_transfer(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep);
5751+extern void dwc_otg_ep_start_zl_transfer(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep);
5752+extern void dwc_otg_ep0_start_transfer(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep);
5753+extern void dwc_otg_ep0_continue_transfer(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep);
5754+extern void dwc_otg_ep_write_packet(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep, int _dma);
5755+extern void dwc_otg_ep_set_stall(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep);
5756+extern void dwc_otg_ep_clear_stall(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep);
5757+extern void dwc_otg_enable_device_interrupts(dwc_otg_core_if_t *_core_if);
5758+extern void dwc_otg_dump_dev_registers(dwc_otg_core_if_t *_core_if);
5759+extern void dwc_otg_dump_spram(dwc_otg_core_if_t *_core_if);
5760+#ifdef DWC_EN_ISOC
5761+extern void dwc_otg_iso_ep_start_frm_transfer(dwc_otg_core_if_t *core_if, dwc_ep_t *ep);
5762+extern void dwc_otg_iso_ep_start_buf_transfer(dwc_otg_core_if_t *core_if, dwc_ep_t *ep);
5763+#endif //DWC_EN_ISOC
5764+/**@}*/
5765+
5766+/** @name Host CIL Functions
5767+ * The following functions support managing the DWC_otg controller in host
5768+ * mode.
5769+ */
5770+/**@{*/
5771+extern void dwc_otg_hc_init(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc);
5772+extern void dwc_otg_hc_halt(dwc_otg_core_if_t *_core_if,
5773+ dwc_hc_t *_hc,
5774+ dwc_otg_halt_status_e _halt_status);
5775+extern void dwc_otg_hc_cleanup(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc);
5776+extern void dwc_otg_hc_start_transfer(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc);
5777+extern int dwc_otg_hc_continue_transfer(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc);
5778+extern void dwc_otg_hc_do_ping(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc);
5779+extern void dwc_otg_hc_write_packet(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc);
5780+extern void dwc_otg_enable_host_interrupts(dwc_otg_core_if_t *_core_if);
5781+extern void dwc_otg_disable_host_interrupts(dwc_otg_core_if_t *_core_if);
5782+
5783+/**
5784+ * This function Reads HPRT0 in preparation to modify. It keeps the
5785+ * WC bits 0 so that if they are read as 1, they won't clear when you
5786+ * write it back
5787+ */
5788+static inline uint32_t dwc_otg_read_hprt0(dwc_otg_core_if_t *_core_if)
5789+{
5790+ hprt0_data_t hprt0;
5791+ hprt0.d32 = dwc_read_reg32(_core_if->host_if->hprt0);
5792+ hprt0.b.prtena = 0;
5793+ hprt0.b.prtconndet = 0;
5794+ hprt0.b.prtenchng = 0;
5795+ hprt0.b.prtovrcurrchng = 0;
5796+ return hprt0.d32;
5797+}
5798+
5799+extern void dwc_otg_dump_host_registers(dwc_otg_core_if_t *_core_if);
5800+/**@}*/
5801+
5802+/** @name Common CIL Functions
5803+ * The following functions support managing the DWC_otg controller in either
5804+ * device or host mode.
5805+ */
5806+/**@{*/
5807+
5808+extern void dwc_otg_read_packet(dwc_otg_core_if_t *core_if,
5809+ uint8_t *dest,
5810+ uint16_t bytes);
5811+
5812+extern void dwc_otg_dump_global_registers(dwc_otg_core_if_t *_core_if);
5813+
5814+extern void dwc_otg_flush_tx_fifo( dwc_otg_core_if_t *_core_if,
5815+ const int _num );
5816+extern void dwc_otg_flush_rx_fifo( dwc_otg_core_if_t *_core_if );
5817+extern void dwc_otg_core_reset( dwc_otg_core_if_t *_core_if );
5818+
5819+extern dwc_otg_dma_desc_t* dwc_otg_ep_alloc_desc_chain(uint32_t * dma_desc_addr, uint32_t count);
5820+extern void dwc_otg_ep_free_desc_chain(dwc_otg_dma_desc_t* desc_addr, uint32_t dma_desc_addr, uint32_t count);
5821+
5822+/**
5823+ * This function returns the Core Interrupt register.
5824+ */
5825+static inline uint32_t dwc_otg_read_core_intr(dwc_otg_core_if_t *_core_if)
5826+{
5827+ return (dwc_read_reg32(&_core_if->core_global_regs->gintsts) &
5828+ dwc_read_reg32(&_core_if->core_global_regs->gintmsk));
5829+}
5830+
5831+/**
5832+ * This function returns the OTG Interrupt register.
5833+ */
5834+static inline uint32_t dwc_otg_read_otg_intr (dwc_otg_core_if_t *_core_if)
5835+{
5836+ return (dwc_read_reg32 (&_core_if->core_global_regs->gotgint));
5837+}
5838+
5839+/**
5840+ * This function reads the Device All Endpoints Interrupt register and
5841+ * returns the IN endpoint interrupt bits.
5842+ */
5843+static inline uint32_t dwc_otg_read_dev_all_in_ep_intr(dwc_otg_core_if_t *core_if)
5844+{
5845+ uint32_t v;
5846+
5847+ if(core_if->multiproc_int_enable) {
5848+ v = dwc_read_reg32(&core_if->dev_if->dev_global_regs->deachint) &
5849+ dwc_read_reg32(&core_if->dev_if->dev_global_regs->deachintmsk);
5850+ } else {
5851+ v = dwc_read_reg32(&core_if->dev_if->dev_global_regs->daint) &
5852+ dwc_read_reg32(&core_if->dev_if->dev_global_regs->daintmsk);
5853+ }
5854+ return (v & 0xffff);
5855+
5856+}
5857+
5858+/**
5859+ * This function reads the Device All Endpoints Interrupt register and
5860+ * returns the OUT endpoint interrupt bits.
5861+ */
5862+static inline uint32_t dwc_otg_read_dev_all_out_ep_intr(dwc_otg_core_if_t *core_if)
5863+{
5864+ uint32_t v;
5865+
5866+ if(core_if->multiproc_int_enable) {
5867+ v = dwc_read_reg32(&core_if->dev_if->dev_global_regs->deachint) &
5868+ dwc_read_reg32(&core_if->dev_if->dev_global_regs->deachintmsk);
5869+ } else {
5870+ v = dwc_read_reg32(&core_if->dev_if->dev_global_regs->daint) &
5871+ dwc_read_reg32(&core_if->dev_if->dev_global_regs->daintmsk);
5872+ }
5873+
5874+ return ((v & 0xffff0000) >> 16);
5875+}
5876+
5877+/**
5878+ * This function returns the Device IN EP Interrupt register
5879+ */
5880+static inline uint32_t dwc_otg_read_dev_in_ep_intr(dwc_otg_core_if_t *core_if,
5881+ dwc_ep_t *ep)
5882+{
5883+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
5884+ uint32_t v, msk, emp;
5885+
5886+ if(core_if->multiproc_int_enable) {
5887+ msk = dwc_read_reg32(&dev_if->dev_global_regs->diepeachintmsk[ep->num]);
5888+ emp = dwc_read_reg32(&dev_if->dev_global_regs->dtknqr4_fifoemptymsk);
5889+ msk |= ((emp >> ep->num) & 0x1) << 7;
5890+ v = dwc_read_reg32(&dev_if->in_ep_regs[ep->num]->diepint) & msk;
5891+ } else {
5892+ msk = dwc_read_reg32(&dev_if->dev_global_regs->diepmsk);
5893+ emp = dwc_read_reg32(&dev_if->dev_global_regs->dtknqr4_fifoemptymsk);
5894+ msk |= ((emp >> ep->num) & 0x1) << 7;
5895+ v = dwc_read_reg32(&dev_if->in_ep_regs[ep->num]->diepint) & msk;
5896+ }
5897+
5898+
5899+ return v;
5900+}
5901+/**
5902+ * This function returns the Device OUT EP Interrupt register
5903+ */
5904+static inline uint32_t dwc_otg_read_dev_out_ep_intr(dwc_otg_core_if_t *_core_if,
5905+ dwc_ep_t *_ep)
5906+{
5907+ dwc_otg_dev_if_t *dev_if = _core_if->dev_if;
5908+ uint32_t v;
5909+ doepmsk_data_t msk = { .d32 = 0 };
5910+
5911+ if(_core_if->multiproc_int_enable) {
5912+ msk.d32 = dwc_read_reg32(&dev_if->dev_global_regs->doepeachintmsk[_ep->num]);
5913+ if(_core_if->pti_enh_enable) {
5914+ msk.b.pktdrpsts = 1;
5915+ }
5916+ v = dwc_read_reg32( &dev_if->out_ep_regs[_ep->num]->doepint) & msk.d32;
5917+ } else {
5918+ msk.d32 = dwc_read_reg32(&dev_if->dev_global_regs->doepmsk);
5919+ if(_core_if->pti_enh_enable) {
5920+ msk.b.pktdrpsts = 1;
5921+ }
5922+ v = dwc_read_reg32( &dev_if->out_ep_regs[_ep->num]->doepint) & msk.d32;
5923+ }
5924+ return v;
5925+}
5926+
5927+/**
5928+ * This function returns the Host All Channel Interrupt register
5929+ */
5930+static inline uint32_t dwc_otg_read_host_all_channels_intr (dwc_otg_core_if_t *_core_if)
5931+{
5932+ return (dwc_read_reg32 (&_core_if->host_if->host_global_regs->haint));
5933+}
5934+
5935+static inline uint32_t dwc_otg_read_host_channel_intr (dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc)
5936+{
5937+ return (dwc_read_reg32 (&_core_if->host_if->hc_regs[_hc->hc_num]->hcint));
5938+}
5939+
5940+
5941+/**
5942+ * This function returns the mode of the operation, host or device.
5943+ *
5944+ * @return 0 - Device Mode, 1 - Host Mode
5945+ */
5946+static inline uint32_t dwc_otg_mode(dwc_otg_core_if_t *_core_if)
5947+{
5948+ return (dwc_read_reg32( &_core_if->core_global_regs->gintsts ) & 0x1);
5949+}
5950+
5951+static inline uint8_t dwc_otg_is_device_mode(dwc_otg_core_if_t *_core_if)
5952+{
5953+ return (dwc_otg_mode(_core_if) != DWC_HOST_MODE);
5954+}
5955+static inline uint8_t dwc_otg_is_host_mode(dwc_otg_core_if_t *_core_if)
5956+{
5957+ return (dwc_otg_mode(_core_if) == DWC_HOST_MODE);
5958+}
5959+
5960+extern int32_t dwc_otg_handle_common_intr( dwc_otg_core_if_t *_core_if );
5961+
5962+
5963+/**@}*/
5964+
5965+/**
5966+ * DWC_otg CIL callback structure. This structure allows the HCD and
5967+ * PCD to register functions used for starting and stopping the PCD
5968+ * and HCD for role change on for a DRD.
5969+ */
5970+typedef struct dwc_otg_cil_callbacks
5971+{
5972+ /** Start function for role change */
5973+ int (*start) (void *_p);
5974+ /** Stop Function for role change */
5975+ int (*stop) (void *_p);
5976+ /** Disconnect Function for role change */
5977+ int (*disconnect) (void *_p);
5978+ /** Resume/Remote wakeup Function */
5979+ int (*resume_wakeup) (void *_p);
5980+ /** Suspend function */
5981+ int (*suspend) (void *_p);
5982+ /** Session Start (SRP) */
5983+ int (*session_start) (void *_p);
5984+ /** Pointer passed to start() and stop() */
5985+ void *p;
5986+} dwc_otg_cil_callbacks_t;
5987+
5988+extern void dwc_otg_cil_register_pcd_callbacks( dwc_otg_core_if_t *_core_if,
5989+ dwc_otg_cil_callbacks_t *_cb,
5990+ void *_p);
5991+extern void dwc_otg_cil_register_hcd_callbacks( dwc_otg_core_if_t *_core_if,
5992+ dwc_otg_cil_callbacks_t *_cb,
5993+ void *_p);
5994+#ifndef warn
5995+#define warn printk
5996+#endif
5997+
5998+#endif
5999+
6000--- /dev/null
6001+++ b/drivers/usb/dwc/otg_cil_intr.c
6002@@ -0,0 +1,852 @@
6003+/* ==========================================================================
6004+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_cil_intr.c $
6005+ * $Revision: #10 $
6006+ * $Date: 2008/07/16 $
6007+ * $Change: 1065567 $
6008+ *
6009+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
6010+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
6011+ * otherwise expressly agreed to in writing between Synopsys and you.
6012+ *
6013+ * The Software IS NOT an item of Licensed Software or Licensed Product under
6014+ * any End User Software License Agreement or Agreement for Licensed Product
6015+ * with Synopsys or any supplement thereto. You are permitted to use and
6016+ * redistribute this Software in source and binary forms, with or without
6017+ * modification, provided that redistributions of source code must retain this
6018+ * notice. You may not view, use, disclose, copy or distribute this file or
6019+ * any information contained herein except pursuant to this license grant from
6020+ * Synopsys. If you do not agree with this notice, including the disclaimer
6021+ * below, then you are not authorized to use the Software.
6022+ *
6023+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
6024+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
6025+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
6026+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
6027+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
6028+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
6029+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
6030+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
6031+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
6032+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
6033+ * DAMAGE.
6034+ * ========================================================================== */
6035+
6036+/** @file
6037+ *
6038+ * The Core Interface Layer provides basic services for accessing and
6039+ * managing the DWC_otg hardware. These services are used by both the
6040+ * Host Controller Driver and the Peripheral Controller Driver.
6041+ *
6042+ * This file contains the Common Interrupt handlers.
6043+ */
6044+#include "otg_plat.h"
6045+#include "otg_regs.h"
6046+#include "otg_cil.h"
6047+#include "otg_pcd.h"
6048+
6049+#ifdef DEBUG
6050+inline const char *op_state_str(dwc_otg_core_if_t *core_if)
6051+{
6052+ return (core_if->op_state==A_HOST?"a_host":
6053+ (core_if->op_state==A_SUSPEND?"a_suspend":
6054+ (core_if->op_state==A_PERIPHERAL?"a_peripheral":
6055+ (core_if->op_state==B_PERIPHERAL?"b_peripheral":
6056+ (core_if->op_state==B_HOST?"b_host":
6057+ "unknown")))));
6058+}
6059+#endif
6060+
6061+/** This function will log a debug message
6062+ *
6063+ * @param core_if Programming view of DWC_otg controller.
6064+ */
6065+int32_t dwc_otg_handle_mode_mismatch_intr (dwc_otg_core_if_t *core_if)
6066+{
6067+ gintsts_data_t gintsts;
6068+ DWC_WARN("Mode Mismatch Interrupt: currently in %s mode\n",
6069+ dwc_otg_mode(core_if) ? "Host" : "Device");
6070+
6071+ /* Clear interrupt */
6072+ gintsts.d32 = 0;
6073+ gintsts.b.modemismatch = 1;
6074+ dwc_write_reg32 (&core_if->core_global_regs->gintsts, gintsts.d32);
6075+ return 1;
6076+}
6077+
6078+/** Start the HCD. Helper function for using the HCD callbacks.
6079+ *
6080+ * @param core_if Programming view of DWC_otg controller.
6081+ */
6082+static inline void hcd_start(dwc_otg_core_if_t *core_if)
6083+{
6084+ if (core_if->hcd_cb && core_if->hcd_cb->start) {
6085+ core_if->hcd_cb->start(core_if->hcd_cb->p);
6086+ }
6087+}
6088+/** Stop the HCD. Helper function for using the HCD callbacks.
6089+ *
6090+ * @param core_if Programming view of DWC_otg controller.
6091+ */
6092+static inline void hcd_stop(dwc_otg_core_if_t *core_if)
6093+{
6094+ if (core_if->hcd_cb && core_if->hcd_cb->stop) {
6095+ core_if->hcd_cb->stop(core_if->hcd_cb->p);
6096+ }
6097+}
6098+/** Disconnect the HCD. Helper function for using the HCD callbacks.
6099+ *
6100+ * @param core_if Programming view of DWC_otg controller.
6101+ */
6102+static inline void hcd_disconnect(dwc_otg_core_if_t *core_if)
6103+{
6104+ if (core_if->hcd_cb && core_if->hcd_cb->disconnect) {
6105+ core_if->hcd_cb->disconnect(core_if->hcd_cb->p);
6106+ }
6107+}
6108+/** Inform the HCD the a New Session has begun. Helper function for
6109+ * using the HCD callbacks.
6110+ *
6111+ * @param core_if Programming view of DWC_otg controller.
6112+ */
6113+static inline void hcd_session_start(dwc_otg_core_if_t *core_if)
6114+{
6115+ if (core_if->hcd_cb && core_if->hcd_cb->session_start) {
6116+ core_if->hcd_cb->session_start(core_if->hcd_cb->p);
6117+ }
6118+}
6119+
6120+/** Start the PCD. Helper function for using the PCD callbacks.
6121+ *
6122+ * @param core_if Programming view of DWC_otg controller.
6123+ */
6124+static inline void pcd_start(dwc_otg_core_if_t *core_if)
6125+{
6126+ if (core_if->pcd_cb && core_if->pcd_cb->start) {
6127+ core_if->pcd_cb->start(core_if->pcd_cb->p);
6128+ }
6129+}
6130+/** Stop the PCD. Helper function for using the PCD callbacks.
6131+ *
6132+ * @param core_if Programming view of DWC_otg controller.
6133+ */
6134+static inline void pcd_stop(dwc_otg_core_if_t *core_if)
6135+{
6136+ if (core_if->pcd_cb && core_if->pcd_cb->stop) {
6137+ core_if->pcd_cb->stop(core_if->pcd_cb->p);
6138+ }
6139+}
6140+/** Suspend the PCD. Helper function for using the PCD callbacks.
6141+ *
6142+ * @param core_if Programming view of DWC_otg controller.
6143+ */
6144+static inline void pcd_suspend(dwc_otg_core_if_t *core_if)
6145+{
6146+ if (core_if->pcd_cb && core_if->pcd_cb->suspend) {
6147+ core_if->pcd_cb->suspend(core_if->pcd_cb->p);
6148+ }
6149+}
6150+/** Resume the PCD. Helper function for using the PCD callbacks.
6151+ *
6152+ * @param core_if Programming view of DWC_otg controller.
6153+ */
6154+static inline void pcd_resume(dwc_otg_core_if_t *core_if)
6155+{
6156+ if (core_if->pcd_cb && core_if->pcd_cb->resume_wakeup) {
6157+ core_if->pcd_cb->resume_wakeup(core_if->pcd_cb->p);
6158+ }
6159+}
6160+
6161+/**
6162+ * This function handles the OTG Interrupts. It reads the OTG
6163+ * Interrupt Register (GOTGINT) to determine what interrupt has
6164+ * occurred.
6165+ *
6166+ * @param core_if Programming view of DWC_otg controller.
6167+ */
6168+int32_t dwc_otg_handle_otg_intr(dwc_otg_core_if_t *core_if)
6169+{
6170+ dwc_otg_core_global_regs_t *global_regs =
6171+ core_if->core_global_regs;
6172+ gotgint_data_t gotgint;
6173+ gotgctl_data_t gotgctl;
6174+ gintmsk_data_t gintmsk;
6175+ gotgint.d32 = dwc_read_reg32(&global_regs->gotgint);
6176+ gotgctl.d32 = dwc_read_reg32(&global_regs->gotgctl);
6177+ DWC_DEBUGPL(DBG_CIL, "++OTG Interrupt gotgint=%0x [%s]\n", gotgint.d32,
6178+ op_state_str(core_if));
6179+ //DWC_DEBUGPL(DBG_CIL, "gotgctl=%08x\n", gotgctl.d32);
6180+
6181+ if (gotgint.b.sesenddet) {
6182+ DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: "
6183+ "Session End Detected++ (%s)\n",
6184+ op_state_str(core_if));
6185+ gotgctl.d32 = dwc_read_reg32(&global_regs->gotgctl);
6186+
6187+ if (core_if->op_state == B_HOST) {
6188+
6189+ dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *)core_if->pcd_cb->p;
6190+ if(unlikely(!pcd)) {
6191+ DWC_ERROR("%s: data structure not initialized properly, core_if->pcd_cb->p = NULL!!!",__func__);
6192+ BUG();
6193+ }
6194+ SPIN_LOCK(&pcd->lock);
6195+
6196+ pcd_start(core_if);
6197+
6198+ SPIN_UNLOCK(&pcd->lock);
6199+ core_if->op_state = B_PERIPHERAL;
6200+ } else {
6201+ dwc_otg_pcd_t *pcd;
6202+
6203+ /* If not B_HOST and Device HNP still set. HNP
6204+ * Did not succeed!*/
6205+ if (gotgctl.b.devhnpen) {
6206+ DWC_DEBUGPL(DBG_ANY, "Session End Detected\n");
6207+ DWC_ERROR("Device Not Connected/Responding!\n");
6208+ }
6209+
6210+ /* If Session End Detected the B-Cable has
6211+ * been disconnected. */
6212+ /* Reset PCD and Gadget driver to a
6213+ * clean state. */
6214+
6215+ pcd=(dwc_otg_pcd_t *)core_if->pcd_cb->p;
6216+ if(unlikely(!pcd)) {
6217+ DWC_ERROR("%s: data structure not initialized properly, core_if->pcd_cb->p = NULL!!!",__func__);
6218+ BUG();
6219+ }
6220+ SPIN_LOCK(&pcd->lock);
6221+
6222+ pcd_stop(core_if);
6223+
6224+ SPIN_UNLOCK(&pcd->lock);
6225+ }
6226+ gotgctl.d32 = 0;
6227+ gotgctl.b.devhnpen = 1;
6228+ dwc_modify_reg32(&global_regs->gotgctl,
6229+ gotgctl.d32, 0);
6230+ }
6231+ if (gotgint.b.sesreqsucstschng) {
6232+ DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: "
6233+ "Session Reqeust Success Status Change++\n");
6234+ gotgctl.d32 = dwc_read_reg32(&global_regs->gotgctl);
6235+ if (gotgctl.b.sesreqscs) {
6236+ if ((core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS) &&
6237+ (core_if->core_params->i2c_enable)) {
6238+ core_if->srp_success = 1;
6239+ }
6240+ else {
6241+ dwc_otg_pcd_t *pcd=(dwc_otg_pcd_t *)core_if->pcd_cb->p;
6242+ if(unlikely(!pcd)) {
6243+ DWC_ERROR("%s: data structure not initialized properly, core_if->pcd_cb->p = NULL!!!",__func__);
6244+ BUG();
6245+ }
6246+ SPIN_LOCK(&pcd->lock);
6247+
6248+ pcd_resume(core_if);
6249+
6250+ SPIN_UNLOCK(&pcd->lock);
6251+ /* Clear Session Request */
6252+ gotgctl.d32 = 0;
6253+ gotgctl.b.sesreq = 1;
6254+ dwc_modify_reg32(&global_regs->gotgctl,
6255+ gotgctl.d32, 0);
6256+ }
6257+ }
6258+ }
6259+ if (gotgint.b.hstnegsucstschng) {
6260+ /* Print statements during the HNP interrupt handling
6261+ * can cause it to fail.*/
6262+ gotgctl.d32 = dwc_read_reg32(&global_regs->gotgctl);
6263+ if (gotgctl.b.hstnegscs) {
6264+ if (dwc_otg_is_host_mode(core_if)) {
6265+ dwc_otg_pcd_t *pcd;
6266+
6267+ core_if->op_state = B_HOST;
6268+ /*
6269+ * Need to disable SOF interrupt immediately.
6270+ * When switching from device to host, the PCD
6271+ * interrupt handler won't handle the
6272+ * interrupt if host mode is already set. The
6273+ * HCD interrupt handler won't get called if
6274+ * the HCD state is HALT. This means that the
6275+ * interrupt does not get handled and Linux
6276+ * complains loudly.
6277+ */
6278+ gintmsk.d32 = 0;
6279+ gintmsk.b.sofintr = 1;
6280+ dwc_modify_reg32(&global_regs->gintmsk,
6281+ gintmsk.d32, 0);
6282+
6283+ pcd=(dwc_otg_pcd_t *)core_if->pcd_cb->p;
6284+ if(unlikely(!pcd)) {
6285+ DWC_ERROR("%s: data structure not initialized properly, core_if->pcd_cb->p = NULL!!!",__func__);
6286+ BUG();
6287+ }
6288+ SPIN_LOCK(&pcd->lock);
6289+
6290+ pcd_stop(core_if);
6291+
6292+ SPIN_UNLOCK(&pcd->lock);
6293+ /*
6294+ * Initialize the Core for Host mode.
6295+ */
6296+ hcd_start(core_if);
6297+ core_if->op_state = B_HOST;
6298+ }
6299+ } else {
6300+ gotgctl.d32 = 0;
6301+ gotgctl.b.hnpreq = 1;
6302+ gotgctl.b.devhnpen = 1;
6303+ dwc_modify_reg32(&global_regs->gotgctl,
6304+ gotgctl.d32, 0);
6305+ DWC_DEBUGPL(DBG_ANY, "HNP Failed\n");
6306+ DWC_ERROR("Device Not Connected/Responding\n");
6307+ }
6308+ }
6309+ if (gotgint.b.hstnegdet) {
6310+ /* The disconnect interrupt is set at the same time as
6311+ * Host Negotiation Detected. During the mode
6312+ * switch all interrupts are cleared so the disconnect
6313+ * interrupt handler will not get executed.
6314+ */
6315+ DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: "
6316+ "Host Negotiation Detected++ (%s)\n",
6317+ (dwc_otg_is_host_mode(core_if)?"Host":"Device"));
6318+ if (dwc_otg_is_device_mode(core_if)){
6319+ dwc_otg_pcd_t *pcd;
6320+
6321+ DWC_DEBUGPL(DBG_ANY, "a_suspend->a_peripheral (%d)\n", core_if->op_state);
6322+ hcd_disconnect(core_if);
6323+
6324+ pcd=(dwc_otg_pcd_t *)core_if->pcd_cb->p;
6325+ if(unlikely(!pcd)) {
6326+ DWC_ERROR("%s: data structure not initialized properly, core_if->pcd_cb->p = NULL!!!",__func__);
6327+ BUG();
6328+ }
6329+ SPIN_LOCK(&pcd->lock);
6330+
6331+ pcd_start(core_if);
6332+
6333+ SPIN_UNLOCK(&pcd->lock);
6334+ core_if->op_state = A_PERIPHERAL;
6335+ } else {
6336+ dwc_otg_pcd_t *pcd;
6337+
6338+ /*
6339+ * Need to disable SOF interrupt immediately. When
6340+ * switching from device to host, the PCD interrupt
6341+ * handler won't handle the interrupt if host mode is
6342+ * already set. The HCD interrupt handler won't get
6343+ * called if the HCD state is HALT. This means that
6344+ * the interrupt does not get handled and Linux
6345+ * complains loudly.
6346+ */
6347+ gintmsk.d32 = 0;
6348+ gintmsk.b.sofintr = 1;
6349+ dwc_modify_reg32(&global_regs->gintmsk,
6350+ gintmsk.d32, 0);
6351+
6352+ pcd=(dwc_otg_pcd_t *)core_if->pcd_cb->p;
6353+ if(unlikely(!pcd)) {
6354+ DWC_ERROR("%s: data structure not initialized properly, core_if->pcd_cb->p = NULL!!!",__func__);
6355+ BUG();
6356+ }
6357+ SPIN_LOCK(&pcd->lock);
6358+
6359+ pcd_stop(core_if);
6360+
6361+ SPIN_UNLOCK(&pcd->lock);
6362+ hcd_start(core_if);
6363+ core_if->op_state = A_HOST;
6364+ }
6365+ }
6366+ if (gotgint.b.adevtoutchng) {
6367+ DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: "
6368+ "A-Device Timeout Change++\n");
6369+ }
6370+ if (gotgint.b.debdone) {
6371+ DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: "
6372+ "Debounce Done++\n");
6373+ }
6374+
6375+ /* Clear GOTGINT */
6376+ dwc_write_reg32 (&core_if->core_global_regs->gotgint, gotgint.d32);
6377+
6378+ return 1;
6379+}
6380+
6381+
6382+void w_conn_id_status_change(struct work_struct *p)
6383+{
6384+ dwc_otg_core_if_t *core_if = container_of(p, dwc_otg_core_if_t, w_conn_id);
6385+
6386+ uint32_t count = 0;
6387+ gotgctl_data_t gotgctl = { .d32 = 0 };
6388+
6389+ gotgctl.d32 = dwc_read_reg32(&core_if->core_global_regs->gotgctl);
6390+ DWC_DEBUGPL(DBG_CIL, "gotgctl=%0x\n", gotgctl.d32);
6391+ DWC_DEBUGPL(DBG_CIL, "gotgctl.b.conidsts=%d\n", gotgctl.b.conidsts);
6392+
6393+ /* B-Device connector (Device Mode) */
6394+ if (gotgctl.b.conidsts) {
6395+ dwc_otg_pcd_t *pcd;
6396+
6397+ /* Wait for switch to device mode. */
6398+ while (!dwc_otg_is_device_mode(core_if)){
6399+ DWC_PRINT("Waiting for Peripheral Mode, Mode=%s\n",
6400+ (dwc_otg_is_host_mode(core_if)?"Host":"Peripheral"));
6401+ MDELAY(100);
6402+ if (++count > 10000) *(uint32_t*)NULL=0;
6403+ }
6404+ core_if->op_state = B_PERIPHERAL;
6405+ dwc_otg_core_init(core_if);
6406+ dwc_otg_enable_global_interrupts(core_if);
6407+
6408+ pcd=(dwc_otg_pcd_t *)core_if->pcd_cb->p;
6409+ if(unlikely(!pcd)) {
6410+ DWC_ERROR("%s: data structure not initialized properly, core_if->pcd_cb->p = NULL!!!",__func__);
6411+ BUG();
6412+ }
6413+ SPIN_LOCK(&pcd->lock);
6414+
6415+ pcd_start(core_if);
6416+
6417+ SPIN_UNLOCK(&pcd->lock);
6418+ } else {
6419+ /* A-Device connector (Host Mode) */
6420+ while (!dwc_otg_is_host_mode(core_if)) {
6421+ DWC_PRINT("Waiting for Host Mode, Mode=%s\n",
6422+ (dwc_otg_is_host_mode(core_if)?"Host":"Peripheral"));
6423+ MDELAY(100);
6424+ if (++count > 10000) *(uint32_t*)NULL=0;
6425+ }
6426+ core_if->op_state = A_HOST;
6427+ /*
6428+ * Initialize the Core for Host mode.
6429+ */
6430+ dwc_otg_core_init(core_if);
6431+ dwc_otg_enable_global_interrupts(core_if);
6432+ hcd_start(core_if);
6433+ }
6434+}
6435+
6436+
6437+/**
6438+ * This function handles the Connector ID Status Change Interrupt. It
6439+ * reads the OTG Interrupt Register (GOTCTL) to determine whether this
6440+ * is a Device to Host Mode transition or a Host Mode to Device
6441+ * Transition.
6442+ *
6443+ * This only occurs when the cable is connected/removed from the PHY
6444+ * connector.
6445+ *
6446+ * @param core_if Programming view of DWC_otg controller.
6447+ */
6448+int32_t dwc_otg_handle_conn_id_status_change_intr(dwc_otg_core_if_t *core_if)
6449+{
6450+
6451+ /*
6452+ * Need to disable SOF interrupt immediately. If switching from device
6453+ * to host, the PCD interrupt handler won't handle the interrupt if
6454+ * host mode is already set. The HCD interrupt handler won't get
6455+ * called if the HCD state is HALT. This means that the interrupt does
6456+ * not get handled and Linux complains loudly.
6457+ */
6458+ gintmsk_data_t gintmsk = { .d32 = 0 };
6459+ gintsts_data_t gintsts = { .d32 = 0 };
6460+
6461+ gintmsk.b.sofintr = 1;
6462+ dwc_modify_reg32(&core_if->core_global_regs->gintmsk, gintmsk.d32, 0);
6463+
6464+ DWC_DEBUGPL(DBG_CIL, " ++Connector ID Status Change Interrupt++ (%s)\n",
6465+ (dwc_otg_is_host_mode(core_if)?"Host":"Device"));
6466+
6467+ /*
6468+ * Need to schedule a work, as there are possible DELAY function calls
6469+ */
6470+ queue_work(core_if->wq_otg, &core_if->w_conn_id);
6471+
6472+ /* Set flag and clear interrupt */
6473+ gintsts.b.conidstschng = 1;
6474+ dwc_write_reg32 (&core_if->core_global_regs->gintsts, gintsts.d32);
6475+
6476+ return 1;
6477+}
6478+
6479+/**
6480+ * This interrupt indicates that a device is initiating the Session
6481+ * Request Protocol to request the host to turn on bus power so a new
6482+ * session can begin. The handler responds by turning on bus power. If
6483+ * the DWC_otg controller is in low power mode, the handler brings the
6484+ * controller out of low power mode before turning on bus power.
6485+ *
6486+ * @param core_if Programming view of DWC_otg controller.
6487+ */
6488+int32_t dwc_otg_handle_session_req_intr(dwc_otg_core_if_t *core_if)
6489+{
6490+ hprt0_data_t hprt0;
6491+ gintsts_data_t gintsts;
6492+
6493+#ifndef DWC_HOST_ONLY
6494+ DWC_DEBUGPL(DBG_ANY, "++Session Request Interrupt++\n");
6495+
6496+ if (dwc_otg_is_device_mode(core_if)) {
6497+ DWC_PRINT("SRP: Device mode\n");
6498+ } else {
6499+ DWC_PRINT("SRP: Host mode\n");
6500+
6501+ /* Turn on the port power bit. */
6502+ hprt0.d32 = dwc_otg_read_hprt0(core_if);
6503+ hprt0.b.prtpwr = 1;
6504+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
6505+
6506+ /* Start the Connection timer. So a message can be displayed
6507+ * if connect does not occur within 10 seconds. */
6508+ hcd_session_start(core_if);
6509+ }
6510+#endif
6511+
6512+ /* Clear interrupt */
6513+ gintsts.d32 = 0;
6514+ gintsts.b.sessreqintr = 1;
6515+ dwc_write_reg32 (&core_if->core_global_regs->gintsts, gintsts.d32);
6516+
6517+ return 1;
6518+}
6519+
6520+
6521+void w_wakeup_detected(struct work_struct *p)
6522+{
6523+ struct delayed_work *dw = container_of(p, struct delayed_work, work);
6524+ dwc_otg_core_if_t *core_if = container_of(dw, dwc_otg_core_if_t, w_wkp);
6525+
6526+ /*
6527+ * Clear the Resume after 70ms. (Need 20 ms minimum. Use 70 ms
6528+ * so that OPT tests pass with all PHYs).
6529+ */
6530+ hprt0_data_t hprt0 = {.d32=0};
6531+ hprt0.d32 = dwc_otg_read_hprt0(core_if);
6532+ DWC_DEBUGPL(DBG_ANY,"Resume: HPRT0=%0x\n", hprt0.d32);
6533+// MDELAY(70);
6534+ hprt0.b.prtres = 0; /* Resume */
6535+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
6536+ DWC_DEBUGPL(DBG_ANY,"Clear Resume: HPRT0=%0x\n", dwc_read_reg32(core_if->host_if->hprt0));
6537+}
6538+/**
6539+ * This interrupt indicates that the DWC_otg controller has detected a
6540+ * resume or remote wakeup sequence. If the DWC_otg controller is in
6541+ * low power mode, the handler must brings the controller out of low
6542+ * power mode. The controller automatically begins resume
6543+ * signaling. The handler schedules a time to stop resume signaling.
6544+ */
6545+int32_t dwc_otg_handle_wakeup_detected_intr(dwc_otg_core_if_t *core_if)
6546+{
6547+ gintsts_data_t gintsts;
6548+
6549+ DWC_DEBUGPL(DBG_ANY, "++Resume and Remote Wakeup Detected Interrupt++\n");
6550+
6551+ if (dwc_otg_is_device_mode(core_if)) {
6552+ dctl_data_t dctl = {.d32=0};
6553+ DWC_DEBUGPL(DBG_PCD, "DSTS=0x%0x\n",
6554+ dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts));
6555+#ifdef PARTIAL_POWER_DOWN
6556+ if (core_if->hwcfg4.b.power_optimiz) {
6557+ pcgcctl_data_t power = {.d32=0};
6558+
6559+ power.d32 = dwc_read_reg32(core_if->pcgcctl);
6560+ DWC_DEBUGPL(DBG_CIL, "PCGCCTL=%0x\n", power.d32);
6561+
6562+ power.b.stoppclk = 0;
6563+ dwc_write_reg32(core_if->pcgcctl, power.d32);
6564+
6565+ power.b.pwrclmp = 0;
6566+ dwc_write_reg32(core_if->pcgcctl, power.d32);
6567+
6568+ power.b.rstpdwnmodule = 0;
6569+ dwc_write_reg32(core_if->pcgcctl, power.d32);
6570+ }
6571+#endif
6572+ /* Clear the Remote Wakeup Signalling */
6573+ dctl.b.rmtwkupsig = 1;
6574+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->dctl,
6575+ dctl.d32, 0);
6576+
6577+ if (core_if->pcd_cb && core_if->pcd_cb->resume_wakeup) {
6578+ core_if->pcd_cb->resume_wakeup(core_if->pcd_cb->p);
6579+ }
6580+
6581+ } else {
6582+ pcgcctl_data_t pcgcctl = {.d32=0};
6583+
6584+ /* Restart the Phy Clock */
6585+ pcgcctl.b.stoppclk = 1;
6586+ dwc_modify_reg32(core_if->pcgcctl, pcgcctl.d32, 0);
6587+
6588+ queue_delayed_work(core_if->wq_otg, &core_if->w_wkp, ((70 * HZ / 1000) + 1));
6589+ }
6590+
6591+ /* Clear interrupt */
6592+ gintsts.d32 = 0;
6593+ gintsts.b.wkupintr = 1;
6594+ dwc_write_reg32 (&core_if->core_global_regs->gintsts, gintsts.d32);
6595+
6596+ return 1;
6597+}
6598+
6599+/**
6600+ * This interrupt indicates that a device has been disconnected from
6601+ * the root port.
6602+ */
6603+int32_t dwc_otg_handle_disconnect_intr(dwc_otg_core_if_t *core_if)
6604+{
6605+ gintsts_data_t gintsts;
6606+
6607+ DWC_DEBUGPL(DBG_ANY, "++Disconnect Detected Interrupt++ (%s) %s\n",
6608+ (dwc_otg_is_host_mode(core_if)?"Host":"Device"),
6609+ op_state_str(core_if));
6610+
6611+/** @todo Consolidate this if statement. */
6612+#ifndef DWC_HOST_ONLY
6613+ if (core_if->op_state == B_HOST) {
6614+ dwc_otg_pcd_t *pcd;
6615+
6616+ /* If in device mode Disconnect and stop the HCD, then
6617+ * start the PCD. */
6618+ hcd_disconnect(core_if);
6619+
6620+ pcd=(dwc_otg_pcd_t *)core_if->pcd_cb->p;
6621+ if(unlikely(!pcd)) {
6622+ DWC_ERROR("%s: data structure not initialized properly, core_if->pcd_cb->p = NULL!!!",__func__);
6623+ BUG();
6624+ }
6625+ SPIN_LOCK(&pcd->lock);
6626+
6627+ pcd_start(core_if);
6628+
6629+ SPIN_UNLOCK(&pcd->lock);
6630+ core_if->op_state = B_PERIPHERAL;
6631+ } else if (dwc_otg_is_device_mode(core_if)) {
6632+ gotgctl_data_t gotgctl = { .d32 = 0 };
6633+ gotgctl.d32 = dwc_read_reg32(&core_if->core_global_regs->gotgctl);
6634+ if (gotgctl.b.hstsethnpen==1) {
6635+ /* Do nothing, if HNP in process the OTG
6636+ * interrupt "Host Negotiation Detected"
6637+ * interrupt will do the mode switch.
6638+ */
6639+ } else if (gotgctl.b.devhnpen == 0) {
6640+ dwc_otg_pcd_t *pcd;
6641+
6642+ /* If in device mode Disconnect and stop the HCD, then
6643+ * start the PCD. */
6644+ hcd_disconnect(core_if);
6645+
6646+ pcd=(dwc_otg_pcd_t *)core_if->pcd_cb->p;
6647+ if(unlikely(!pcd)) {
6648+ DWC_ERROR("%s: data structure not initialized properly, core_if->pcd_cb->p = NULL!!!",__func__);
6649+ BUG();
6650+ }
6651+ SPIN_LOCK(&pcd->lock);
6652+
6653+ pcd_start(core_if);
6654+
6655+ SPIN_UNLOCK(&pcd->lock);
6656+
6657+ core_if->op_state = B_PERIPHERAL;
6658+ } else {
6659+ DWC_DEBUGPL(DBG_ANY,"!a_peripheral && !devhnpen\n");
6660+ }
6661+ } else {
6662+ if (core_if->op_state == A_HOST) {
6663+ /* A-Cable still connected but device disconnected. */
6664+ hcd_disconnect(core_if);
6665+ }
6666+ }
6667+#endif
6668+
6669+ gintsts.d32 = 0;
6670+ gintsts.b.disconnect = 1;
6671+ dwc_write_reg32 (&core_if->core_global_regs->gintsts, gintsts.d32);
6672+ return 1;
6673+}
6674+/**
6675+ * This interrupt indicates that SUSPEND state has been detected on
6676+ * the USB.
6677+ *
6678+ * For HNP the USB Suspend interrupt signals the change from
6679+ * "a_peripheral" to "a_host".
6680+ *
6681+ * When power management is enabled the core will be put in low power
6682+ * mode.
6683+ */
6684+int32_t dwc_otg_handle_usb_suspend_intr(dwc_otg_core_if_t *core_if)
6685+{
6686+ dsts_data_t dsts;
6687+ gintsts_data_t gintsts;
6688+
6689+ DWC_DEBUGPL(DBG_ANY,"USB SUSPEND\n");
6690+
6691+ if (dwc_otg_is_device_mode(core_if)) {
6692+ dwc_otg_pcd_t *pcd;
6693+
6694+ /* Check the Device status register to determine if the Suspend
6695+ * state is active. */
6696+ dsts.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts);
6697+ DWC_DEBUGPL(DBG_PCD, "DSTS=0x%0x\n", dsts.d32);
6698+ DWC_DEBUGPL(DBG_PCD, "DSTS.Suspend Status=%d "
6699+ "HWCFG4.power Optimize=%d\n",
6700+ dsts.b.suspsts, core_if->hwcfg4.b.power_optimiz);
6701+
6702+
6703+#ifdef PARTIAL_POWER_DOWN
6704+/** @todo Add a module parameter for power management. */
6705+ if (dsts.b.suspsts && core_if->hwcfg4.b.power_optimiz) {
6706+ pcgcctl_data_t power = {.d32=0};
6707+ DWC_DEBUGPL(DBG_CIL, "suspend\n");
6708+
6709+ power.b.pwrclmp = 1;
6710+ dwc_write_reg32(core_if->pcgcctl, power.d32);
6711+
6712+ power.b.rstpdwnmodule = 1;
6713+ dwc_modify_reg32(core_if->pcgcctl, 0, power.d32);
6714+
6715+ power.b.stoppclk = 1;
6716+ dwc_modify_reg32(core_if->pcgcctl, 0, power.d32);
6717+ } else {
6718+ DWC_DEBUGPL(DBG_ANY,"disconnect?\n");
6719+ }
6720+#endif
6721+ /* PCD callback for suspend. */
6722+ pcd=(dwc_otg_pcd_t *)core_if->pcd_cb->p;
6723+ if(unlikely(!pcd)) {
6724+ DWC_ERROR("%s: data structure not initialized properly, core_if->pcd_cb->p = NULL!!!",__func__);
6725+ BUG();
6726+ }
6727+ SPIN_LOCK(&pcd->lock);
6728+
6729+ pcd_suspend(core_if);
6730+
6731+ SPIN_UNLOCK(&pcd->lock);
6732+ } else {
6733+ if (core_if->op_state == A_PERIPHERAL) {
6734+ dwc_otg_pcd_t *pcd;
6735+
6736+ DWC_DEBUGPL(DBG_ANY,"a_peripheral->a_host\n");
6737+ /* Clear the a_peripheral flag, back to a_host. */
6738+
6739+ pcd=(dwc_otg_pcd_t *)core_if->pcd_cb->p;
6740+ if(unlikely(!pcd)) {
6741+ DWC_ERROR("%s: data structure not initialized properly, core_if->pcd_cb->p = NULL!!!",__func__);
6742+ BUG();
6743+ }
6744+ SPIN_LOCK(&pcd->lock);
6745+
6746+ pcd_stop(core_if);
6747+
6748+ SPIN_UNLOCK(&pcd->lock);
6749+
6750+ hcd_start(core_if);
6751+ core_if->op_state = A_HOST;
6752+ }
6753+ }
6754+
6755+ /* Clear interrupt */
6756+ gintsts.d32 = 0;
6757+ gintsts.b.usbsuspend = 1;
6758+ dwc_write_reg32(&core_if->core_global_regs->gintsts, gintsts.d32);
6759+
6760+ return 1;
6761+}
6762+
6763+
6764+/**
6765+ * This function returns the Core Interrupt register.
6766+ */
6767+static inline uint32_t dwc_otg_read_common_intr(dwc_otg_core_if_t *core_if)
6768+{
6769+ gintsts_data_t gintsts;
6770+ gintmsk_data_t gintmsk;
6771+ gintmsk_data_t gintmsk_common = {.d32=0};
6772+ gintmsk_common.b.wkupintr = 1;
6773+ gintmsk_common.b.sessreqintr = 1;
6774+ gintmsk_common.b.conidstschng = 1;
6775+ gintmsk_common.b.otgintr = 1;
6776+ gintmsk_common.b.modemismatch = 1;
6777+ gintmsk_common.b.disconnect = 1;
6778+ gintmsk_common.b.usbsuspend = 1;
6779+ /** @todo: The port interrupt occurs while in device
6780+ * mode. Added code to CIL to clear the interrupt for now!
6781+ */
6782+ gintmsk_common.b.portintr = 1;
6783+
6784+ gintsts.d32 = dwc_read_reg32(&core_if->core_global_regs->gintsts);
6785+ gintmsk.d32 = dwc_read_reg32(&core_if->core_global_regs->gintmsk);
6786+#ifdef DEBUG
6787+ /* if any common interrupts set */
6788+ if (gintsts.d32 & gintmsk_common.d32) {
6789+ DWC_DEBUGPL(DBG_ANY, "gintsts=%08x gintmsk=%08x\n",
6790+ gintsts.d32, gintmsk.d32);
6791+ }
6792+#endif
6793+
6794+ return ((gintsts.d32 & gintmsk.d32) & gintmsk_common.d32);
6795+
6796+}
6797+
6798+/**
6799+ * Common interrupt handler.
6800+ *
6801+ * The common interrupts are those that occur in both Host and Device mode.
6802+ * This handler handles the following interrupts:
6803+ * - Mode Mismatch Interrupt
6804+ * - Disconnect Interrupt
6805+ * - OTG Interrupt
6806+ * - Connector ID Status Change Interrupt
6807+ * - Session Request Interrupt.
6808+ * - Resume / Remote Wakeup Detected Interrupt.
6809+ *
6810+ */
6811+int32_t dwc_otg_handle_common_intr(dwc_otg_core_if_t *core_if)
6812+{
6813+ int retval = 0;
6814+ gintsts_data_t gintsts;
6815+
6816+ gintsts.d32 = dwc_otg_read_common_intr(core_if);
6817+
6818+ if (gintsts.b.modemismatch) {
6819+ retval |= dwc_otg_handle_mode_mismatch_intr(core_if);
6820+ }
6821+ if (gintsts.b.otgintr) {
6822+ retval |= dwc_otg_handle_otg_intr(core_if);
6823+ }
6824+ if (gintsts.b.conidstschng) {
6825+ retval |= dwc_otg_handle_conn_id_status_change_intr(core_if);
6826+ }
6827+ if (gintsts.b.disconnect) {
6828+ retval |= dwc_otg_handle_disconnect_intr(core_if);
6829+ }
6830+ if (gintsts.b.sessreqintr) {
6831+ retval |= dwc_otg_handle_session_req_intr(core_if);
6832+ }
6833+ if (gintsts.b.wkupintr) {
6834+ retval |= dwc_otg_handle_wakeup_detected_intr(core_if);
6835+ }
6836+ if (gintsts.b.usbsuspend) {
6837+ retval |= dwc_otg_handle_usb_suspend_intr(core_if);
6838+ }
6839+ if (gintsts.b.portintr && dwc_otg_is_device_mode(core_if)) {
6840+ /* The port interrupt occurs while in device mode with HPRT0
6841+ * Port Enable/Disable.
6842+ */
6843+ gintsts.d32 = 0;
6844+ gintsts.b.portintr = 1;
6845+ dwc_write_reg32(&core_if->core_global_regs->gintsts,
6846+ gintsts.d32);
6847+ retval |= 1;
6848+
6849+ }
6850+
6851+ S3C2410X_CLEAR_EINTPEND();
6852+
6853+ return retval;
6854+}
6855--- /dev/null
6856+++ b/drivers/usb/dwc/otg_driver.c
6857@@ -0,0 +1,960 @@
6858+/* ==========================================================================
6859+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_driver.c $
6860+ * $Revision: #63 $
6861+ * $Date: 2008/09/24 $
6862+ * $Change: 1101777 $
6863+ *
6864+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
6865+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
6866+ * otherwise expressly agreed to in writing between Synopsys and you.
6867+ *
6868+ * The Software IS NOT an item of Licensed Software or Licensed Product under
6869+ * any End User Software License Agreement or Agreement for Licensed Product
6870+ * with Synopsys or any supplement thereto. You are permitted to use and
6871+ * redistribute this Software in source and binary forms, with or without
6872+ * modification, provided that redistributions of source code must retain this
6873+ * notice. You may not view, use, disclose, copy or distribute this file or
6874+ * any information contained herein except pursuant to this license grant from
6875+ * Synopsys. If you do not agree with this notice, including the disclaimer
6876+ * below, then you are not authorized to use the Software.
6877+ *
6878+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
6879+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
6880+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
6881+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
6882+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
6883+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
6884+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
6885+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
6886+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
6887+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
6888+ * DAMAGE.
6889+ * ========================================================================== */
6890+
6891+/** @file
6892+ * The dwc_otg_driver module provides the initialization and cleanup entry
6893+ * points for the DWC_otg driver. This module will be dynamically installed
6894+ * after Linux is booted using the insmod command. When the module is
6895+ * installed, the dwc_otg_driver_init function is called. When the module is
6896+ * removed (using rmmod), the dwc_otg_driver_cleanup function is called.
6897+ *
6898+ * This module also defines a data structure for the dwc_otg_driver, which is
6899+ * used in conjunction with the standard ARM lm_device structure. These
6900+ * structures allow the OTG driver to comply with the standard Linux driver
6901+ * model in which devices and drivers are registered with a bus driver. This
6902+ * has the benefit that Linux can expose attributes of the driver and device
6903+ * in its special sysfs file system. Users can then read or write files in
6904+ * this file system to perform diagnostics on the driver components or the
6905+ * device.
6906+ */
6907+
6908+#include <linux/kernel.h>
6909+#include <linux/module.h>
6910+#include <linux/moduleparam.h>
6911+#include <linux/init.h>
6912+#include <linux/device.h>
6913+#include <linux/errno.h>
6914+#include <linux/types.h>
6915+#include <linux/stat.h> /* permission constants */
6916+#include <linux/version.h>
6917+#include <linux/platform_device.h>
6918+#include <linux/io.h>
6919+#include <linux/irq.h>
6920+#include <asm/io.h>
6921+
6922+#include <asm/sizes.h>
6923+#include <mach/pm.h>
6924+
6925+#include "otg_plat.h"
6926+#include "otg_attr.h"
6927+#include "otg_driver.h"
6928+#include "otg_cil.h"
6929+#include "otg_pcd.h"
6930+#include "otg_hcd.h"
6931+
6932+#define DWC_DRIVER_VERSION "2.72a 24-JUN-2008"
6933+#define DWC_DRIVER_DESC "HS OTG USB Controller driver"
6934+
6935+static const char dwc_driver_name[] = "dwc_otg";
6936+
6937+/*-------------------------------------------------------------------------*/
6938+/* Encapsulate the module parameter settings */
6939+
6940+static dwc_otg_core_params_t dwc_otg_module_params = {
6941+ .opt = -1,
6942+ .otg_cap = -1,
6943+ .dma_enable = -1,
6944+ .dma_desc_enable = -1,
6945+ .dma_burst_size = -1,
6946+ .speed = -1,
6947+ .host_support_fs_ls_low_power = -1,
6948+ .host_ls_low_power_phy_clk = -1,
6949+ .enable_dynamic_fifo = -1,
6950+ .data_fifo_size = -1,
6951+ .dev_rx_fifo_size = -1,
6952+ .dev_nperio_tx_fifo_size = -1,
6953+ .dev_perio_tx_fifo_size = {
6954+ /* dev_perio_tx_fifo_size_1 */
6955+ -1,
6956+ -1,
6957+ -1,
6958+ -1,
6959+ -1,
6960+ -1,
6961+ -1,
6962+ -1,
6963+ -1,
6964+ -1,
6965+ -1,
6966+ -1,
6967+ -1,
6968+ -1,
6969+ -1
6970+ /* 15 */
6971+ },
6972+ .host_rx_fifo_size = -1,
6973+ .host_nperio_tx_fifo_size = -1,
6974+ .host_perio_tx_fifo_size = -1,
6975+ .max_transfer_size = -1,
6976+ .max_packet_count = -1,
6977+ .host_channels = -1,
6978+ .dev_endpoints = -1,
6979+ .phy_type = -1,
6980+ .phy_utmi_width = -1,
6981+ .phy_ulpi_ddr = -1,
6982+ .phy_ulpi_ext_vbus = -1,
6983+ .i2c_enable = -1,
6984+ .ulpi_fs_ls = -1,
6985+ .ts_dline = -1,
6986+ .en_multiple_tx_fifo = -1,
6987+ .dev_tx_fifo_size = {
6988+ /* dev_tx_fifo_size */
6989+ -1,
6990+ -1,
6991+ -1,
6992+ -1,
6993+ -1,
6994+ -1,
6995+ -1,
6996+ -1,
6997+ -1,
6998+ -1,
6999+ -1,
7000+ -1,
7001+ -1,
7002+ -1,
7003+ -1
7004+ /* 15 */
7005+ },
7006+ .thr_ctl = -1,
7007+ .tx_thr_length = -1,
7008+ .rx_thr_length = -1,
7009+ .pti_enable = -1,
7010+ .mpi_enable = -1,
7011+};
7012+
7013+/**
7014+ * Global Debug Level Mask.
7015+ */
7016+uint32_t g_dbg_lvl = 0; /* OFF */
7017+
7018+/**
7019+ * This function is called during module intialization to verify that
7020+ * the module parameters are in a valid state.
7021+ */
7022+static int check_parameters(dwc_otg_core_if_t *core_if)
7023+{
7024+ int i;
7025+ int retval = 0;
7026+
7027+/* Checks if the parameter is outside of its valid range of values */
7028+#define DWC_OTG_PARAM_TEST(_param_, _low_, _high_) \
7029+ ((dwc_otg_module_params._param_ < (_low_)) || \
7030+ (dwc_otg_module_params._param_ > (_high_)))
7031+
7032+/* If the parameter has been set by the user, check that the parameter value is
7033+ * within the value range of values. If not, report a module error. */
7034+#define DWC_OTG_PARAM_ERR(_param_, _low_, _high_, _string_) \
7035+ do { \
7036+ if (dwc_otg_module_params._param_ != -1) { \
7037+ if (DWC_OTG_PARAM_TEST(_param_, (_low_), (_high_))) { \
7038+ DWC_ERROR("`%d' invalid for parameter `%s'\n", \
7039+ dwc_otg_module_params._param_, _string_); \
7040+ dwc_otg_module_params._param_ = dwc_param_##_param_##_default; \
7041+ retval++; \
7042+ } \
7043+ } \
7044+ } while (0)
7045+
7046+ DWC_OTG_PARAM_ERR(opt,0,1,"opt");
7047+ DWC_OTG_PARAM_ERR(otg_cap,0,2,"otg_cap");
7048+ DWC_OTG_PARAM_ERR(dma_enable,0,1,"dma_enable");
7049+ DWC_OTG_PARAM_ERR(dma_desc_enable,0,1,"dma_desc_enable");
7050+ DWC_OTG_PARAM_ERR(speed,0,1,"speed");
7051+ DWC_OTG_PARAM_ERR(host_support_fs_ls_low_power,0,1,"host_support_fs_ls_low_power");
7052+ DWC_OTG_PARAM_ERR(host_ls_low_power_phy_clk,0,1,"host_ls_low_power_phy_clk");
7053+ DWC_OTG_PARAM_ERR(enable_dynamic_fifo,0,1,"enable_dynamic_fifo");
7054+ DWC_OTG_PARAM_ERR(data_fifo_size,32,32768,"data_fifo_size");
7055+ DWC_OTG_PARAM_ERR(dev_rx_fifo_size,16,32768,"dev_rx_fifo_size");
7056+ DWC_OTG_PARAM_ERR(dev_nperio_tx_fifo_size,16,32768,"dev_nperio_tx_fifo_size");
7057+ DWC_OTG_PARAM_ERR(host_rx_fifo_size,16,32768,"host_rx_fifo_size");
7058+ DWC_OTG_PARAM_ERR(host_nperio_tx_fifo_size,16,32768,"host_nperio_tx_fifo_size");
7059+ DWC_OTG_PARAM_ERR(host_perio_tx_fifo_size,16,32768,"host_perio_tx_fifo_size");
7060+ DWC_OTG_PARAM_ERR(max_transfer_size,2047,524288,"max_transfer_size");
7061+ DWC_OTG_PARAM_ERR(max_packet_count,15,511,"max_packet_count");
7062+ DWC_OTG_PARAM_ERR(host_channels,1,16,"host_channels");
7063+ DWC_OTG_PARAM_ERR(dev_endpoints,1,15,"dev_endpoints");
7064+ DWC_OTG_PARAM_ERR(phy_type,0,2,"phy_type");
7065+ DWC_OTG_PARAM_ERR(phy_ulpi_ddr,0,1,"phy_ulpi_ddr");
7066+ DWC_OTG_PARAM_ERR(phy_ulpi_ext_vbus,0,1,"phy_ulpi_ext_vbus");
7067+ DWC_OTG_PARAM_ERR(i2c_enable,0,1,"i2c_enable");
7068+ DWC_OTG_PARAM_ERR(ulpi_fs_ls,0,1,"ulpi_fs_ls");
7069+ DWC_OTG_PARAM_ERR(ts_dline,0,1,"ts_dline");
7070+
7071+ if (dwc_otg_module_params.dma_burst_size != -1) {
7072+ if (DWC_OTG_PARAM_TEST(dma_burst_size,1,1) &&
7073+ DWC_OTG_PARAM_TEST(dma_burst_size,4,4) &&
7074+ DWC_OTG_PARAM_TEST(dma_burst_size,8,8) &&
7075+ DWC_OTG_PARAM_TEST(dma_burst_size,16,16) &&
7076+ DWC_OTG_PARAM_TEST(dma_burst_size,32,32) &&
7077+ DWC_OTG_PARAM_TEST(dma_burst_size,64,64) &&
7078+ DWC_OTG_PARAM_TEST(dma_burst_size,128,128) &&
7079+ DWC_OTG_PARAM_TEST(dma_burst_size,256,256)) {
7080+ DWC_ERROR("`%d' invalid for parameter `dma_burst_size'\n",
7081+ dwc_otg_module_params.dma_burst_size);
7082+ dwc_otg_module_params.dma_burst_size = 32;
7083+ retval++;
7084+ }
7085+
7086+ {
7087+ uint8_t brst_sz = 0;
7088+ while(dwc_otg_module_params.dma_burst_size > 1) {
7089+ brst_sz ++;
7090+ dwc_otg_module_params.dma_burst_size >>= 1;
7091+ }
7092+ dwc_otg_module_params.dma_burst_size = brst_sz;
7093+ }
7094+ }
7095+
7096+ if (dwc_otg_module_params.phy_utmi_width != -1) {
7097+ if (DWC_OTG_PARAM_TEST(phy_utmi_width, 8, 8) &&
7098+ DWC_OTG_PARAM_TEST(phy_utmi_width, 16, 16)) {
7099+ DWC_ERROR("`%d' invalid for parameter `phy_utmi_width'\n",
7100+ dwc_otg_module_params.phy_utmi_width);
7101+ dwc_otg_module_params.phy_utmi_width = 16;
7102+ retval++;
7103+ }
7104+ }
7105+
7106+ for (i = 0; i < 15; i++) {
7107+ /** @todo should be like above */
7108+ //DWC_OTG_PARAM_ERR(dev_perio_tx_fifo_size[i], 4, 768, "dev_perio_tx_fifo_size");
7109+ if (dwc_otg_module_params.dev_perio_tx_fifo_size[i] != -1) {
7110+ if (DWC_OTG_PARAM_TEST(dev_perio_tx_fifo_size[i], 4, 768)) {
7111+ DWC_ERROR("`%d' invalid for parameter `%s_%d'\n",
7112+ dwc_otg_module_params.dev_perio_tx_fifo_size[i], "dev_perio_tx_fifo_size", i);
7113+ dwc_otg_module_params.dev_perio_tx_fifo_size[i] = dwc_param_dev_perio_tx_fifo_size_default;
7114+ retval++;
7115+ }
7116+ }
7117+ }
7118+
7119+ DWC_OTG_PARAM_ERR(en_multiple_tx_fifo, 0, 1, "en_multiple_tx_fifo");
7120+
7121+ for (i = 0; i < 15; i++) {
7122+ /** @todo should be like above */
7123+ //DWC_OTG_PARAM_ERR(dev_tx_fifo_size[i], 4, 768, "dev_tx_fifo_size");
7124+ if (dwc_otg_module_params.dev_tx_fifo_size[i] != -1) {
7125+ if (DWC_OTG_PARAM_TEST(dev_tx_fifo_size[i], 4, 768)) {
7126+ DWC_ERROR("`%d' invalid for parameter `%s_%d'\n",
7127+ dwc_otg_module_params.dev_tx_fifo_size[i], "dev_tx_fifo_size", i);
7128+ dwc_otg_module_params.dev_tx_fifo_size[i] = dwc_param_dev_tx_fifo_size_default;
7129+ retval++;
7130+ }
7131+ }
7132+ }
7133+
7134+ DWC_OTG_PARAM_ERR(thr_ctl, 0, 7, "thr_ctl");
7135+ DWC_OTG_PARAM_ERR(tx_thr_length, 8, 128, "tx_thr_length");
7136+ DWC_OTG_PARAM_ERR(rx_thr_length, 8, 128, "rx_thr_length");
7137+
7138+ DWC_OTG_PARAM_ERR(pti_enable,0,1,"pti_enable");
7139+ DWC_OTG_PARAM_ERR(mpi_enable,0,1,"mpi_enable");
7140+
7141+ /* At this point, all module parameters that have been set by the user
7142+ * are valid, and those that have not are left unset. Now set their
7143+ * default values and/or check the parameters against the hardware
7144+ * configurations of the OTG core. */
7145+
7146+/* This sets the parameter to the default value if it has not been set by the
7147+ * user */
7148+#define DWC_OTG_PARAM_SET_DEFAULT(_param_) \
7149+ ({ \
7150+ int changed = 1; \
7151+ if (dwc_otg_module_params._param_ == -1) { \
7152+ changed = 0; \
7153+ dwc_otg_module_params._param_ = dwc_param_##_param_##_default; \
7154+ } \
7155+ changed; \
7156+ })
7157+
7158+/* This checks the macro agains the hardware configuration to see if it is
7159+ * valid. It is possible that the default value could be invalid. In this
7160+ * case, it will report a module error if the user touched the parameter.
7161+ * Otherwise it will adjust the value without any error. */
7162+#define DWC_OTG_PARAM_CHECK_VALID(_param_, _str_, _is_valid_, _set_valid_) \
7163+ ({ \
7164+ int changed = DWC_OTG_PARAM_SET_DEFAULT(_param_); \
7165+ int error = 0; \
7166+ if (!(_is_valid_)) { \
7167+ if (changed) { \
7168+ DWC_ERROR("`%d' invalid for parameter `%s'. Check HW configuration.\n", dwc_otg_module_params._param_, _str_); \
7169+ error = 1; \
7170+ } \
7171+ dwc_otg_module_params._param_ = (_set_valid_); \
7172+ } \
7173+ error; \
7174+ })
7175+
7176+ /* OTG Cap */
7177+ retval += DWC_OTG_PARAM_CHECK_VALID(otg_cap, "otg_cap",
7178+ ({
7179+ int valid;
7180+ valid = 1;
7181+ switch (dwc_otg_module_params.otg_cap) {
7182+ case DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE:
7183+ if (core_if->hwcfg2.b.op_mode != DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
7184+ valid = 0;
7185+ break;
7186+ case DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE:
7187+ if ((core_if->hwcfg2.b.op_mode != DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG) &&
7188+ (core_if->hwcfg2.b.op_mode != DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG) &&
7189+ (core_if->hwcfg2.b.op_mode != DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE) &&
7190+ (core_if->hwcfg2.b.op_mode != DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)) {
7191+ valid = 0;
7192+ }
7193+ break;
7194+ case DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE:
7195+ /* always valid */
7196+ break;
7197+ }
7198+ valid;
7199+ }),
7200+ (((core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG) ||
7201+ (core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG) ||
7202+ (core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE) ||
7203+ (core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)) ?
7204+ DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE :
7205+ DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE));
7206+
7207+ retval += DWC_OTG_PARAM_CHECK_VALID(dma_enable, "dma_enable",
7208+ ((dwc_otg_module_params.dma_enable == 1) && (core_if->hwcfg2.b.architecture == 0)) ? 0 : 1,
7209+ 0);
7210+
7211+ retval += DWC_OTG_PARAM_CHECK_VALID(dma_desc_enable, "dma_desc_enable",
7212+ ((dwc_otg_module_params.dma_desc_enable == 1) &&
7213+ ((dwc_otg_module_params.dma_enable == 0) || (core_if->hwcfg4.b.desc_dma == 0))) ? 0 : 1,
7214+ 0);
7215+
7216+ retval += DWC_OTG_PARAM_CHECK_VALID(opt, "opt", 1, 0);
7217+
7218+ DWC_OTG_PARAM_SET_DEFAULT(dma_burst_size);
7219+
7220+ retval += DWC_OTG_PARAM_CHECK_VALID(host_support_fs_ls_low_power,
7221+ "host_support_fs_ls_low_power",
7222+ 1, 0);
7223+
7224+ retval += DWC_OTG_PARAM_CHECK_VALID(enable_dynamic_fifo,
7225+ "enable_dynamic_fifo",
7226+ ((dwc_otg_module_params.enable_dynamic_fifo == 0) ||
7227+ (core_if->hwcfg2.b.dynamic_fifo == 1)), 0);
7228+
7229+ retval += DWC_OTG_PARAM_CHECK_VALID(data_fifo_size,
7230+ "data_fifo_size",
7231+ (dwc_otg_module_params.data_fifo_size <= core_if->hwcfg3.b.dfifo_depth),
7232+ core_if->hwcfg3.b.dfifo_depth);
7233+
7234+ retval += DWC_OTG_PARAM_CHECK_VALID(dev_rx_fifo_size,
7235+ "dev_rx_fifo_size",
7236+ (dwc_otg_module_params.dev_rx_fifo_size <= dwc_read_reg32(&core_if->core_global_regs->grxfsiz)),
7237+ dwc_read_reg32(&core_if->core_global_regs->grxfsiz));
7238+
7239+ retval += DWC_OTG_PARAM_CHECK_VALID(dev_nperio_tx_fifo_size,
7240+ "dev_nperio_tx_fifo_size",
7241+ (dwc_otg_module_params.dev_nperio_tx_fifo_size <= (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16)),
7242+ (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16));
7243+
7244+ retval += DWC_OTG_PARAM_CHECK_VALID(host_rx_fifo_size,
7245+ "host_rx_fifo_size",
7246+ (dwc_otg_module_params.host_rx_fifo_size <= dwc_read_reg32(&core_if->core_global_regs->grxfsiz)),
7247+ dwc_read_reg32(&core_if->core_global_regs->grxfsiz));
7248+
7249+ retval += DWC_OTG_PARAM_CHECK_VALID(host_nperio_tx_fifo_size,
7250+ "host_nperio_tx_fifo_size",
7251+ (dwc_otg_module_params.host_nperio_tx_fifo_size <= (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16)),
7252+ (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16));
7253+
7254+ retval += DWC_OTG_PARAM_CHECK_VALID(host_perio_tx_fifo_size,
7255+ "host_perio_tx_fifo_size",
7256+ (dwc_otg_module_params.host_perio_tx_fifo_size <= ((dwc_read_reg32(&core_if->core_global_regs->hptxfsiz) >> 16))),
7257+ ((dwc_read_reg32(&core_if->core_global_regs->hptxfsiz) >> 16)));
7258+
7259+ retval += DWC_OTG_PARAM_CHECK_VALID(max_transfer_size,
7260+ "max_transfer_size",
7261+ (dwc_otg_module_params.max_transfer_size < (1 << (core_if->hwcfg3.b.xfer_size_cntr_width + 11))),
7262+ ((1 << (core_if->hwcfg3.b.xfer_size_cntr_width + 11)) - 1));
7263+
7264+ retval += DWC_OTG_PARAM_CHECK_VALID(max_packet_count,
7265+ "max_packet_count",
7266+ (dwc_otg_module_params.max_packet_count < (1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4))),
7267+ ((1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4)) - 1));
7268+
7269+ retval += DWC_OTG_PARAM_CHECK_VALID(host_channels,
7270+ "host_channels",
7271+ (dwc_otg_module_params.host_channels <= (core_if->hwcfg2.b.num_host_chan + 1)),
7272+ (core_if->hwcfg2.b.num_host_chan + 1));
7273+
7274+ retval += DWC_OTG_PARAM_CHECK_VALID(dev_endpoints,
7275+ "dev_endpoints",
7276+ (dwc_otg_module_params.dev_endpoints <= (core_if->hwcfg2.b.num_dev_ep)),
7277+ core_if->hwcfg2.b.num_dev_ep);
7278+
7279+/*
7280+ * Define the following to disable the FS PHY Hardware checking. This is for
7281+ * internal testing only.
7282+ *
7283+ * #define NO_FS_PHY_HW_CHECKS
7284+ */
7285+
7286+#ifdef NO_FS_PHY_HW_CHECKS
7287+ retval += DWC_OTG_PARAM_CHECK_VALID(phy_type,
7288+ "phy_type", 1, 0);
7289+#else
7290+ retval += DWC_OTG_PARAM_CHECK_VALID(phy_type,
7291+ "phy_type",
7292+ ({
7293+ int valid = 0;
7294+ if ((dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_UTMI) &&
7295+ ((core_if->hwcfg2.b.hs_phy_type == 1) ||
7296+ (core_if->hwcfg2.b.hs_phy_type == 3))) {
7297+ valid = 1;
7298+ }
7299+ else if ((dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_ULPI) &&
7300+ ((core_if->hwcfg2.b.hs_phy_type == 2) ||
7301+ (core_if->hwcfg2.b.hs_phy_type == 3))) {
7302+ valid = 1;
7303+ }
7304+ else if ((dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_FS) &&
7305+ (core_if->hwcfg2.b.fs_phy_type == 1)) {
7306+ valid = 1;
7307+ }
7308+ valid;
7309+ }),
7310+ ({
7311+ int set = DWC_PHY_TYPE_PARAM_FS;
7312+ if (core_if->hwcfg2.b.hs_phy_type) {
7313+ if ((core_if->hwcfg2.b.hs_phy_type == 3) ||
7314+ (core_if->hwcfg2.b.hs_phy_type == 1)) {
7315+ set = DWC_PHY_TYPE_PARAM_UTMI;
7316+ }
7317+ else {
7318+ set = DWC_PHY_TYPE_PARAM_ULPI;
7319+ }
7320+ }
7321+ set;
7322+ }));
7323+#endif
7324+
7325+ retval += DWC_OTG_PARAM_CHECK_VALID(speed, "speed",
7326+ (dwc_otg_module_params.speed == 0) && (dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_FS) ? 0 : 1,
7327+ dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_FS ? 1 : 0);
7328+
7329+ retval += DWC_OTG_PARAM_CHECK_VALID(host_ls_low_power_phy_clk,
7330+ "host_ls_low_power_phy_clk",
7331+ ((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),
7332+ ((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));
7333+
7334+ DWC_OTG_PARAM_SET_DEFAULT(phy_ulpi_ddr);
7335+ DWC_OTG_PARAM_SET_DEFAULT(phy_ulpi_ext_vbus);
7336+ DWC_OTG_PARAM_SET_DEFAULT(phy_utmi_width);
7337+ DWC_OTG_PARAM_SET_DEFAULT(ulpi_fs_ls);
7338+ DWC_OTG_PARAM_SET_DEFAULT(ts_dline);
7339+
7340+#ifdef NO_FS_PHY_HW_CHECKS
7341+ retval += DWC_OTG_PARAM_CHECK_VALID(i2c_enable, "i2c_enable", 1, 0);
7342+#else
7343+ retval += DWC_OTG_PARAM_CHECK_VALID(i2c_enable,
7344+ "i2c_enable",
7345+ (dwc_otg_module_params.i2c_enable == 1) && (core_if->hwcfg3.b.i2c == 0) ? 0 : 1,
7346+ 0);
7347+#endif
7348+
7349+ for (i = 0; i < 15; i++) {
7350+ int changed = 1;
7351+ int error = 0;
7352+
7353+ if (dwc_otg_module_params.dev_perio_tx_fifo_size[i] == -1) {
7354+ changed = 0;
7355+ dwc_otg_module_params.dev_perio_tx_fifo_size[i] = dwc_param_dev_perio_tx_fifo_size_default;
7356+ }
7357+ if (!(dwc_otg_module_params.dev_perio_tx_fifo_size[i] <= (dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[i])))) {
7358+ if (changed) {
7359+ 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);
7360+ error = 1;
7361+ }
7362+ dwc_otg_module_params.dev_perio_tx_fifo_size[i] = dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[i]);
7363+ }
7364+ retval += error;
7365+ }
7366+
7367+ retval += DWC_OTG_PARAM_CHECK_VALID(en_multiple_tx_fifo, "en_multiple_tx_fifo",
7368+ ((dwc_otg_module_params.en_multiple_tx_fifo == 1) && (core_if->hwcfg4.b.ded_fifo_en == 0)) ? 0 : 1,
7369+ 0);
7370+
7371+ for (i = 0; i < 15; i++) {
7372+ int changed = 1;
7373+ int error = 0;
7374+
7375+ if (dwc_otg_module_params.dev_tx_fifo_size[i] == -1) {
7376+ changed = 0;
7377+ dwc_otg_module_params.dev_tx_fifo_size[i] = dwc_param_dev_tx_fifo_size_default;
7378+ }
7379+ if (!(dwc_otg_module_params.dev_tx_fifo_size[i] <= (dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[i])))) {
7380+ if (changed) {
7381+ DWC_ERROR("%d' invalid for parameter `dev_perio_fifo_size_%d'. Check HW configuration.\n", dwc_otg_module_params.dev_tx_fifo_size[i], i);
7382+ error = 1;
7383+ }
7384+ dwc_otg_module_params.dev_tx_fifo_size[i] = dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[i]);
7385+ }
7386+ retval += error;
7387+ }
7388+
7389+ retval += DWC_OTG_PARAM_CHECK_VALID(thr_ctl, "thr_ctl",
7390+ ((dwc_otg_module_params.thr_ctl != 0) && ((dwc_otg_module_params.dma_enable == 0) || (core_if->hwcfg4.b.ded_fifo_en == 0))) ? 0 : 1,
7391+ 0);
7392+
7393+ DWC_OTG_PARAM_SET_DEFAULT(tx_thr_length);
7394+ DWC_OTG_PARAM_SET_DEFAULT(rx_thr_length);
7395+
7396+ retval += DWC_OTG_PARAM_CHECK_VALID(pti_enable, "pti_enable",
7397+ ((dwc_otg_module_params.pti_enable == 0) || ((dwc_otg_module_params.pti_enable == 1) && (core_if->snpsid >= 0x4F54272A))) ? 1 : 0,
7398+ 0);
7399+
7400+ retval += DWC_OTG_PARAM_CHECK_VALID(mpi_enable, "mpi_enable",
7401+ ((dwc_otg_module_params.mpi_enable == 0) || ((dwc_otg_module_params.mpi_enable == 1) && (core_if->hwcfg2.b.multi_proc_int == 1))) ? 1 : 0,
7402+ 0);
7403+ return retval;
7404+}
7405+
7406+/**
7407+ * This function is the top level interrupt handler for the Common
7408+ * (Device and host modes) interrupts.
7409+ */
7410+static irqreturn_t dwc_otg_common_irq(int irq, void *dev)
7411+{
7412+ dwc_otg_device_t *otg_dev = dev;
7413+ int32_t retval = IRQ_NONE;
7414+
7415+ retval = dwc_otg_handle_common_intr(otg_dev->core_if);
7416+ return IRQ_RETVAL(retval);
7417+}
7418+
7419+/**
7420+ * This function is called when a lm_device is unregistered with the
7421+ * dwc_otg_driver. This happens, for example, when the rmmod command is
7422+ * executed. The device may or may not be electrically present. If it is
7423+ * present, the driver stops device processing. Any resources used on behalf
7424+ * of this device are freed.
7425+ *
7426+ * @param[in] lmdev
7427+ */
7428+static int __devexit dwc_otg_driver_remove(struct platform_device *pdev)
7429+{
7430+ dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev);
7431+ DWC_DEBUGPL(DBG_ANY, "%s(%p)\n", __func__, pdev);
7432+
7433+ if (!otg_dev) {
7434+ /* Memory allocation for the dwc_otg_device failed. */
7435+ DWC_DEBUGPL(DBG_ANY, "%s: otg_dev NULL!\n", __func__);
7436+ return 0;
7437+ }
7438+
7439+ /*
7440+ * Free the IRQ
7441+ */
7442+ if (otg_dev->common_irq_installed) {
7443+ free_irq(otg_dev->irq, otg_dev);
7444+ }
7445+
7446+#ifndef DWC_DEVICE_ONLY
7447+ if (otg_dev->hcd) {
7448+ dwc_otg_hcd_remove(pdev);
7449+ } else {
7450+ DWC_DEBUGPL(DBG_ANY, "%s: otg_dev->hcd NULL!\n", __func__);
7451+ return 0;
7452+ }
7453+#endif
7454+
7455+#ifndef DWC_HOST_ONLY
7456+ if (otg_dev->pcd) {
7457+ dwc_otg_pcd_remove(pdev);
7458+ }
7459+#endif
7460+ if (otg_dev->core_if) {
7461+ dwc_otg_cil_remove(otg_dev->core_if);
7462+ }
7463+
7464+ /*
7465+ * Remove the device attributes
7466+ */
7467+ dwc_otg_attr_remove(pdev);
7468+
7469+ /*
7470+ * Return the memory.
7471+ */
7472+ if (otg_dev->base) {
7473+ iounmap(otg_dev->base);
7474+ }
7475+ kfree(otg_dev);
7476+
7477+ /*
7478+ * Clear the drvdata pointer.
7479+ */
7480+ platform_set_drvdata(pdev, 0);
7481+
7482+ return 0;
7483+}
7484+
7485+/**
7486+ * This function is called when an lm_device is bound to a
7487+ * dwc_otg_driver. It creates the driver components required to
7488+ * control the device (CIL, HCD, and PCD) and it initializes the
7489+ * device. The driver components are stored in a dwc_otg_device
7490+ * structure. A reference to the dwc_otg_device is saved in the
7491+ * lm_device. This allows the driver to access the dwc_otg_device
7492+ * structure on subsequent calls to driver methods for this device.
7493+ *
7494+ * @param[in] lmdev lm_device definition
7495+ */
7496+static int __devinit dwc_otg_driver_probe(struct platform_device *pdev)
7497+{
7498+ struct device *dev = &pdev->dev;
7499+ int retval = 0;
7500+ uint32_t snpsid;
7501+ dwc_otg_device_t *dwc_otg_device;
7502+ struct resource *res;
7503+
7504+ dev_dbg(dev, "dwc_otg_driver_probe(%p)\n", pdev);
7505+
7506+ dwc_otg_device = kmalloc(sizeof(dwc_otg_device_t), GFP_KERNEL);
7507+
7508+ if (!dwc_otg_device) {
7509+ dev_err(dev, "kmalloc of dwc_otg_device failed\n");
7510+ retval = -ENOMEM;
7511+ goto fail;
7512+ }
7513+
7514+ memset(dwc_otg_device, 0, sizeof(*dwc_otg_device));
7515+ dwc_otg_device->reg_offset = 0xFFFFFFFF;
7516+
7517+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
7518+ if (!res) {
7519+ dev_err(dev, "Found OTG with no register addr.\n");
7520+ retval = -ENODEV;
7521+ goto fail;
7522+ }
7523+ dwc_otg_device->rsrc_start = res->start;
7524+ dwc_otg_device->rsrc_len = res->end - res->start + 1;
7525+
7526+ dwc_otg_device->base = ioremap(dwc_otg_device->rsrc_start, dwc_otg_device->rsrc_len);
7527+
7528+ if (!dwc_otg_device->base) {
7529+ dev_err(dev, "ioremap() failed\n");
7530+ retval = -ENOMEM;
7531+ goto fail;
7532+ }
7533+ dev_dbg(dev, "base=0x%08x\n", (unsigned)dwc_otg_device->base);
7534+
7535+ /*
7536+ * Attempt to ensure this device is really a DWC_otg Controller.
7537+ * Read and verify the SNPSID register contents. The value should be
7538+ * 0x45F42XXX, which corresponds to "OT2", as in "OTG version 2.XX".
7539+ */
7540+ snpsid = dwc_read_reg32((uint32_t *)((uint8_t *)dwc_otg_device->base + 0x40));
7541+
7542+ if ((snpsid & 0xFFFFF000) != OTG_CORE_REV_2_00) {
7543+ dev_err(dev, "Bad value for SNPSID: 0x%08x\n", snpsid);
7544+ retval = -EINVAL;
7545+ goto fail;
7546+ }
7547+
7548+ DWC_PRINT("Core Release: %x.%x%x%x\n",
7549+ (snpsid >> 12 & 0xF),
7550+ (snpsid >> 8 & 0xF),
7551+ (snpsid >> 4 & 0xF),
7552+ (snpsid & 0xF));
7553+
7554+ /*
7555+ * Initialize driver data to point to the global DWC_otg
7556+ * Device structure.
7557+ */
7558+ platform_set_drvdata(pdev, dwc_otg_device);
7559+
7560+ dev_dbg(dev, "dwc_otg_device=0x%p\n", dwc_otg_device);
7561+
7562+ dwc_otg_device->core_if = dwc_otg_cil_init(dwc_otg_device->base,
7563+ &dwc_otg_module_params);
7564+
7565+ dwc_otg_device->core_if->snpsid = snpsid;
7566+
7567+ if (!dwc_otg_device->core_if) {
7568+ dev_err(dev, "CIL initialization failed!\n");
7569+ retval = -ENOMEM;
7570+ goto fail;
7571+ }
7572+
7573+ /*
7574+ * Validate parameter values.
7575+ */
7576+ if (check_parameters(dwc_otg_device->core_if)) {
7577+ retval = -EINVAL;
7578+ goto fail;
7579+ }
7580+
7581+ /*
7582+ * Create Device Attributes in sysfs
7583+ */
7584+ dwc_otg_attr_create(pdev);
7585+
7586+ /*
7587+ * Disable the global interrupt until all the interrupt
7588+ * handlers are installed.
7589+ */
7590+ dwc_otg_disable_global_interrupts(dwc_otg_device->core_if);
7591+
7592+ /*
7593+ * Install the interrupt handler for the common interrupts before
7594+ * enabling common interrupts in core_init below.
7595+ */
7596+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
7597+ if (!res) {
7598+ dev_err(dev, "Fount OTG with to IRQ.\n");
7599+ retval = -ENODEV;
7600+ goto fail;
7601+ }
7602+ dwc_otg_device->irq = res->start;
7603+
7604+ retval = request_irq(res->start, dwc_otg_common_irq,
7605+ IRQF_SHARED, "dwc_otg", dwc_otg_device);
7606+ if (retval) {
7607+ DWC_ERROR("request of irq%d failed\n", res->start);
7608+ retval = -EBUSY;
7609+ goto fail;
7610+ } else {
7611+ dwc_otg_device->common_irq_installed = 1;
7612+ }
7613+
7614+ /*
7615+ * Initialize the DWC_otg core.
7616+ */
7617+ dwc_otg_core_init(dwc_otg_device->core_if);
7618+
7619+#ifndef DWC_HOST_ONLY
7620+ /*
7621+ * Initialize the PCD
7622+ */
7623+ retval = dwc_otg_pcd_init(pdev);
7624+ if (retval != 0) {
7625+ DWC_ERROR("dwc_otg_pcd_init failed\n");
7626+ dwc_otg_device->pcd = NULL;
7627+ goto fail;
7628+ }
7629+#endif
7630+#ifndef DWC_DEVICE_ONLY
7631+ /*
7632+ * Initialize the HCD
7633+ */
7634+ retval = dwc_otg_hcd_init(pdev);
7635+ if (retval != 0) {
7636+ DWC_ERROR("dwc_otg_hcd_init failed\n");
7637+ dwc_otg_device->hcd = NULL;
7638+ goto fail;
7639+ }
7640+#endif
7641+
7642+ /*
7643+ * Enable the global interrupt after all the interrupt
7644+ * handlers are installed.
7645+ */
7646+ dwc_otg_enable_global_interrupts(dwc_otg_device->core_if);
7647+
7648+ return 0;
7649+
7650+ fail:
7651+ dwc_otg_driver_remove(pdev);
7652+ return retval;
7653+}
7654+
7655+static struct platform_driver dwc_otg_platform_driver = {
7656+ .driver.name = "dwc_otg",
7657+ .probe = dwc_otg_driver_probe,
7658+ .remove = dwc_otg_driver_remove,
7659+};
7660+
7661+static int __init dwc_otg_init_module(void)
7662+{
7663+ return platform_driver_register(&dwc_otg_platform_driver);
7664+}
7665+
7666+static void __exit dwc_otg_cleanup_module(void)
7667+{
7668+ platform_driver_unregister(&dwc_otg_platform_driver);
7669+}
7670+
7671+module_init(dwc_otg_init_module);
7672+module_exit(dwc_otg_cleanup_module);
7673+
7674+/**
7675+ * This function is called when the driver is removed from the kernel
7676+ * with the rmmod command. The driver unregisters itself with its bus
7677+ * driver.
7678+ *
7679+ */
7680+
7681+MODULE_DESCRIPTION(DWC_DRIVER_DESC);
7682+MODULE_AUTHOR("Synopsys Inc.");
7683+MODULE_LICENSE("GPL");
7684+
7685+module_param_named(otg_cap, dwc_otg_module_params.otg_cap, int, 0444);
7686+MODULE_PARM_DESC(otg_cap, "OTG Capabilities 0=HNP&SRP 1=SRP Only 2=None");
7687+module_param_named(opt, dwc_otg_module_params.opt, int, 0444);
7688+MODULE_PARM_DESC(opt, "OPT Mode");
7689+module_param_named(dma_enable, dwc_otg_module_params.dma_enable, int, 0444);
7690+MODULE_PARM_DESC(dma_enable, "DMA Mode 0=Slave 1=DMA enabled");
7691+
7692+module_param_named(dma_desc_enable, dwc_otg_module_params.dma_desc_enable, int, 0444);
7693+MODULE_PARM_DESC(dma_desc_enable, "DMA Desc Mode 0=Address DMA 1=DMA Descriptor enabled");
7694+
7695+module_param_named(dma_burst_size, dwc_otg_module_params.dma_burst_size, int, 0444);
7696+MODULE_PARM_DESC(dma_burst_size, "DMA Burst Size 1, 4, 8, 16, 32, 64, 128, 256");
7697+module_param_named(speed, dwc_otg_module_params.speed, int, 0444);
7698+MODULE_PARM_DESC(speed, "Speed 0=High Speed 1=Full Speed");
7699+module_param_named(host_support_fs_ls_low_power, dwc_otg_module_params.host_support_fs_ls_low_power, int, 0444);
7700+MODULE_PARM_DESC(host_support_fs_ls_low_power, "Support Low Power w/FS or LS 0=Support 1=Don't Support");
7701+module_param_named(host_ls_low_power_phy_clk, dwc_otg_module_params.host_ls_low_power_phy_clk, int, 0444);
7702+MODULE_PARM_DESC(host_ls_low_power_phy_clk, "Low Speed Low Power Clock 0=48Mhz 1=6Mhz");
7703+module_param_named(enable_dynamic_fifo, dwc_otg_module_params.enable_dynamic_fifo, int, 0444);
7704+MODULE_PARM_DESC(enable_dynamic_fifo, "0=cC Setting 1=Allow Dynamic Sizing");
7705+module_param_named(data_fifo_size, dwc_otg_module_params.data_fifo_size, int, 0444);
7706+MODULE_PARM_DESC(data_fifo_size, "Total number of words in the data FIFO memory 32-32768");
7707+module_param_named(dev_rx_fifo_size, dwc_otg_module_params.dev_rx_fifo_size, int, 0444);
7708+MODULE_PARM_DESC(dev_rx_fifo_size, "Number of words in the Rx FIFO 16-32768");
7709+module_param_named(dev_nperio_tx_fifo_size, dwc_otg_module_params.dev_nperio_tx_fifo_size, int, 0444);
7710+MODULE_PARM_DESC(dev_nperio_tx_fifo_size, "Number of words in the non-periodic Tx FIFO 16-32768");
7711+module_param_named(dev_perio_tx_fifo_size_1, dwc_otg_module_params.dev_perio_tx_fifo_size[0], int, 0444);
7712+MODULE_PARM_DESC(dev_perio_tx_fifo_size_1, "Number of words in the periodic Tx FIFO 4-768");
7713+module_param_named(dev_perio_tx_fifo_size_2, dwc_otg_module_params.dev_perio_tx_fifo_size[1], int, 0444);
7714+MODULE_PARM_DESC(dev_perio_tx_fifo_size_2, "Number of words in the periodic Tx FIFO 4-768");
7715+module_param_named(dev_perio_tx_fifo_size_3, dwc_otg_module_params.dev_perio_tx_fifo_size[2], int, 0444);
7716+MODULE_PARM_DESC(dev_perio_tx_fifo_size_3, "Number of words in the periodic Tx FIFO 4-768");
7717+module_param_named(dev_perio_tx_fifo_size_4, dwc_otg_module_params.dev_perio_tx_fifo_size[3], int, 0444);
7718+MODULE_PARM_DESC(dev_perio_tx_fifo_size_4, "Number of words in the periodic Tx FIFO 4-768");
7719+module_param_named(dev_perio_tx_fifo_size_5, dwc_otg_module_params.dev_perio_tx_fifo_size[4], int, 0444);
7720+MODULE_PARM_DESC(dev_perio_tx_fifo_size_5, "Number of words in the periodic Tx FIFO 4-768");
7721+module_param_named(dev_perio_tx_fifo_size_6, dwc_otg_module_params.dev_perio_tx_fifo_size[5], int, 0444);
7722+MODULE_PARM_DESC(dev_perio_tx_fifo_size_6, "Number of words in the periodic Tx FIFO 4-768");
7723+module_param_named(dev_perio_tx_fifo_size_7, dwc_otg_module_params.dev_perio_tx_fifo_size[6], int, 0444);
7724+MODULE_PARM_DESC(dev_perio_tx_fifo_size_7, "Number of words in the periodic Tx FIFO 4-768");
7725+module_param_named(dev_perio_tx_fifo_size_8, dwc_otg_module_params.dev_perio_tx_fifo_size[7], int, 0444);
7726+MODULE_PARM_DESC(dev_perio_tx_fifo_size_8, "Number of words in the periodic Tx FIFO 4-768");
7727+module_param_named(dev_perio_tx_fifo_size_9, dwc_otg_module_params.dev_perio_tx_fifo_size[8], int, 0444);
7728+MODULE_PARM_DESC(dev_perio_tx_fifo_size_9, "Number of words in the periodic Tx FIFO 4-768");
7729+module_param_named(dev_perio_tx_fifo_size_10, dwc_otg_module_params.dev_perio_tx_fifo_size[9], int, 0444);
7730+MODULE_PARM_DESC(dev_perio_tx_fifo_size_10, "Number of words in the periodic Tx FIFO 4-768");
7731+module_param_named(dev_perio_tx_fifo_size_11, dwc_otg_module_params.dev_perio_tx_fifo_size[10], int, 0444);
7732+MODULE_PARM_DESC(dev_perio_tx_fifo_size_11, "Number of words in the periodic Tx FIFO 4-768");
7733+module_param_named(dev_perio_tx_fifo_size_12, dwc_otg_module_params.dev_perio_tx_fifo_size[11], int, 0444);
7734+MODULE_PARM_DESC(dev_perio_tx_fifo_size_12, "Number of words in the periodic Tx FIFO 4-768");
7735+module_param_named(dev_perio_tx_fifo_size_13, dwc_otg_module_params.dev_perio_tx_fifo_size[12], int, 0444);
7736+MODULE_PARM_DESC(dev_perio_tx_fifo_size_13, "Number of words in the periodic Tx FIFO 4-768");
7737+module_param_named(dev_perio_tx_fifo_size_14, dwc_otg_module_params.dev_perio_tx_fifo_size[13], int, 0444);
7738+MODULE_PARM_DESC(dev_perio_tx_fifo_size_14, "Number of words in the periodic Tx FIFO 4-768");
7739+module_param_named(dev_perio_tx_fifo_size_15, dwc_otg_module_params.dev_perio_tx_fifo_size[14], int, 0444);
7740+MODULE_PARM_DESC(dev_perio_tx_fifo_size_15, "Number of words in the periodic Tx FIFO 4-768");
7741+module_param_named(host_rx_fifo_size, dwc_otg_module_params.host_rx_fifo_size, int, 0444);
7742+MODULE_PARM_DESC(host_rx_fifo_size, "Number of words in the Rx FIFO 16-32768");
7743+module_param_named(host_nperio_tx_fifo_size, dwc_otg_module_params.host_nperio_tx_fifo_size, int, 0444);
7744+MODULE_PARM_DESC(host_nperio_tx_fifo_size, "Number of words in the non-periodic Tx FIFO 16-32768");
7745+module_param_named(host_perio_tx_fifo_size, dwc_otg_module_params.host_perio_tx_fifo_size, int, 0444);
7746+MODULE_PARM_DESC(host_perio_tx_fifo_size, "Number of words in the host periodic Tx FIFO 16-32768");
7747+module_param_named(max_transfer_size, dwc_otg_module_params.max_transfer_size, int, 0444);
7748+/** @todo Set the max to 512K, modify checks */
7749+MODULE_PARM_DESC(max_transfer_size, "The maximum transfer size supported in bytes 2047-65535");
7750+module_param_named(max_packet_count, dwc_otg_module_params.max_packet_count, int, 0444);
7751+MODULE_PARM_DESC(max_packet_count, "The maximum number of packets in a transfer 15-511");
7752+module_param_named(host_channels, dwc_otg_module_params.host_channels, int, 0444);
7753+MODULE_PARM_DESC(host_channels, "The number of host channel registers to use 1-16");
7754+module_param_named(dev_endpoints, dwc_otg_module_params.dev_endpoints, int, 0444);
7755+MODULE_PARM_DESC(dev_endpoints, "The number of endpoints in addition to EP0 available for device mode 1-15");
7756+module_param_named(phy_type, dwc_otg_module_params.phy_type, int, 0444);
7757+MODULE_PARM_DESC(phy_type, "0=Reserved 1=UTMI+ 2=ULPI");
7758+module_param_named(phy_utmi_width, dwc_otg_module_params.phy_utmi_width, int, 0444);
7759+MODULE_PARM_DESC(phy_utmi_width, "Specifies the UTMI+ Data Width 8 or 16 bits");
7760+module_param_named(phy_ulpi_ddr, dwc_otg_module_params.phy_ulpi_ddr, int, 0444);
7761+MODULE_PARM_DESC(phy_ulpi_ddr, "ULPI at double or single data rate 0=Single 1=Double");
7762+module_param_named(phy_ulpi_ext_vbus, dwc_otg_module_params.phy_ulpi_ext_vbus, int, 0444);
7763+MODULE_PARM_DESC(phy_ulpi_ext_vbus, "ULPI PHY using internal or external vbus 0=Internal");
7764+module_param_named(i2c_enable, dwc_otg_module_params.i2c_enable, int, 0444);
7765+MODULE_PARM_DESC(i2c_enable, "FS PHY Interface");
7766+module_param_named(ulpi_fs_ls, dwc_otg_module_params.ulpi_fs_ls, int, 0444);
7767+MODULE_PARM_DESC(ulpi_fs_ls, "ULPI PHY FS/LS mode only");
7768+module_param_named(ts_dline, dwc_otg_module_params.ts_dline, int, 0444);
7769+MODULE_PARM_DESC(ts_dline, "Term select Dline pulsing for all PHYs");
7770+module_param_named(debug, g_dbg_lvl, int, 0444);
7771+MODULE_PARM_DESC(debug, "");
7772+
7773+module_param_named(en_multiple_tx_fifo, dwc_otg_module_params.en_multiple_tx_fifo, int, 0444);
7774+MODULE_PARM_DESC(en_multiple_tx_fifo, "Dedicated Non Periodic Tx FIFOs 0=disabled 1=enabled");
7775+module_param_named(dev_tx_fifo_size_1, dwc_otg_module_params.dev_tx_fifo_size[0], int, 0444);
7776+MODULE_PARM_DESC(dev_tx_fifo_size_1, "Number of words in the Tx FIFO 4-768");
7777+module_param_named(dev_tx_fifo_size_2, dwc_otg_module_params.dev_tx_fifo_size[1], int, 0444);
7778+MODULE_PARM_DESC(dev_tx_fifo_size_2, "Number of words in the Tx FIFO 4-768");
7779+module_param_named(dev_tx_fifo_size_3, dwc_otg_module_params.dev_tx_fifo_size[2], int, 0444);
7780+MODULE_PARM_DESC(dev_tx_fifo_size_3, "Number of words in the Tx FIFO 4-768");
7781+module_param_named(dev_tx_fifo_size_4, dwc_otg_module_params.dev_tx_fifo_size[3], int, 0444);
7782+MODULE_PARM_DESC(dev_tx_fifo_size_4, "Number of words in the Tx FIFO 4-768");
7783+module_param_named(dev_tx_fifo_size_5, dwc_otg_module_params.dev_tx_fifo_size[4], int, 0444);
7784+MODULE_PARM_DESC(dev_tx_fifo_size_5, "Number of words in the Tx FIFO 4-768");
7785+module_param_named(dev_tx_fifo_size_6, dwc_otg_module_params.dev_tx_fifo_size[5], int, 0444);
7786+MODULE_PARM_DESC(dev_tx_fifo_size_6, "Number of words in the Tx FIFO 4-768");
7787+module_param_named(dev_tx_fifo_size_7, dwc_otg_module_params.dev_tx_fifo_size[6], int, 0444);
7788+MODULE_PARM_DESC(dev_tx_fifo_size_7, "Number of words in the Tx FIFO 4-768");
7789+module_param_named(dev_tx_fifo_size_8, dwc_otg_module_params.dev_tx_fifo_size[7], int, 0444);
7790+MODULE_PARM_DESC(dev_tx_fifo_size_8, "Number of words in the Tx FIFO 4-768");
7791+module_param_named(dev_tx_fifo_size_9, dwc_otg_module_params.dev_tx_fifo_size[8], int, 0444);
7792+MODULE_PARM_DESC(dev_tx_fifo_size_9, "Number of words in the Tx FIFO 4-768");
7793+module_param_named(dev_tx_fifo_size_10, dwc_otg_module_params.dev_tx_fifo_size[9], int, 0444);
7794+MODULE_PARM_DESC(dev_tx_fifo_size_10, "Number of words in the Tx FIFO 4-768");
7795+module_param_named(dev_tx_fifo_size_11, dwc_otg_module_params.dev_tx_fifo_size[10], int, 0444);
7796+MODULE_PARM_DESC(dev_tx_fifo_size_11, "Number of words in the Tx FIFO 4-768");
7797+module_param_named(dev_tx_fifo_size_12, dwc_otg_module_params.dev_tx_fifo_size[11], int, 0444);
7798+MODULE_PARM_DESC(dev_tx_fifo_size_12, "Number of words in the Tx FIFO 4-768");
7799+module_param_named(dev_tx_fifo_size_13, dwc_otg_module_params.dev_tx_fifo_size[12], int, 0444);
7800+MODULE_PARM_DESC(dev_tx_fifo_size_13, "Number of words in the Tx FIFO 4-768");
7801+module_param_named(dev_tx_fifo_size_14, dwc_otg_module_params.dev_tx_fifo_size[13], int, 0444);
7802+MODULE_PARM_DESC(dev_tx_fifo_size_14, "Number of words in the Tx FIFO 4-768");
7803+module_param_named(dev_tx_fifo_size_15, dwc_otg_module_params.dev_tx_fifo_size[14], int, 0444);
7804+MODULE_PARM_DESC(dev_tx_fifo_size_15, "Number of words in the Tx FIFO 4-768");
7805+
7806+module_param_named(thr_ctl, dwc_otg_module_params.thr_ctl, int, 0444);
7807+MODULE_PARM_DESC(thr_ctl, "Thresholding enable flag bit 0 - non ISO Tx thr., 1 - ISO Tx thr., 2 - Rx thr.- bit 0=disabled 1=enabled");
7808+module_param_named(tx_thr_length, dwc_otg_module_params.tx_thr_length, int, 0444);
7809+MODULE_PARM_DESC(tx_thr_length, "Tx Threshold length in 32 bit DWORDs");
7810+module_param_named(rx_thr_length, dwc_otg_module_params.rx_thr_length, int, 0444);
7811+MODULE_PARM_DESC(rx_thr_length, "Rx Threshold length in 32 bit DWORDs");
7812+
7813+module_param_named(pti_enable, dwc_otg_module_params.pti_enable, int, 0444);
7814+MODULE_PARM_DESC(pti_enable, "Per Transfer Interrupt mode 0=disabled 1=enabled");
7815+
7816+module_param_named(mpi_enable, dwc_otg_module_params.mpi_enable, int, 0444);
7817+MODULE_PARM_DESC(mpi_enable, "Multiprocessor Interrupt mode 0=disabled 1=enabled");
7818--- /dev/null
7819+++ b/drivers/usb/dwc/otg_driver.h
7820@@ -0,0 +1,62 @@
7821+/* ==========================================================================
7822+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_driver.h $
7823+ * $Revision: #12 $
7824+ * $Date: 2008/07/15 $
7825+ * $Change: 1064918 $
7826+ *
7827+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
7828+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
7829+ * otherwise expressly agreed to in writing between Synopsys and you.
7830+ *
7831+ * The Software IS NOT an item of Licensed Software or Licensed Product under
7832+ * any End User Software License Agreement or Agreement for Licensed Product
7833+ * with Synopsys or any supplement thereto. You are permitted to use and
7834+ * redistribute this Software in source and binary forms, with or without
7835+ * modification, provided that redistributions of source code must retain this
7836+ * notice. You may not view, use, disclose, copy or distribute this file or
7837+ * any information contained herein except pursuant to this license grant from
7838+ * Synopsys. If you do not agree with this notice, including the disclaimer
7839+ * below, then you are not authorized to use the Software.
7840+ *
7841+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
7842+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
7843+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
7844+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
7845+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
7846+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
7847+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
7848+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
7849+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
7850+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
7851+ * DAMAGE.
7852+ * ========================================================================== */
7853+
7854+#ifndef __DWC_OTG_DRIVER_H__
7855+#define __DWC_OTG_DRIVER_H__
7856+
7857+/** @file
7858+ * This file contains the interface to the Linux driver.
7859+ */
7860+#include "otg_cil.h"
7861+
7862+/* Type declarations */
7863+struct dwc_otg_pcd;
7864+struct dwc_otg_hcd;
7865+
7866+/**
7867+ * This structure is a wrapper that encapsulates the driver components used to
7868+ * manage a single DWC_otg controller.
7869+ */
7870+typedef struct dwc_otg_device {
7871+ void *base;
7872+ dwc_otg_core_if_t *core_if;
7873+ uint32_t reg_offset;
7874+ struct dwc_otg_pcd *pcd;
7875+ struct dwc_otg_hcd *hcd;
7876+ uint8_t common_irq_installed;
7877+ int irq;
7878+ uint32_t rsrc_start;
7879+ uint32_t rsrc_len;
7880+} dwc_otg_device_t;
7881+
7882+#endif
7883--- /dev/null
7884+++ b/drivers/usb/dwc/otg_hcd.c
7885@@ -0,0 +1,2735 @@
7886+/* ==========================================================================
7887+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd.c $
7888+ * $Revision: #75 $
7889+ * $Date: 2008/07/15 $
7890+ * $Change: 1064940 $
7891+ *
7892+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
7893+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
7894+ * otherwise expressly agreed to in writing between Synopsys and you.
7895+ *
7896+ * The Software IS NOT an item of Licensed Software or Licensed Product under
7897+ * any End User Software License Agreement or Agreement for Licensed Product
7898+ * with Synopsys or any supplement thereto. You are permitted to use and
7899+ * redistribute this Software in source and binary forms, with or without
7900+ * modification, provided that redistributions of source code must retain this
7901+ * notice. You may not view, use, disclose, copy or distribute this file or
7902+ * any information contained herein except pursuant to this license grant from
7903+ * Synopsys. If you do not agree with this notice, including the disclaimer
7904+ * below, then you are not authorized to use the Software.
7905+ *
7906+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
7907+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
7908+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
7909+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
7910+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
7911+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
7912+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
7913+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
7914+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
7915+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
7916+ * DAMAGE.
7917+ * ========================================================================== */
7918+#ifndef DWC_DEVICE_ONLY
7919+
7920+/**
7921+ * @file
7922+ *
7923+ * This file contains the implementation of the HCD. In Linux, the HCD
7924+ * implements the hc_driver API.
7925+ */
7926+#include <linux/kernel.h>
7927+#include <linux/module.h>
7928+#include <linux/moduleparam.h>
7929+#include <linux/init.h>
7930+#include <linux/device.h>
7931+#include <linux/platform_device.h>
7932+#include <linux/errno.h>
7933+#include <linux/list.h>
7934+#include <linux/interrupt.h>
7935+#include <linux/string.h>
7936+#include <linux/dma-mapping.h>
7937+#include <linux/version.h>
7938+
7939+#include <mach/irqs.h>
7940+
7941+#include "otg_driver.h"
7942+#include "otg_hcd.h"
7943+#include "otg_regs.h"
7944+
7945+static const char dwc_otg_hcd_name[] = "dwc_otg_hcd";
7946+
7947+static const struct hc_driver dwc_otg_hc_driver = {
7948+
7949+ .description = dwc_otg_hcd_name,
7950+ .product_desc = "DWC OTG Controller",
7951+ .hcd_priv_size = sizeof(dwc_otg_hcd_t),
7952+ .irq = dwc_otg_hcd_irq,
7953+ .flags = HCD_MEMORY | HCD_USB2,
7954+ .start = dwc_otg_hcd_start,
7955+ .stop = dwc_otg_hcd_stop,
7956+ .urb_enqueue = dwc_otg_hcd_urb_enqueue,
7957+ .urb_dequeue = dwc_otg_hcd_urb_dequeue,
7958+ .endpoint_disable = dwc_otg_hcd_endpoint_disable,
7959+ .get_frame_number = dwc_otg_hcd_get_frame_number,
7960+ .hub_status_data = dwc_otg_hcd_hub_status_data,
7961+ .hub_control = dwc_otg_hcd_hub_control,
7962+};
7963+
7964+/**
7965+ * Work queue function for starting the HCD when A-Cable is connected.
7966+ * The dwc_otg_hcd_start() must be called in a process context.
7967+ */
7968+static void hcd_start_func(struct work_struct *_work)
7969+{
7970+ struct delayed_work *dw = container_of(_work, struct delayed_work, work);
7971+ struct dwc_otg_hcd *otg_hcd = container_of(dw, struct dwc_otg_hcd, start_work);
7972+ struct usb_hcd *usb_hcd = container_of((void *)otg_hcd, struct usb_hcd, hcd_priv);
7973+ DWC_DEBUGPL(DBG_HCDV, "%s() %p\n", __func__, usb_hcd);
7974+ if (usb_hcd) {
7975+ dwc_otg_hcd_start(usb_hcd);
7976+ }
7977+}
7978+
7979+/**
7980+ * HCD Callback function for starting the HCD when A-Cable is
7981+ * connected.
7982+ *
7983+ * @param p void pointer to the <code>struct usb_hcd</code>
7984+ */
7985+static int32_t dwc_otg_hcd_start_cb(void *p)
7986+{
7987+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(p);
7988+ dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
7989+ hprt0_data_t hprt0;
7990+
7991+ if (core_if->op_state == B_HOST) {
7992+ /*
7993+ * Reset the port. During a HNP mode switch the reset
7994+ * needs to occur within 1ms and have a duration of at
7995+ * least 50ms.
7996+ */
7997+ hprt0.d32 = dwc_otg_read_hprt0(core_if);
7998+ hprt0.b.prtrst = 1;
7999+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
8000+ ((struct usb_hcd *)p)->self.is_b_host = 1;
8001+ } else {
8002+ ((struct usb_hcd *)p)->self.is_b_host = 0;
8003+ }
8004+
8005+ /* Need to start the HCD in a non-interrupt context. */
8006+// INIT_WORK(&dwc_otg_hcd->start_work, hcd_start_func);
8007+ INIT_DELAYED_WORK(&dwc_otg_hcd->start_work, hcd_start_func);
8008+// schedule_work(&dwc_otg_hcd->start_work);
8009+ queue_delayed_work(core_if->wq_otg, &dwc_otg_hcd->start_work, 50 * HZ / 1000);
8010+
8011+ return 1;
8012+}
8013+
8014+/**
8015+ * HCD Callback function for stopping the HCD.
8016+ *
8017+ * @param p void pointer to the <code>struct usb_hcd</code>
8018+ */
8019+static int32_t dwc_otg_hcd_stop_cb(void *p)
8020+{
8021+ struct usb_hcd *usb_hcd = (struct usb_hcd *)p;
8022+ DWC_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, p);
8023+ dwc_otg_hcd_stop(usb_hcd);
8024+ return 1;
8025+}
8026+
8027+static void del_xfer_timers(dwc_otg_hcd_t *hcd)
8028+{
8029+#ifdef DEBUG
8030+ int i;
8031+ int num_channels = hcd->core_if->core_params->host_channels;
8032+ for (i = 0; i < num_channels; i++) {
8033+ del_timer(&hcd->core_if->hc_xfer_timer[i]);
8034+ }
8035+#endif
8036+}
8037+
8038+static void del_timers(dwc_otg_hcd_t *hcd)
8039+{
8040+ del_xfer_timers(hcd);
8041+ del_timer(&hcd->conn_timer);
8042+}
8043+
8044+/**
8045+ * Processes all the URBs in a single list of QHs. Completes them with
8046+ * -ETIMEDOUT and frees the QTD.
8047+ */
8048+static void kill_urbs_in_qh_list(dwc_otg_hcd_t *hcd, struct list_head *qh_list)
8049+{
8050+ struct list_head *qh_item;
8051+ dwc_otg_qh_t *qh;
8052+ struct list_head *qtd_item;
8053+ dwc_otg_qtd_t *qtd;
8054+
8055+ list_for_each(qh_item, qh_list) {
8056+ qh = list_entry(qh_item, dwc_otg_qh_t, qh_list_entry);
8057+ for (qtd_item = qh->qtd_list.next;
8058+ qtd_item != &qh->qtd_list;
8059+ qtd_item = qh->qtd_list.next) {
8060+ qtd = list_entry(qtd_item, dwc_otg_qtd_t, qtd_list_entry);
8061+ if (qtd->urb != NULL) {
8062+ dwc_otg_hcd_complete_urb(hcd, qtd->urb,
8063+ -ETIMEDOUT);
8064+ }
8065+ dwc_otg_hcd_qtd_remove_and_free(hcd, qtd);
8066+ }
8067+ }
8068+}
8069+
8070+/**
8071+ * Responds with an error status of ETIMEDOUT to all URBs in the non-periodic
8072+ * and periodic schedules. The QTD associated with each URB is removed from
8073+ * the schedule and freed. This function may be called when a disconnect is
8074+ * detected or when the HCD is being stopped.
8075+ */
8076+static void kill_all_urbs(dwc_otg_hcd_t *hcd)
8077+{
8078+ kill_urbs_in_qh_list(hcd, &hcd->non_periodic_sched_inactive);
8079+ kill_urbs_in_qh_list(hcd, &hcd->non_periodic_sched_active);
8080+ kill_urbs_in_qh_list(hcd, &hcd->periodic_sched_inactive);
8081+ kill_urbs_in_qh_list(hcd, &hcd->periodic_sched_ready);
8082+ kill_urbs_in_qh_list(hcd, &hcd->periodic_sched_assigned);
8083+ kill_urbs_in_qh_list(hcd, &hcd->periodic_sched_queued);
8084+}
8085+
8086+/**
8087+ * HCD Callback function for disconnect of the HCD.
8088+ *
8089+ * @param p void pointer to the <code>struct usb_hcd</code>
8090+ */
8091+static int32_t dwc_otg_hcd_disconnect_cb(void *p)
8092+{
8093+ gintsts_data_t intr;
8094+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(p);
8095+
8096+ //DWC_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, p);
8097+
8098+ /*
8099+ * Set status flags for the hub driver.
8100+ */
8101+ dwc_otg_hcd->flags.b.port_connect_status_change = 1;
8102+ dwc_otg_hcd->flags.b.port_connect_status = 0;
8103+
8104+ /*
8105+ * Shutdown any transfers in process by clearing the Tx FIFO Empty
8106+ * interrupt mask and status bits and disabling subsequent host
8107+ * channel interrupts.
8108+ */
8109+ intr.d32 = 0;
8110+ intr.b.nptxfempty = 1;
8111+ intr.b.ptxfempty = 1;
8112+ intr.b.hcintr = 1;
8113+ dwc_modify_reg32(&dwc_otg_hcd->core_if->core_global_regs->gintmsk, intr.d32, 0);
8114+ dwc_modify_reg32(&dwc_otg_hcd->core_if->core_global_regs->gintsts, intr.d32, 0);
8115+
8116+ del_timers(dwc_otg_hcd);
8117+
8118+ /*
8119+ * Turn off the vbus power only if the core has transitioned to device
8120+ * mode. If still in host mode, need to keep power on to detect a
8121+ * reconnection.
8122+ */
8123+ if (dwc_otg_is_device_mode(dwc_otg_hcd->core_if)) {
8124+ if (dwc_otg_hcd->core_if->op_state != A_SUSPEND) {
8125+ hprt0_data_t hprt0 = { .d32=0 };
8126+ DWC_PRINT("Disconnect: PortPower off\n");
8127+ hprt0.b.prtpwr = 0;
8128+ dwc_write_reg32(dwc_otg_hcd->core_if->host_if->hprt0, hprt0.d32);
8129+ }
8130+
8131+ dwc_otg_disable_host_interrupts(dwc_otg_hcd->core_if);
8132+ }
8133+
8134+ /* Respond with an error status to all URBs in the schedule. */
8135+ kill_all_urbs(dwc_otg_hcd);
8136+
8137+ if (dwc_otg_is_host_mode(dwc_otg_hcd->core_if)) {
8138+ /* Clean up any host channels that were in use. */
8139+ int num_channels;
8140+ int i;
8141+ dwc_hc_t *channel;
8142+ dwc_otg_hc_regs_t *hc_regs;
8143+ hcchar_data_t hcchar;
8144+
8145+ num_channels = dwc_otg_hcd->core_if->core_params->host_channels;
8146+
8147+ if (!dwc_otg_hcd->core_if->dma_enable) {
8148+ /* Flush out any channel requests in slave mode. */
8149+ for (i = 0; i < num_channels; i++) {
8150+ channel = dwc_otg_hcd->hc_ptr_array[i];
8151+ if (list_empty(&channel->hc_list_entry)) {
8152+ hc_regs = dwc_otg_hcd->core_if->host_if->hc_regs[i];
8153+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8154+ if (hcchar.b.chen) {
8155+ hcchar.b.chen = 0;
8156+ hcchar.b.chdis = 1;
8157+ hcchar.b.epdir = 0;
8158+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
8159+ }
8160+ }
8161+ }
8162+ }
8163+
8164+ for (i = 0; i < num_channels; i++) {
8165+ channel = dwc_otg_hcd->hc_ptr_array[i];
8166+ if (list_empty(&channel->hc_list_entry)) {
8167+ hc_regs = dwc_otg_hcd->core_if->host_if->hc_regs[i];
8168+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8169+ if (hcchar.b.chen) {
8170+ /* Halt the channel. */
8171+ hcchar.b.chdis = 1;
8172+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
8173+ }
8174+
8175+ dwc_otg_hc_cleanup(dwc_otg_hcd->core_if, channel);
8176+ list_add_tail(&channel->hc_list_entry,
8177+ &dwc_otg_hcd->free_hc_list);
8178+ }
8179+ }
8180+ }
8181+
8182+ /* A disconnect will end the session so the B-Device is no
8183+ * longer a B-host. */
8184+ ((struct usb_hcd *)p)->self.is_b_host = 0;
8185+ return 1;
8186+}
8187+
8188+/**
8189+ * Connection timeout function. An OTG host is required to display a
8190+ * message if the device does not connect within 10 seconds.
8191+ */
8192+void dwc_otg_hcd_connect_timeout(unsigned long ptr)
8193+{
8194+ DWC_DEBUGPL(DBG_HCDV, "%s(%x)\n", __func__, (int)ptr);
8195+ DWC_PRINT("Connect Timeout\n");
8196+ DWC_ERROR("Device Not Connected/Responding\n");
8197+}
8198+
8199+/**
8200+ * Start the connection timer. An OTG host is required to display a
8201+ * message if the device does not connect within 10 seconds. The
8202+ * timer is deleted if a port connect interrupt occurs before the
8203+ * timer expires.
8204+ */
8205+static void dwc_otg_hcd_start_connect_timer(dwc_otg_hcd_t *hcd)
8206+{
8207+ init_timer(&hcd->conn_timer);
8208+ hcd->conn_timer.function = dwc_otg_hcd_connect_timeout;
8209+ hcd->conn_timer.data = 0;
8210+ hcd->conn_timer.expires = jiffies + (HZ * 10);
8211+ add_timer(&hcd->conn_timer);
8212+}
8213+
8214+/**
8215+ * HCD Callback function for disconnect of the HCD.
8216+ *
8217+ * @param p void pointer to the <code>struct usb_hcd</code>
8218+ */
8219+static int32_t dwc_otg_hcd_session_start_cb(void *p)
8220+{
8221+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(p);
8222+ DWC_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, p);
8223+ dwc_otg_hcd_start_connect_timer(dwc_otg_hcd);
8224+ return 1;
8225+}
8226+
8227+/**
8228+ * HCD Callback structure for handling mode switching.
8229+ */
8230+static dwc_otg_cil_callbacks_t hcd_cil_callbacks = {
8231+ .start = dwc_otg_hcd_start_cb,
8232+ .stop = dwc_otg_hcd_stop_cb,
8233+ .disconnect = dwc_otg_hcd_disconnect_cb,
8234+ .session_start = dwc_otg_hcd_session_start_cb,
8235+ .p = 0,
8236+};
8237+
8238+/**
8239+ * Reset tasklet function
8240+ */
8241+static void reset_tasklet_func(unsigned long data)
8242+{
8243+ dwc_otg_hcd_t *dwc_otg_hcd = (dwc_otg_hcd_t *)data;
8244+ dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
8245+ hprt0_data_t hprt0;
8246+
8247+ DWC_DEBUGPL(DBG_HCDV, "USB RESET tasklet called\n");
8248+
8249+ hprt0.d32 = dwc_otg_read_hprt0(core_if);
8250+ hprt0.b.prtrst = 1;
8251+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
8252+ mdelay(60);
8253+
8254+ hprt0.b.prtrst = 0;
8255+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
8256+ dwc_otg_hcd->flags.b.port_reset_change = 1;
8257+}
8258+
8259+static struct tasklet_struct reset_tasklet = {
8260+ .next = NULL,
8261+ .state = 0,
8262+ .count = ATOMIC_INIT(0),
8263+ .func = reset_tasklet_func,
8264+ .data = 0,
8265+};
8266+
8267+/**
8268+ * Initializes the HCD. This function allocates memory for and initializes the
8269+ * static parts of the usb_hcd and dwc_otg_hcd structures. It also registers the
8270+ * USB bus with the core and calls the hc_driver->start() function. It returns
8271+ * a negative error on failure.
8272+ */
8273+int dwc_otg_hcd_init(struct platform_device *pdev)
8274+{
8275+ struct usb_hcd *hcd = NULL;
8276+ dwc_otg_hcd_t *dwc_otg_hcd = NULL;
8277+ dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev);
8278+
8279+ int num_channels;
8280+ int i;
8281+ dwc_hc_t *channel;
8282+
8283+ int retval = 0;
8284+
8285+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT\n");
8286+
8287+ /* Set device flags indicating whether the HCD supports DMA. */
8288+ if (otg_dev->core_if->dma_enable) {
8289+ DWC_PRINT("Using DMA mode\n");
8290+
8291+ if (otg_dev->core_if->dma_desc_enable) {
8292+ DWC_PRINT("Device using Descriptor DMA mode\n");
8293+ } else {
8294+ DWC_PRINT("Device using Buffer DMA mode\n");
8295+ }
8296+ }
8297+ /*
8298+ * Allocate memory for the base HCD plus the DWC OTG HCD.
8299+ * Initialize the base HCD.
8300+ */
8301+
8302+ hcd = usb_create_hcd(&dwc_otg_hc_driver, &pdev->dev, "gadget");
8303+ if (!hcd) {
8304+ retval = -ENOMEM;
8305+ goto error1;
8306+ }
8307+
8308+ hcd->regs = otg_dev->base;
8309+ hcd->self.otg_port = 1;
8310+
8311+ /* Initialize the DWC OTG HCD. */
8312+ dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
8313+ dwc_otg_hcd->core_if = otg_dev->core_if;
8314+ otg_dev->hcd = dwc_otg_hcd;
8315+
8316+ /* */
8317+ spin_lock_init(&dwc_otg_hcd->lock);
8318+
8319+ /* Register the HCD CIL Callbacks */
8320+ dwc_otg_cil_register_hcd_callbacks(otg_dev->core_if,
8321+ &hcd_cil_callbacks, hcd);
8322+
8323+ /* Initialize the non-periodic schedule. */
8324+ INIT_LIST_HEAD(&dwc_otg_hcd->non_periodic_sched_inactive);
8325+ INIT_LIST_HEAD(&dwc_otg_hcd->non_periodic_sched_active);
8326+
8327+ /* Initialize the periodic schedule. */
8328+ INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_inactive);
8329+ INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_ready);
8330+ INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_assigned);
8331+ INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_queued);
8332+
8333+ /*
8334+ * Create a host channel descriptor for each host channel implemented
8335+ * in the controller. Initialize the channel descriptor array.
8336+ */
8337+ INIT_LIST_HEAD(&dwc_otg_hcd->free_hc_list);
8338+ num_channels = dwc_otg_hcd->core_if->core_params->host_channels;
8339+ memset(dwc_otg_hcd->hc_ptr_array, 0, sizeof(dwc_otg_hcd->hc_ptr_array));
8340+ for (i = 0; i < num_channels; i++) {
8341+ channel = kmalloc(sizeof(dwc_hc_t), GFP_KERNEL);
8342+ if (channel == NULL) {
8343+ retval = -ENOMEM;
8344+ DWC_ERROR("%s: host channel allocation failed\n", __func__);
8345+ goto error2;
8346+ }
8347+ memset(channel, 0, sizeof(dwc_hc_t));
8348+ channel->hc_num = i;
8349+ dwc_otg_hcd->hc_ptr_array[i] = channel;
8350+#ifdef DEBUG
8351+ init_timer(&dwc_otg_hcd->core_if->hc_xfer_timer[i]);
8352+#endif
8353+ DWC_DEBUGPL(DBG_HCDV, "HCD Added channel #%d, hc=%p\n", i, channel);
8354+ }
8355+
8356+ /* Initialize the Connection timeout timer. */
8357+ init_timer(&dwc_otg_hcd->conn_timer);
8358+
8359+ /* Initialize reset tasklet. */
8360+ reset_tasklet.data = (unsigned long) dwc_otg_hcd;
8361+ dwc_otg_hcd->reset_tasklet = &reset_tasklet;
8362+
8363+ /*
8364+ * Finish generic HCD initialization and start the HCD. This function
8365+ * allocates the DMA buffer pool, registers the USB bus, requests the
8366+ * IRQ line, and calls dwc_otg_hcd_start method.
8367+ */
8368+ retval = usb_add_hcd(hcd, otg_dev->irq, IRQF_SHARED);
8369+ if (retval < 0) {
8370+ goto error2;
8371+ }
8372+
8373+ /*
8374+ * Allocate space for storing data on status transactions. Normally no
8375+ * data is sent, but this space acts as a bit bucket. This must be
8376+ * done after usb_add_hcd since that function allocates the DMA buffer
8377+ * pool.
8378+ */
8379+ if (otg_dev->core_if->dma_enable) {
8380+ dwc_otg_hcd->status_buf =
8381+ dma_alloc_coherent(&pdev->dev,
8382+ DWC_OTG_HCD_STATUS_BUF_SIZE,
8383+ &dwc_otg_hcd->status_buf_dma,
8384+ GFP_KERNEL | GFP_DMA);
8385+ } else {
8386+ dwc_otg_hcd->status_buf = kmalloc(DWC_OTG_HCD_STATUS_BUF_SIZE,
8387+ GFP_KERNEL);
8388+ }
8389+ if (!dwc_otg_hcd->status_buf) {
8390+ retval = -ENOMEM;
8391+ DWC_ERROR("%s: status_buf allocation failed\n", __func__);
8392+ goto error3;
8393+ }
8394+
8395+ dwc_otg_hcd->otg_dev = otg_dev;
8396+
8397+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Initialized HCD, usbbus=%d\n",
8398+ hcd->self.busnum);
8399+ return 0;
8400+
8401+ /* Error conditions */
8402+ error3:
8403+ usb_remove_hcd(hcd);
8404+ error2:
8405+ dwc_otg_hcd_free(hcd);
8406+ usb_put_hcd(hcd);
8407+ error1:
8408+ return retval;
8409+}
8410+
8411+/**
8412+ * Removes the HCD.
8413+ * Frees memory and resources associated with the HCD and deregisters the bus.
8414+ */
8415+void dwc_otg_hcd_remove(struct platform_device *pdev)
8416+{
8417+ dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev);
8418+ dwc_otg_hcd_t *dwc_otg_hcd;
8419+ struct usb_hcd *hcd;
8420+
8421+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD REMOVE\n");
8422+
8423+ if (!otg_dev) {
8424+ DWC_DEBUGPL(DBG_ANY, "%s: otg_dev NULL!\n", __func__);
8425+ return;
8426+ }
8427+
8428+ dwc_otg_hcd = otg_dev->hcd;
8429+
8430+ if (!dwc_otg_hcd) {
8431+ DWC_DEBUGPL(DBG_ANY, "%s: otg_dev->hcd NULL!\n", __func__);
8432+ return;
8433+ }
8434+
8435+ hcd = dwc_otg_hcd_to_hcd(dwc_otg_hcd);
8436+
8437+ if (!hcd) {
8438+ DWC_DEBUGPL(DBG_ANY, "%s: dwc_otg_hcd_to_hcd(dwc_otg_hcd) NULL!\n", __func__);
8439+ return;
8440+ }
8441+
8442+ /* Turn off all interrupts */
8443+ dwc_write_reg32(&dwc_otg_hcd->core_if->core_global_regs->gintmsk, 0);
8444+ dwc_modify_reg32(&dwc_otg_hcd->core_if->core_global_regs->gahbcfg, 1, 0);
8445+
8446+ usb_remove_hcd(hcd);
8447+ dwc_otg_hcd_free(hcd);
8448+ usb_put_hcd(hcd);
8449+}
8450+
8451+/* =========================================================================
8452+ * Linux HC Driver Functions
8453+ * ========================================================================= */
8454+
8455+/**
8456+ * Initializes dynamic portions of the DWC_otg HCD state.
8457+ */
8458+static void hcd_reinit(dwc_otg_hcd_t *hcd)
8459+{
8460+ struct list_head *item;
8461+ int num_channels;
8462+ int i;
8463+ dwc_hc_t *channel;
8464+
8465+ hcd->flags.d32 = 0;
8466+
8467+ hcd->non_periodic_qh_ptr = &hcd->non_periodic_sched_active;
8468+ hcd->non_periodic_channels = 0;
8469+ hcd->periodic_channels = 0;
8470+
8471+ /*
8472+ * Put all channels in the free channel list and clean up channel
8473+ * states.
8474+ */
8475+ item = hcd->free_hc_list.next;
8476+ while (item != &hcd->free_hc_list) {
8477+ list_del(item);
8478+ item = hcd->free_hc_list.next;
8479+ }
8480+ num_channels = hcd->core_if->core_params->host_channels;
8481+ for (i = 0; i < num_channels; i++) {
8482+ channel = hcd->hc_ptr_array[i];
8483+ list_add_tail(&channel->hc_list_entry, &hcd->free_hc_list);
8484+ dwc_otg_hc_cleanup(hcd->core_if, channel);
8485+ }
8486+
8487+ /* Initialize the DWC core for host mode operation. */
8488+ dwc_otg_core_host_init(hcd->core_if);
8489+}
8490+
8491+/** Initializes the DWC_otg controller and its root hub and prepares it for host
8492+ * mode operation. Activates the root port. Returns 0 on success and a negative
8493+ * error code on failure. */
8494+int dwc_otg_hcd_start(struct usb_hcd *hcd)
8495+{
8496+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
8497+ dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
8498+ struct usb_bus *bus;
8499+
8500+
8501+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD START\n");
8502+
8503+ bus = hcd_to_bus(hcd);
8504+
8505+ /* Initialize the bus state. If the core is in Device Mode
8506+ * HALT the USB bus and return. */
8507+ if (dwc_otg_is_device_mode(core_if)) {
8508+ hcd->state = HC_STATE_RUNNING;
8509+ return 0;
8510+ }
8511+ hcd->state = HC_STATE_RUNNING;
8512+
8513+ /* Initialize and connect root hub if one is not already attached */
8514+ if (bus->root_hub) {
8515+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Has Root Hub\n");
8516+ /* Inform the HUB driver to resume. */
8517+ usb_hcd_resume_root_hub(hcd);
8518+ }
8519+ else {
8520+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Does Not Have Root Hub\n");
8521+ }
8522+
8523+ hcd_reinit(dwc_otg_hcd);
8524+
8525+ return 0;
8526+}
8527+
8528+static void qh_list_free(dwc_otg_hcd_t *hcd, struct list_head *qh_list)
8529+{
8530+ struct list_head *item;
8531+ dwc_otg_qh_t *qh;
8532+
8533+ if (!qh_list->next) {
8534+ /* The list hasn't been initialized yet. */
8535+ return;
8536+ }
8537+
8538+ /* Ensure there are no QTDs or URBs left. */
8539+ kill_urbs_in_qh_list(hcd, qh_list);
8540+
8541+ for (item = qh_list->next; item != qh_list; item = qh_list->next) {
8542+ qh = list_entry(item, dwc_otg_qh_t, qh_list_entry);
8543+ dwc_otg_hcd_qh_remove_and_free(hcd, qh);
8544+ }
8545+}
8546+
8547+/**
8548+ * Halts the DWC_otg host mode operations in a clean manner. USB transfers are
8549+ * stopped.
8550+ */
8551+void dwc_otg_hcd_stop(struct usb_hcd *hcd)
8552+{
8553+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
8554+ hprt0_data_t hprt0 = { .d32=0 };
8555+
8556+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD STOP\n");
8557+
8558+ /* Turn off all host-specific interrupts. */
8559+ dwc_otg_disable_host_interrupts(dwc_otg_hcd->core_if);
8560+
8561+ /*
8562+ * The root hub should be disconnected before this function is called.
8563+ * The disconnect will clear the QTD lists (via ..._hcd_urb_dequeue)
8564+ * and the QH lists (via ..._hcd_endpoint_disable).
8565+ */
8566+
8567+ /* Turn off the vbus power */
8568+ DWC_PRINT("PortPower off\n");
8569+ hprt0.b.prtpwr = 0;
8570+ dwc_write_reg32(dwc_otg_hcd->core_if->host_if->hprt0, hprt0.d32);
8571+}
8572+
8573+/** Returns the current frame number. */
8574+int dwc_otg_hcd_get_frame_number(struct usb_hcd *hcd)
8575+{
8576+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
8577+ hfnum_data_t hfnum;
8578+
8579+ hfnum.d32 = dwc_read_reg32(&dwc_otg_hcd->core_if->
8580+ host_if->host_global_regs->hfnum);
8581+
8582+#ifdef DEBUG_SOF
8583+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD GET FRAME NUMBER %d\n", hfnum.b.frnum);
8584+#endif
8585+ return hfnum.b.frnum;
8586+}
8587+
8588+/**
8589+ * Frees secondary storage associated with the dwc_otg_hcd structure contained
8590+ * in the struct usb_hcd field.
8591+ */
8592+void dwc_otg_hcd_free(struct usb_hcd *hcd)
8593+{
8594+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
8595+ int i;
8596+
8597+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD FREE\n");
8598+
8599+ del_timers(dwc_otg_hcd);
8600+
8601+ /* Free memory for QH/QTD lists */
8602+ qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->non_periodic_sched_inactive);
8603+ qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->non_periodic_sched_active);
8604+ qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_inactive);
8605+ qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_ready);
8606+ qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_assigned);
8607+ qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_queued);
8608+
8609+ /* Free memory for the host channels. */
8610+ for (i = 0; i < MAX_EPS_CHANNELS; i++) {
8611+ dwc_hc_t *hc = dwc_otg_hcd->hc_ptr_array[i];
8612+ if (hc != NULL) {
8613+ DWC_DEBUGPL(DBG_HCDV, "HCD Free channel #%i, hc=%p\n", i, hc);
8614+ kfree(hc);
8615+ }
8616+ }
8617+
8618+ if (dwc_otg_hcd->core_if->dma_enable) {
8619+ if (dwc_otg_hcd->status_buf_dma) {
8620+ dma_free_coherent(hcd->self.controller,
8621+ DWC_OTG_HCD_STATUS_BUF_SIZE,
8622+ dwc_otg_hcd->status_buf,
8623+ dwc_otg_hcd->status_buf_dma);
8624+ }
8625+ } else if (dwc_otg_hcd->status_buf != NULL) {
8626+ kfree(dwc_otg_hcd->status_buf);
8627+ }
8628+}
8629+
8630+#ifdef DEBUG
8631+static void dump_urb_info(struct urb *urb, char* fn_name)
8632+{
8633+ DWC_PRINT("%s, urb %p\n", fn_name, urb);
8634+ DWC_PRINT(" Device address: %d\n", usb_pipedevice(urb->pipe));
8635+ DWC_PRINT(" Endpoint: %d, %s\n", usb_pipeendpoint(urb->pipe),
8636+ (usb_pipein(urb->pipe) ? "IN" : "OUT"));
8637+ DWC_PRINT(" Endpoint type: %s\n",
8638+ ({char *pipetype;
8639+ switch (usb_pipetype(urb->pipe)) {
8640+ case PIPE_CONTROL: pipetype = "CONTROL"; break;
8641+ case PIPE_BULK: pipetype = "BULK"; break;
8642+ case PIPE_INTERRUPT: pipetype = "INTERRUPT"; break;
8643+ case PIPE_ISOCHRONOUS: pipetype = "ISOCHRONOUS"; break;
8644+ default: pipetype = "UNKNOWN"; break;
8645+ }; pipetype;}));
8646+ DWC_PRINT(" Speed: %s\n",
8647+ ({char *speed;
8648+ switch (urb->dev->speed) {
8649+ case USB_SPEED_HIGH: speed = "HIGH"; break;
8650+ case USB_SPEED_FULL: speed = "FULL"; break;
8651+ case USB_SPEED_LOW: speed = "LOW"; break;
8652+ default: speed = "UNKNOWN"; break;
8653+ }; speed;}));
8654+ DWC_PRINT(" Max packet size: %d\n",
8655+ usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)));
8656+ DWC_PRINT(" Data buffer length: %d\n", urb->transfer_buffer_length);
8657+ DWC_PRINT(" Transfer buffer: %p, Transfer DMA: %p\n",
8658+ urb->transfer_buffer, (void *)urb->transfer_dma);
8659+ DWC_PRINT(" Setup buffer: %p, Setup DMA: %p\n",
8660+ urb->setup_packet, (void *)urb->setup_dma);
8661+ DWC_PRINT(" Interval: %d\n", urb->interval);
8662+ if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
8663+ int i;
8664+ for (i = 0; i < urb->number_of_packets; i++) {
8665+ DWC_PRINT(" ISO Desc %d:\n", i);
8666+ DWC_PRINT(" offset: %d, length %d\n",
8667+ urb->iso_frame_desc[i].offset,
8668+ urb->iso_frame_desc[i].length);
8669+ }
8670+ }
8671+}
8672+
8673+static void dump_channel_info(dwc_otg_hcd_t *hcd,
8674+ dwc_otg_qh_t *qh)
8675+{
8676+ if (qh->channel != NULL) {
8677+ dwc_hc_t *hc = qh->channel;
8678+ struct list_head *item;
8679+ dwc_otg_qh_t *qh_item;
8680+ int num_channels = hcd->core_if->core_params->host_channels;
8681+ int i;
8682+
8683+ dwc_otg_hc_regs_t *hc_regs;
8684+ hcchar_data_t hcchar;
8685+ hcsplt_data_t hcsplt;
8686+ hctsiz_data_t hctsiz;
8687+ uint32_t hcdma;
8688+
8689+ hc_regs = hcd->core_if->host_if->hc_regs[hc->hc_num];
8690+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
8691+ hcsplt.d32 = dwc_read_reg32(&hc_regs->hcsplt);
8692+ hctsiz.d32 = dwc_read_reg32(&hc_regs->hctsiz);
8693+ hcdma = dwc_read_reg32(&hc_regs->hcdma);
8694+
8695+ DWC_PRINT(" Assigned to channel %p:\n", hc);
8696+ DWC_PRINT(" hcchar 0x%08x, hcsplt 0x%08x\n", hcchar.d32, hcsplt.d32);
8697+ DWC_PRINT(" hctsiz 0x%08x, hcdma 0x%08x\n", hctsiz.d32, hcdma);
8698+ DWC_PRINT(" dev_addr: %d, ep_num: %d, ep_is_in: %d\n",
8699+ hc->dev_addr, hc->ep_num, hc->ep_is_in);
8700+ DWC_PRINT(" ep_type: %d\n", hc->ep_type);
8701+ DWC_PRINT(" max_packet: %d\n", hc->max_packet);
8702+ DWC_PRINT(" data_pid_start: %d\n", hc->data_pid_start);
8703+ DWC_PRINT(" xfer_started: %d\n", hc->xfer_started);
8704+ DWC_PRINT(" halt_status: %d\n", hc->halt_status);
8705+ DWC_PRINT(" xfer_buff: %p\n", hc->xfer_buff);
8706+ DWC_PRINT(" xfer_len: %d\n", hc->xfer_len);
8707+ DWC_PRINT(" qh: %p\n", hc->qh);
8708+ DWC_PRINT(" NP inactive sched:\n");
8709+ list_for_each(item, &hcd->non_periodic_sched_inactive) {
8710+ qh_item = list_entry(item, dwc_otg_qh_t, qh_list_entry);
8711+ DWC_PRINT(" %p\n", qh_item);
8712+ }
8713+ DWC_PRINT(" NP active sched:\n");
8714+ list_for_each(item, &hcd->non_periodic_sched_active) {
8715+ qh_item = list_entry(item, dwc_otg_qh_t, qh_list_entry);
8716+ DWC_PRINT(" %p\n", qh_item);
8717+ }
8718+ DWC_PRINT(" Channels: \n");
8719+ for (i = 0; i < num_channels; i++) {
8720+ dwc_hc_t *hc = hcd->hc_ptr_array[i];
8721+ DWC_PRINT(" %2d: %p\n", i, hc);
8722+ }
8723+ }
8724+}
8725+#endif
8726+
8727+
8728+//OTG host require the DMA addr is DWORD-aligned,
8729+//patch it if the buffer is not DWORD-aligned
8730+inline
8731+void hcd_check_and_patch_dma_addr(struct urb *urb){
8732+
8733+ if((!urb->transfer_buffer)||!urb->transfer_dma||urb->transfer_dma==0xffffffff)
8734+ return;
8735+
8736+ if(((u32)urb->transfer_buffer)& 0x3){
8737+ /*
8738+ printk("%s: "
8739+ "urb(%.8x) "
8740+ "transfer_buffer=%.8x, "
8741+ "transfer_dma=%.8x, "
8742+ "transfer_buffer_length=%d, "
8743+ "actual_length=%d(%x), "
8744+ "\n",
8745+ ((urb->transfer_flags & URB_DIR_MASK)==URB_DIR_OUT)?"OUT":"IN",
8746+ urb,
8747+ urb->transfer_buffer,
8748+ urb->transfer_dma,
8749+ urb->transfer_buffer_length,
8750+ urb->actual_length,urb->actual_length
8751+ );
8752+ */
8753+ if(!urb->aligned_transfer_buffer||urb->aligned_transfer_buffer_length<urb->transfer_buffer_length){
8754+ urb->aligned_transfer_buffer_length=urb->transfer_buffer_length;
8755+ if(urb->aligned_transfer_buffer) {
8756+ kfree(urb->aligned_transfer_buffer);
8757+ }
8758+ urb->aligned_transfer_buffer=kmalloc(urb->aligned_transfer_buffer_length,GFP_KERNEL|GFP_DMA|GFP_ATOMIC);
8759+ urb->aligned_transfer_dma=dma_map_single(NULL,(void *)(urb->aligned_transfer_buffer),(urb->aligned_transfer_buffer_length),DMA_FROM_DEVICE);
8760+ if(!urb->aligned_transfer_buffer){
8761+ DWC_ERROR("Cannot alloc required buffer!!\n");
8762+ BUG();
8763+ }
8764+ //printk(" new allocated aligned_buf=%.8x aligned_buf_len=%d\n", (u32)urb->aligned_transfer_buffer, urb->aligned_transfer_buffer_length);
8765+ }
8766+ urb->transfer_dma=urb->aligned_transfer_dma;
8767+ if((urb->transfer_flags & URB_DIR_MASK)==URB_DIR_OUT) {
8768+ memcpy(urb->aligned_transfer_buffer,urb->transfer_buffer,urb->transfer_buffer_length);
8769+ dma_sync_single_for_device(NULL,urb->transfer_dma,urb->transfer_buffer_length,DMA_TO_DEVICE);
8770+ }
8771+ }
8772+}
8773+
8774+
8775+
8776+/** Starts processing a USB transfer request specified by a USB Request Block
8777+ * (URB). mem_flags indicates the type of memory allocation to use while
8778+ * processing this URB. */
8779+int dwc_otg_hcd_urb_enqueue(struct usb_hcd *hcd,
8780+// struct usb_host_endpoint *ep,
8781+ struct urb *urb,
8782+ gfp_t mem_flags
8783+ )
8784+{
8785+ int retval = 0;
8786+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
8787+ dwc_otg_qtd_t *qtd;
8788+
8789+#ifdef DEBUG
8790+ if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
8791+ dump_urb_info(urb, "dwc_otg_hcd_urb_enqueue");
8792+ }
8793+#endif
8794+ if (!dwc_otg_hcd->flags.b.port_connect_status) {
8795+ /* No longer connected. */
8796+ return -ENODEV;
8797+ }
8798+
8799+ hcd_check_and_patch_dma_addr(urb);
8800+ qtd = dwc_otg_hcd_qtd_create(urb);
8801+ if (qtd == NULL) {
8802+ DWC_ERROR("DWC OTG HCD URB Enqueue failed creating QTD\n");
8803+ return -ENOMEM;
8804+ }
8805+
8806+ retval = dwc_otg_hcd_qtd_add(qtd, dwc_otg_hcd);
8807+ if (retval < 0) {
8808+ DWC_ERROR("DWC OTG HCD URB Enqueue failed adding QTD. "
8809+ "Error status %d\n", retval);
8810+ dwc_otg_hcd_qtd_free(qtd);
8811+ }
8812+
8813+ return retval;
8814+}
8815+
8816+/** Aborts/cancels a USB transfer request. Always returns 0 to indicate
8817+ * success. */
8818+int dwc_otg_hcd_urb_dequeue(struct usb_hcd *hcd,
8819+ struct urb *urb, int status)
8820+{
8821+ unsigned long flags;
8822+ dwc_otg_hcd_t *dwc_otg_hcd;
8823+ dwc_otg_qtd_t *urb_qtd;
8824+ dwc_otg_qh_t *qh;
8825+ struct usb_host_endpoint *ep = dwc_urb_to_endpoint(urb);
8826+
8827+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD URB Dequeue\n");
8828+
8829+ dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
8830+
8831+ SPIN_LOCK_IRQSAVE(&dwc_otg_hcd->lock, flags);
8832+
8833+ urb_qtd = (dwc_otg_qtd_t *)urb->hcpriv;
8834+ qh = (dwc_otg_qh_t *)ep->hcpriv;
8835+
8836+#ifdef DEBUG
8837+ if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
8838+ dump_urb_info(urb, "dwc_otg_hcd_urb_dequeue");
8839+ if (urb_qtd == qh->qtd_in_process) {
8840+ dump_channel_info(dwc_otg_hcd, qh);
8841+ }
8842+ }
8843+#endif
8844+
8845+ if (urb_qtd == qh->qtd_in_process) {
8846+ /* The QTD is in process (it has been assigned to a channel). */
8847+
8848+ if (dwc_otg_hcd->flags.b.port_connect_status) {
8849+ /*
8850+ * If still connected (i.e. in host mode), halt the
8851+ * channel so it can be used for other transfers. If
8852+ * no longer connected, the host registers can't be
8853+ * written to halt the channel since the core is in
8854+ * device mode.
8855+ */
8856+ dwc_otg_hc_halt(dwc_otg_hcd->core_if, qh->channel,
8857+ DWC_OTG_HC_XFER_URB_DEQUEUE);
8858+ }
8859+ }
8860+
8861+ /*
8862+ * Free the QTD and clean up the associated QH. Leave the QH in the
8863+ * schedule if it has any remaining QTDs.
8864+ */
8865+ dwc_otg_hcd_qtd_remove_and_free(dwc_otg_hcd, urb_qtd);
8866+ if (urb_qtd == qh->qtd_in_process) {
8867+ dwc_otg_hcd_qh_deactivate(dwc_otg_hcd, qh, 0);
8868+ qh->channel = NULL;
8869+ qh->qtd_in_process = NULL;
8870+ } else if (list_empty(&qh->qtd_list)) {
8871+ dwc_otg_hcd_qh_remove(dwc_otg_hcd, qh);
8872+ }
8873+
8874+ SPIN_UNLOCK_IRQRESTORE(&dwc_otg_hcd->lock, flags);
8875+
8876+ urb->hcpriv = NULL;
8877+
8878+ /* Higher layer software sets URB status. */
8879+ usb_hcd_giveback_urb(hcd, urb, status);
8880+ if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
8881+ DWC_PRINT("Called usb_hcd_giveback_urb()\n");
8882+ DWC_PRINT(" urb->status = %d\n", urb->status);
8883+ }
8884+
8885+ return 0;
8886+}
8887+
8888+/** Frees resources in the DWC_otg controller related to a given endpoint. Also
8889+ * clears state in the HCD related to the endpoint. Any URBs for the endpoint
8890+ * must already be dequeued. */
8891+void dwc_otg_hcd_endpoint_disable(struct usb_hcd *hcd,
8892+ struct usb_host_endpoint *ep)
8893+{
8894+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
8895+ dwc_otg_qh_t *qh;
8896+
8897+ unsigned long flags;
8898+ int retry = 0;
8899+
8900+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD EP DISABLE: _bEndpointAddress=0x%02x, "
8901+ "endpoint=%d\n", ep->desc.bEndpointAddress,
8902+ dwc_ep_addr_to_endpoint(ep->desc.bEndpointAddress));
8903+
8904+rescan:
8905+ SPIN_LOCK_IRQSAVE(&dwc_otg_hcd->lock, flags);
8906+ qh = (dwc_otg_qh_t *)(ep->hcpriv);
8907+ if (!qh)
8908+ goto done;
8909+
8910+ /** Check that the QTD list is really empty */
8911+ if (!list_empty(&qh->qtd_list)) {
8912+ if (retry++ < 250) {
8913+ SPIN_UNLOCK_IRQRESTORE(&dwc_otg_hcd->lock, flags);
8914+ schedule_timeout_uninterruptible(1);
8915+ goto rescan;
8916+ }
8917+
8918+ DWC_WARN("DWC OTG HCD EP DISABLE:"
8919+ " QTD List for this endpoint is not empty\n");
8920+ }
8921+
8922+ dwc_otg_hcd_qh_remove_and_free(dwc_otg_hcd, qh);
8923+ ep->hcpriv = NULL;
8924+done:
8925+ SPIN_UNLOCK_IRQRESTORE(&dwc_otg_hcd->lock, flags);
8926+
8927+}
8928+
8929+/** Handles host mode interrupts for the DWC_otg controller. Returns IRQ_NONE if
8930+ * there was no interrupt to handle. Returns IRQ_HANDLED if there was a valid
8931+ * interrupt.
8932+ *
8933+ * This function is called by the USB core when an interrupt occurs */
8934+irqreturn_t dwc_otg_hcd_irq(struct usb_hcd *hcd)
8935+{
8936+ int retVal = 0;
8937+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
8938+ retVal = dwc_otg_hcd_handle_intr(dwc_otg_hcd);
8939+ if (dwc_otg_hcd->flags.b.port_connect_status_change == 1)
8940+ usb_hcd_poll_rh_status(hcd);
8941+ return IRQ_RETVAL(retVal);
8942+}
8943+
8944+/** Creates Status Change bitmap for the root hub and root port. The bitmap is
8945+ * returned in buf. Bit 0 is the status change indicator for the root hub. Bit 1
8946+ * is the status change indicator for the single root port. Returns 1 if either
8947+ * change indicator is 1, otherwise returns 0. */
8948+int dwc_otg_hcd_hub_status_data(struct usb_hcd *hcd, char *buf)
8949+{
8950+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
8951+
8952+ buf[0] = 0;
8953+ buf[0] |= (dwc_otg_hcd->flags.b.port_connect_status_change ||
8954+ dwc_otg_hcd->flags.b.port_reset_change ||
8955+ dwc_otg_hcd->flags.b.port_enable_change ||
8956+ dwc_otg_hcd->flags.b.port_suspend_change ||
8957+ dwc_otg_hcd->flags.b.port_over_current_change) << 1;
8958+
8959+#ifdef DEBUG
8960+ if (buf[0]) {
8961+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB STATUS DATA:"
8962+ " Root port status changed\n");
8963+ DWC_DEBUGPL(DBG_HCDV, " port_connect_status_change: %d\n",
8964+ dwc_otg_hcd->flags.b.port_connect_status_change);
8965+ DWC_DEBUGPL(DBG_HCDV, " port_reset_change: %d\n",
8966+ dwc_otg_hcd->flags.b.port_reset_change);
8967+ DWC_DEBUGPL(DBG_HCDV, " port_enable_change: %d\n",
8968+ dwc_otg_hcd->flags.b.port_enable_change);
8969+ DWC_DEBUGPL(DBG_HCDV, " port_suspend_change: %d\n",
8970+ dwc_otg_hcd->flags.b.port_suspend_change);
8971+ DWC_DEBUGPL(DBG_HCDV, " port_over_current_change: %d\n",
8972+ dwc_otg_hcd->flags.b.port_over_current_change);
8973+ }
8974+#endif
8975+ return (buf[0] != 0);
8976+}
8977+
8978+#ifdef DWC_HS_ELECT_TST
8979+/*
8980+ * Quick and dirty hack to implement the HS Electrical Test
8981+ * SINGLE_STEP_GET_DEVICE_DESCRIPTOR feature.
8982+ *
8983+ * This code was copied from our userspace app "hset". It sends a
8984+ * Get Device Descriptor control sequence in two parts, first the
8985+ * Setup packet by itself, followed some time later by the In and
8986+ * Ack packets. Rather than trying to figure out how to add this
8987+ * functionality to the normal driver code, we just hijack the
8988+ * hardware, using these two function to drive the hardware
8989+ * directly.
8990+ */
8991+
8992+dwc_otg_core_global_regs_t *global_regs;
8993+dwc_otg_host_global_regs_t *hc_global_regs;
8994+dwc_otg_hc_regs_t *hc_regs;
8995+uint32_t *data_fifo;
8996+
8997+static void do_setup(void)
8998+{
8999+ gintsts_data_t gintsts;
9000+ hctsiz_data_t hctsiz;
9001+ hcchar_data_t hcchar;
9002+ haint_data_t haint;
9003+ hcint_data_t hcint;
9004+
9005+ /* Enable HAINTs */
9006+ dwc_write_reg32(&hc_global_regs->haintmsk, 0x0001);
9007+
9008+ /* Enable HCINTs */
9009+ dwc_write_reg32(&hc_regs->hcintmsk, 0x04a3);
9010+
9011+ /* Read GINTSTS */
9012+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9013+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
9014+
9015+ /* Read HAINT */
9016+ haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
9017+ //fprintf(stderr, "HAINT: %08x\n", haint.d32);
9018+
9019+ /* Read HCINT */
9020+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
9021+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
9022+
9023+ /* Read HCCHAR */
9024+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
9025+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
9026+
9027+ /* Clear HCINT */
9028+ dwc_write_reg32(&hc_regs->hcint, hcint.d32);
9029+
9030+ /* Clear HAINT */
9031+ dwc_write_reg32(&hc_global_regs->haint, haint.d32);
9032+
9033+ /* Clear GINTSTS */
9034+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
9035+
9036+ /* Read GINTSTS */
9037+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9038+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
9039+
9040+ /*
9041+ * Send Setup packet (Get Device Descriptor)
9042+ */
9043+
9044+ /* Make sure channel is disabled */
9045+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
9046+ if (hcchar.b.chen) {
9047+ //fprintf(stderr, "Channel already enabled 1, HCCHAR = %08x\n", hcchar.d32);
9048+ hcchar.b.chdis = 1;
9049+// hcchar.b.chen = 1;
9050+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
9051+ //sleep(1);
9052+ mdelay(1000);
9053+
9054+ /* Read GINTSTS */
9055+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9056+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
9057+
9058+ /* Read HAINT */
9059+ haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
9060+ //fprintf(stderr, "HAINT: %08x\n", haint.d32);
9061+
9062+ /* Read HCINT */
9063+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
9064+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
9065+
9066+ /* Read HCCHAR */
9067+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
9068+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
9069+
9070+ /* Clear HCINT */
9071+ dwc_write_reg32(&hc_regs->hcint, hcint.d32);
9072+
9073+ /* Clear HAINT */
9074+ dwc_write_reg32(&hc_global_regs->haint, haint.d32);
9075+
9076+ /* Clear GINTSTS */
9077+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
9078+
9079+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
9080+ //if (hcchar.b.chen) {
9081+ // fprintf(stderr, "** Channel _still_ enabled 1, HCCHAR = %08x **\n", hcchar.d32);
9082+ //}
9083+ }
9084+
9085+ /* Set HCTSIZ */
9086+ hctsiz.d32 = 0;
9087+ hctsiz.b.xfersize = 8;
9088+ hctsiz.b.pktcnt = 1;
9089+ hctsiz.b.pid = DWC_OTG_HC_PID_SETUP;
9090+ dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
9091+
9092+ /* Set HCCHAR */
9093+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
9094+ hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;
9095+ hcchar.b.epdir = 0;
9096+ hcchar.b.epnum = 0;
9097+ hcchar.b.mps = 8;
9098+ hcchar.b.chen = 1;
9099+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
9100+
9101+ /* Fill FIFO with Setup data for Get Device Descriptor */
9102+ data_fifo = (uint32_t *)((char *)global_regs + 0x1000);
9103+ dwc_write_reg32(data_fifo++, 0x01000680);
9104+ dwc_write_reg32(data_fifo++, 0x00080000);
9105+
9106+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9107+ //fprintf(stderr, "Waiting for HCINTR intr 1, GINTSTS = %08x\n", gintsts.d32);
9108+
9109+ /* Wait for host channel interrupt */
9110+ do {
9111+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9112+ } while (gintsts.b.hcintr == 0);
9113+
9114+ //fprintf(stderr, "Got HCINTR intr 1, GINTSTS = %08x\n", gintsts.d32);
9115+
9116+ /* Disable HCINTs */
9117+ dwc_write_reg32(&hc_regs->hcintmsk, 0x0000);
9118+
9119+ /* Disable HAINTs */
9120+ dwc_write_reg32(&hc_global_regs->haintmsk, 0x0000);
9121+
9122+ /* Read HAINT */
9123+ haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
9124+ //fprintf(stderr, "HAINT: %08x\n", haint.d32);
9125+
9126+ /* Read HCINT */
9127+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
9128+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
9129+
9130+ /* Read HCCHAR */
9131+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
9132+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
9133+
9134+ /* Clear HCINT */
9135+ dwc_write_reg32(&hc_regs->hcint, hcint.d32);
9136+
9137+ /* Clear HAINT */
9138+ dwc_write_reg32(&hc_global_regs->haint, haint.d32);
9139+
9140+ /* Clear GINTSTS */
9141+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
9142+
9143+ /* Read GINTSTS */
9144+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9145+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
9146+}
9147+
9148+static void do_in_ack(void)
9149+{
9150+ gintsts_data_t gintsts;
9151+ hctsiz_data_t hctsiz;
9152+ hcchar_data_t hcchar;
9153+ haint_data_t haint;
9154+ hcint_data_t hcint;
9155+ host_grxsts_data_t grxsts;
9156+
9157+ /* Enable HAINTs */
9158+ dwc_write_reg32(&hc_global_regs->haintmsk, 0x0001);
9159+
9160+ /* Enable HCINTs */
9161+ dwc_write_reg32(&hc_regs->hcintmsk, 0x04a3);
9162+
9163+ /* Read GINTSTS */
9164+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9165+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
9166+
9167+ /* Read HAINT */
9168+ haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
9169+ //fprintf(stderr, "HAINT: %08x\n", haint.d32);
9170+
9171+ /* Read HCINT */
9172+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
9173+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
9174+
9175+ /* Read HCCHAR */
9176+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
9177+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
9178+
9179+ /* Clear HCINT */
9180+ dwc_write_reg32(&hc_regs->hcint, hcint.d32);
9181+
9182+ /* Clear HAINT */
9183+ dwc_write_reg32(&hc_global_regs->haint, haint.d32);
9184+
9185+ /* Clear GINTSTS */
9186+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
9187+
9188+ /* Read GINTSTS */
9189+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9190+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
9191+
9192+ /*
9193+ * Receive Control In packet
9194+ */
9195+
9196+ /* Make sure channel is disabled */
9197+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
9198+ if (hcchar.b.chen) {
9199+ //fprintf(stderr, "Channel already enabled 2, HCCHAR = %08x\n", hcchar.d32);
9200+ hcchar.b.chdis = 1;
9201+ hcchar.b.chen = 1;
9202+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
9203+ //sleep(1);
9204+ mdelay(1000);
9205+
9206+ /* Read GINTSTS */
9207+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9208+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
9209+
9210+ /* Read HAINT */
9211+ haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
9212+ //fprintf(stderr, "HAINT: %08x\n", haint.d32);
9213+
9214+ /* Read HCINT */
9215+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
9216+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
9217+
9218+ /* Read HCCHAR */
9219+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
9220+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
9221+
9222+ /* Clear HCINT */
9223+ dwc_write_reg32(&hc_regs->hcint, hcint.d32);
9224+
9225+ /* Clear HAINT */
9226+ dwc_write_reg32(&hc_global_regs->haint, haint.d32);
9227+
9228+ /* Clear GINTSTS */
9229+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
9230+
9231+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
9232+ //if (hcchar.b.chen) {
9233+ // fprintf(stderr, "** Channel _still_ enabled 2, HCCHAR = %08x **\n", hcchar.d32);
9234+ //}
9235+ }
9236+
9237+ /* Set HCTSIZ */
9238+ hctsiz.d32 = 0;
9239+ hctsiz.b.xfersize = 8;
9240+ hctsiz.b.pktcnt = 1;
9241+ hctsiz.b.pid = DWC_OTG_HC_PID_DATA1;
9242+ dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
9243+
9244+ /* Set HCCHAR */
9245+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
9246+ hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;
9247+ hcchar.b.epdir = 1;
9248+ hcchar.b.epnum = 0;
9249+ hcchar.b.mps = 8;
9250+ hcchar.b.chen = 1;
9251+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
9252+
9253+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9254+ //fprintf(stderr, "Waiting for RXSTSQLVL intr 1, GINTSTS = %08x\n", gintsts.d32);
9255+
9256+ /* Wait for receive status queue interrupt */
9257+ do {
9258+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9259+ } while (gintsts.b.rxstsqlvl == 0);
9260+
9261+ //fprintf(stderr, "Got RXSTSQLVL intr 1, GINTSTS = %08x\n", gintsts.d32);
9262+
9263+ /* Read RXSTS */
9264+ grxsts.d32 = dwc_read_reg32(&global_regs->grxstsp);
9265+ //fprintf(stderr, "GRXSTS: %08x\n", grxsts.d32);
9266+
9267+ /* Clear RXSTSQLVL in GINTSTS */
9268+ gintsts.d32 = 0;
9269+ gintsts.b.rxstsqlvl = 1;
9270+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
9271+
9272+ switch (grxsts.b.pktsts) {
9273+ case DWC_GRXSTS_PKTSTS_IN:
9274+ /* Read the data into the host buffer */
9275+ if (grxsts.b.bcnt > 0) {
9276+ int i;
9277+ int word_count = (grxsts.b.bcnt + 3) / 4;
9278+
9279+ data_fifo = (uint32_t *)((char *)global_regs + 0x1000);
9280+
9281+ for (i = 0; i < word_count; i++) {
9282+ (void)dwc_read_reg32(data_fifo++);
9283+ }
9284+ }
9285+
9286+ //fprintf(stderr, "Received %u bytes\n", (unsigned)grxsts.b.bcnt);
9287+ break;
9288+
9289+ default:
9290+ //fprintf(stderr, "** Unexpected GRXSTS packet status 1 **\n");
9291+ break;
9292+ }
9293+
9294+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9295+ //fprintf(stderr, "Waiting for RXSTSQLVL intr 2, GINTSTS = %08x\n", gintsts.d32);
9296+
9297+ /* Wait for receive status queue interrupt */
9298+ do {
9299+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9300+ } while (gintsts.b.rxstsqlvl == 0);
9301+
9302+ //fprintf(stderr, "Got RXSTSQLVL intr 2, GINTSTS = %08x\n", gintsts.d32);
9303+
9304+ /* Read RXSTS */
9305+ grxsts.d32 = dwc_read_reg32(&global_regs->grxstsp);
9306+ //fprintf(stderr, "GRXSTS: %08x\n", grxsts.d32);
9307+
9308+ /* Clear RXSTSQLVL in GINTSTS */
9309+ gintsts.d32 = 0;
9310+ gintsts.b.rxstsqlvl = 1;
9311+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
9312+
9313+ switch (grxsts.b.pktsts) {
9314+ case DWC_GRXSTS_PKTSTS_IN_XFER_COMP:
9315+ break;
9316+
9317+ default:
9318+ //fprintf(stderr, "** Unexpected GRXSTS packet status 2 **\n");
9319+ break;
9320+ }
9321+
9322+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9323+ //fprintf(stderr, "Waiting for HCINTR intr 2, GINTSTS = %08x\n", gintsts.d32);
9324+
9325+ /* Wait for host channel interrupt */
9326+ do {
9327+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9328+ } while (gintsts.b.hcintr == 0);
9329+
9330+ //fprintf(stderr, "Got HCINTR intr 2, GINTSTS = %08x\n", gintsts.d32);
9331+
9332+ /* Read HAINT */
9333+ haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
9334+ //fprintf(stderr, "HAINT: %08x\n", haint.d32);
9335+
9336+ /* Read HCINT */
9337+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
9338+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
9339+
9340+ /* Read HCCHAR */
9341+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
9342+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
9343+
9344+ /* Clear HCINT */
9345+ dwc_write_reg32(&hc_regs->hcint, hcint.d32);
9346+
9347+ /* Clear HAINT */
9348+ dwc_write_reg32(&hc_global_regs->haint, haint.d32);
9349+
9350+ /* Clear GINTSTS */
9351+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
9352+
9353+ /* Read GINTSTS */
9354+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9355+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
9356+
9357+// usleep(100000);
9358+// mdelay(100);
9359+ mdelay(1);
9360+
9361+ /*
9362+ * Send handshake packet
9363+ */
9364+
9365+ /* Read HAINT */
9366+ haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
9367+ //fprintf(stderr, "HAINT: %08x\n", haint.d32);
9368+
9369+ /* Read HCINT */
9370+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
9371+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
9372+
9373+ /* Read HCCHAR */
9374+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
9375+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
9376+
9377+ /* Clear HCINT */
9378+ dwc_write_reg32(&hc_regs->hcint, hcint.d32);
9379+
9380+ /* Clear HAINT */
9381+ dwc_write_reg32(&hc_global_regs->haint, haint.d32);
9382+
9383+ /* Clear GINTSTS */
9384+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
9385+
9386+ /* Read GINTSTS */
9387+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9388+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
9389+
9390+ /* Make sure channel is disabled */
9391+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
9392+ if (hcchar.b.chen) {
9393+ //fprintf(stderr, "Channel already enabled 3, HCCHAR = %08x\n", hcchar.d32);
9394+ hcchar.b.chdis = 1;
9395+ hcchar.b.chen = 1;
9396+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
9397+ //sleep(1);
9398+ mdelay(1000);
9399+
9400+ /* Read GINTSTS */
9401+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9402+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
9403+
9404+ /* Read HAINT */
9405+ haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
9406+ //fprintf(stderr, "HAINT: %08x\n", haint.d32);
9407+
9408+ /* Read HCINT */
9409+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
9410+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
9411+
9412+ /* Read HCCHAR */
9413+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
9414+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
9415+
9416+ /* Clear HCINT */
9417+ dwc_write_reg32(&hc_regs->hcint, hcint.d32);
9418+
9419+ /* Clear HAINT */
9420+ dwc_write_reg32(&hc_global_regs->haint, haint.d32);
9421+
9422+ /* Clear GINTSTS */
9423+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
9424+
9425+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
9426+ //if (hcchar.b.chen) {
9427+ // fprintf(stderr, "** Channel _still_ enabled 3, HCCHAR = %08x **\n", hcchar.d32);
9428+ //}
9429+ }
9430+
9431+ /* Set HCTSIZ */
9432+ hctsiz.d32 = 0;
9433+ hctsiz.b.xfersize = 0;
9434+ hctsiz.b.pktcnt = 1;
9435+ hctsiz.b.pid = DWC_OTG_HC_PID_DATA1;
9436+ dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
9437+
9438+ /* Set HCCHAR */
9439+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
9440+ hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;
9441+ hcchar.b.epdir = 0;
9442+ hcchar.b.epnum = 0;
9443+ hcchar.b.mps = 8;
9444+ hcchar.b.chen = 1;
9445+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
9446+
9447+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9448+ //fprintf(stderr, "Waiting for HCINTR intr 3, GINTSTS = %08x\n", gintsts.d32);
9449+
9450+ /* Wait for host channel interrupt */
9451+ do {
9452+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9453+ } while (gintsts.b.hcintr == 0);
9454+
9455+ //fprintf(stderr, "Got HCINTR intr 3, GINTSTS = %08x\n", gintsts.d32);
9456+
9457+ /* Disable HCINTs */
9458+ dwc_write_reg32(&hc_regs->hcintmsk, 0x0000);
9459+
9460+ /* Disable HAINTs */
9461+ dwc_write_reg32(&hc_global_regs->haintmsk, 0x0000);
9462+
9463+ /* Read HAINT */
9464+ haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
9465+ //fprintf(stderr, "HAINT: %08x\n", haint.d32);
9466+
9467+ /* Read HCINT */
9468+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
9469+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
9470+
9471+ /* Read HCCHAR */
9472+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
9473+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
9474+
9475+ /* Clear HCINT */
9476+ dwc_write_reg32(&hc_regs->hcint, hcint.d32);
9477+
9478+ /* Clear HAINT */
9479+ dwc_write_reg32(&hc_global_regs->haint, haint.d32);
9480+
9481+ /* Clear GINTSTS */
9482+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
9483+
9484+ /* Read GINTSTS */
9485+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
9486+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
9487+}
9488+#endif /* DWC_HS_ELECT_TST */
9489+
9490+/** Handles hub class-specific requests. */
9491+int dwc_otg_hcd_hub_control(struct usb_hcd *hcd,
9492+ u16 typeReq,
9493+ u16 wValue,
9494+ u16 wIndex,
9495+ char *buf,
9496+ u16 wLength)
9497+{
9498+ int retval = 0;
9499+
9500+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
9501+ dwc_otg_core_if_t *core_if = hcd_to_dwc_otg_hcd(hcd)->core_if;
9502+ struct usb_hub_descriptor *desc;
9503+ hprt0_data_t hprt0 = {.d32 = 0};
9504+
9505+ uint32_t port_status;
9506+
9507+ switch (typeReq) {
9508+ case ClearHubFeature:
9509+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9510+ "ClearHubFeature 0x%x\n", wValue);
9511+ switch (wValue) {
9512+ case C_HUB_LOCAL_POWER:
9513+ case C_HUB_OVER_CURRENT:
9514+ /* Nothing required here */
9515+ break;
9516+ default:
9517+ retval = -EINVAL;
9518+ DWC_ERROR("DWC OTG HCD - "
9519+ "ClearHubFeature request %xh unknown\n", wValue);
9520+ }
9521+ break;
9522+ case ClearPortFeature:
9523+ if (!wIndex || wIndex > 1)
9524+ goto error;
9525+
9526+ switch (wValue) {
9527+ case USB_PORT_FEAT_ENABLE:
9528+ DWC_DEBUGPL(DBG_ANY, "DWC OTG HCD HUB CONTROL - "
9529+ "ClearPortFeature USB_PORT_FEAT_ENABLE\n");
9530+ hprt0.d32 = dwc_otg_read_hprt0(core_if);
9531+ hprt0.b.prtena = 1;
9532+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
9533+ break;
9534+ case USB_PORT_FEAT_SUSPEND:
9535+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9536+ "ClearPortFeature USB_PORT_FEAT_SUSPEND\n");
9537+ hprt0.d32 = dwc_otg_read_hprt0(core_if);
9538+ hprt0.b.prtres = 1;
9539+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
9540+ /* Clear Resume bit */
9541+ mdelay(100);
9542+ hprt0.b.prtres = 0;
9543+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
9544+ break;
9545+ case USB_PORT_FEAT_POWER:
9546+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9547+ "ClearPortFeature USB_PORT_FEAT_POWER\n");
9548+ hprt0.d32 = dwc_otg_read_hprt0(core_if);
9549+ hprt0.b.prtpwr = 0;
9550+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
9551+ break;
9552+ case USB_PORT_FEAT_INDICATOR:
9553+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9554+ "ClearPortFeature USB_PORT_FEAT_INDICATOR\n");
9555+ /* Port inidicator not supported */
9556+ break;
9557+ case USB_PORT_FEAT_C_CONNECTION:
9558+ /* Clears drivers internal connect status change
9559+ * flag */
9560+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9561+ "ClearPortFeature USB_PORT_FEAT_C_CONNECTION\n");
9562+ dwc_otg_hcd->flags.b.port_connect_status_change = 0;
9563+ break;
9564+ case USB_PORT_FEAT_C_RESET:
9565+ /* Clears the driver's internal Port Reset Change
9566+ * flag */
9567+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9568+ "ClearPortFeature USB_PORT_FEAT_C_RESET\n");
9569+ dwc_otg_hcd->flags.b.port_reset_change = 0;
9570+ break;
9571+ case USB_PORT_FEAT_C_ENABLE:
9572+ /* Clears the driver's internal Port
9573+ * Enable/Disable Change flag */
9574+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9575+ "ClearPortFeature USB_PORT_FEAT_C_ENABLE\n");
9576+ dwc_otg_hcd->flags.b.port_enable_change = 0;
9577+ break;
9578+ case USB_PORT_FEAT_C_SUSPEND:
9579+ /* Clears the driver's internal Port Suspend
9580+ * Change flag, which is set when resume signaling on
9581+ * the host port is complete */
9582+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9583+ "ClearPortFeature USB_PORT_FEAT_C_SUSPEND\n");
9584+ dwc_otg_hcd->flags.b.port_suspend_change = 0;
9585+ break;
9586+ case USB_PORT_FEAT_C_OVER_CURRENT:
9587+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9588+ "ClearPortFeature USB_PORT_FEAT_C_OVER_CURRENT\n");
9589+ dwc_otg_hcd->flags.b.port_over_current_change = 0;
9590+ break;
9591+ default:
9592+ retval = -EINVAL;
9593+ DWC_ERROR("DWC OTG HCD - "
9594+ "ClearPortFeature request %xh "
9595+ "unknown or unsupported\n", wValue);
9596+ }
9597+ break;
9598+ case GetHubDescriptor:
9599+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9600+ "GetHubDescriptor\n");
9601+ desc = (struct usb_hub_descriptor *)buf;
9602+ desc->bDescLength = 9;
9603+ desc->bDescriptorType = 0x29;
9604+ desc->bNbrPorts = 1;
9605+ desc->wHubCharacteristics = 0x08;
9606+ desc->bPwrOn2PwrGood = 1;
9607+ desc->bHubContrCurrent = 0;
9608+ desc->u.hs.DeviceRemovable[0] = 0;
9609+ desc->u.hs.DeviceRemovable[1] = 0xff;
9610+ break;
9611+ case GetHubStatus:
9612+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9613+ "GetHubStatus\n");
9614+ memset(buf, 0, 4);
9615+ break;
9616+ case GetPortStatus:
9617+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9618+ "GetPortStatus\n");
9619+
9620+ if (!wIndex || wIndex > 1)
9621+ goto error;
9622+
9623+ port_status = 0;
9624+
9625+ if (dwc_otg_hcd->flags.b.port_connect_status_change)
9626+ port_status |= (1 << USB_PORT_FEAT_C_CONNECTION);
9627+
9628+ if (dwc_otg_hcd->flags.b.port_enable_change)
9629+ port_status |= (1 << USB_PORT_FEAT_C_ENABLE);
9630+
9631+ if (dwc_otg_hcd->flags.b.port_suspend_change)
9632+ port_status |= (1 << USB_PORT_FEAT_C_SUSPEND);
9633+
9634+ if (dwc_otg_hcd->flags.b.port_reset_change)
9635+ port_status |= (1 << USB_PORT_FEAT_C_RESET);
9636+
9637+ if (dwc_otg_hcd->flags.b.port_over_current_change) {
9638+ DWC_ERROR("Device Not Supported\n");
9639+ port_status |= (1 << USB_PORT_FEAT_C_OVER_CURRENT);
9640+ }
9641+
9642+ if (!dwc_otg_hcd->flags.b.port_connect_status) {
9643+ /*
9644+ * The port is disconnected, which means the core is
9645+ * either in device mode or it soon will be. Just
9646+ * return 0's for the remainder of the port status
9647+ * since the port register can't be read if the core
9648+ * is in device mode.
9649+ */
9650+ *((__le32 *) buf) = cpu_to_le32(port_status);
9651+ break;
9652+ }
9653+
9654+ hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
9655+ DWC_DEBUGPL(DBG_HCDV, " HPRT0: 0x%08x\n", hprt0.d32);
9656+
9657+ if (hprt0.b.prtconnsts)
9658+ port_status |= (1 << USB_PORT_FEAT_CONNECTION);
9659+
9660+ if (hprt0.b.prtena)
9661+ port_status |= (1 << USB_PORT_FEAT_ENABLE);
9662+
9663+ if (hprt0.b.prtsusp)
9664+ port_status |= (1 << USB_PORT_FEAT_SUSPEND);
9665+
9666+ if (hprt0.b.prtovrcurract)
9667+ port_status |= (1 << USB_PORT_FEAT_OVER_CURRENT);
9668+
9669+ if (hprt0.b.prtrst)
9670+ port_status |= (1 << USB_PORT_FEAT_RESET);
9671+
9672+ if (hprt0.b.prtpwr)
9673+ port_status |= (1 << USB_PORT_FEAT_POWER);
9674+
9675+ if (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_HIGH_SPEED)
9676+ port_status |= (USB_PORT_STAT_HIGH_SPEED);
9677+ else if (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_LOW_SPEED)
9678+ port_status |= (USB_PORT_STAT_LOW_SPEED);
9679+
9680+ if (hprt0.b.prttstctl)
9681+ port_status |= (1 << USB_PORT_FEAT_TEST);
9682+
9683+ /* USB_PORT_FEAT_INDICATOR unsupported always 0 */
9684+
9685+ *((__le32 *) buf) = cpu_to_le32(port_status);
9686+
9687+ break;
9688+ case SetHubFeature:
9689+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9690+ "SetHubFeature\n");
9691+ /* No HUB features supported */
9692+ break;
9693+ case SetPortFeature:
9694+ if (wValue != USB_PORT_FEAT_TEST && (!wIndex || wIndex > 1))
9695+ goto error;
9696+
9697+ if (!dwc_otg_hcd->flags.b.port_connect_status) {
9698+ /*
9699+ * The port is disconnected, which means the core is
9700+ * either in device mode or it soon will be. Just
9701+ * return without doing anything since the port
9702+ * register can't be written if the core is in device
9703+ * mode.
9704+ */
9705+ break;
9706+ }
9707+
9708+ switch (wValue) {
9709+ case USB_PORT_FEAT_SUSPEND:
9710+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9711+ "SetPortFeature - USB_PORT_FEAT_SUSPEND\n");
9712+ if (hcd->self.otg_port == wIndex &&
9713+ hcd->self.b_hnp_enable) {
9714+ gotgctl_data_t gotgctl = {.d32=0};
9715+ gotgctl.b.hstsethnpen = 1;
9716+ dwc_modify_reg32(&core_if->core_global_regs->gotgctl,
9717+ 0, gotgctl.d32);
9718+ core_if->op_state = A_SUSPEND;
9719+ }
9720+ hprt0.d32 = dwc_otg_read_hprt0(core_if);
9721+ hprt0.b.prtsusp = 1;
9722+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
9723+ //DWC_PRINT("SUSPEND: HPRT0=%0x\n", hprt0.d32);
9724+ /* Suspend the Phy Clock */
9725+ {
9726+ pcgcctl_data_t pcgcctl = {.d32=0};
9727+ pcgcctl.b.stoppclk = 1;
9728+ dwc_write_reg32(core_if->pcgcctl, pcgcctl.d32);
9729+ }
9730+
9731+ /* For HNP the bus must be suspended for at least 200ms. */
9732+ if (hcd->self.b_hnp_enable) {
9733+ mdelay(200);
9734+ //DWC_PRINT("SUSPEND: wait complete! (%d)\n", _hcd->state);
9735+ }
9736+ break;
9737+ case USB_PORT_FEAT_POWER:
9738+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9739+ "SetPortFeature - USB_PORT_FEAT_POWER\n");
9740+ hprt0.d32 = dwc_otg_read_hprt0(core_if);
9741+ hprt0.b.prtpwr = 1;
9742+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
9743+ break;
9744+ case USB_PORT_FEAT_RESET:
9745+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9746+ "SetPortFeature - USB_PORT_FEAT_RESET\n");
9747+ hprt0.d32 = dwc_otg_read_hprt0(core_if);
9748+ /* When B-Host the Port reset bit is set in
9749+ * the Start HCD Callback function, so that
9750+ * the reset is started within 1ms of the HNP
9751+ * success interrupt. */
9752+ if (!hcd->self.is_b_host) {
9753+ hprt0.b.prtrst = 1;
9754+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
9755+ }
9756+ /* Clear reset bit in 10ms (FS/LS) or 50ms (HS) */
9757+ MDELAY(60);
9758+ hprt0.b.prtrst = 0;
9759+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
9760+ break;
9761+
9762+#ifdef DWC_HS_ELECT_TST
9763+ case USB_PORT_FEAT_TEST:
9764+ {
9765+ uint32_t t;
9766+ gintmsk_data_t gintmsk;
9767+
9768+ t = (wIndex >> 8); /* MSB wIndex USB */
9769+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9770+ "SetPortFeature - USB_PORT_FEAT_TEST %d\n", t);
9771+ warn("USB_PORT_FEAT_TEST %d\n", t);
9772+ if (t < 6) {
9773+ hprt0.d32 = dwc_otg_read_hprt0(core_if);
9774+ hprt0.b.prttstctl = t;
9775+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
9776+ } else {
9777+ /* Setup global vars with reg addresses (quick and
9778+ * dirty hack, should be cleaned up)
9779+ */
9780+ global_regs = core_if->core_global_regs;
9781+ hc_global_regs = core_if->host_if->host_global_regs;
9782+ hc_regs = (dwc_otg_hc_regs_t *)((char *)global_regs + 0x500);
9783+ data_fifo = (uint32_t *)((char *)global_regs + 0x1000);
9784+
9785+ if (t == 6) { /* HS_HOST_PORT_SUSPEND_RESUME */
9786+ /* Save current interrupt mask */
9787+ gintmsk.d32 = dwc_read_reg32(&global_regs->gintmsk);
9788+
9789+ /* Disable all interrupts while we muck with
9790+ * the hardware directly
9791+ */
9792+ dwc_write_reg32(&global_regs->gintmsk, 0);
9793+
9794+ /* 15 second delay per the test spec */
9795+ mdelay(15000);
9796+
9797+ /* Drive suspend on the root port */
9798+ hprt0.d32 = dwc_otg_read_hprt0(core_if);
9799+ hprt0.b.prtsusp = 1;
9800+ hprt0.b.prtres = 0;
9801+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
9802+
9803+ /* 15 second delay per the test spec */
9804+ mdelay(15000);
9805+
9806+ /* Drive resume on the root port */
9807+ hprt0.d32 = dwc_otg_read_hprt0(core_if);
9808+ hprt0.b.prtsusp = 0;
9809+ hprt0.b.prtres = 1;
9810+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
9811+ mdelay(100);
9812+
9813+ /* Clear the resume bit */
9814+ hprt0.b.prtres = 0;
9815+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
9816+
9817+ /* Restore interrupts */
9818+ dwc_write_reg32(&global_regs->gintmsk, gintmsk.d32);
9819+ } else if (t == 7) { /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR setup */
9820+ /* Save current interrupt mask */
9821+ gintmsk.d32 = dwc_read_reg32(&global_regs->gintmsk);
9822+
9823+ /* Disable all interrupts while we muck with
9824+ * the hardware directly
9825+ */
9826+ dwc_write_reg32(&global_regs->gintmsk, 0);
9827+
9828+ /* 15 second delay per the test spec */
9829+ mdelay(15000);
9830+
9831+ /* Send the Setup packet */
9832+ do_setup();
9833+
9834+ /* 15 second delay so nothing else happens for awhile */
9835+ mdelay(15000);
9836+
9837+ /* Restore interrupts */
9838+ dwc_write_reg32(&global_regs->gintmsk, gintmsk.d32);
9839+ } else if (t == 8) { /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR execute */
9840+ /* Save current interrupt mask */
9841+ gintmsk.d32 = dwc_read_reg32(&global_regs->gintmsk);
9842+
9843+ /* Disable all interrupts while we muck with
9844+ * the hardware directly
9845+ */
9846+ dwc_write_reg32(&global_regs->gintmsk, 0);
9847+
9848+ /* Send the Setup packet */
9849+ do_setup();
9850+
9851+ /* 15 second delay so nothing else happens for awhile */
9852+ mdelay(15000);
9853+
9854+ /* Send the In and Ack packets */
9855+ do_in_ack();
9856+
9857+ /* 15 second delay so nothing else happens for awhile */
9858+ mdelay(15000);
9859+
9860+ /* Restore interrupts */
9861+ dwc_write_reg32(&global_regs->gintmsk, gintmsk.d32);
9862+ }
9863+ }
9864+ break;
9865+ }
9866+#endif /* DWC_HS_ELECT_TST */
9867+
9868+ case USB_PORT_FEAT_INDICATOR:
9869+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
9870+ "SetPortFeature - USB_PORT_FEAT_INDICATOR\n");
9871+ /* Not supported */
9872+ break;
9873+ default:
9874+ retval = -EINVAL;
9875+ DWC_ERROR("DWC OTG HCD - "
9876+ "SetPortFeature request %xh "
9877+ "unknown or unsupported\n", wValue);
9878+ break;
9879+ }
9880+ break;
9881+ default:
9882+ error:
9883+ retval = -EINVAL;
9884+ DWC_WARN("DWC OTG HCD - "
9885+ "Unknown hub control request type or invalid typeReq: %xh wIndex: %xh wValue: %xh\n",
9886+ typeReq, wIndex, wValue);
9887+ break;
9888+ }
9889+
9890+ return retval;
9891+}
9892+
9893+/**
9894+ * Assigns transactions from a QTD to a free host channel and initializes the
9895+ * host channel to perform the transactions. The host channel is removed from
9896+ * the free list.
9897+ *
9898+ * @param hcd The HCD state structure.
9899+ * @param qh Transactions from the first QTD for this QH are selected and
9900+ * assigned to a free host channel.
9901+ */
9902+static void assign_and_init_hc(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh)
9903+{
9904+ dwc_hc_t *hc;
9905+ dwc_otg_qtd_t *qtd;
9906+ struct urb *urb;
9907+
9908+ DWC_DEBUGPL(DBG_HCDV, "%s(%p,%p)\n", __func__, hcd, qh);
9909+
9910+ hc = list_entry(hcd->free_hc_list.next, dwc_hc_t, hc_list_entry);
9911+
9912+ /* Remove the host channel from the free list. */
9913+ list_del_init(&hc->hc_list_entry);
9914+
9915+ qtd = list_entry(qh->qtd_list.next, dwc_otg_qtd_t, qtd_list_entry);
9916+ urb = qtd->urb;
9917+ qh->channel = hc;
9918+ qh->qtd_in_process = qtd;
9919+
9920+ /*
9921+ * Use usb_pipedevice to determine device address. This address is
9922+ * 0 before the SET_ADDRESS command and the correct address afterward.
9923+ */
9924+ hc->dev_addr = usb_pipedevice(urb->pipe);
9925+ hc->ep_num = usb_pipeendpoint(urb->pipe);
9926+
9927+ if (urb->dev->speed == USB_SPEED_LOW) {
9928+ hc->speed = DWC_OTG_EP_SPEED_LOW;
9929+ } else if (urb->dev->speed == USB_SPEED_FULL) {
9930+ hc->speed = DWC_OTG_EP_SPEED_FULL;
9931+ } else {
9932+ hc->speed = DWC_OTG_EP_SPEED_HIGH;
9933+ }
9934+
9935+ hc->max_packet = dwc_max_packet(qh->maxp);
9936+
9937+ hc->xfer_started = 0;
9938+ hc->halt_status = DWC_OTG_HC_XFER_NO_HALT_STATUS;
9939+ hc->error_state = (qtd->error_count > 0);
9940+ hc->halt_on_queue = 0;
9941+ hc->halt_pending = 0;
9942+ hc->requests = 0;
9943+
9944+ /*
9945+ * The following values may be modified in the transfer type section
9946+ * below. The xfer_len value may be reduced when the transfer is
9947+ * started to accommodate the max widths of the XferSize and PktCnt
9948+ * fields in the HCTSIZn register.
9949+ */
9950+ hc->do_ping = qh->ping_state;
9951+ hc->ep_is_in = (usb_pipein(urb->pipe) != 0);
9952+ hc->data_pid_start = qh->data_toggle;
9953+ hc->multi_count = 1;
9954+
9955+ if (hcd->core_if->dma_enable) {
9956+ hc->xfer_buff = (uint8_t *)urb->transfer_dma + urb->actual_length;
9957+ } else {
9958+ hc->xfer_buff = (uint8_t *)urb->transfer_buffer + urb->actual_length;
9959+ }
9960+ hc->xfer_len = urb->transfer_buffer_length - urb->actual_length;
9961+ hc->xfer_count = 0;
9962+
9963+ /*
9964+ * Set the split attributes
9965+ */
9966+ hc->do_split = 0;
9967+ if (qh->do_split) {
9968+ hc->do_split = 1;
9969+ hc->xact_pos = qtd->isoc_split_pos;
9970+ hc->complete_split = qtd->complete_split;
9971+ hc->hub_addr = urb->dev->tt->hub->devnum;
9972+ hc->port_addr = urb->dev->ttport;
9973+ }
9974+
9975+ switch (usb_pipetype(urb->pipe)) {
9976+ case PIPE_CONTROL:
9977+ hc->ep_type = DWC_OTG_EP_TYPE_CONTROL;
9978+ switch (qtd->control_phase) {
9979+ case DWC_OTG_CONTROL_SETUP:
9980+ DWC_DEBUGPL(DBG_HCDV, " Control setup transaction\n");
9981+ hc->do_ping = 0;
9982+ hc->ep_is_in = 0;
9983+ hc->data_pid_start = DWC_OTG_HC_PID_SETUP;
9984+ if (hcd->core_if->dma_enable) {
9985+ hc->xfer_buff = (uint8_t *)urb->setup_dma;
9986+ } else {
9987+ hc->xfer_buff = (uint8_t *)urb->setup_packet;
9988+ }
9989+ hc->xfer_len = 8;
9990+ break;
9991+ case DWC_OTG_CONTROL_DATA:
9992+ DWC_DEBUGPL(DBG_HCDV, " Control data transaction\n");
9993+ hc->data_pid_start = qtd->data_toggle;
9994+ break;
9995+ case DWC_OTG_CONTROL_STATUS:
9996+ /*
9997+ * Direction is opposite of data direction or IN if no
9998+ * data.
9999+ */
10000+ DWC_DEBUGPL(DBG_HCDV, " Control status transaction\n");
10001+ if (urb->transfer_buffer_length == 0) {
10002+ hc->ep_is_in = 1;
10003+ } else {
10004+ hc->ep_is_in = (usb_pipein(urb->pipe) != USB_DIR_IN);
10005+ }
10006+ if (hc->ep_is_in) {
10007+ hc->do_ping = 0;
10008+ }
10009+ hc->data_pid_start = DWC_OTG_HC_PID_DATA1;
10010+ hc->xfer_len = 0;
10011+ if (hcd->core_if->dma_enable) {
10012+ hc->xfer_buff = (uint8_t *)hcd->status_buf_dma;
10013+ } else {
10014+ hc->xfer_buff = (uint8_t *)hcd->status_buf;
10015+ }
10016+ break;
10017+ }
10018+ break;
10019+ case PIPE_BULK:
10020+ hc->ep_type = DWC_OTG_EP_TYPE_BULK;
10021+ break;
10022+ case PIPE_INTERRUPT:
10023+ hc->ep_type = DWC_OTG_EP_TYPE_INTR;
10024+ break;
10025+ case PIPE_ISOCHRONOUS:
10026+ {
10027+ struct usb_iso_packet_descriptor *frame_desc;
10028+ frame_desc = &urb->iso_frame_desc[qtd->isoc_frame_index];
10029+ hc->ep_type = DWC_OTG_EP_TYPE_ISOC;
10030+ if (hcd->core_if->dma_enable) {
10031+ hc->xfer_buff = (uint8_t *)urb->transfer_dma;
10032+ } else {
10033+ hc->xfer_buff = (uint8_t *)urb->transfer_buffer;
10034+ }
10035+ hc->xfer_buff += frame_desc->offset + qtd->isoc_split_offset;
10036+ hc->xfer_len = frame_desc->length - qtd->isoc_split_offset;
10037+
10038+ if (hc->xact_pos == DWC_HCSPLIT_XACTPOS_ALL) {
10039+ if (hc->xfer_len <= 188) {
10040+ hc->xact_pos = DWC_HCSPLIT_XACTPOS_ALL;
10041+ }
10042+ else {
10043+ hc->xact_pos = DWC_HCSPLIT_XACTPOS_BEGIN;
10044+ }
10045+ }
10046+ }
10047+ break;
10048+ }
10049+
10050+ if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
10051+ hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
10052+ /*
10053+ * This value may be modified when the transfer is started to
10054+ * reflect the actual transfer length.
10055+ */
10056+ hc->multi_count = dwc_hb_mult(qh->maxp);
10057+ }
10058+
10059+ dwc_otg_hc_init(hcd->core_if, hc);
10060+ hc->qh = qh;
10061+}
10062+
10063+/**
10064+ * This function selects transactions from the HCD transfer schedule and
10065+ * assigns them to available host channels. It is called from HCD interrupt
10066+ * handler functions.
10067+ *
10068+ * @param hcd The HCD state structure.
10069+ *
10070+ * @return The types of new transactions that were assigned to host channels.
10071+ */
10072+dwc_otg_transaction_type_e dwc_otg_hcd_select_transactions(dwc_otg_hcd_t *hcd)
10073+{
10074+ struct list_head *qh_ptr;
10075+ dwc_otg_qh_t *qh;
10076+ int num_channels;
10077+ dwc_otg_transaction_type_e ret_val = DWC_OTG_TRANSACTION_NONE;
10078+
10079+#ifdef DEBUG_SOF
10080+ DWC_DEBUGPL(DBG_HCD, " Select Transactions\n");
10081+#endif
10082+
10083+ /* Process entries in the periodic ready list. */
10084+ qh_ptr = hcd->periodic_sched_ready.next;
10085+ while (qh_ptr != &hcd->periodic_sched_ready &&
10086+ !list_empty(&hcd->free_hc_list)) {
10087+
10088+ qh = list_entry(qh_ptr, dwc_otg_qh_t, qh_list_entry);
10089+ assign_and_init_hc(hcd, qh);
10090+
10091+ /*
10092+ * Move the QH from the periodic ready schedule to the
10093+ * periodic assigned schedule.
10094+ */
10095+ qh_ptr = qh_ptr->next;
10096+ list_move(&qh->qh_list_entry, &hcd->periodic_sched_assigned);
10097+
10098+ ret_val = DWC_OTG_TRANSACTION_PERIODIC;
10099+ }
10100+
10101+ /*
10102+ * Process entries in the inactive portion of the non-periodic
10103+ * schedule. Some free host channels may not be used if they are
10104+ * reserved for periodic transfers.
10105+ */
10106+ qh_ptr = hcd->non_periodic_sched_inactive.next;
10107+ num_channels = hcd->core_if->core_params->host_channels;
10108+ while (qh_ptr != &hcd->non_periodic_sched_inactive &&
10109+ (hcd->non_periodic_channels <
10110+ num_channels - hcd->periodic_channels) &&
10111+ !list_empty(&hcd->free_hc_list)) {
10112+
10113+ qh = list_entry(qh_ptr, dwc_otg_qh_t, qh_list_entry);
10114+ assign_and_init_hc(hcd, qh);
10115+
10116+ /*
10117+ * Move the QH from the non-periodic inactive schedule to the
10118+ * non-periodic active schedule.
10119+ */
10120+ qh_ptr = qh_ptr->next;
10121+ list_move(&qh->qh_list_entry, &hcd->non_periodic_sched_active);
10122+
10123+ if (ret_val == DWC_OTG_TRANSACTION_NONE) {
10124+ ret_val = DWC_OTG_TRANSACTION_NON_PERIODIC;
10125+ } else {
10126+ ret_val = DWC_OTG_TRANSACTION_ALL;
10127+ }
10128+
10129+ hcd->non_periodic_channels++;
10130+ }
10131+
10132+ return ret_val;
10133+}
10134+
10135+/**
10136+ * Attempts to queue a single transaction request for a host channel
10137+ * associated with either a periodic or non-periodic transfer. This function
10138+ * assumes that there is space available in the appropriate request queue. For
10139+ * an OUT transfer or SETUP transaction in Slave mode, it checks whether space
10140+ * is available in the appropriate Tx FIFO.
10141+ *
10142+ * @param hcd The HCD state structure.
10143+ * @param hc Host channel descriptor associated with either a periodic or
10144+ * non-periodic transfer.
10145+ * @param fifo_dwords_avail Number of DWORDs available in the periodic Tx
10146+ * FIFO for periodic transfers or the non-periodic Tx FIFO for non-periodic
10147+ * transfers.
10148+ *
10149+ * @return 1 if a request is queued and more requests may be needed to
10150+ * complete the transfer, 0 if no more requests are required for this
10151+ * transfer, -1 if there is insufficient space in the Tx FIFO.
10152+ */
10153+static int queue_transaction(dwc_otg_hcd_t *hcd,
10154+ dwc_hc_t *hc,
10155+ uint16_t fifo_dwords_avail)
10156+{
10157+ int retval;
10158+
10159+ if (hcd->core_if->dma_enable) {
10160+ if (!hc->xfer_started) {
10161+ dwc_otg_hc_start_transfer(hcd->core_if, hc);
10162+ hc->qh->ping_state = 0;
10163+ }
10164+ retval = 0;
10165+ } else if (hc->halt_pending) {
10166+ /* Don't queue a request if the channel has been halted. */
10167+ retval = 0;
10168+ } else if (hc->halt_on_queue) {
10169+ dwc_otg_hc_halt(hcd->core_if, hc, hc->halt_status);
10170+ retval = 0;
10171+ } else if (hc->do_ping) {
10172+ if (!hc->xfer_started) {
10173+ dwc_otg_hc_start_transfer(hcd->core_if, hc);
10174+ }
10175+ retval = 0;
10176+ } else if (!hc->ep_is_in ||
10177+ hc->data_pid_start == DWC_OTG_HC_PID_SETUP) {
10178+ if ((fifo_dwords_avail * 4) >= hc->max_packet) {
10179+ if (!hc->xfer_started) {
10180+ dwc_otg_hc_start_transfer(hcd->core_if, hc);
10181+ retval = 1;
10182+ } else {
10183+ retval = dwc_otg_hc_continue_transfer(hcd->core_if, hc);
10184+ }
10185+ } else {
10186+ retval = -1;
10187+ }
10188+ } else {
10189+ if (!hc->xfer_started) {
10190+ dwc_otg_hc_start_transfer(hcd->core_if, hc);
10191+ retval = 1;
10192+ } else {
10193+ retval = dwc_otg_hc_continue_transfer(hcd->core_if, hc);
10194+ }
10195+ }
10196+
10197+ return retval;
10198+}
10199+
10200+/**
10201+ * Processes active non-periodic channels and queues transactions for these
10202+ * channels to the DWC_otg controller. After queueing transactions, the NP Tx
10203+ * FIFO Empty interrupt is enabled if there are more transactions to queue as
10204+ * NP Tx FIFO or request queue space becomes available. Otherwise, the NP Tx
10205+ * FIFO Empty interrupt is disabled.
10206+ */
10207+static void process_non_periodic_channels(dwc_otg_hcd_t *hcd)
10208+{
10209+ gnptxsts_data_t tx_status;
10210+ struct list_head *orig_qh_ptr;
10211+ dwc_otg_qh_t *qh;
10212+ int status;
10213+ int no_queue_space = 0;
10214+ int no_fifo_space = 0;
10215+ int more_to_do = 0;
10216+
10217+ dwc_otg_core_global_regs_t *global_regs = hcd->core_if->core_global_regs;
10218+
10219+ DWC_DEBUGPL(DBG_HCDV, "Queue non-periodic transactions\n");
10220+#ifdef DEBUG
10221+ tx_status.d32 = dwc_read_reg32(&global_regs->gnptxsts);
10222+ DWC_DEBUGPL(DBG_HCDV, " NP Tx Req Queue Space Avail (before queue): %d\n",
10223+ tx_status.b.nptxqspcavail);
10224+ DWC_DEBUGPL(DBG_HCDV, " NP Tx FIFO Space Avail (before queue): %d\n",
10225+ tx_status.b.nptxfspcavail);
10226+#endif
10227+ /*
10228+ * Keep track of the starting point. Skip over the start-of-list
10229+ * entry.
10230+ */
10231+ if (hcd->non_periodic_qh_ptr == &hcd->non_periodic_sched_active) {
10232+ hcd->non_periodic_qh_ptr = hcd->non_periodic_qh_ptr->next;
10233+ }
10234+ orig_qh_ptr = hcd->non_periodic_qh_ptr;
10235+
10236+ /*
10237+ * Process once through the active list or until no more space is
10238+ * available in the request queue or the Tx FIFO.
10239+ */
10240+ do {
10241+ tx_status.d32 = dwc_read_reg32(&global_regs->gnptxsts);
10242+ if (!hcd->core_if->dma_enable && tx_status.b.nptxqspcavail == 0) {
10243+ no_queue_space = 1;
10244+ break;
10245+ }
10246+
10247+ qh = list_entry(hcd->non_periodic_qh_ptr, dwc_otg_qh_t, qh_list_entry);
10248+ status = queue_transaction(hcd, qh->channel, tx_status.b.nptxfspcavail);
10249+
10250+ if (status > 0) {
10251+ more_to_do = 1;
10252+ } else if (status < 0) {
10253+ no_fifo_space = 1;
10254+ break;
10255+ }
10256+
10257+ /* Advance to next QH, skipping start-of-list entry. */
10258+ hcd->non_periodic_qh_ptr = hcd->non_periodic_qh_ptr->next;
10259+ if (hcd->non_periodic_qh_ptr == &hcd->non_periodic_sched_active) {
10260+ hcd->non_periodic_qh_ptr = hcd->non_periodic_qh_ptr->next;
10261+ }
10262+
10263+ } while (hcd->non_periodic_qh_ptr != orig_qh_ptr);
10264+
10265+ if (!hcd->core_if->dma_enable) {
10266+ gintmsk_data_t intr_mask = {.d32 = 0};
10267+ intr_mask.b.nptxfempty = 1;
10268+
10269+#ifdef DEBUG
10270+ tx_status.d32 = dwc_read_reg32(&global_regs->gnptxsts);
10271+ DWC_DEBUGPL(DBG_HCDV, " NP Tx Req Queue Space Avail (after queue): %d\n",
10272+ tx_status.b.nptxqspcavail);
10273+ DWC_DEBUGPL(DBG_HCDV, " NP Tx FIFO Space Avail (after queue): %d\n",
10274+ tx_status.b.nptxfspcavail);
10275+#endif
10276+ if (more_to_do || no_queue_space || no_fifo_space) {
10277+ /*
10278+ * May need to queue more transactions as the request
10279+ * queue or Tx FIFO empties. Enable the non-periodic
10280+ * Tx FIFO empty interrupt. (Always use the half-empty
10281+ * level to ensure that new requests are loaded as
10282+ * soon as possible.)
10283+ */
10284+ dwc_modify_reg32(&global_regs->gintmsk, 0, intr_mask.d32);
10285+ } else {
10286+ /*
10287+ * Disable the Tx FIFO empty interrupt since there are
10288+ * no more transactions that need to be queued right
10289+ * now. This function is called from interrupt
10290+ * handlers to queue more transactions as transfer
10291+ * states change.
10292+ */
10293+ dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, 0);
10294+ }
10295+ }
10296+}
10297+
10298+/**
10299+ * Processes periodic channels for the next frame and queues transactions for
10300+ * these channels to the DWC_otg controller. After queueing transactions, the
10301+ * Periodic Tx FIFO Empty interrupt is enabled if there are more transactions
10302+ * to queue as Periodic Tx FIFO or request queue space becomes available.
10303+ * Otherwise, the Periodic Tx FIFO Empty interrupt is disabled.
10304+ */
10305+static void process_periodic_channels(dwc_otg_hcd_t *hcd)
10306+{
10307+ hptxsts_data_t tx_status;
10308+ struct list_head *qh_ptr;
10309+ dwc_otg_qh_t *qh;
10310+ int status;
10311+ int no_queue_space = 0;
10312+ int no_fifo_space = 0;
10313+
10314+ dwc_otg_host_global_regs_t *host_regs;
10315+ host_regs = hcd->core_if->host_if->host_global_regs;
10316+
10317+ DWC_DEBUGPL(DBG_HCDV, "Queue periodic transactions\n");
10318+#ifdef DEBUG
10319+ tx_status.d32 = dwc_read_reg32(&host_regs->hptxsts);
10320+ DWC_DEBUGPL(DBG_HCDV, " P Tx Req Queue Space Avail (before queue): %d\n",
10321+ tx_status.b.ptxqspcavail);
10322+ DWC_DEBUGPL(DBG_HCDV, " P Tx FIFO Space Avail (before queue): %d\n",
10323+ tx_status.b.ptxfspcavail);
10324+#endif
10325+
10326+ qh_ptr = hcd->periodic_sched_assigned.next;
10327+ while (qh_ptr != &hcd->periodic_sched_assigned) {
10328+ tx_status.d32 = dwc_read_reg32(&host_regs->hptxsts);
10329+ if (tx_status.b.ptxqspcavail == 0) {
10330+ no_queue_space = 1;
10331+ break;
10332+ }
10333+
10334+ qh = list_entry(qh_ptr, dwc_otg_qh_t, qh_list_entry);
10335+
10336+ /*
10337+ * Set a flag if we're queuing high-bandwidth in slave mode.
10338+ * The flag prevents any halts to get into the request queue in
10339+ * the middle of multiple high-bandwidth packets getting queued.
10340+ */
10341+ if (!hcd->core_if->dma_enable &&
10342+ qh->channel->multi_count > 1)
10343+ {
10344+ hcd->core_if->queuing_high_bandwidth = 1;
10345+ }
10346+
10347+ status = queue_transaction(hcd, qh->channel, tx_status.b.ptxfspcavail);
10348+ if (status < 0) {
10349+ no_fifo_space = 1;
10350+ break;
10351+ }
10352+
10353+ /*
10354+ * In Slave mode, stay on the current transfer until there is
10355+ * nothing more to do or the high-bandwidth request count is
10356+ * reached. In DMA mode, only need to queue one request. The
10357+ * controller automatically handles multiple packets for
10358+ * high-bandwidth transfers.
10359+ */
10360+ if (hcd->core_if->dma_enable || status == 0 ||
10361+ qh->channel->requests == qh->channel->multi_count) {
10362+ qh_ptr = qh_ptr->next;
10363+ /*
10364+ * Move the QH from the periodic assigned schedule to
10365+ * the periodic queued schedule.
10366+ */
10367+ list_move(&qh->qh_list_entry, &hcd->periodic_sched_queued);
10368+
10369+ /* done queuing high bandwidth */
10370+ hcd->core_if->queuing_high_bandwidth = 0;
10371+ }
10372+ }
10373+
10374+ if (!hcd->core_if->dma_enable) {
10375+ dwc_otg_core_global_regs_t *global_regs;
10376+ gintmsk_data_t intr_mask = {.d32 = 0};
10377+
10378+ global_regs = hcd->core_if->core_global_regs;
10379+ intr_mask.b.ptxfempty = 1;
10380+#ifdef DEBUG
10381+ tx_status.d32 = dwc_read_reg32(&host_regs->hptxsts);
10382+ DWC_DEBUGPL(DBG_HCDV, " P Tx Req Queue Space Avail (after queue): %d\n",
10383+ tx_status.b.ptxqspcavail);
10384+ DWC_DEBUGPL(DBG_HCDV, " P Tx FIFO Space Avail (after queue): %d\n",
10385+ tx_status.b.ptxfspcavail);
10386+#endif
10387+ if (!list_empty(&hcd->periodic_sched_assigned) ||
10388+ no_queue_space || no_fifo_space) {
10389+ /*
10390+ * May need to queue more transactions as the request
10391+ * queue or Tx FIFO empties. Enable the periodic Tx
10392+ * FIFO empty interrupt. (Always use the half-empty
10393+ * level to ensure that new requests are loaded as
10394+ * soon as possible.)
10395+ */
10396+ dwc_modify_reg32(&global_regs->gintmsk, 0, intr_mask.d32);
10397+ } else {
10398+ /*
10399+ * Disable the Tx FIFO empty interrupt since there are
10400+ * no more transactions that need to be queued right
10401+ * now. This function is called from interrupt
10402+ * handlers to queue more transactions as transfer
10403+ * states change.
10404+ */
10405+ dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, 0);
10406+ }
10407+ }
10408+}
10409+
10410+/**
10411+ * This function processes the currently active host channels and queues
10412+ * transactions for these channels to the DWC_otg controller. It is called
10413+ * from HCD interrupt handler functions.
10414+ *
10415+ * @param hcd The HCD state structure.
10416+ * @param tr_type The type(s) of transactions to queue (non-periodic,
10417+ * periodic, or both).
10418+ */
10419+void dwc_otg_hcd_queue_transactions(dwc_otg_hcd_t *hcd,
10420+ dwc_otg_transaction_type_e tr_type)
10421+{
10422+#ifdef DEBUG_SOF
10423+ DWC_DEBUGPL(DBG_HCD, "Queue Transactions\n");
10424+#endif
10425+ /* Process host channels associated with periodic transfers. */
10426+ if ((tr_type == DWC_OTG_TRANSACTION_PERIODIC ||
10427+ tr_type == DWC_OTG_TRANSACTION_ALL) &&
10428+ !list_empty(&hcd->periodic_sched_assigned)) {
10429+
10430+ process_periodic_channels(hcd);
10431+ }
10432+
10433+ /* Process host channels associated with non-periodic transfers. */
10434+ if (tr_type == DWC_OTG_TRANSACTION_NON_PERIODIC ||
10435+ tr_type == DWC_OTG_TRANSACTION_ALL) {
10436+ if (!list_empty(&hcd->non_periodic_sched_active)) {
10437+ process_non_periodic_channels(hcd);
10438+ } else {
10439+ /*
10440+ * Ensure NP Tx FIFO empty interrupt is disabled when
10441+ * there are no non-periodic transfers to process.
10442+ */
10443+ gintmsk_data_t gintmsk = {.d32 = 0};
10444+ gintmsk.b.nptxfempty = 1;
10445+ dwc_modify_reg32(&hcd->core_if->core_global_regs->gintmsk,
10446+ gintmsk.d32, 0);
10447+ }
10448+ }
10449+}
10450+
10451+/**
10452+ * Sets the final status of an URB and returns it to the device driver. Any
10453+ * required cleanup of the URB is performed.
10454+ */
10455+void dwc_otg_hcd_complete_urb(dwc_otg_hcd_t *hcd, struct urb *urb, int status)
10456+{
10457+#ifdef DEBUG
10458+ if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
10459+ DWC_PRINT("%s: urb %p, device %d, ep %d %s, status=%d\n",
10460+ __func__, urb, usb_pipedevice(urb->pipe),
10461+ usb_pipeendpoint(urb->pipe),
10462+ usb_pipein(urb->pipe) ? "IN" : "OUT", status);
10463+ if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
10464+ int i;
10465+ for (i = 0; i < urb->number_of_packets; i++) {
10466+ DWC_PRINT(" ISO Desc %d status: %d\n",
10467+ i, urb->iso_frame_desc[i].status);
10468+ }
10469+ }
10470+ }
10471+#endif
10472+
10473+ //if we use the aligned buffer instead of the original unaligned buffer,
10474+ //for IN data, we have to move the data to the original buffer
10475+ if((urb->transfer_dma==urb->aligned_transfer_dma)&&((urb->transfer_flags & URB_DIR_MASK)==URB_DIR_IN)){
10476+ dma_sync_single_for_device(NULL,urb->transfer_dma,urb->actual_length,DMA_FROM_DEVICE);
10477+ memcpy(urb->transfer_buffer,urb->aligned_transfer_buffer,urb->actual_length);
10478+ }
10479+
10480+
10481+ urb->status = status;
10482+ urb->hcpriv = NULL;
10483+ usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(hcd), urb, status);
10484+}
10485+
10486+/*
10487+ * Returns the Queue Head for an URB.
10488+ */
10489+dwc_otg_qh_t *dwc_urb_to_qh(struct urb *urb)
10490+{
10491+ struct usb_host_endpoint *ep = dwc_urb_to_endpoint(urb);
10492+ return (dwc_otg_qh_t *)ep->hcpriv;
10493+}
10494+
10495+#ifdef DEBUG
10496+void dwc_print_setup_data(uint8_t *setup)
10497+{
10498+ int i;
10499+ if (CHK_DEBUG_LEVEL(DBG_HCD)){
10500+ DWC_PRINT("Setup Data = MSB ");
10501+ for (i = 7; i >= 0; i--) DWC_PRINT("%02x ", setup[i]);
10502+ DWC_PRINT("\n");
10503+ DWC_PRINT(" bmRequestType Tranfer = %s\n", (setup[0] & 0x80) ? "Device-to-Host" : "Host-to-Device");
10504+ DWC_PRINT(" bmRequestType Type = ");
10505+ switch ((setup[0] & 0x60) >> 5) {
10506+ case 0: DWC_PRINT("Standard\n"); break;
10507+ case 1: DWC_PRINT("Class\n"); break;
10508+ case 2: DWC_PRINT("Vendor\n"); break;
10509+ case 3: DWC_PRINT("Reserved\n"); break;
10510+ }
10511+ DWC_PRINT(" bmRequestType Recipient = ");
10512+ switch (setup[0] & 0x1f) {
10513+ case 0: DWC_PRINT("Device\n"); break;
10514+ case 1: DWC_PRINT("Interface\n"); break;
10515+ case 2: DWC_PRINT("Endpoint\n"); break;
10516+ case 3: DWC_PRINT("Other\n"); break;
10517+ default: DWC_PRINT("Reserved\n"); break;
10518+ }
10519+ DWC_PRINT(" bRequest = 0x%0x\n", setup[1]);
10520+ DWC_PRINT(" wValue = 0x%0x\n", *((uint16_t *)&setup[2]));
10521+ DWC_PRINT(" wIndex = 0x%0x\n", *((uint16_t *)&setup[4]));
10522+ DWC_PRINT(" wLength = 0x%0x\n\n", *((uint16_t *)&setup[6]));
10523+ }
10524+}
10525+#endif
10526+
10527+void dwc_otg_hcd_dump_frrem(dwc_otg_hcd_t *hcd) {
10528+}
10529+
10530+void dwc_otg_hcd_dump_state(dwc_otg_hcd_t *hcd)
10531+{
10532+#ifdef DEBUG
10533+ int num_channels;
10534+ int i;
10535+ gnptxsts_data_t np_tx_status;
10536+ hptxsts_data_t p_tx_status;
10537+
10538+ num_channels = hcd->core_if->core_params->host_channels;
10539+ DWC_PRINT("\n");
10540+ DWC_PRINT("************************************************************\n");
10541+ DWC_PRINT("HCD State:\n");
10542+ DWC_PRINT(" Num channels: %d\n", num_channels);
10543+ for (i = 0; i < num_channels; i++) {
10544+ dwc_hc_t *hc = hcd->hc_ptr_array[i];
10545+ DWC_PRINT(" Channel %d:\n", i);
10546+ DWC_PRINT(" dev_addr: %d, ep_num: %d, ep_is_in: %d\n",
10547+ hc->dev_addr, hc->ep_num, hc->ep_is_in);
10548+ DWC_PRINT(" speed: %d\n", hc->speed);
10549+ DWC_PRINT(" ep_type: %d\n", hc->ep_type);
10550+ DWC_PRINT(" max_packet: %d\n", hc->max_packet);
10551+ DWC_PRINT(" data_pid_start: %d\n", hc->data_pid_start);
10552+ DWC_PRINT(" multi_count: %d\n", hc->multi_count);
10553+ DWC_PRINT(" xfer_started: %d\n", hc->xfer_started);
10554+ DWC_PRINT(" xfer_buff: %p\n", hc->xfer_buff);
10555+ DWC_PRINT(" xfer_len: %d\n", hc->xfer_len);
10556+ DWC_PRINT(" xfer_count: %d\n", hc->xfer_count);
10557+ DWC_PRINT(" halt_on_queue: %d\n", hc->halt_on_queue);
10558+ DWC_PRINT(" halt_pending: %d\n", hc->halt_pending);
10559+ DWC_PRINT(" halt_status: %d\n", hc->halt_status);
10560+ DWC_PRINT(" do_split: %d\n", hc->do_split);
10561+ DWC_PRINT(" complete_split: %d\n", hc->complete_split);
10562+ DWC_PRINT(" hub_addr: %d\n", hc->hub_addr);
10563+ DWC_PRINT(" port_addr: %d\n", hc->port_addr);
10564+ DWC_PRINT(" xact_pos: %d\n", hc->xact_pos);
10565+ DWC_PRINT(" requests: %d\n", hc->requests);
10566+ DWC_PRINT(" qh: %p\n", hc->qh);
10567+ if (hc->xfer_started) {
10568+ hfnum_data_t hfnum;
10569+ hcchar_data_t hcchar;
10570+ hctsiz_data_t hctsiz;
10571+ hcint_data_t hcint;
10572+ hcintmsk_data_t hcintmsk;
10573+ hfnum.d32 = dwc_read_reg32(&hcd->core_if->host_if->host_global_regs->hfnum);
10574+ hcchar.d32 = dwc_read_reg32(&hcd->core_if->host_if->hc_regs[i]->hcchar);
10575+ hctsiz.d32 = dwc_read_reg32(&hcd->core_if->host_if->hc_regs[i]->hctsiz);
10576+ hcint.d32 = dwc_read_reg32(&hcd->core_if->host_if->hc_regs[i]->hcint);
10577+ hcintmsk.d32 = dwc_read_reg32(&hcd->core_if->host_if->hc_regs[i]->hcintmsk);
10578+ DWC_PRINT(" hfnum: 0x%08x\n", hfnum.d32);
10579+ DWC_PRINT(" hcchar: 0x%08x\n", hcchar.d32);
10580+ DWC_PRINT(" hctsiz: 0x%08x\n", hctsiz.d32);
10581+ DWC_PRINT(" hcint: 0x%08x\n", hcint.d32);
10582+ DWC_PRINT(" hcintmsk: 0x%08x\n", hcintmsk.d32);
10583+ }
10584+ if (hc->xfer_started && hc->qh && hc->qh->qtd_in_process) {
10585+ dwc_otg_qtd_t *qtd;
10586+ struct urb *urb;
10587+ qtd = hc->qh->qtd_in_process;
10588+ urb = qtd->urb;
10589+ DWC_PRINT(" URB Info:\n");
10590+ DWC_PRINT(" qtd: %p, urb: %p\n", qtd, urb);
10591+ if (urb) {
10592+ DWC_PRINT(" Dev: %d, EP: %d %s\n",
10593+ usb_pipedevice(urb->pipe), usb_pipeendpoint(urb->pipe),
10594+ usb_pipein(urb->pipe) ? "IN" : "OUT");
10595+ DWC_PRINT(" Max packet size: %d\n",
10596+ usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)));
10597+ DWC_PRINT(" transfer_buffer: %p\n", urb->transfer_buffer);
10598+ DWC_PRINT(" transfer_dma: %p\n", (void *)urb->transfer_dma);
10599+ DWC_PRINT(" transfer_buffer_length: %d\n", urb->transfer_buffer_length);
10600+ DWC_PRINT(" actual_length: %d\n", urb->actual_length);
10601+ }
10602+ }
10603+ }
10604+ DWC_PRINT(" non_periodic_channels: %d\n", hcd->non_periodic_channels);
10605+ DWC_PRINT(" periodic_channels: %d\n", hcd->periodic_channels);
10606+ DWC_PRINT(" periodic_usecs: %d\n", hcd->periodic_usecs);
10607+ np_tx_status.d32 = dwc_read_reg32(&hcd->core_if->core_global_regs->gnptxsts);
10608+ DWC_PRINT(" NP Tx Req Queue Space Avail: %d\n", np_tx_status.b.nptxqspcavail);
10609+ DWC_PRINT(" NP Tx FIFO Space Avail: %d\n", np_tx_status.b.nptxfspcavail);
10610+ p_tx_status.d32 = dwc_read_reg32(&hcd->core_if->host_if->host_global_regs->hptxsts);
10611+ DWC_PRINT(" P Tx Req Queue Space Avail: %d\n", p_tx_status.b.ptxqspcavail);
10612+ DWC_PRINT(" P Tx FIFO Space Avail: %d\n", p_tx_status.b.ptxfspcavail);
10613+ dwc_otg_hcd_dump_frrem(hcd);
10614+ dwc_otg_dump_global_registers(hcd->core_if);
10615+ dwc_otg_dump_host_registers(hcd->core_if);
10616+ DWC_PRINT("************************************************************\n");
10617+ DWC_PRINT("\n");
10618+#endif
10619+}
10620+#endif /* DWC_DEVICE_ONLY */
10621--- /dev/null
10622+++ b/drivers/usb/dwc/otg_hcd.h
10623@@ -0,0 +1,647 @@
10624+/* ==========================================================================
10625+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd.h $
10626+ * $Revision: #45 $
10627+ * $Date: 2008/07/15 $
10628+ * $Change: 1064918 $
10629+ *
10630+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
10631+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
10632+ * otherwise expressly agreed to in writing between Synopsys and you.
10633+ *
10634+ * The Software IS NOT an item of Licensed Software or Licensed Product under
10635+ * any End User Software License Agreement or Agreement for Licensed Product
10636+ * with Synopsys or any supplement thereto. You are permitted to use and
10637+ * redistribute this Software in source and binary forms, with or without
10638+ * modification, provided that redistributions of source code must retain this
10639+ * notice. You may not view, use, disclose, copy or distribute this file or
10640+ * any information contained herein except pursuant to this license grant from
10641+ * Synopsys. If you do not agree with this notice, including the disclaimer
10642+ * below, then you are not authorized to use the Software.
10643+ *
10644+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
10645+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
10646+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
10647+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
10648+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
10649+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
10650+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
10651+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
10652+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
10653+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
10654+ * DAMAGE.
10655+ * ========================================================================== */
10656+#ifndef DWC_DEVICE_ONLY
10657+#ifndef __DWC_HCD_H__
10658+#define __DWC_HCD_H__
10659+
10660+#include <linux/list.h>
10661+#include <linux/usb.h>
10662+#include <linux/usb/hcd.h>
10663+
10664+struct dwc_otg_device;
10665+
10666+#include "otg_cil.h"
10667+
10668+/**
10669+ * @file
10670+ *
10671+ * This file contains the structures, constants, and interfaces for
10672+ * the Host Contoller Driver (HCD).
10673+ *
10674+ * The Host Controller Driver (HCD) is responsible for translating requests
10675+ * from the USB Driver into the appropriate actions on the DWC_otg controller.
10676+ * It isolates the USBD from the specifics of the controller by providing an
10677+ * API to the USBD.
10678+ */
10679+
10680+/**
10681+ * Phases for control transfers.
10682+ */
10683+typedef enum dwc_otg_control_phase {
10684+ DWC_OTG_CONTROL_SETUP,
10685+ DWC_OTG_CONTROL_DATA,
10686+ DWC_OTG_CONTROL_STATUS
10687+} dwc_otg_control_phase_e;
10688+
10689+/** Transaction types. */
10690+typedef enum dwc_otg_transaction_type {
10691+ DWC_OTG_TRANSACTION_NONE,
10692+ DWC_OTG_TRANSACTION_PERIODIC,
10693+ DWC_OTG_TRANSACTION_NON_PERIODIC,
10694+ DWC_OTG_TRANSACTION_ALL
10695+} dwc_otg_transaction_type_e;
10696+
10697+/**
10698+ * A Queue Transfer Descriptor (QTD) holds the state of a bulk, control,
10699+ * interrupt, or isochronous transfer. A single QTD is created for each URB
10700+ * (of one of these types) submitted to the HCD. The transfer associated with
10701+ * a QTD may require one or multiple transactions.
10702+ *
10703+ * A QTD is linked to a Queue Head, which is entered in either the
10704+ * non-periodic or periodic schedule for execution. When a QTD is chosen for
10705+ * execution, some or all of its transactions may be executed. After
10706+ * execution, the state of the QTD is updated. The QTD may be retired if all
10707+ * its transactions are complete or if an error occurred. Otherwise, it
10708+ * remains in the schedule so more transactions can be executed later.
10709+ */
10710+typedef struct dwc_otg_qtd {
10711+ /**
10712+ * Determines the PID of the next data packet for the data phase of
10713+ * control transfers. Ignored for other transfer types.<br>
10714+ * One of the following values:
10715+ * - DWC_OTG_HC_PID_DATA0
10716+ * - DWC_OTG_HC_PID_DATA1
10717+ */
10718+ uint8_t data_toggle;
10719+
10720+ /** Current phase for control transfers (Setup, Data, or Status). */
10721+ dwc_otg_control_phase_e control_phase;
10722+
10723+ /** Keep track of the current split type
10724+ * for FS/LS endpoints on a HS Hub */
10725+ uint8_t complete_split;
10726+
10727+ /** How many bytes transferred during SSPLIT OUT */
10728+ uint32_t ssplit_out_xfer_count;
10729+
10730+ /**
10731+ * Holds the number of bus errors that have occurred for a transaction
10732+ * within this transfer.
10733+ */
10734+ uint8_t error_count;
10735+
10736+ /**
10737+ * Index of the next frame descriptor for an isochronous transfer. A
10738+ * frame descriptor describes the buffer position and length of the
10739+ * data to be transferred in the next scheduled (micro)frame of an
10740+ * isochronous transfer. It also holds status for that transaction.
10741+ * The frame index starts at 0.
10742+ */
10743+ int isoc_frame_index;
10744+
10745+ /** Position of the ISOC split on full/low speed */
10746+ uint8_t isoc_split_pos;
10747+
10748+ /** Position of the ISOC split in the buffer for the current frame */
10749+ uint16_t isoc_split_offset;
10750+
10751+ /** URB for this transfer */
10752+ struct urb *urb;
10753+
10754+ /** This list of QTDs */
10755+ struct list_head qtd_list_entry;
10756+
10757+} dwc_otg_qtd_t;
10758+
10759+/**
10760+ * A Queue Head (QH) holds the static characteristics of an endpoint and
10761+ * maintains a list of transfers (QTDs) for that endpoint. A QH structure may
10762+ * be entered in either the non-periodic or periodic schedule.
10763+ */
10764+typedef struct dwc_otg_qh {
10765+ /**
10766+ * Endpoint type.
10767+ * One of the following values:
10768+ * - USB_ENDPOINT_XFER_CONTROL
10769+ * - USB_ENDPOINT_XFER_ISOC
10770+ * - USB_ENDPOINT_XFER_BULK
10771+ * - USB_ENDPOINT_XFER_INT
10772+ */
10773+ uint8_t ep_type;
10774+ uint8_t ep_is_in;
10775+
10776+ /** wMaxPacketSize Field of Endpoint Descriptor. */
10777+ uint16_t maxp;
10778+
10779+ /**
10780+ * Determines the PID of the next data packet for non-control
10781+ * transfers. Ignored for control transfers.<br>
10782+ * One of the following values:
10783+ * - DWC_OTG_HC_PID_DATA0
10784+ * - DWC_OTG_HC_PID_DATA1
10785+ */
10786+ uint8_t data_toggle;
10787+
10788+ /** Ping state if 1. */
10789+ uint8_t ping_state;
10790+
10791+ /**
10792+ * List of QTDs for this QH.
10793+ */
10794+ struct list_head qtd_list;
10795+
10796+ /** Host channel currently processing transfers for this QH. */
10797+ dwc_hc_t *channel;
10798+
10799+ /** QTD currently assigned to a host channel for this QH. */
10800+ dwc_otg_qtd_t *qtd_in_process;
10801+
10802+ /** Full/low speed endpoint on high-speed hub requires split. */
10803+ uint8_t do_split;
10804+
10805+ /** @name Periodic schedule information */
10806+ /** @{ */
10807+
10808+ /** Bandwidth in microseconds per (micro)frame. */
10809+ uint8_t usecs;
10810+
10811+ /** Interval between transfers in (micro)frames. */
10812+ uint16_t interval;
10813+
10814+ /**
10815+ * (micro)frame to initialize a periodic transfer. The transfer
10816+ * executes in the following (micro)frame.
10817+ */
10818+ uint16_t sched_frame;
10819+
10820+ /** (micro)frame at which last start split was initialized. */
10821+ uint16_t start_split_frame;
10822+
10823+ /** @} */
10824+
10825+ /** Entry for QH in either the periodic or non-periodic schedule. */
10826+ struct list_head qh_list_entry;
10827+} dwc_otg_qh_t;
10828+
10829+/**
10830+ * This structure holds the state of the HCD, including the non-periodic and
10831+ * periodic schedules.
10832+ */
10833+typedef struct dwc_otg_hcd {
10834+ /** The DWC otg device pointer */
10835+ struct dwc_otg_device *otg_dev;
10836+
10837+ /** DWC OTG Core Interface Layer */
10838+ dwc_otg_core_if_t *core_if;
10839+
10840+ /** Internal DWC HCD Flags */
10841+ volatile union dwc_otg_hcd_internal_flags {
10842+ uint32_t d32;
10843+ struct {
10844+ unsigned port_connect_status_change : 1;
10845+ unsigned port_connect_status : 1;
10846+ unsigned port_reset_change : 1;
10847+ unsigned port_enable_change : 1;
10848+ unsigned port_suspend_change : 1;
10849+ unsigned port_over_current_change : 1;
10850+ unsigned reserved : 27;
10851+ } b;
10852+ } flags;
10853+
10854+ /**
10855+ * Inactive items in the non-periodic schedule. This is a list of
10856+ * Queue Heads. Transfers associated with these Queue Heads are not
10857+ * currently assigned to a host channel.
10858+ */
10859+ struct list_head non_periodic_sched_inactive;
10860+
10861+ /**
10862+ * Active items in the non-periodic schedule. This is a list of
10863+ * Queue Heads. Transfers associated with these Queue Heads are
10864+ * currently assigned to a host channel.
10865+ */
10866+ struct list_head non_periodic_sched_active;
10867+
10868+ /**
10869+ * Pointer to the next Queue Head to process in the active
10870+ * non-periodic schedule.
10871+ */
10872+ struct list_head *non_periodic_qh_ptr;
10873+
10874+ /**
10875+ * Inactive items in the periodic schedule. This is a list of QHs for
10876+ * periodic transfers that are _not_ scheduled for the next frame.
10877+ * Each QH in the list has an interval counter that determines when it
10878+ * needs to be scheduled for execution. This scheduling mechanism
10879+ * allows only a simple calculation for periodic bandwidth used (i.e.
10880+ * must assume that all periodic transfers may need to execute in the
10881+ * same frame). However, it greatly simplifies scheduling and should
10882+ * be sufficient for the vast majority of OTG hosts, which need to
10883+ * connect to a small number of peripherals at one time.
10884+ *
10885+ * Items move from this list to periodic_sched_ready when the QH
10886+ * interval counter is 0 at SOF.
10887+ */
10888+ struct list_head periodic_sched_inactive;
10889+
10890+ /**
10891+ * List of periodic QHs that are ready for execution in the next
10892+ * frame, but have not yet been assigned to host channels.
10893+ *
10894+ * Items move from this list to periodic_sched_assigned as host
10895+ * channels become available during the current frame.
10896+ */
10897+ struct list_head periodic_sched_ready;
10898+
10899+ /**
10900+ * List of periodic QHs to be executed in the next frame that are
10901+ * assigned to host channels.
10902+ *
10903+ * Items move from this list to periodic_sched_queued as the
10904+ * transactions for the QH are queued to the DWC_otg controller.
10905+ */
10906+ struct list_head periodic_sched_assigned;
10907+
10908+ /**
10909+ * List of periodic QHs that have been queued for execution.
10910+ *
10911+ * Items move from this list to either periodic_sched_inactive or
10912+ * periodic_sched_ready when the channel associated with the transfer
10913+ * is released. If the interval for the QH is 1, the item moves to
10914+ * periodic_sched_ready because it must be rescheduled for the next
10915+ * frame. Otherwise, the item moves to periodic_sched_inactive.
10916+ */
10917+ struct list_head periodic_sched_queued;
10918+
10919+ /**
10920+ * Total bandwidth claimed so far for periodic transfers. This value
10921+ * is in microseconds per (micro)frame. The assumption is that all
10922+ * periodic transfers may occur in the same (micro)frame.
10923+ */
10924+ uint16_t periodic_usecs;
10925+
10926+ /**
10927+ * Frame number read from the core at SOF. The value ranges from 0 to
10928+ * DWC_HFNUM_MAX_FRNUM.
10929+ */
10930+ uint16_t frame_number;
10931+
10932+ /**
10933+ * Free host channels in the controller. This is a list of
10934+ * dwc_hc_t items.
10935+ */
10936+ struct list_head free_hc_list;
10937+
10938+ /**
10939+ * Number of host channels assigned to periodic transfers. Currently
10940+ * assuming that there is a dedicated host channel for each periodic
10941+ * transaction and at least one host channel available for
10942+ * non-periodic transactions.
10943+ */
10944+ int periodic_channels;
10945+
10946+ /**
10947+ * Number of host channels assigned to non-periodic transfers.
10948+ */
10949+ int non_periodic_channels;
10950+
10951+ /**
10952+ * Array of pointers to the host channel descriptors. Allows accessing
10953+ * a host channel descriptor given the host channel number. This is
10954+ * useful in interrupt handlers.
10955+ */
10956+ dwc_hc_t *hc_ptr_array[MAX_EPS_CHANNELS];
10957+
10958+ /**
10959+ * Buffer to use for any data received during the status phase of a
10960+ * control transfer. Normally no data is transferred during the status
10961+ * phase. This buffer is used as a bit bucket.
10962+ */
10963+ uint8_t *status_buf;
10964+
10965+ /**
10966+ * DMA address for status_buf.
10967+ */
10968+ dma_addr_t status_buf_dma;
10969+#define DWC_OTG_HCD_STATUS_BUF_SIZE 64
10970+
10971+ /**
10972+ * Structure to allow starting the HCD in a non-interrupt context
10973+ * during an OTG role change.
10974+ */
10975+ struct delayed_work start_work;
10976+
10977+ /**
10978+ * Connection timer. An OTG host must display a message if the device
10979+ * does not connect. Started when the VBus power is turned on via
10980+ * sysfs attribute "buspower".
10981+ */
10982+ struct timer_list conn_timer;
10983+
10984+ /* Tasket to do a reset */
10985+ struct tasklet_struct *reset_tasklet;
10986+
10987+ /* */
10988+ spinlock_t lock;
10989+
10990+#ifdef DEBUG
10991+ uint32_t frrem_samples;
10992+ uint64_t frrem_accum;
10993+
10994+ uint32_t hfnum_7_samples_a;
10995+ uint64_t hfnum_7_frrem_accum_a;
10996+ uint32_t hfnum_0_samples_a;
10997+ uint64_t hfnum_0_frrem_accum_a;
10998+ uint32_t hfnum_other_samples_a;
10999+ uint64_t hfnum_other_frrem_accum_a;
11000+
11001+ uint32_t hfnum_7_samples_b;
11002+ uint64_t hfnum_7_frrem_accum_b;
11003+ uint32_t hfnum_0_samples_b;
11004+ uint64_t hfnum_0_frrem_accum_b;
11005+ uint32_t hfnum_other_samples_b;
11006+ uint64_t hfnum_other_frrem_accum_b;
11007+#endif
11008+} dwc_otg_hcd_t;
11009+
11010+/** Gets the dwc_otg_hcd from a struct usb_hcd */
11011+static inline dwc_otg_hcd_t *hcd_to_dwc_otg_hcd(struct usb_hcd *hcd)
11012+{
11013+ return (dwc_otg_hcd_t *)(hcd->hcd_priv);
11014+}
11015+
11016+/** Gets the struct usb_hcd that contains a dwc_otg_hcd_t. */
11017+static inline struct usb_hcd *dwc_otg_hcd_to_hcd(dwc_otg_hcd_t *dwc_otg_hcd)
11018+{
11019+ return container_of((void *)dwc_otg_hcd, struct usb_hcd, hcd_priv);
11020+}
11021+
11022+/** @name HCD Create/Destroy Functions */
11023+/** @{ */
11024+extern int dwc_otg_hcd_init(struct platform_device *pdev);
11025+extern void dwc_otg_hcd_remove(struct platform_device *pdev);
11026+/** @} */
11027+
11028+/** @name Linux HC Driver API Functions */
11029+/** @{ */
11030+
11031+extern int dwc_otg_hcd_start(struct usb_hcd *hcd);
11032+extern void dwc_otg_hcd_stop(struct usb_hcd *hcd);
11033+extern int dwc_otg_hcd_get_frame_number(struct usb_hcd *hcd);
11034+extern void dwc_otg_hcd_free(struct usb_hcd *hcd);
11035+extern int dwc_otg_hcd_urb_enqueue(struct usb_hcd *hcd,
11036+ // struct usb_host_endpoint *ep,
11037+ struct urb *urb,
11038+ gfp_t mem_flags
11039+ );
11040+extern int dwc_otg_hcd_urb_dequeue(struct usb_hcd *hcd,
11041+ struct urb *urb, int status);
11042+extern void dwc_otg_hcd_endpoint_disable(struct usb_hcd *hcd,
11043+ struct usb_host_endpoint *ep);
11044+extern irqreturn_t dwc_otg_hcd_irq(struct usb_hcd *hcd);
11045+extern int dwc_otg_hcd_hub_status_data(struct usb_hcd *hcd,
11046+ char *buf);
11047+extern int dwc_otg_hcd_hub_control(struct usb_hcd *hcd,
11048+ u16 typeReq,
11049+ u16 wValue,
11050+ u16 wIndex,
11051+ char *buf,
11052+ u16 wLength);
11053+
11054+/** @} */
11055+
11056+/** @name Transaction Execution Functions */
11057+/** @{ */
11058+extern dwc_otg_transaction_type_e dwc_otg_hcd_select_transactions(dwc_otg_hcd_t *hcd);
11059+extern void dwc_otg_hcd_queue_transactions(dwc_otg_hcd_t *hcd,
11060+ dwc_otg_transaction_type_e tr_type);
11061+extern void dwc_otg_hcd_complete_urb(dwc_otg_hcd_t *_hcd, struct urb *urb,
11062+ int status);
11063+/** @} */
11064+
11065+/** @name Interrupt Handler Functions */
11066+/** @{ */
11067+extern int32_t dwc_otg_hcd_handle_intr(dwc_otg_hcd_t *dwc_otg_hcd);
11068+extern int32_t dwc_otg_hcd_handle_sof_intr(dwc_otg_hcd_t *dwc_otg_hcd);
11069+extern int32_t dwc_otg_hcd_handle_rx_status_q_level_intr(dwc_otg_hcd_t *dwc_otg_hcd);
11070+extern int32_t dwc_otg_hcd_handle_np_tx_fifo_empty_intr(dwc_otg_hcd_t *dwc_otg_hcd);
11071+extern int32_t dwc_otg_hcd_handle_perio_tx_fifo_empty_intr(dwc_otg_hcd_t *dwc_otg_hcd);
11072+extern int32_t dwc_otg_hcd_handle_incomplete_periodic_intr(dwc_otg_hcd_t *dwc_otg_hcd);
11073+extern int32_t dwc_otg_hcd_handle_port_intr(dwc_otg_hcd_t *dwc_otg_hcd);
11074+extern int32_t dwc_otg_hcd_handle_conn_id_status_change_intr(dwc_otg_hcd_t *dwc_otg_hcd);
11075+extern int32_t dwc_otg_hcd_handle_disconnect_intr(dwc_otg_hcd_t *dwc_otg_hcd);
11076+extern int32_t dwc_otg_hcd_handle_hc_intr(dwc_otg_hcd_t *dwc_otg_hcd);
11077+extern int32_t dwc_otg_hcd_handle_hc_n_intr(dwc_otg_hcd_t *dwc_otg_hcd, uint32_t num);
11078+extern int32_t dwc_otg_hcd_handle_session_req_intr(dwc_otg_hcd_t *dwc_otg_hcd);
11079+extern int32_t dwc_otg_hcd_handle_wakeup_detected_intr(dwc_otg_hcd_t *dwc_otg_hcd);
11080+/** @} */
11081+
11082+
11083+/** @name Schedule Queue Functions */
11084+/** @{ */
11085+
11086+/* Implemented in dwc_otg_hcd_queue.c */
11087+extern dwc_otg_qh_t *dwc_otg_hcd_qh_create(dwc_otg_hcd_t *hcd, struct urb *urb);
11088+extern void dwc_otg_hcd_qh_init(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh, struct urb *urb);
11089+extern void dwc_otg_hcd_qh_free(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh);
11090+extern int dwc_otg_hcd_qh_add(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh);
11091+extern void dwc_otg_hcd_qh_remove(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh);
11092+extern void dwc_otg_hcd_qh_deactivate(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh, int sched_csplit);
11093+
11094+/** Remove and free a QH */
11095+static inline void dwc_otg_hcd_qh_remove_and_free(dwc_otg_hcd_t *hcd,
11096+ dwc_otg_qh_t *qh)
11097+{
11098+ dwc_otg_hcd_qh_remove(hcd, qh);
11099+ dwc_otg_hcd_qh_free(hcd, qh);
11100+}
11101+
11102+/** Allocates memory for a QH structure.
11103+ * @return Returns the memory allocate or NULL on error. */
11104+static inline dwc_otg_qh_t *dwc_otg_hcd_qh_alloc(void)
11105+{
11106+ return (dwc_otg_qh_t *) kmalloc(sizeof(dwc_otg_qh_t), GFP_KERNEL);
11107+}
11108+
11109+extern dwc_otg_qtd_t *dwc_otg_hcd_qtd_create(struct urb *urb);
11110+extern void dwc_otg_hcd_qtd_init(dwc_otg_qtd_t *qtd, struct urb *urb);
11111+extern int dwc_otg_hcd_qtd_add(dwc_otg_qtd_t *qtd, dwc_otg_hcd_t *dwc_otg_hcd);
11112+
11113+/** Allocates memory for a QTD structure.
11114+ * @return Returns the memory allocate or NULL on error. */
11115+static inline dwc_otg_qtd_t *dwc_otg_hcd_qtd_alloc(void)
11116+{
11117+ return (dwc_otg_qtd_t *) kmalloc(sizeof(dwc_otg_qtd_t), GFP_KERNEL);
11118+}
11119+
11120+/** Frees the memory for a QTD structure. QTD should already be removed from
11121+ * list.
11122+ * @param[in] qtd QTD to free.*/
11123+static inline void dwc_otg_hcd_qtd_free(dwc_otg_qtd_t *qtd)
11124+{
11125+ kfree(qtd);
11126+}
11127+
11128+/** Removes a QTD from list.
11129+ * @param[in] hcd HCD instance.
11130+ * @param[in] qtd QTD to remove from list. */
11131+static inline void dwc_otg_hcd_qtd_remove(dwc_otg_hcd_t *hcd, dwc_otg_qtd_t *qtd)
11132+{
11133+ unsigned long flags;
11134+ SPIN_LOCK_IRQSAVE(&hcd->lock, flags);
11135+ list_del(&qtd->qtd_list_entry);
11136+ SPIN_UNLOCK_IRQRESTORE(&hcd->lock, flags);
11137+}
11138+
11139+/** Remove and free a QTD */
11140+static inline void dwc_otg_hcd_qtd_remove_and_free(dwc_otg_hcd_t *hcd, dwc_otg_qtd_t *qtd)
11141+{
11142+ dwc_otg_hcd_qtd_remove(hcd, qtd);
11143+ dwc_otg_hcd_qtd_free(qtd);
11144+}
11145+
11146+/** @} */
11147+
11148+
11149+/** @name Internal Functions */
11150+/** @{ */
11151+dwc_otg_qh_t *dwc_urb_to_qh(struct urb *urb);
11152+void dwc_otg_hcd_dump_frrem(dwc_otg_hcd_t *hcd);
11153+void dwc_otg_hcd_dump_state(dwc_otg_hcd_t *hcd);
11154+/** @} */
11155+
11156+/** Gets the usb_host_endpoint associated with an URB. */
11157+static inline struct usb_host_endpoint *dwc_urb_to_endpoint(struct urb *urb)
11158+{
11159+ struct usb_device *dev = urb->dev;
11160+ int ep_num = usb_pipeendpoint(urb->pipe);
11161+
11162+ if (usb_pipein(urb->pipe))
11163+ return dev->ep_in[ep_num];
11164+ else
11165+ return dev->ep_out[ep_num];
11166+}
11167+
11168+/**
11169+ * Gets the endpoint number from a _bEndpointAddress argument. The endpoint is
11170+ * qualified with its direction (possible 32 endpoints per device).
11171+ */
11172+#define dwc_ep_addr_to_endpoint(_bEndpointAddress_) ((_bEndpointAddress_ & USB_ENDPOINT_NUMBER_MASK) | \
11173+ ((_bEndpointAddress_ & USB_DIR_IN) != 0) << 4)
11174+
11175+/** Gets the QH that contains the list_head */
11176+#define dwc_list_to_qh(_list_head_ptr_) container_of(_list_head_ptr_, dwc_otg_qh_t, qh_list_entry)
11177+
11178+/** Gets the QTD that contains the list_head */
11179+#define dwc_list_to_qtd(_list_head_ptr_) container_of(_list_head_ptr_, dwc_otg_qtd_t, qtd_list_entry)
11180+
11181+/** Check if QH is non-periodic */
11182+#define dwc_qh_is_non_per(_qh_ptr_) ((_qh_ptr_->ep_type == USB_ENDPOINT_XFER_BULK) || \
11183+ (_qh_ptr_->ep_type == USB_ENDPOINT_XFER_CONTROL))
11184+
11185+/** High bandwidth multiplier as encoded in highspeed endpoint descriptors */
11186+#define dwc_hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
11187+
11188+/** Packet size for any kind of endpoint descriptor */
11189+#define dwc_max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff)
11190+
11191+/**
11192+ * Returns true if _frame1 is less than or equal to _frame2. The comparison is
11193+ * done modulo DWC_HFNUM_MAX_FRNUM. This accounts for the rollover of the
11194+ * frame number when the max frame number is reached.
11195+ */
11196+static inline int dwc_frame_num_le(uint16_t frame1, uint16_t frame2)
11197+{
11198+ return ((frame2 - frame1) & DWC_HFNUM_MAX_FRNUM) <=
11199+ (DWC_HFNUM_MAX_FRNUM >> 1);
11200+}
11201+
11202+/**
11203+ * Returns true if _frame1 is greater than _frame2. The comparison is done
11204+ * modulo DWC_HFNUM_MAX_FRNUM. This accounts for the rollover of the frame
11205+ * number when the max frame number is reached.
11206+ */
11207+static inline int dwc_frame_num_gt(uint16_t frame1, uint16_t frame2)
11208+{
11209+ return (frame1 != frame2) &&
11210+ (((frame1 - frame2) & DWC_HFNUM_MAX_FRNUM) <
11211+ (DWC_HFNUM_MAX_FRNUM >> 1));
11212+}
11213+
11214+/**
11215+ * Increments _frame by the amount specified by _inc. The addition is done
11216+ * modulo DWC_HFNUM_MAX_FRNUM. Returns the incremented value.
11217+ */
11218+static inline uint16_t dwc_frame_num_inc(uint16_t frame, uint16_t inc)
11219+{
11220+ return (frame + inc) & DWC_HFNUM_MAX_FRNUM;
11221+}
11222+
11223+static inline uint16_t dwc_full_frame_num(uint16_t frame)
11224+{
11225+ return (frame & DWC_HFNUM_MAX_FRNUM) >> 3;
11226+}
11227+
11228+static inline uint16_t dwc_micro_frame_num(uint16_t frame)
11229+{
11230+ return frame & 0x7;
11231+}
11232+
11233+#ifdef DEBUG
11234+/**
11235+ * Macro to sample the remaining PHY clocks left in the current frame. This
11236+ * may be used during debugging to determine the average time it takes to
11237+ * execute sections of code. There are two possible sample points, "a" and
11238+ * "b", so the _letter argument must be one of these values.
11239+ *
11240+ * To dump the average sample times, read the "hcd_frrem" sysfs attribute. For
11241+ * example, "cat /sys/devices/lm0/hcd_frrem".
11242+ */
11243+#define dwc_sample_frrem(_hcd, _qh, _letter) \
11244+{ \
11245+ hfnum_data_t hfnum; \
11246+ dwc_otg_qtd_t *qtd; \
11247+ qtd = list_entry(_qh->qtd_list.next, dwc_otg_qtd_t, qtd_list_entry); \
11248+ if (usb_pipeint(qtd->urb->pipe) && _qh->start_split_frame != 0 && !qtd->complete_split) { \
11249+ hfnum.d32 = dwc_read_reg32(&_hcd->core_if->host_if->host_global_regs->hfnum); \
11250+ switch (hfnum.b.frnum & 0x7) { \
11251+ case 7: \
11252+ _hcd->hfnum_7_samples_##_letter++; \
11253+ _hcd->hfnum_7_frrem_accum_##_letter += hfnum.b.frrem; \
11254+ break; \
11255+ case 0: \
11256+ _hcd->hfnum_0_samples_##_letter++; \
11257+ _hcd->hfnum_0_frrem_accum_##_letter += hfnum.b.frrem; \
11258+ break; \
11259+ default: \
11260+ _hcd->hfnum_other_samples_##_letter++; \
11261+ _hcd->hfnum_other_frrem_accum_##_letter += hfnum.b.frrem; \
11262+ break; \
11263+ } \
11264+ } \
11265+}
11266+#else
11267+#define dwc_sample_frrem(_hcd, _qh, _letter)
11268+#endif
11269+#endif
11270+#endif /* DWC_DEVICE_ONLY */
11271--- /dev/null
11272+++ b/drivers/usb/dwc/otg_hcd_intr.c
11273@@ -0,0 +1,1826 @@
11274+/* ==========================================================================
11275+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd_intr.c $
11276+ * $Revision: #70 $
11277+ * $Date: 2008/10/16 $
11278+ * $Change: 1117667 $
11279+ *
11280+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
11281+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
11282+ * otherwise expressly agreed to in writing between Synopsys and you.
11283+ *
11284+ * The Software IS NOT an item of Licensed Software or Licensed Product under
11285+ * any End User Software License Agreement or Agreement for Licensed Product
11286+ * with Synopsys or any supplement thereto. You are permitted to use and
11287+ * redistribute this Software in source and binary forms, with or without
11288+ * modification, provided that redistributions of source code must retain this
11289+ * notice. You may not view, use, disclose, copy or distribute this file or
11290+ * any information contained herein except pursuant to this license grant from
11291+ * Synopsys. If you do not agree with this notice, including the disclaimer
11292+ * below, then you are not authorized to use the Software.
11293+ *
11294+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
11295+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
11296+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
11297+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
11298+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
11299+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
11300+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
11301+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
11302+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
11303+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
11304+ * DAMAGE.
11305+ * ========================================================================== */
11306+#ifndef DWC_DEVICE_ONLY
11307+
11308+#include <linux/version.h>
11309+
11310+#include "otg_driver.h"
11311+#include "otg_hcd.h"
11312+#include "otg_regs.h"
11313+
11314+/** @file
11315+ * This file contains the implementation of the HCD Interrupt handlers.
11316+ */
11317+
11318+/** This function handles interrupts for the HCD. */
11319+int32_t dwc_otg_hcd_handle_intr(dwc_otg_hcd_t *dwc_otg_hcd)
11320+{
11321+ int retval = 0;
11322+
11323+ dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
11324+ gintsts_data_t gintsts;
11325+#ifdef DEBUG
11326+ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
11327+#endif
11328+
11329+ /* Check if HOST Mode */
11330+ if (dwc_otg_is_host_mode(core_if)) {
11331+ gintsts.d32 = dwc_otg_read_core_intr(core_if);
11332+ if (!gintsts.d32) {
11333+ return 0;
11334+ }
11335+
11336+#ifdef DEBUG
11337+ /* Don't print debug message in the interrupt handler on SOF */
11338+# ifndef DEBUG_SOF
11339+ if (gintsts.d32 != DWC_SOF_INTR_MASK)
11340+# endif
11341+ DWC_DEBUGPL(DBG_HCD, "\n");
11342+#endif
11343+
11344+#ifdef DEBUG
11345+# ifndef DEBUG_SOF
11346+ if (gintsts.d32 != DWC_SOF_INTR_MASK)
11347+# endif
11348+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Interrupt Detected gintsts&gintmsk=0x%08x\n", gintsts.d32);
11349+#endif
11350+ if (gintsts.b.usbreset) {
11351+ DWC_PRINT("Usb Reset In Host Mode\n");
11352+ }
11353+ if (gintsts.b.sofintr) {
11354+ retval |= dwc_otg_hcd_handle_sof_intr(dwc_otg_hcd);
11355+ }
11356+ if (gintsts.b.rxstsqlvl) {
11357+ retval |= dwc_otg_hcd_handle_rx_status_q_level_intr(dwc_otg_hcd);
11358+ }
11359+ if (gintsts.b.nptxfempty) {
11360+ retval |= dwc_otg_hcd_handle_np_tx_fifo_empty_intr(dwc_otg_hcd);
11361+ }
11362+ if (gintsts.b.i2cintr) {
11363+ /** @todo Implement i2cintr handler. */
11364+ }
11365+ if (gintsts.b.portintr) {
11366+ retval |= dwc_otg_hcd_handle_port_intr(dwc_otg_hcd);
11367+ }
11368+ if (gintsts.b.hcintr) {
11369+ retval |= dwc_otg_hcd_handle_hc_intr(dwc_otg_hcd);
11370+ }
11371+ if (gintsts.b.ptxfempty) {
11372+ retval |= dwc_otg_hcd_handle_perio_tx_fifo_empty_intr(dwc_otg_hcd);
11373+ }
11374+#ifdef DEBUG
11375+# ifndef DEBUG_SOF
11376+ if (gintsts.d32 != DWC_SOF_INTR_MASK)
11377+# endif
11378+ {
11379+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Finished Servicing Interrupts\n");
11380+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD gintsts=0x%08x\n",
11381+ dwc_read_reg32(&global_regs->gintsts));
11382+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD gintmsk=0x%08x\n",
11383+ dwc_read_reg32(&global_regs->gintmsk));
11384+ }
11385+#endif
11386+
11387+#ifdef DEBUG
11388+# ifndef DEBUG_SOF
11389+ if (gintsts.d32 != DWC_SOF_INTR_MASK)
11390+# endif
11391+ DWC_DEBUGPL(DBG_HCD, "\n");
11392+#endif
11393+
11394+ }
11395+ S3C2410X_CLEAR_EINTPEND();
11396+
11397+ return retval;
11398+}
11399+
11400+#ifdef DWC_TRACK_MISSED_SOFS
11401+#warning Compiling code to track missed SOFs
11402+#define FRAME_NUM_ARRAY_SIZE 1000
11403+/**
11404+ * This function is for debug only.
11405+ */
11406+static inline void track_missed_sofs(uint16_t curr_frame_number)
11407+{
11408+ static uint16_t frame_num_array[FRAME_NUM_ARRAY_SIZE];
11409+ static uint16_t last_frame_num_array[FRAME_NUM_ARRAY_SIZE];
11410+ static int frame_num_idx = 0;
11411+ static uint16_t last_frame_num = DWC_HFNUM_MAX_FRNUM;
11412+ static int dumped_frame_num_array = 0;
11413+
11414+ if (frame_num_idx < FRAME_NUM_ARRAY_SIZE) {
11415+ if (((last_frame_num + 1) & DWC_HFNUM_MAX_FRNUM) != curr_frame_number) {
11416+ frame_num_array[frame_num_idx] = curr_frame_number;
11417+ last_frame_num_array[frame_num_idx++] = last_frame_num;
11418+ }
11419+ } else if (!dumped_frame_num_array) {
11420+ int i;
11421+ printk(KERN_EMERG USB_DWC "Frame Last Frame\n");
11422+ printk(KERN_EMERG USB_DWC "----- ----------\n");
11423+ for (i = 0; i < FRAME_NUM_ARRAY_SIZE; i++) {
11424+ printk(KERN_EMERG USB_DWC "0x%04x 0x%04x\n",
11425+ frame_num_array[i], last_frame_num_array[i]);
11426+ }
11427+ dumped_frame_num_array = 1;
11428+ }
11429+ last_frame_num = curr_frame_number;
11430+}
11431+#endif
11432+
11433+/**
11434+ * Handles the start-of-frame interrupt in host mode. Non-periodic
11435+ * transactions may be queued to the DWC_otg controller for the current
11436+ * (micro)frame. Periodic transactions may be queued to the controller for the
11437+ * next (micro)frame.
11438+ */
11439+int32_t dwc_otg_hcd_handle_sof_intr(dwc_otg_hcd_t *hcd)
11440+{
11441+ hfnum_data_t hfnum;
11442+ struct list_head *qh_entry;
11443+ dwc_otg_qh_t *qh;
11444+ dwc_otg_transaction_type_e tr_type;
11445+ gintsts_data_t gintsts = {.d32 = 0};
11446+
11447+ hfnum.d32 = dwc_read_reg32(&hcd->core_if->host_if->host_global_regs->hfnum);
11448+
11449+#ifdef DEBUG_SOF
11450+ DWC_DEBUGPL(DBG_HCD, "--Start of Frame Interrupt--\n");
11451+#endif
11452+ hcd->frame_number = hfnum.b.frnum;
11453+
11454+#ifdef DEBUG
11455+ hcd->frrem_accum += hfnum.b.frrem;
11456+ hcd->frrem_samples++;
11457+#endif
11458+
11459+#ifdef DWC_TRACK_MISSED_SOFS
11460+ track_missed_sofs(hcd->frame_number);
11461+#endif
11462+
11463+ /* Determine whether any periodic QHs should be executed. */
11464+ qh_entry = hcd->periodic_sched_inactive.next;
11465+ while (qh_entry != &hcd->periodic_sched_inactive) {
11466+ qh = list_entry(qh_entry, dwc_otg_qh_t, qh_list_entry);
11467+ qh_entry = qh_entry->next;
11468+ if (dwc_frame_num_le(qh->sched_frame, hcd->frame_number)) {
11469+ /*
11470+ * Move QH to the ready list to be executed next
11471+ * (micro)frame.
11472+ */
11473+ list_move(&qh->qh_list_entry, &hcd->periodic_sched_ready);
11474+ }
11475+ }
11476+
11477+ tr_type = dwc_otg_hcd_select_transactions(hcd);
11478+ if (tr_type != DWC_OTG_TRANSACTION_NONE) {
11479+ dwc_otg_hcd_queue_transactions(hcd, tr_type);
11480+ }
11481+
11482+ /* Clear interrupt */
11483+ gintsts.b.sofintr = 1;
11484+ dwc_write_reg32(&hcd->core_if->core_global_regs->gintsts, gintsts.d32);
11485+
11486+ return 1;
11487+}
11488+
11489+/** Handles the Rx Status Queue Level Interrupt, which indicates that there is at
11490+ * least one packet in the Rx FIFO. The packets are moved from the FIFO to
11491+ * memory if the DWC_otg controller is operating in Slave mode. */
11492+int32_t dwc_otg_hcd_handle_rx_status_q_level_intr(dwc_otg_hcd_t *dwc_otg_hcd)
11493+{
11494+ host_grxsts_data_t grxsts;
11495+ dwc_hc_t *hc = NULL;
11496+
11497+ DWC_DEBUGPL(DBG_HCD, "--RxStsQ Level Interrupt--\n");
11498+
11499+ grxsts.d32 = dwc_read_reg32(&dwc_otg_hcd->core_if->core_global_regs->grxstsp);
11500+
11501+ hc = dwc_otg_hcd->hc_ptr_array[grxsts.b.chnum];
11502+
11503+ /* Packet Status */
11504+ DWC_DEBUGPL(DBG_HCDV, " Ch num = %d\n", grxsts.b.chnum);
11505+ DWC_DEBUGPL(DBG_HCDV, " Count = %d\n", grxsts.b.bcnt);
11506+ DWC_DEBUGPL(DBG_HCDV, " DPID = %d, hc.dpid = %d\n", grxsts.b.dpid, hc->data_pid_start);
11507+ DWC_DEBUGPL(DBG_HCDV, " PStatus = %d\n", grxsts.b.pktsts);
11508+
11509+ switch (grxsts.b.pktsts) {
11510+ case DWC_GRXSTS_PKTSTS_IN:
11511+ /* Read the data into the host buffer. */
11512+ if (grxsts.b.bcnt > 0) {
11513+ dwc_otg_read_packet(dwc_otg_hcd->core_if,
11514+ hc->xfer_buff,
11515+ grxsts.b.bcnt);
11516+
11517+ /* Update the HC fields for the next packet received. */
11518+ hc->xfer_count += grxsts.b.bcnt;
11519+ hc->xfer_buff += grxsts.b.bcnt;
11520+ }
11521+
11522+ case DWC_GRXSTS_PKTSTS_IN_XFER_COMP:
11523+ case DWC_GRXSTS_PKTSTS_DATA_TOGGLE_ERR:
11524+ case DWC_GRXSTS_PKTSTS_CH_HALTED:
11525+ /* Handled in interrupt, just ignore data */
11526+ break;
11527+ default:
11528+ DWC_ERROR("RX_STS_Q Interrupt: Unknown status %d\n", grxsts.b.pktsts);
11529+ break;
11530+ }
11531+
11532+ return 1;
11533+}
11534+
11535+/** This interrupt occurs when the non-periodic Tx FIFO is half-empty. More
11536+ * data packets may be written to the FIFO for OUT transfers. More requests
11537+ * may be written to the non-periodic request queue for IN transfers. This
11538+ * interrupt is enabled only in Slave mode. */
11539+int32_t dwc_otg_hcd_handle_np_tx_fifo_empty_intr(dwc_otg_hcd_t *dwc_otg_hcd)
11540+{
11541+ DWC_DEBUGPL(DBG_HCD, "--Non-Periodic TxFIFO Empty Interrupt--\n");
11542+ dwc_otg_hcd_queue_transactions(dwc_otg_hcd,
11543+ DWC_OTG_TRANSACTION_NON_PERIODIC);
11544+ return 1;
11545+}
11546+
11547+/** This interrupt occurs when the periodic Tx FIFO is half-empty. More data
11548+ * packets may be written to the FIFO for OUT transfers. More requests may be
11549+ * written to the periodic request queue for IN transfers. This interrupt is
11550+ * enabled only in Slave mode. */
11551+int32_t dwc_otg_hcd_handle_perio_tx_fifo_empty_intr(dwc_otg_hcd_t *dwc_otg_hcd)
11552+{
11553+ DWC_DEBUGPL(DBG_HCD, "--Periodic TxFIFO Empty Interrupt--\n");
11554+ dwc_otg_hcd_queue_transactions(dwc_otg_hcd,
11555+ DWC_OTG_TRANSACTION_PERIODIC);
11556+ return 1;
11557+}
11558+
11559+/** There are multiple conditions that can cause a port interrupt. This function
11560+ * determines which interrupt conditions have occurred and handles them
11561+ * appropriately. */
11562+int32_t dwc_otg_hcd_handle_port_intr(dwc_otg_hcd_t *dwc_otg_hcd)
11563+{
11564+ int retval = 0;
11565+ hprt0_data_t hprt0;
11566+ hprt0_data_t hprt0_modify;
11567+
11568+ hprt0.d32 = dwc_read_reg32(dwc_otg_hcd->core_if->host_if->hprt0);
11569+ hprt0_modify.d32 = dwc_read_reg32(dwc_otg_hcd->core_if->host_if->hprt0);
11570+
11571+ /* Clear appropriate bits in HPRT0 to clear the interrupt bit in
11572+ * GINTSTS */
11573+
11574+ hprt0_modify.b.prtena = 0;
11575+ hprt0_modify.b.prtconndet = 0;
11576+ hprt0_modify.b.prtenchng = 0;
11577+ hprt0_modify.b.prtovrcurrchng = 0;
11578+
11579+ /* Port Connect Detected
11580+ * Set flag and clear if detected */
11581+ if (hprt0.b.prtconndet) {
11582+ DWC_DEBUGPL(DBG_HCD, "--Port Interrupt HPRT0=0x%08x "
11583+ "Port Connect Detected--\n", hprt0.d32);
11584+ dwc_otg_hcd->flags.b.port_connect_status_change = 1;
11585+ dwc_otg_hcd->flags.b.port_connect_status = 1;
11586+ hprt0_modify.b.prtconndet = 1;
11587+
11588+ /* B-Device has connected, Delete the connection timer. */
11589+ del_timer( &dwc_otg_hcd->conn_timer );
11590+
11591+ /* The Hub driver asserts a reset when it sees port connect
11592+ * status change flag */
11593+ retval |= 1;
11594+ }
11595+
11596+ /* Port Enable Changed
11597+ * Clear if detected - Set internal flag if disabled */
11598+ if (hprt0.b.prtenchng) {
11599+ DWC_DEBUGPL(DBG_HCD, " --Port Interrupt HPRT0=0x%08x "
11600+ "Port Enable Changed--\n", hprt0.d32);
11601+ hprt0_modify.b.prtenchng = 1;
11602+ if (hprt0.b.prtena == 1) {
11603+ int do_reset = 0;
11604+ dwc_otg_core_params_t *params = dwc_otg_hcd->core_if->core_params;
11605+ dwc_otg_core_global_regs_t *global_regs = dwc_otg_hcd->core_if->core_global_regs;
11606+ dwc_otg_host_if_t *host_if = dwc_otg_hcd->core_if->host_if;
11607+
11608+ /* Check if we need to adjust the PHY clock speed for
11609+ * low power and adjust it */
11610+ if (params->host_support_fs_ls_low_power) {
11611+ gusbcfg_data_t usbcfg;
11612+
11613+ usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
11614+
11615+ if (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_LOW_SPEED ||
11616+ hprt0.b.prtspd == DWC_HPRT0_PRTSPD_FULL_SPEED) {
11617+ /*
11618+ * Low power
11619+ */
11620+ hcfg_data_t hcfg;
11621+ if (usbcfg.b.phylpwrclksel == 0) {
11622+ /* Set PHY low power clock select for FS/LS devices */
11623+ usbcfg.b.phylpwrclksel = 1;
11624+ dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
11625+ do_reset = 1;
11626+ }
11627+
11628+ hcfg.d32 = dwc_read_reg32(&host_if->host_global_regs->hcfg);
11629+
11630+ if (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_LOW_SPEED &&
11631+ params->host_ls_low_power_phy_clk ==
11632+ DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ) {
11633+ /* 6 MHZ */
11634+ DWC_DEBUGPL(DBG_CIL, "FS_PHY programming HCFG to 6 MHz (Low Power)\n");
11635+ if (hcfg.b.fslspclksel != DWC_HCFG_6_MHZ) {
11636+ hcfg.b.fslspclksel = DWC_HCFG_6_MHZ;
11637+ dwc_write_reg32(&host_if->host_global_regs->hcfg,
11638+ hcfg.d32);
11639+ do_reset = 1;
11640+ }
11641+ } else {
11642+ /* 48 MHZ */
11643+ DWC_DEBUGPL(DBG_CIL, "FS_PHY programming HCFG to 48 MHz ()\n");
11644+ if (hcfg.b.fslspclksel != DWC_HCFG_48_MHZ) {
11645+ hcfg.b.fslspclksel = DWC_HCFG_48_MHZ;
11646+ dwc_write_reg32(&host_if->host_global_regs->hcfg,
11647+ hcfg.d32);
11648+ do_reset = 1;
11649+ }
11650+ }
11651+ } else {
11652+ /*
11653+ * Not low power
11654+ */
11655+ if (usbcfg.b.phylpwrclksel == 1) {
11656+ usbcfg.b.phylpwrclksel = 0;
11657+ dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
11658+ do_reset = 1;
11659+ }
11660+ }
11661+
11662+ if (do_reset) {
11663+ tasklet_schedule(dwc_otg_hcd->reset_tasklet);
11664+ }
11665+ }
11666+
11667+ if (!do_reset) {
11668+ /* Port has been enabled set the reset change flag */
11669+ dwc_otg_hcd->flags.b.port_reset_change = 1;
11670+ }
11671+ } else {
11672+ dwc_otg_hcd->flags.b.port_enable_change = 1;
11673+ }
11674+ retval |= 1;
11675+ }
11676+
11677+ /** Overcurrent Change Interrupt */
11678+ if (hprt0.b.prtovrcurrchng) {
11679+ DWC_DEBUGPL(DBG_HCD, " --Port Interrupt HPRT0=0x%08x "
11680+ "Port Overcurrent Changed--\n", hprt0.d32);
11681+ dwc_otg_hcd->flags.b.port_over_current_change = 1;
11682+ hprt0_modify.b.prtovrcurrchng = 1;
11683+ retval |= 1;
11684+ }
11685+
11686+ /* Clear Port Interrupts */
11687+ dwc_write_reg32(dwc_otg_hcd->core_if->host_if->hprt0, hprt0_modify.d32);
11688+
11689+ return retval;
11690+}
11691+
11692+/** This interrupt indicates that one or more host channels has a pending
11693+ * interrupt. There are multiple conditions that can cause each host channel
11694+ * interrupt. This function determines which conditions have occurred for each
11695+ * host channel interrupt and handles them appropriately. */
11696+int32_t dwc_otg_hcd_handle_hc_intr(dwc_otg_hcd_t *dwc_otg_hcd)
11697+{
11698+ int i;
11699+ int retval = 0;
11700+ haint_data_t haint;
11701+
11702+ /* Clear appropriate bits in HCINTn to clear the interrupt bit in
11703+ * GINTSTS */
11704+
11705+ haint.d32 = dwc_otg_read_host_all_channels_intr(dwc_otg_hcd->core_if);
11706+
11707+ for (i = 0; i < dwc_otg_hcd->core_if->core_params->host_channels; i++) {
11708+ if (haint.b2.chint & (1 << i)) {
11709+ retval |= dwc_otg_hcd_handle_hc_n_intr(dwc_otg_hcd, i);
11710+ }
11711+ }
11712+
11713+ return retval;
11714+}
11715+
11716+/* Macro used to clear one channel interrupt */
11717+#define clear_hc_int(_hc_regs_, _intr_) \
11718+do { \
11719+ hcint_data_t hcint_clear = {.d32 = 0}; \
11720+ hcint_clear.b._intr_ = 1; \
11721+ dwc_write_reg32(&(_hc_regs_)->hcint, hcint_clear.d32); \
11722+} while (0)
11723+
11724+/*
11725+ * Macro used to disable one channel interrupt. Channel interrupts are
11726+ * disabled when the channel is halted or released by the interrupt handler.
11727+ * There is no need to handle further interrupts of that type until the
11728+ * channel is re-assigned. In fact, subsequent handling may cause crashes
11729+ * because the channel structures are cleaned up when the channel is released.
11730+ */
11731+#define disable_hc_int(_hc_regs_, _intr_) \
11732+do { \
11733+ hcintmsk_data_t hcintmsk = {.d32 = 0}; \
11734+ hcintmsk.b._intr_ = 1; \
11735+ dwc_modify_reg32(&(_hc_regs_)->hcintmsk, hcintmsk.d32, 0); \
11736+} while (0)
11737+
11738+/**
11739+ * Gets the actual length of a transfer after the transfer halts. _halt_status
11740+ * holds the reason for the halt.
11741+ *
11742+ * For IN transfers where halt_status is DWC_OTG_HC_XFER_COMPLETE,
11743+ * *short_read is set to 1 upon return if less than the requested
11744+ * number of bytes were transferred. Otherwise, *short_read is set to 0 upon
11745+ * return. short_read may also be NULL on entry, in which case it remains
11746+ * unchanged.
11747+ */
11748+static uint32_t get_actual_xfer_length(dwc_hc_t *hc,
11749+ dwc_otg_hc_regs_t *hc_regs,
11750+ dwc_otg_qtd_t *qtd,
11751+ dwc_otg_halt_status_e halt_status,
11752+ int *short_read)
11753+{
11754+ hctsiz_data_t hctsiz;
11755+ uint32_t length;
11756+
11757+ if (short_read != NULL) {
11758+ *short_read = 0;
11759+ }
11760+ hctsiz.d32 = dwc_read_reg32(&hc_regs->hctsiz);
11761+
11762+ if (halt_status == DWC_OTG_HC_XFER_COMPLETE) {
11763+ if (hc->ep_is_in) {
11764+ length = hc->xfer_len - hctsiz.b.xfersize;
11765+ if (short_read != NULL) {
11766+ *short_read = (hctsiz.b.xfersize != 0);
11767+ }
11768+ } else if (hc->qh->do_split) {
11769+ length = qtd->ssplit_out_xfer_count;
11770+ } else {
11771+ length = hc->xfer_len;
11772+ }
11773+ } else {
11774+ /*
11775+ * Must use the hctsiz.pktcnt field to determine how much data
11776+ * has been transferred. This field reflects the number of
11777+ * packets that have been transferred via the USB. This is
11778+ * always an integral number of packets if the transfer was
11779+ * halted before its normal completion. (Can't use the
11780+ * hctsiz.xfersize field because that reflects the number of
11781+ * bytes transferred via the AHB, not the USB).
11782+ */
11783+ length = (hc->start_pkt_count - hctsiz.b.pktcnt) * hc->max_packet;
11784+ }
11785+
11786+ return length;
11787+}
11788+
11789+/**
11790+ * Updates the state of the URB after a Transfer Complete interrupt on the
11791+ * host channel. Updates the actual_length field of the URB based on the
11792+ * number of bytes transferred via the host channel. Sets the URB status
11793+ * if the data transfer is finished.
11794+ *
11795+ * @return 1 if the data transfer specified by the URB is completely finished,
11796+ * 0 otherwise.
11797+ */
11798+static int update_urb_state_xfer_comp(dwc_hc_t *hc,
11799+ dwc_otg_hc_regs_t *hc_regs,
11800+ struct urb *urb,
11801+ dwc_otg_qtd_t *qtd)
11802+{
11803+ int xfer_done = 0;
11804+ int short_read = 0;
11805+
11806+ urb->actual_length += get_actual_xfer_length(hc, hc_regs, qtd,
11807+ DWC_OTG_HC_XFER_COMPLETE,
11808+ &short_read);
11809+
11810+ if (short_read || urb->actual_length == urb->transfer_buffer_length) {
11811+ xfer_done = 1;
11812+ if (short_read && (urb->transfer_flags & URB_SHORT_NOT_OK)) {
11813+ urb->status = -EREMOTEIO;
11814+ } else {
11815+ urb->status = 0;
11816+ }
11817+ }
11818+
11819+#ifdef DEBUG
11820+ {
11821+ hctsiz_data_t hctsiz;
11822+ hctsiz.d32 = dwc_read_reg32(&hc_regs->hctsiz);
11823+ DWC_DEBUGPL(DBG_HCDV, "DWC_otg: %s: %s, channel %d\n",
11824+ __func__, (hc->ep_is_in ? "IN" : "OUT"), hc->hc_num);
11825+ DWC_DEBUGPL(DBG_HCDV, " hc->xfer_len %d\n", hc->xfer_len);
11826+ DWC_DEBUGPL(DBG_HCDV, " hctsiz.xfersize %d\n", hctsiz.b.xfersize);
11827+ DWC_DEBUGPL(DBG_HCDV, " urb->transfer_buffer_length %d\n",
11828+ urb->transfer_buffer_length);
11829+ DWC_DEBUGPL(DBG_HCDV, " urb->actual_length %d\n", urb->actual_length);
11830+ DWC_DEBUGPL(DBG_HCDV, " short_read %d, xfer_done %d\n",
11831+ short_read, xfer_done);
11832+ }
11833+#endif
11834+
11835+ return xfer_done;
11836+}
11837+
11838+/*
11839+ * Save the starting data toggle for the next transfer. The data toggle is
11840+ * saved in the QH for non-control transfers and it's saved in the QTD for
11841+ * control transfers.
11842+ */
11843+static void save_data_toggle(dwc_hc_t *hc,
11844+ dwc_otg_hc_regs_t *hc_regs,
11845+ dwc_otg_qtd_t *qtd)
11846+{
11847+ hctsiz_data_t hctsiz;
11848+ hctsiz.d32 = dwc_read_reg32(&hc_regs->hctsiz);
11849+
11850+ if (hc->ep_type != DWC_OTG_EP_TYPE_CONTROL) {
11851+ dwc_otg_qh_t *qh = hc->qh;
11852+ if (hctsiz.b.pid == DWC_HCTSIZ_DATA0) {
11853+ qh->data_toggle = DWC_OTG_HC_PID_DATA0;
11854+ } else {
11855+ qh->data_toggle = DWC_OTG_HC_PID_DATA1;
11856+ }
11857+ } else {
11858+ if (hctsiz.b.pid == DWC_HCTSIZ_DATA0) {
11859+ qtd->data_toggle = DWC_OTG_HC_PID_DATA0;
11860+ } else {
11861+ qtd->data_toggle = DWC_OTG_HC_PID_DATA1;
11862+ }
11863+ }
11864+}
11865+
11866+/**
11867+ * Frees the first QTD in the QH's list if free_qtd is 1. For non-periodic
11868+ * QHs, removes the QH from the active non-periodic schedule. If any QTDs are
11869+ * still linked to the QH, the QH is added to the end of the inactive
11870+ * non-periodic schedule. For periodic QHs, removes the QH from the periodic
11871+ * schedule if no more QTDs are linked to the QH.
11872+ */
11873+static void deactivate_qh(dwc_otg_hcd_t *hcd,
11874+ dwc_otg_qh_t *qh,
11875+ int free_qtd)
11876+{
11877+ int continue_split = 0;
11878+ dwc_otg_qtd_t *qtd;
11879+
11880+ DWC_DEBUGPL(DBG_HCDV, " %s(%p,%p,%d)\n", __func__, hcd, qh, free_qtd);
11881+
11882+ qtd = list_entry(qh->qtd_list.next, dwc_otg_qtd_t, qtd_list_entry);
11883+
11884+ if (qtd->complete_split) {
11885+ continue_split = 1;
11886+ } else if (qtd->isoc_split_pos == DWC_HCSPLIT_XACTPOS_MID ||
11887+ qtd->isoc_split_pos == DWC_HCSPLIT_XACTPOS_END) {
11888+ continue_split = 1;
11889+ }
11890+
11891+ if (free_qtd) {
11892+ dwc_otg_hcd_qtd_remove_and_free(hcd, qtd);
11893+ continue_split = 0;
11894+ }
11895+
11896+ qh->channel = NULL;
11897+ qh->qtd_in_process = NULL;
11898+ dwc_otg_hcd_qh_deactivate(hcd, qh, continue_split);
11899+}
11900+
11901+/**
11902+ * Updates the state of an Isochronous URB when the transfer is stopped for
11903+ * any reason. The fields of the current entry in the frame descriptor array
11904+ * are set based on the transfer state and the input _halt_status. Completes
11905+ * the Isochronous URB if all the URB frames have been completed.
11906+ *
11907+ * @return DWC_OTG_HC_XFER_COMPLETE if there are more frames remaining to be
11908+ * transferred in the URB. Otherwise return DWC_OTG_HC_XFER_URB_COMPLETE.
11909+ */
11910+static dwc_otg_halt_status_e
11911+update_isoc_urb_state(dwc_otg_hcd_t *hcd,
11912+ dwc_hc_t *hc,
11913+ dwc_otg_hc_regs_t *hc_regs,
11914+ dwc_otg_qtd_t *qtd,
11915+ dwc_otg_halt_status_e halt_status)
11916+{
11917+ struct urb *urb = qtd->urb;
11918+ dwc_otg_halt_status_e ret_val = halt_status;
11919+ struct usb_iso_packet_descriptor *frame_desc;
11920+
11921+ frame_desc = &urb->iso_frame_desc[qtd->isoc_frame_index];
11922+ switch (halt_status) {
11923+ case DWC_OTG_HC_XFER_COMPLETE:
11924+ frame_desc->status = 0;
11925+ frame_desc->actual_length =
11926+ get_actual_xfer_length(hc, hc_regs, qtd,
11927+ halt_status, NULL);
11928+ break;
11929+ case DWC_OTG_HC_XFER_FRAME_OVERRUN:
11930+ urb->error_count++;
11931+ if (hc->ep_is_in) {
11932+ frame_desc->status = -ENOSR;
11933+ } else {
11934+ frame_desc->status = -ECOMM;
11935+ }
11936+ frame_desc->actual_length = 0;
11937+ break;
11938+ case DWC_OTG_HC_XFER_BABBLE_ERR:
11939+ urb->error_count++;
11940+ frame_desc->status = -EOVERFLOW;
11941+ /* Don't need to update actual_length in this case. */
11942+ break;
11943+ case DWC_OTG_HC_XFER_XACT_ERR:
11944+ urb->error_count++;
11945+ frame_desc->status = -EPROTO;
11946+ frame_desc->actual_length =
11947+ get_actual_xfer_length(hc, hc_regs, qtd,
11948+ halt_status, NULL);
11949+ default:
11950+ DWC_ERROR("%s: Unhandled _halt_status (%d)\n", __func__,
11951+ halt_status);
11952+ BUG();
11953+ break;
11954+ }
11955+
11956+ if (++qtd->isoc_frame_index == urb->number_of_packets) {
11957+ /*
11958+ * urb->status is not used for isoc transfers.
11959+ * The individual frame_desc statuses are used instead.
11960+ */
11961+ dwc_otg_hcd_complete_urb(hcd, urb, 0);
11962+ ret_val = DWC_OTG_HC_XFER_URB_COMPLETE;
11963+ } else {
11964+ ret_val = DWC_OTG_HC_XFER_COMPLETE;
11965+ }
11966+
11967+ return ret_val;
11968+}
11969+
11970+/**
11971+ * Releases a host channel for use by other transfers. Attempts to select and
11972+ * queue more transactions since at least one host channel is available.
11973+ *
11974+ * @param hcd The HCD state structure.
11975+ * @param hc The host channel to release.
11976+ * @param qtd The QTD associated with the host channel. This QTD may be freed
11977+ * if the transfer is complete or an error has occurred.
11978+ * @param halt_status Reason the channel is being released. This status
11979+ * determines the actions taken by this function.
11980+ */
11981+static void release_channel(dwc_otg_hcd_t *hcd,
11982+ dwc_hc_t *hc,
11983+ dwc_otg_qtd_t *qtd,
11984+ dwc_otg_halt_status_e halt_status)
11985+{
11986+ dwc_otg_transaction_type_e tr_type;
11987+ int free_qtd;
11988+
11989+ DWC_DEBUGPL(DBG_HCDV, " %s: channel %d, halt_status %d\n",
11990+ __func__, hc->hc_num, halt_status);
11991+
11992+ switch (halt_status) {
11993+ case DWC_OTG_HC_XFER_URB_COMPLETE:
11994+ free_qtd = 1;
11995+ break;
11996+ case DWC_OTG_HC_XFER_AHB_ERR:
11997+ case DWC_OTG_HC_XFER_STALL:
11998+ case DWC_OTG_HC_XFER_BABBLE_ERR:
11999+ free_qtd = 1;
12000+ break;
12001+ case DWC_OTG_HC_XFER_XACT_ERR:
12002+ if (qtd->error_count >= 3) {
12003+ DWC_DEBUGPL(DBG_HCDV, " Complete URB with transaction error\n");
12004+ free_qtd = 1;
12005+ qtd->urb->status = -EPROTO;
12006+ dwc_otg_hcd_complete_urb(hcd, qtd->urb, -EPROTO);
12007+ } else {
12008+ free_qtd = 0;
12009+ }
12010+ break;
12011+ case DWC_OTG_HC_XFER_URB_DEQUEUE:
12012+ /*
12013+ * The QTD has already been removed and the QH has been
12014+ * deactivated. Don't want to do anything except release the
12015+ * host channel and try to queue more transfers.
12016+ */
12017+ goto cleanup;
12018+ case DWC_OTG_HC_XFER_NO_HALT_STATUS:
12019+ DWC_ERROR("%s: No halt_status, channel %d\n", __func__, hc->hc_num);
12020+ free_qtd = 0;
12021+ break;
12022+ default:
12023+ free_qtd = 0;
12024+ break;
12025+ }
12026+
12027+ deactivate_qh(hcd, hc->qh, free_qtd);
12028+
12029+ cleanup:
12030+ /*
12031+ * Release the host channel for use by other transfers. The cleanup
12032+ * function clears the channel interrupt enables and conditions, so
12033+ * there's no need to clear the Channel Halted interrupt separately.
12034+ */
12035+ dwc_otg_hc_cleanup(hcd->core_if, hc);
12036+ list_add_tail(&hc->hc_list_entry, &hcd->free_hc_list);
12037+
12038+ switch (hc->ep_type) {
12039+ case DWC_OTG_EP_TYPE_CONTROL:
12040+ case DWC_OTG_EP_TYPE_BULK:
12041+ hcd->non_periodic_channels--;
12042+ break;
12043+
12044+ default:
12045+ /*
12046+ * Don't release reservations for periodic channels here.
12047+ * That's done when a periodic transfer is descheduled (i.e.
12048+ * when the QH is removed from the periodic schedule).
12049+ */
12050+ break;
12051+ }
12052+
12053+ /* Try to queue more transfers now that there's a free channel. */
12054+ tr_type = dwc_otg_hcd_select_transactions(hcd);
12055+ if (tr_type != DWC_OTG_TRANSACTION_NONE) {
12056+ dwc_otg_hcd_queue_transactions(hcd, tr_type);
12057+ }
12058+}
12059+
12060+/**
12061+ * Halts a host channel. If the channel cannot be halted immediately because
12062+ * the request queue is full, this function ensures that the FIFO empty
12063+ * interrupt for the appropriate queue is enabled so that the halt request can
12064+ * be queued when there is space in the request queue.
12065+ *
12066+ * This function may also be called in DMA mode. In that case, the channel is
12067+ * simply released since the core always halts the channel automatically in
12068+ * DMA mode.
12069+ */
12070+static void halt_channel(dwc_otg_hcd_t *hcd,
12071+ dwc_hc_t *hc,
12072+ dwc_otg_qtd_t *qtd,
12073+ dwc_otg_halt_status_e halt_status)
12074+{
12075+ if (hcd->core_if->dma_enable) {
12076+ release_channel(hcd, hc, qtd, halt_status);
12077+ return;
12078+ }
12079+
12080+ /* Slave mode processing... */
12081+ dwc_otg_hc_halt(hcd->core_if, hc, halt_status);
12082+
12083+ if (hc->halt_on_queue) {
12084+ gintmsk_data_t gintmsk = {.d32 = 0};
12085+ dwc_otg_core_global_regs_t *global_regs;
12086+ global_regs = hcd->core_if->core_global_regs;
12087+
12088+ if (hc->ep_type == DWC_OTG_EP_TYPE_CONTROL ||
12089+ hc->ep_type == DWC_OTG_EP_TYPE_BULK) {
12090+ /*
12091+ * Make sure the Non-periodic Tx FIFO empty interrupt
12092+ * is enabled so that the non-periodic schedule will
12093+ * be processed.
12094+ */
12095+ gintmsk.b.nptxfempty = 1;
12096+ dwc_modify_reg32(&global_regs->gintmsk, 0, gintmsk.d32);
12097+ } else {
12098+ /*
12099+ * Move the QH from the periodic queued schedule to
12100+ * the periodic assigned schedule. This allows the
12101+ * halt to be queued when the periodic schedule is
12102+ * processed.
12103+ */
12104+ list_move(&hc->qh->qh_list_entry,
12105+ &hcd->periodic_sched_assigned);
12106+
12107+ /*
12108+ * Make sure the Periodic Tx FIFO Empty interrupt is
12109+ * enabled so that the periodic schedule will be
12110+ * processed.
12111+ */
12112+ gintmsk.b.ptxfempty = 1;
12113+ dwc_modify_reg32(&global_regs->gintmsk, 0, gintmsk.d32);
12114+ }
12115+ }
12116+}
12117+
12118+/**
12119+ * Performs common cleanup for non-periodic transfers after a Transfer
12120+ * Complete interrupt. This function should be called after any endpoint type
12121+ * specific handling is finished to release the host channel.
12122+ */
12123+static void complete_non_periodic_xfer(dwc_otg_hcd_t *hcd,
12124+ dwc_hc_t *hc,
12125+ dwc_otg_hc_regs_t *hc_regs,
12126+ dwc_otg_qtd_t *qtd,
12127+ dwc_otg_halt_status_e halt_status)
12128+{
12129+ hcint_data_t hcint;
12130+
12131+ qtd->error_count = 0;
12132+
12133+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
12134+ if (hcint.b.nyet) {
12135+ /*
12136+ * Got a NYET on the last transaction of the transfer. This
12137+ * means that the endpoint should be in the PING state at the
12138+ * beginning of the next transfer.
12139+ */
12140+ hc->qh->ping_state = 1;
12141+ clear_hc_int(hc_regs, nyet);
12142+ }
12143+
12144+ /*
12145+ * Always halt and release the host channel to make it available for
12146+ * more transfers. There may still be more phases for a control
12147+ * transfer or more data packets for a bulk transfer at this point,
12148+ * but the host channel is still halted. A channel will be reassigned
12149+ * to the transfer when the non-periodic schedule is processed after
12150+ * the channel is released. This allows transactions to be queued
12151+ * properly via dwc_otg_hcd_queue_transactions, which also enables the
12152+ * Tx FIFO Empty interrupt if necessary.
12153+ */
12154+ if (hc->ep_is_in) {
12155+ /*
12156+ * IN transfers in Slave mode require an explicit disable to
12157+ * halt the channel. (In DMA mode, this call simply releases
12158+ * the channel.)
12159+ */
12160+ halt_channel(hcd, hc, qtd, halt_status);
12161+ } else {
12162+ /*
12163+ * The channel is automatically disabled by the core for OUT
12164+ * transfers in Slave mode.
12165+ */
12166+ release_channel(hcd, hc, qtd, halt_status);
12167+ }
12168+}
12169+
12170+/**
12171+ * Performs common cleanup for periodic transfers after a Transfer Complete
12172+ * interrupt. This function should be called after any endpoint type specific
12173+ * handling is finished to release the host channel.
12174+ */
12175+static void complete_periodic_xfer(dwc_otg_hcd_t *hcd,
12176+ dwc_hc_t *hc,
12177+ dwc_otg_hc_regs_t *hc_regs,
12178+ dwc_otg_qtd_t *qtd,
12179+ dwc_otg_halt_status_e halt_status)
12180+{
12181+ hctsiz_data_t hctsiz;
12182+ qtd->error_count = 0;
12183+
12184+ hctsiz.d32 = dwc_read_reg32(&hc_regs->hctsiz);
12185+ if (!hc->ep_is_in || hctsiz.b.pktcnt == 0) {
12186+ /* Core halts channel in these cases. */
12187+ release_channel(hcd, hc, qtd, halt_status);
12188+ } else {
12189+ /* Flush any outstanding requests from the Tx queue. */
12190+ halt_channel(hcd, hc, qtd, halt_status);
12191+ }
12192+}
12193+
12194+/**
12195+ * Handles a host channel Transfer Complete interrupt. This handler may be
12196+ * called in either DMA mode or Slave mode.
12197+ */
12198+static int32_t handle_hc_xfercomp_intr(dwc_otg_hcd_t *hcd,
12199+ dwc_hc_t *hc,
12200+ dwc_otg_hc_regs_t *hc_regs,
12201+ dwc_otg_qtd_t *qtd)
12202+{
12203+ int urb_xfer_done;
12204+ dwc_otg_halt_status_e halt_status = DWC_OTG_HC_XFER_COMPLETE;
12205+ struct urb *urb = qtd->urb;
12206+ int pipe_type = usb_pipetype(urb->pipe);
12207+
12208+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
12209+ "Transfer Complete--\n", hc->hc_num);
12210+
12211+ /*
12212+ * Handle xfer complete on CSPLIT.
12213+ */
12214+ if (hc->qh->do_split) {
12215+ qtd->complete_split = 0;
12216+ }
12217+
12218+ /* Update the QTD and URB states. */
12219+ switch (pipe_type) {
12220+ case PIPE_CONTROL:
12221+ switch (qtd->control_phase) {
12222+ case DWC_OTG_CONTROL_SETUP:
12223+ if (urb->transfer_buffer_length > 0) {
12224+ qtd->control_phase = DWC_OTG_CONTROL_DATA;
12225+ } else {
12226+ qtd->control_phase = DWC_OTG_CONTROL_STATUS;
12227+ }
12228+ DWC_DEBUGPL(DBG_HCDV, " Control setup transaction done\n");
12229+ halt_status = DWC_OTG_HC_XFER_COMPLETE;
12230+ break;
12231+ case DWC_OTG_CONTROL_DATA: {
12232+ urb_xfer_done = update_urb_state_xfer_comp(hc, hc_regs, urb, qtd);
12233+ if (urb_xfer_done) {
12234+ qtd->control_phase = DWC_OTG_CONTROL_STATUS;
12235+ DWC_DEBUGPL(DBG_HCDV, " Control data transfer done\n");
12236+ } else {
12237+ save_data_toggle(hc, hc_regs, qtd);
12238+ }
12239+ halt_status = DWC_OTG_HC_XFER_COMPLETE;
12240+ break;
12241+ }
12242+ case DWC_OTG_CONTROL_STATUS:
12243+ DWC_DEBUGPL(DBG_HCDV, " Control transfer complete\n");
12244+ if (urb->status == -EINPROGRESS) {
12245+ urb->status = 0;
12246+ }
12247+ dwc_otg_hcd_complete_urb(hcd, urb, urb->status);
12248+ halt_status = DWC_OTG_HC_XFER_URB_COMPLETE;
12249+ break;
12250+ }
12251+
12252+ complete_non_periodic_xfer(hcd, hc, hc_regs, qtd, halt_status);
12253+ break;
12254+ case PIPE_BULK:
12255+ DWC_DEBUGPL(DBG_HCDV, " Bulk transfer complete\n");
12256+ urb_xfer_done = update_urb_state_xfer_comp(hc, hc_regs, urb, qtd);
12257+ if (urb_xfer_done) {
12258+ dwc_otg_hcd_complete_urb(hcd, urb, urb->status);
12259+ halt_status = DWC_OTG_HC_XFER_URB_COMPLETE;
12260+ } else {
12261+ halt_status = DWC_OTG_HC_XFER_COMPLETE;
12262+ }
12263+
12264+ save_data_toggle(hc, hc_regs, qtd);
12265+ complete_non_periodic_xfer(hcd, hc, hc_regs, qtd, halt_status);
12266+ break;
12267+ case PIPE_INTERRUPT:
12268+ DWC_DEBUGPL(DBG_HCDV, " Interrupt transfer complete\n");
12269+ update_urb_state_xfer_comp(hc, hc_regs, urb, qtd);
12270+
12271+ /*
12272+ * Interrupt URB is done on the first transfer complete
12273+ * interrupt.
12274+ */
12275+ dwc_otg_hcd_complete_urb(hcd, urb, urb->status);
12276+ save_data_toggle(hc, hc_regs, qtd);
12277+ complete_periodic_xfer(hcd, hc, hc_regs, qtd,
12278+ DWC_OTG_HC_XFER_URB_COMPLETE);
12279+ break;
12280+ case PIPE_ISOCHRONOUS:
12281+ DWC_DEBUGPL(DBG_HCDV, " Isochronous transfer complete\n");
12282+ if (qtd->isoc_split_pos == DWC_HCSPLIT_XACTPOS_ALL) {
12283+ halt_status = update_isoc_urb_state(hcd, hc, hc_regs, qtd,
12284+ DWC_OTG_HC_XFER_COMPLETE);
12285+ }
12286+ complete_periodic_xfer(hcd, hc, hc_regs, qtd, halt_status);
12287+ break;
12288+ }
12289+
12290+ disable_hc_int(hc_regs, xfercompl);
12291+
12292+ return 1;
12293+}
12294+
12295+/**
12296+ * Handles a host channel STALL interrupt. This handler may be called in
12297+ * either DMA mode or Slave mode.
12298+ */
12299+static int32_t handle_hc_stall_intr(dwc_otg_hcd_t *hcd,
12300+ dwc_hc_t *hc,
12301+ dwc_otg_hc_regs_t *hc_regs,
12302+ dwc_otg_qtd_t *qtd)
12303+{
12304+ struct urb *urb = qtd->urb;
12305+ int pipe_type = usb_pipetype(urb->pipe);
12306+
12307+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
12308+ "STALL Received--\n", hc->hc_num);
12309+
12310+ if (pipe_type == PIPE_CONTROL) {
12311+ dwc_otg_hcd_complete_urb(hcd, urb, -EPIPE);
12312+ }
12313+
12314+ if (pipe_type == PIPE_BULK || pipe_type == PIPE_INTERRUPT) {
12315+ dwc_otg_hcd_complete_urb(hcd, urb, -EPIPE);
12316+ /*
12317+ * USB protocol requires resetting the data toggle for bulk
12318+ * and interrupt endpoints when a CLEAR_FEATURE(ENDPOINT_HALT)
12319+ * setup command is issued to the endpoint. Anticipate the
12320+ * CLEAR_FEATURE command since a STALL has occurred and reset
12321+ * the data toggle now.
12322+ */
12323+ hc->qh->data_toggle = 0;
12324+ }
12325+
12326+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_STALL);
12327+
12328+ disable_hc_int(hc_regs, stall);
12329+
12330+ return 1;
12331+}
12332+
12333+/*
12334+ * Updates the state of the URB when a transfer has been stopped due to an
12335+ * abnormal condition before the transfer completes. Modifies the
12336+ * actual_length field of the URB to reflect the number of bytes that have
12337+ * actually been transferred via the host channel.
12338+ */
12339+static void update_urb_state_xfer_intr(dwc_hc_t *hc,
12340+ dwc_otg_hc_regs_t *hc_regs,
12341+ struct urb *urb,
12342+ dwc_otg_qtd_t *qtd,
12343+ dwc_otg_halt_status_e halt_status)
12344+{
12345+ uint32_t bytes_transferred = get_actual_xfer_length(hc, hc_regs, qtd,
12346+ halt_status, NULL);
12347+ urb->actual_length += bytes_transferred;
12348+
12349+#ifdef DEBUG
12350+ {
12351+ hctsiz_data_t hctsiz;
12352+ hctsiz.d32 = dwc_read_reg32(&hc_regs->hctsiz);
12353+ DWC_DEBUGPL(DBG_HCDV, "DWC_otg: %s: %s, channel %d\n",
12354+ __func__, (hc->ep_is_in ? "IN" : "OUT"), hc->hc_num);
12355+ DWC_DEBUGPL(DBG_HCDV, " hc->start_pkt_count %d\n", hc->start_pkt_count);
12356+ DWC_DEBUGPL(DBG_HCDV, " hctsiz.pktcnt %d\n", hctsiz.b.pktcnt);
12357+ DWC_DEBUGPL(DBG_HCDV, " hc->max_packet %d\n", hc->max_packet);
12358+ DWC_DEBUGPL(DBG_HCDV, " bytes_transferred %d\n", bytes_transferred);
12359+ DWC_DEBUGPL(DBG_HCDV, " urb->actual_length %d\n", urb->actual_length);
12360+ DWC_DEBUGPL(DBG_HCDV, " urb->transfer_buffer_length %d\n",
12361+ urb->transfer_buffer_length);
12362+ }
12363+#endif
12364+}
12365+
12366+/**
12367+ * Handles a host channel NAK interrupt. This handler may be called in either
12368+ * DMA mode or Slave mode.
12369+ */
12370+static int32_t handle_hc_nak_intr(dwc_otg_hcd_t *hcd,
12371+ dwc_hc_t *hc,
12372+ dwc_otg_hc_regs_t *hc_regs,
12373+ dwc_otg_qtd_t *qtd)
12374+{
12375+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
12376+ "NAK Received--\n", hc->hc_num);
12377+
12378+ /*
12379+ * Handle NAK for IN/OUT SSPLIT/CSPLIT transfers, bulk, control, and
12380+ * interrupt. Re-start the SSPLIT transfer.
12381+ */
12382+ if (hc->do_split) {
12383+ if (hc->complete_split) {
12384+ qtd->error_count = 0;
12385+ }
12386+ qtd->complete_split = 0;
12387+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NAK);
12388+ goto handle_nak_done;
12389+ }
12390+
12391+ switch (usb_pipetype(qtd->urb->pipe)) {
12392+ case PIPE_CONTROL:
12393+ case PIPE_BULK:
12394+ if (hcd->core_if->dma_enable && hc->ep_is_in) {
12395+ /*
12396+ * NAK interrupts are enabled on bulk/control IN
12397+ * transfers in DMA mode for the sole purpose of
12398+ * resetting the error count after a transaction error
12399+ * occurs. The core will continue transferring data.
12400+ */
12401+ qtd->error_count = 0;
12402+ goto handle_nak_done;
12403+ }
12404+
12405+ /*
12406+ * NAK interrupts normally occur during OUT transfers in DMA
12407+ * or Slave mode. For IN transfers, more requests will be
12408+ * queued as request queue space is available.
12409+ */
12410+ qtd->error_count = 0;
12411+
12412+ if (!hc->qh->ping_state) {
12413+ update_urb_state_xfer_intr(hc, hc_regs, qtd->urb,
12414+ qtd, DWC_OTG_HC_XFER_NAK);
12415+ save_data_toggle(hc, hc_regs, qtd);
12416+ if (qtd->urb->dev->speed == USB_SPEED_HIGH) {
12417+ hc->qh->ping_state = 1;
12418+ }
12419+ }
12420+
12421+ /*
12422+ * Halt the channel so the transfer can be re-started from
12423+ * the appropriate point or the PING protocol will
12424+ * start/continue.
12425+ */
12426+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NAK);
12427+ break;
12428+ case PIPE_INTERRUPT:
12429+ qtd->error_count = 0;
12430+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NAK);
12431+ break;
12432+ case PIPE_ISOCHRONOUS:
12433+ /* Should never get called for isochronous transfers. */
12434+ BUG();
12435+ break;
12436+ }
12437+
12438+ handle_nak_done:
12439+ disable_hc_int(hc_regs, nak);
12440+
12441+ return 1;
12442+}
12443+
12444+/**
12445+ * Handles a host channel ACK interrupt. This interrupt is enabled when
12446+ * performing the PING protocol in Slave mode, when errors occur during
12447+ * either Slave mode or DMA mode, and during Start Split transactions.
12448+ */
12449+static int32_t handle_hc_ack_intr(dwc_otg_hcd_t *hcd,
12450+ dwc_hc_t *hc,
12451+ dwc_otg_hc_regs_t *hc_regs,
12452+ dwc_otg_qtd_t *qtd)
12453+{
12454+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
12455+ "ACK Received--\n", hc->hc_num);
12456+
12457+ if (hc->do_split) {
12458+ /*
12459+ * Handle ACK on SSPLIT.
12460+ * ACK should not occur in CSPLIT.
12461+ */
12462+ if (!hc->ep_is_in && hc->data_pid_start != DWC_OTG_HC_PID_SETUP) {
12463+ qtd->ssplit_out_xfer_count = hc->xfer_len;
12464+ }
12465+ if (!(hc->ep_type == DWC_OTG_EP_TYPE_ISOC && !hc->ep_is_in)) {
12466+ /* Don't need complete for isochronous out transfers. */
12467+ qtd->complete_split = 1;
12468+ }
12469+
12470+ /* ISOC OUT */
12471+ if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC && !hc->ep_is_in) {
12472+ switch (hc->xact_pos) {
12473+ case DWC_HCSPLIT_XACTPOS_ALL:
12474+ break;
12475+ case DWC_HCSPLIT_XACTPOS_END:
12476+ qtd->isoc_split_pos = DWC_HCSPLIT_XACTPOS_ALL;
12477+ qtd->isoc_split_offset = 0;
12478+ break;
12479+ case DWC_HCSPLIT_XACTPOS_BEGIN:
12480+ case DWC_HCSPLIT_XACTPOS_MID:
12481+ /*
12482+ * For BEGIN or MID, calculate the length for
12483+ * the next microframe to determine the correct
12484+ * SSPLIT token, either MID or END.
12485+ */
12486+ {
12487+ struct usb_iso_packet_descriptor *frame_desc;
12488+
12489+ frame_desc = &qtd->urb->iso_frame_desc[qtd->isoc_frame_index];
12490+ qtd->isoc_split_offset += 188;
12491+
12492+ if ((frame_desc->length - qtd->isoc_split_offset) <= 188) {
12493+ qtd->isoc_split_pos = DWC_HCSPLIT_XACTPOS_END;
12494+ } else {
12495+ qtd->isoc_split_pos = DWC_HCSPLIT_XACTPOS_MID;
12496+ }
12497+
12498+ }
12499+ break;
12500+ }
12501+ } else {
12502+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_ACK);
12503+ }
12504+ } else {
12505+ qtd->error_count = 0;
12506+
12507+ if (hc->qh->ping_state) {
12508+ hc->qh->ping_state = 0;
12509+ /*
12510+ * Halt the channel so the transfer can be re-started
12511+ * from the appropriate point. This only happens in
12512+ * Slave mode. In DMA mode, the ping_state is cleared
12513+ * when the transfer is started because the core
12514+ * automatically executes the PING, then the transfer.
12515+ */
12516+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_ACK);
12517+ }
12518+ }
12519+
12520+ /*
12521+ * If the ACK occurred when _not_ in the PING state, let the channel
12522+ * continue transferring data after clearing the error count.
12523+ */
12524+
12525+ disable_hc_int(hc_regs, ack);
12526+
12527+ return 1;
12528+}
12529+
12530+/**
12531+ * Handles a host channel NYET interrupt. This interrupt should only occur on
12532+ * Bulk and Control OUT endpoints and for complete split transactions. If a
12533+ * NYET occurs at the same time as a Transfer Complete interrupt, it is
12534+ * handled in the xfercomp interrupt handler, not here. This handler may be
12535+ * called in either DMA mode or Slave mode.
12536+ */
12537+static int32_t handle_hc_nyet_intr(dwc_otg_hcd_t *hcd,
12538+ dwc_hc_t *hc,
12539+ dwc_otg_hc_regs_t *hc_regs,
12540+ dwc_otg_qtd_t *qtd)
12541+{
12542+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
12543+ "NYET Received--\n", hc->hc_num);
12544+
12545+ /*
12546+ * NYET on CSPLIT
12547+ * re-do the CSPLIT immediately on non-periodic
12548+ */
12549+ if (hc->do_split && hc->complete_split) {
12550+ if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
12551+ hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
12552+ int frnum = dwc_otg_hcd_get_frame_number(dwc_otg_hcd_to_hcd(hcd));
12553+
12554+ if (dwc_full_frame_num(frnum) !=
12555+ dwc_full_frame_num(hc->qh->sched_frame)) {
12556+ /*
12557+ * No longer in the same full speed frame.
12558+ * Treat this as a transaction error.
12559+ */
12560+#if 0
12561+ /** @todo Fix system performance so this can
12562+ * be treated as an error. Right now complete
12563+ * splits cannot be scheduled precisely enough
12564+ * due to other system activity, so this error
12565+ * occurs regularly in Slave mode.
12566+ */
12567+ qtd->error_count++;
12568+#endif
12569+ qtd->complete_split = 0;
12570+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_XACT_ERR);
12571+ /** @todo add support for isoc release */
12572+ goto handle_nyet_done;
12573+ }
12574+ }
12575+
12576+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NYET);
12577+ goto handle_nyet_done;
12578+ }
12579+
12580+ hc->qh->ping_state = 1;
12581+ qtd->error_count = 0;
12582+
12583+ update_urb_state_xfer_intr(hc, hc_regs, qtd->urb, qtd,
12584+ DWC_OTG_HC_XFER_NYET);
12585+ save_data_toggle(hc, hc_regs, qtd);
12586+
12587+ /*
12588+ * Halt the channel and re-start the transfer so the PING
12589+ * protocol will start.
12590+ */
12591+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NYET);
12592+
12593+handle_nyet_done:
12594+ disable_hc_int(hc_regs, nyet);
12595+ return 1;
12596+}
12597+
12598+/**
12599+ * Handles a host channel babble interrupt. This handler may be called in
12600+ * either DMA mode or Slave mode.
12601+ */
12602+static int32_t handle_hc_babble_intr(dwc_otg_hcd_t *hcd,
12603+ dwc_hc_t *hc,
12604+ dwc_otg_hc_regs_t *hc_regs,
12605+ dwc_otg_qtd_t *qtd)
12606+{
12607+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
12608+ "Babble Error--\n", hc->hc_num);
12609+ if (hc->ep_type != DWC_OTG_EP_TYPE_ISOC) {
12610+ dwc_otg_hcd_complete_urb(hcd, qtd->urb, -EOVERFLOW);
12611+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_BABBLE_ERR);
12612+ } else {
12613+ dwc_otg_halt_status_e halt_status;
12614+ halt_status = update_isoc_urb_state(hcd, hc, hc_regs, qtd,
12615+ DWC_OTG_HC_XFER_BABBLE_ERR);
12616+ halt_channel(hcd, hc, qtd, halt_status);
12617+ }
12618+ disable_hc_int(hc_regs, bblerr);
12619+ return 1;
12620+}
12621+
12622+/**
12623+ * Handles a host channel AHB error interrupt. This handler is only called in
12624+ * DMA mode.
12625+ */
12626+static int32_t handle_hc_ahberr_intr(dwc_otg_hcd_t *hcd,
12627+ dwc_hc_t *hc,
12628+ dwc_otg_hc_regs_t *hc_regs,
12629+ dwc_otg_qtd_t *qtd)
12630+{
12631+ hcchar_data_t hcchar;
12632+ hcsplt_data_t hcsplt;
12633+ hctsiz_data_t hctsiz;
12634+ uint32_t hcdma;
12635+ struct urb *urb = qtd->urb;
12636+
12637+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
12638+ "AHB Error--\n", hc->hc_num);
12639+
12640+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
12641+ hcsplt.d32 = dwc_read_reg32(&hc_regs->hcsplt);
12642+ hctsiz.d32 = dwc_read_reg32(&hc_regs->hctsiz);
12643+ hcdma = dwc_read_reg32(&hc_regs->hcdma);
12644+
12645+ DWC_ERROR("AHB ERROR, Channel %d\n", hc->hc_num);
12646+ DWC_ERROR(" hcchar 0x%08x, hcsplt 0x%08x\n", hcchar.d32, hcsplt.d32);
12647+ DWC_ERROR(" hctsiz 0x%08x, hcdma 0x%08x\n", hctsiz.d32, hcdma);
12648+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD URB Enqueue\n");
12649+ DWC_ERROR(" Device address: %d\n", usb_pipedevice(urb->pipe));
12650+ DWC_ERROR(" Endpoint: %d, %s\n", usb_pipeendpoint(urb->pipe),
12651+ (usb_pipein(urb->pipe) ? "IN" : "OUT"));
12652+ DWC_ERROR(" Endpoint type: %s\n",
12653+ ({char *pipetype;
12654+ switch (usb_pipetype(urb->pipe)) {
12655+ case PIPE_CONTROL: pipetype = "CONTROL"; break;
12656+ case PIPE_BULK: pipetype = "BULK"; break;
12657+ case PIPE_INTERRUPT: pipetype = "INTERRUPT"; break;
12658+ case PIPE_ISOCHRONOUS: pipetype = "ISOCHRONOUS"; break;
12659+ default: pipetype = "UNKNOWN"; break;
12660+ }; pipetype;}));
12661+ DWC_ERROR(" Speed: %s\n",
12662+ ({char *speed;
12663+ switch (urb->dev->speed) {
12664+ case USB_SPEED_HIGH: speed = "HIGH"; break;
12665+ case USB_SPEED_FULL: speed = "FULL"; break;
12666+ case USB_SPEED_LOW: speed = "LOW"; break;
12667+ default: speed = "UNKNOWN"; break;
12668+ }; speed;}));
12669+ DWC_ERROR(" Max packet size: %d\n",
12670+ usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)));
12671+ DWC_ERROR(" Data buffer length: %d\n", urb->transfer_buffer_length);
12672+ DWC_ERROR(" Transfer buffer: %p, Transfer DMA: %p\n",
12673+ urb->transfer_buffer, (void *)urb->transfer_dma);
12674+ DWC_ERROR(" Setup buffer: %p, Setup DMA: %p\n",
12675+ urb->setup_packet, (void *)urb->setup_dma);
12676+ DWC_ERROR(" Interval: %d\n", urb->interval);
12677+
12678+ dwc_otg_hcd_complete_urb(hcd, urb, -EIO);
12679+
12680+ /*
12681+ * Force a channel halt. Don't call halt_channel because that won't
12682+ * write to the HCCHARn register in DMA mode to force the halt.
12683+ */
12684+ dwc_otg_hc_halt(hcd->core_if, hc, DWC_OTG_HC_XFER_AHB_ERR);
12685+
12686+ disable_hc_int(hc_regs, ahberr);
12687+ return 1;
12688+}
12689+
12690+/**
12691+ * Handles a host channel transaction error interrupt. This handler may be
12692+ * called in either DMA mode or Slave mode.
12693+ */
12694+static int32_t handle_hc_xacterr_intr(dwc_otg_hcd_t *hcd,
12695+ dwc_hc_t *hc,
12696+ dwc_otg_hc_regs_t *hc_regs,
12697+ dwc_otg_qtd_t *qtd)
12698+{
12699+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
12700+ "Transaction Error--\n", hc->hc_num);
12701+
12702+ switch (usb_pipetype(qtd->urb->pipe)) {
12703+ case PIPE_CONTROL:
12704+ case PIPE_BULK:
12705+ qtd->error_count++;
12706+ if (!hc->qh->ping_state) {
12707+ update_urb_state_xfer_intr(hc, hc_regs, qtd->urb,
12708+ qtd, DWC_OTG_HC_XFER_XACT_ERR);
12709+ save_data_toggle(hc, hc_regs, qtd);
12710+ if (!hc->ep_is_in && qtd->urb->dev->speed == USB_SPEED_HIGH) {
12711+ hc->qh->ping_state = 1;
12712+ }
12713+ }
12714+
12715+ /*
12716+ * Halt the channel so the transfer can be re-started from
12717+ * the appropriate point or the PING protocol will start.
12718+ */
12719+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_XACT_ERR);
12720+ break;
12721+ case PIPE_INTERRUPT:
12722+ qtd->error_count++;
12723+ if (hc->do_split && hc->complete_split) {
12724+ qtd->complete_split = 0;
12725+ }
12726+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_XACT_ERR);
12727+ break;
12728+ case PIPE_ISOCHRONOUS:
12729+ {
12730+ dwc_otg_halt_status_e halt_status;
12731+ halt_status = update_isoc_urb_state(hcd, hc, hc_regs, qtd,
12732+ DWC_OTG_HC_XFER_XACT_ERR);
12733+
12734+ halt_channel(hcd, hc, qtd, halt_status);
12735+ }
12736+ break;
12737+ }
12738+
12739+ disable_hc_int(hc_regs, xacterr);
12740+
12741+ return 1;
12742+}
12743+
12744+/**
12745+ * Handles a host channel frame overrun interrupt. This handler may be called
12746+ * in either DMA mode or Slave mode.
12747+ */
12748+static int32_t handle_hc_frmovrun_intr(dwc_otg_hcd_t *hcd,
12749+ dwc_hc_t *hc,
12750+ dwc_otg_hc_regs_t *hc_regs,
12751+ dwc_otg_qtd_t *qtd)
12752+{
12753+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
12754+ "Frame Overrun--\n", hc->hc_num);
12755+
12756+ switch (usb_pipetype(qtd->urb->pipe)) {
12757+ case PIPE_CONTROL:
12758+ case PIPE_BULK:
12759+ break;
12760+ case PIPE_INTERRUPT:
12761+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_FRAME_OVERRUN);
12762+ break;
12763+ case PIPE_ISOCHRONOUS:
12764+ {
12765+ dwc_otg_halt_status_e halt_status;
12766+ halt_status = update_isoc_urb_state(hcd, hc, hc_regs, qtd,
12767+ DWC_OTG_HC_XFER_FRAME_OVERRUN);
12768+
12769+ halt_channel(hcd, hc, qtd, halt_status);
12770+ }
12771+ break;
12772+ }
12773+
12774+ disable_hc_int(hc_regs, frmovrun);
12775+
12776+ return 1;
12777+}
12778+
12779+/**
12780+ * Handles a host channel data toggle error interrupt. This handler may be
12781+ * called in either DMA mode or Slave mode.
12782+ */
12783+static int32_t handle_hc_datatglerr_intr(dwc_otg_hcd_t *hcd,
12784+ dwc_hc_t *hc,
12785+ dwc_otg_hc_regs_t *hc_regs,
12786+ dwc_otg_qtd_t *qtd)
12787+{
12788+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
12789+ "Data Toggle Error--\n", hc->hc_num);
12790+
12791+ if (hc->ep_is_in) {
12792+ qtd->error_count = 0;
12793+ } else {
12794+ DWC_ERROR("Data Toggle Error on OUT transfer,"
12795+ "channel %d\n", hc->hc_num);
12796+ }
12797+
12798+ disable_hc_int(hc_regs, datatglerr);
12799+
12800+ return 1;
12801+}
12802+
12803+#ifdef DEBUG
12804+/**
12805+ * This function is for debug only. It checks that a valid halt status is set
12806+ * and that HCCHARn.chdis is clear. If there's a problem, corrective action is
12807+ * taken and a warning is issued.
12808+ * @return 1 if halt status is ok, 0 otherwise.
12809+ */
12810+static inline int halt_status_ok(dwc_otg_hcd_t *hcd,
12811+ dwc_hc_t *hc,
12812+ dwc_otg_hc_regs_t *hc_regs,
12813+ dwc_otg_qtd_t *qtd)
12814+{
12815+ hcchar_data_t hcchar;
12816+ hctsiz_data_t hctsiz;
12817+ hcint_data_t hcint;
12818+ hcintmsk_data_t hcintmsk;
12819+ hcsplt_data_t hcsplt;
12820+
12821+ if (hc->halt_status == DWC_OTG_HC_XFER_NO_HALT_STATUS) {
12822+ /*
12823+ * This code is here only as a check. This condition should
12824+ * never happen. Ignore the halt if it does occur.
12825+ */
12826+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
12827+ hctsiz.d32 = dwc_read_reg32(&hc_regs->hctsiz);
12828+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
12829+ hcintmsk.d32 = dwc_read_reg32(&hc_regs->hcintmsk);
12830+ hcsplt.d32 = dwc_read_reg32(&hc_regs->hcsplt);
12831+ DWC_WARN("%s: hc->halt_status == DWC_OTG_HC_XFER_NO_HALT_STATUS, "
12832+ "channel %d, hcchar 0x%08x, hctsiz 0x%08x, "
12833+ "hcint 0x%08x, hcintmsk 0x%08x, "
12834+ "hcsplt 0x%08x, qtd->complete_split %d\n",
12835+ __func__, hc->hc_num, hcchar.d32, hctsiz.d32,
12836+ hcint.d32, hcintmsk.d32,
12837+ hcsplt.d32, qtd->complete_split);
12838+
12839+ DWC_WARN("%s: no halt status, channel %d, ignoring interrupt\n",
12840+ __func__, hc->hc_num);
12841+ DWC_WARN("\n");
12842+ clear_hc_int(hc_regs, chhltd);
12843+ return 0;
12844+ }
12845+
12846+ /*
12847+ * This code is here only as a check. hcchar.chdis should
12848+ * never be set when the halt interrupt occurs. Halt the
12849+ * channel again if it does occur.
12850+ */
12851+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
12852+ if (hcchar.b.chdis) {
12853+ DWC_WARN("%s: hcchar.chdis set unexpectedly, "
12854+ "hcchar 0x%08x, trying to halt again\n",
12855+ __func__, hcchar.d32);
12856+ clear_hc_int(hc_regs, chhltd);
12857+ hc->halt_pending = 0;
12858+ halt_channel(hcd, hc, qtd, hc->halt_status);
12859+ return 0;
12860+ }
12861+
12862+ return 1;
12863+}
12864+#endif
12865+
12866+/**
12867+ * Handles a host Channel Halted interrupt in DMA mode. This handler
12868+ * determines the reason the channel halted and proceeds accordingly.
12869+ */
12870+static void handle_hc_chhltd_intr_dma(dwc_otg_hcd_t *hcd,
12871+ dwc_hc_t *hc,
12872+ dwc_otg_hc_regs_t *hc_regs,
12873+ dwc_otg_qtd_t *qtd)
12874+{
12875+ hcint_data_t hcint;
12876+ hcintmsk_data_t hcintmsk;
12877+ int out_nak_enh = 0;
12878+
12879+ /* For core with OUT NAK enhancement, the flow for high-
12880+ * speed CONTROL/BULK OUT is handled a little differently.
12881+ */
12882+ if (hcd->core_if->snpsid >= 0x4F54271A) {
12883+ if (hc->speed == DWC_OTG_EP_SPEED_HIGH && !hc->ep_is_in &&
12884+ (hc->ep_type == DWC_OTG_EP_TYPE_CONTROL ||
12885+ hc->ep_type == DWC_OTG_EP_TYPE_BULK)) {
12886+ DWC_DEBUGPL(DBG_HCD, "OUT NAK enhancement enabled\n");
12887+ out_nak_enh = 1;
12888+ } else {
12889+ DWC_DEBUGPL(DBG_HCD, "OUT NAK enhancement disabled, not HS Ctrl/Bulk OUT EP\n");
12890+ }
12891+ } else {
12892+ DWC_DEBUGPL(DBG_HCD, "OUT NAK enhancement disabled, no core support\n");
12893+ }
12894+
12895+ if (hc->halt_status == DWC_OTG_HC_XFER_URB_DEQUEUE ||
12896+ hc->halt_status == DWC_OTG_HC_XFER_AHB_ERR) {
12897+ /*
12898+ * Just release the channel. A dequeue can happen on a
12899+ * transfer timeout. In the case of an AHB Error, the channel
12900+ * was forced to halt because there's no way to gracefully
12901+ * recover.
12902+ */
12903+ release_channel(hcd, hc, qtd, hc->halt_status);
12904+ return;
12905+ }
12906+
12907+ /* Read the HCINTn register to determine the cause for the halt. */
12908+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
12909+ hcintmsk.d32 = dwc_read_reg32(&hc_regs->hcintmsk);
12910+
12911+ if (hcint.b.xfercomp) {
12912+ /** @todo This is here because of a possible hardware bug. Spec
12913+ * says that on SPLIT-ISOC OUT transfers in DMA mode that a HALT
12914+ * interrupt w/ACK bit set should occur, but I only see the
12915+ * XFERCOMP bit, even with it masked out. This is a workaround
12916+ * for that behavior. Should fix this when hardware is fixed.
12917+ */
12918+ if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC && !hc->ep_is_in) {
12919+ handle_hc_ack_intr(hcd, hc, hc_regs, qtd);
12920+ }
12921+ handle_hc_xfercomp_intr(hcd, hc, hc_regs, qtd);
12922+ } else if (hcint.b.stall) {
12923+ handle_hc_stall_intr(hcd, hc, hc_regs, qtd);
12924+ } else if (hcint.b.xacterr) {
12925+ if (out_nak_enh) {
12926+ if (hcint.b.nyet || hcint.b.nak || hcint.b.ack) {
12927+ printk(KERN_DEBUG "XactErr with NYET/NAK/ACK\n");
12928+ qtd->error_count = 0;
12929+ } else {
12930+ printk(KERN_DEBUG "XactErr without NYET/NAK/ACK\n");
12931+ }
12932+ }
12933+
12934+ /*
12935+ * Must handle xacterr before nak or ack. Could get a xacterr
12936+ * at the same time as either of these on a BULK/CONTROL OUT
12937+ * that started with a PING. The xacterr takes precedence.
12938+ */
12939+ handle_hc_xacterr_intr(hcd, hc, hc_regs, qtd);
12940+ } else if (!out_nak_enh) {
12941+ if (hcint.b.nyet) {
12942+ /*
12943+ * Must handle nyet before nak or ack. Could get a nyet at the
12944+ * same time as either of those on a BULK/CONTROL OUT that
12945+ * started with a PING. The nyet takes precedence.
12946+ */
12947+ handle_hc_nyet_intr(hcd, hc, hc_regs, qtd);
12948+ } else if (hcint.b.bblerr) {
12949+ handle_hc_babble_intr(hcd, hc, hc_regs, qtd);
12950+ } else if (hcint.b.frmovrun) {
12951+ handle_hc_frmovrun_intr(hcd, hc, hc_regs, qtd);
12952+ } else if (hcint.b.nak && !hcintmsk.b.nak) {
12953+ /*
12954+ * If nak is not masked, it's because a non-split IN transfer
12955+ * is in an error state. In that case, the nak is handled by
12956+ * the nak interrupt handler, not here. Handle nak here for
12957+ * BULK/CONTROL OUT transfers, which halt on a NAK to allow
12958+ * rewinding the buffer pointer.
12959+ */
12960+ handle_hc_nak_intr(hcd, hc, hc_regs, qtd);
12961+ } else if (hcint.b.ack && !hcintmsk.b.ack) {
12962+ /*
12963+ * If ack is not masked, it's because a non-split IN transfer
12964+ * is in an error state. In that case, the ack is handled by
12965+ * the ack interrupt handler, not here. Handle ack here for
12966+ * split transfers. Start splits halt on ACK.
12967+ */
12968+ handle_hc_ack_intr(hcd, hc, hc_regs, qtd);
12969+ } else {
12970+ if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
12971+ hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
12972+ /*
12973+ * A periodic transfer halted with no other channel
12974+ * interrupts set. Assume it was halted by the core
12975+ * because it could not be completed in its scheduled
12976+ * (micro)frame.
12977+ */
12978+#ifdef DEBUG
12979+ DWC_PRINT("%s: Halt channel %d (assume incomplete periodic transfer)\n",
12980+ __func__, hc->hc_num);
12981+#endif
12982+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_PERIODIC_INCOMPLETE);
12983+ } else {
12984+ DWC_ERROR("%s: Channel %d, DMA Mode -- ChHltd set, but reason "
12985+ "for halting is unknown, hcint 0x%08x, intsts 0x%08x\n",
12986+ __func__, hc->hc_num, hcint.d32,
12987+ dwc_read_reg32(&hcd->core_if->core_global_regs->gintsts));
12988+ }
12989+ }
12990+ } else {
12991+ printk(KERN_DEBUG "NYET/NAK/ACK/other in non-error case, 0x%08x\n", hcint.d32);
12992+ }
12993+}
12994+
12995+/**
12996+ * Handles a host channel Channel Halted interrupt.
12997+ *
12998+ * In slave mode, this handler is called only when the driver specifically
12999+ * requests a halt. This occurs during handling other host channel interrupts
13000+ * (e.g. nak, xacterr, stall, nyet, etc.).
13001+ *
13002+ * In DMA mode, this is the interrupt that occurs when the core has finished
13003+ * processing a transfer on a channel. Other host channel interrupts (except
13004+ * ahberr) are disabled in DMA mode.
13005+ */
13006+static int32_t handle_hc_chhltd_intr(dwc_otg_hcd_t *hcd,
13007+ dwc_hc_t *hc,
13008+ dwc_otg_hc_regs_t *hc_regs,
13009+ dwc_otg_qtd_t *qtd)
13010+{
13011+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
13012+ "Channel Halted--\n", hc->hc_num);
13013+
13014+ if (hcd->core_if->dma_enable) {
13015+ handle_hc_chhltd_intr_dma(hcd, hc, hc_regs, qtd);
13016+ } else {
13017+#ifdef DEBUG
13018+ if (!halt_status_ok(hcd, hc, hc_regs, qtd)) {
13019+ return 1;
13020+ }
13021+#endif
13022+ release_channel(hcd, hc, qtd, hc->halt_status);
13023+ }
13024+
13025+ return 1;
13026+}
13027+
13028+/** Handles interrupt for a specific Host Channel */
13029+int32_t dwc_otg_hcd_handle_hc_n_intr(dwc_otg_hcd_t *dwc_otg_hcd, uint32_t num)
13030+{
13031+ int retval = 0;
13032+ hcint_data_t hcint;
13033+ hcintmsk_data_t hcintmsk;
13034+ dwc_hc_t *hc;
13035+ dwc_otg_hc_regs_t *hc_regs;
13036+ dwc_otg_qtd_t *qtd;
13037+
13038+ DWC_DEBUGPL(DBG_HCDV, "--Host Channel Interrupt--, Channel %d\n", num);
13039+
13040+ hc = dwc_otg_hcd->hc_ptr_array[num];
13041+ hc_regs = dwc_otg_hcd->core_if->host_if->hc_regs[num];
13042+ qtd = list_entry(hc->qh->qtd_list.next, dwc_otg_qtd_t, qtd_list_entry);
13043+
13044+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
13045+ hcintmsk.d32 = dwc_read_reg32(&hc_regs->hcintmsk);
13046+ DWC_DEBUGPL(DBG_HCDV, " hcint 0x%08x, hcintmsk 0x%08x, hcint&hcintmsk 0x%08x\n",
13047+ hcint.d32, hcintmsk.d32, (hcint.d32 & hcintmsk.d32));
13048+ hcint.d32 = hcint.d32 & hcintmsk.d32;
13049+
13050+ if (!dwc_otg_hcd->core_if->dma_enable) {
13051+ if (hcint.b.chhltd && hcint.d32 != 0x2) {
13052+ hcint.b.chhltd = 0;
13053+ }
13054+ }
13055+
13056+ if (hcint.b.xfercomp) {
13057+ retval |= handle_hc_xfercomp_intr(dwc_otg_hcd, hc, hc_regs, qtd);
13058+ /*
13059+ * If NYET occurred at same time as Xfer Complete, the NYET is
13060+ * handled by the Xfer Complete interrupt handler. Don't want
13061+ * to call the NYET interrupt handler in this case.
13062+ */
13063+ hcint.b.nyet = 0;
13064+ }
13065+ if (hcint.b.chhltd) {
13066+ retval |= handle_hc_chhltd_intr(dwc_otg_hcd, hc, hc_regs, qtd);
13067+ }
13068+ if (hcint.b.ahberr) {
13069+ retval |= handle_hc_ahberr_intr(dwc_otg_hcd, hc, hc_regs, qtd);
13070+ }
13071+ if (hcint.b.stall) {
13072+ retval |= handle_hc_stall_intr(dwc_otg_hcd, hc, hc_regs, qtd);
13073+ }
13074+ if (hcint.b.nak) {
13075+ retval |= handle_hc_nak_intr(dwc_otg_hcd, hc, hc_regs, qtd);
13076+ }
13077+ if (hcint.b.ack) {
13078+ retval |= handle_hc_ack_intr(dwc_otg_hcd, hc, hc_regs, qtd);
13079+ }
13080+ if (hcint.b.nyet) {
13081+ retval |= handle_hc_nyet_intr(dwc_otg_hcd, hc, hc_regs, qtd);
13082+ }
13083+ if (hcint.b.xacterr) {
13084+ retval |= handle_hc_xacterr_intr(dwc_otg_hcd, hc, hc_regs, qtd);
13085+ }
13086+ if (hcint.b.bblerr) {
13087+ retval |= handle_hc_babble_intr(dwc_otg_hcd, hc, hc_regs, qtd);
13088+ }
13089+ if (hcint.b.frmovrun) {
13090+ retval |= handle_hc_frmovrun_intr(dwc_otg_hcd, hc, hc_regs, qtd);
13091+ }
13092+ if (hcint.b.datatglerr) {
13093+ retval |= handle_hc_datatglerr_intr(dwc_otg_hcd, hc, hc_regs, qtd);
13094+ }
13095+
13096+ return retval;
13097+}
13098+
13099+#endif /* DWC_DEVICE_ONLY */
13100--- /dev/null
13101+++ b/drivers/usb/dwc/otg_hcd_queue.c
13102@@ -0,0 +1,713 @@
13103+/* ==========================================================================
13104+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd_queue.c $
13105+ * $Revision: #33 $
13106+ * $Date: 2008/07/15 $
13107+ * $Change: 1064918 $
13108+ *
13109+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
13110+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
13111+ * otherwise expressly agreed to in writing between Synopsys and you.
13112+ *
13113+ * The Software IS NOT an item of Licensed Software or Licensed Product under
13114+ * any End User Software License Agreement or Agreement for Licensed Product
13115+ * with Synopsys or any supplement thereto. You are permitted to use and
13116+ * redistribute this Software in source and binary forms, with or without
13117+ * modification, provided that redistributions of source code must retain this
13118+ * notice. You may not view, use, disclose, copy or distribute this file or
13119+ * any information contained herein except pursuant to this license grant from
13120+ * Synopsys. If you do not agree with this notice, including the disclaimer
13121+ * below, then you are not authorized to use the Software.
13122+ *
13123+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
13124+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
13125+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
13126+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
13127+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
13128+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
13129+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
13130+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
13131+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
13132+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
13133+ * DAMAGE.
13134+ * ========================================================================== */
13135+#ifndef DWC_DEVICE_ONLY
13136+
13137+/**
13138+ * @file
13139+ *
13140+ * This file contains the functions to manage Queue Heads and Queue
13141+ * Transfer Descriptors.
13142+ */
13143+#include <linux/kernel.h>
13144+#include <linux/module.h>
13145+#include <linux/moduleparam.h>
13146+#include <linux/init.h>
13147+#include <linux/device.h>
13148+#include <linux/errno.h>
13149+#include <linux/list.h>
13150+#include <linux/interrupt.h>
13151+#include <linux/string.h>
13152+#include <linux/version.h>
13153+
13154+#include <mach/irqs.h>
13155+
13156+#include "otg_driver.h"
13157+#include "otg_hcd.h"
13158+#include "otg_regs.h"
13159+
13160+/**
13161+ * This function allocates and initializes a QH.
13162+ *
13163+ * @param hcd The HCD state structure for the DWC OTG controller.
13164+ * @param[in] urb Holds the information about the device/endpoint that we need
13165+ * to initialize the QH.
13166+ *
13167+ * @return Returns pointer to the newly allocated QH, or NULL on error. */
13168+dwc_otg_qh_t *dwc_otg_hcd_qh_create (dwc_otg_hcd_t *hcd, struct urb *urb)
13169+{
13170+ dwc_otg_qh_t *qh;
13171+
13172+ /* Allocate memory */
13173+ /** @todo add memflags argument */
13174+ qh = dwc_otg_hcd_qh_alloc ();
13175+ if (qh == NULL) {
13176+ return NULL;
13177+ }
13178+
13179+ dwc_otg_hcd_qh_init (hcd, qh, urb);
13180+ return qh;
13181+}
13182+
13183+/** Free each QTD in the QH's QTD-list then free the QH. QH should already be
13184+ * removed from a list. QTD list should already be empty if called from URB
13185+ * Dequeue.
13186+ *
13187+ * @param[in] hcd HCD instance.
13188+ * @param[in] qh The QH to free.
13189+ */
13190+void dwc_otg_hcd_qh_free (dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh)
13191+{
13192+ dwc_otg_qtd_t *qtd;
13193+ struct list_head *pos;
13194+ //unsigned long flags;
13195+
13196+ /* Free each QTD in the QTD list */
13197+
13198+#ifdef CONFIG_SMP
13199+ //the spinlock is locked before this function get called,
13200+ //but in case the lock is needed, the check function is preserved
13201+
13202+ //but in non-SMP mode, all spinlock is lockable.
13203+ //don't do the test in non-SMP mode
13204+
13205+ if(spin_trylock(&hcd->lock)) {
13206+ printk("%s: It is not supposed to be lockable!!\n",__func__);
13207+ BUG();
13208+ }
13209+#endif
13210+// SPIN_LOCK_IRQSAVE(&hcd->lock, flags)
13211+ for (pos = qh->qtd_list.next;
13212+ pos != &qh->qtd_list;
13213+ pos = qh->qtd_list.next)
13214+ {
13215+ list_del (pos);
13216+ qtd = dwc_list_to_qtd (pos);
13217+ dwc_otg_hcd_qtd_free (qtd);
13218+ }
13219+// SPIN_UNLOCK_IRQRESTORE(&hcd->lock, flags)
13220+
13221+ kfree (qh);
13222+ return;
13223+}
13224+
13225+/** Initializes a QH structure.
13226+ *
13227+ * @param[in] hcd The HCD state structure for the DWC OTG controller.
13228+ * @param[in] qh The QH to init.
13229+ * @param[in] urb Holds the information about the device/endpoint that we need
13230+ * to initialize the QH. */
13231+#define SCHEDULE_SLOP 10
13232+void dwc_otg_hcd_qh_init(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh, struct urb *urb)
13233+{
13234+ char *speed, *type;
13235+ memset (qh, 0, sizeof (dwc_otg_qh_t));
13236+
13237+ /* Initialize QH */
13238+ switch (usb_pipetype(urb->pipe)) {
13239+ case PIPE_CONTROL:
13240+ qh->ep_type = USB_ENDPOINT_XFER_CONTROL;
13241+ break;
13242+ case PIPE_BULK:
13243+ qh->ep_type = USB_ENDPOINT_XFER_BULK;
13244+ break;
13245+ case PIPE_ISOCHRONOUS:
13246+ qh->ep_type = USB_ENDPOINT_XFER_ISOC;
13247+ break;
13248+ case PIPE_INTERRUPT:
13249+ qh->ep_type = USB_ENDPOINT_XFER_INT;
13250+ break;
13251+ }
13252+
13253+ qh->ep_is_in = usb_pipein(urb->pipe) ? 1 : 0;
13254+
13255+ qh->data_toggle = DWC_OTG_HC_PID_DATA0;
13256+ qh->maxp = usb_maxpacket(urb->dev, urb->pipe, !(usb_pipein(urb->pipe)));
13257+ INIT_LIST_HEAD(&qh->qtd_list);
13258+ INIT_LIST_HEAD(&qh->qh_list_entry);
13259+ qh->channel = NULL;
13260+
13261+ /* FS/LS Enpoint on HS Hub
13262+ * NOT virtual root hub */
13263+ qh->do_split = 0;
13264+ if (((urb->dev->speed == USB_SPEED_LOW) ||
13265+ (urb->dev->speed == USB_SPEED_FULL)) &&
13266+ (urb->dev->tt) && (urb->dev->tt->hub) && (urb->dev->tt->hub->devnum != 1))
13267+ {
13268+ DWC_DEBUGPL(DBG_HCD, "QH init: EP %d: TT found at hub addr %d, for port %d\n",
13269+ usb_pipeendpoint(urb->pipe), urb->dev->tt->hub->devnum,
13270+ urb->dev->ttport);
13271+ qh->do_split = 1;
13272+ }
13273+
13274+ if (qh->ep_type == USB_ENDPOINT_XFER_INT ||
13275+ qh->ep_type == USB_ENDPOINT_XFER_ISOC) {
13276+ /* Compute scheduling parameters once and save them. */
13277+ hprt0_data_t hprt;
13278+
13279+ /** @todo Account for split transfers in the bus time. */
13280+ int bytecount = dwc_hb_mult(qh->maxp) * dwc_max_packet(qh->maxp);
13281+ qh->usecs = usb_calc_bus_time(urb->dev->speed,
13282+ usb_pipein(urb->pipe),
13283+ (qh->ep_type == USB_ENDPOINT_XFER_ISOC),
13284+ bytecount);
13285+
13286+ /* Start in a slightly future (micro)frame. */
13287+ qh->sched_frame = dwc_frame_num_inc(hcd->frame_number,
13288+ SCHEDULE_SLOP);
13289+ qh->interval = urb->interval;
13290+#if 0
13291+ /* Increase interrupt polling rate for debugging. */
13292+ if (qh->ep_type == USB_ENDPOINT_XFER_INT) {
13293+ qh->interval = 8;
13294+ }
13295+#endif
13296+ hprt.d32 = dwc_read_reg32(hcd->core_if->host_if->hprt0);
13297+ if ((hprt.b.prtspd == DWC_HPRT0_PRTSPD_HIGH_SPEED) &&
13298+ ((urb->dev->speed == USB_SPEED_LOW) ||
13299+ (urb->dev->speed == USB_SPEED_FULL))) {
13300+ qh->interval *= 8;
13301+ qh->sched_frame |= 0x7;
13302+ qh->start_split_frame = qh->sched_frame;
13303+ }
13304+
13305+ }
13306+
13307+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD QH Initialized\n");
13308+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - qh = %p\n", qh);
13309+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - Device Address = %d\n",
13310+ urb->dev->devnum);
13311+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - Endpoint %d, %s\n",
13312+ usb_pipeendpoint(urb->pipe),
13313+ usb_pipein(urb->pipe) == USB_DIR_IN ? "IN" : "OUT");
13314+
13315+ switch(urb->dev->speed) {
13316+ case USB_SPEED_LOW:
13317+ speed = "low";
13318+ break;
13319+ case USB_SPEED_FULL:
13320+ speed = "full";
13321+ break;
13322+ case USB_SPEED_HIGH:
13323+ speed = "high";
13324+ break;
13325+ default:
13326+ speed = "?";
13327+ break;
13328+ }
13329+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - Speed = %s\n", speed);
13330+
13331+ switch (qh->ep_type) {
13332+ case USB_ENDPOINT_XFER_ISOC:
13333+ type = "isochronous";
13334+ break;
13335+ case USB_ENDPOINT_XFER_INT:
13336+ type = "interrupt";
13337+ break;
13338+ case USB_ENDPOINT_XFER_CONTROL:
13339+ type = "control";
13340+ break;
13341+ case USB_ENDPOINT_XFER_BULK:
13342+ type = "bulk";
13343+ break;
13344+ default:
13345+ type = "?";
13346+ break;
13347+ }
13348+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - Type = %s\n",type);
13349+
13350+#ifdef DEBUG
13351+ if (qh->ep_type == USB_ENDPOINT_XFER_INT) {
13352+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - usecs = %d\n",
13353+ qh->usecs);
13354+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - interval = %d\n",
13355+ qh->interval);
13356+ }
13357+#endif
13358+
13359+ return;
13360+}
13361+
13362+/**
13363+ * Checks that a channel is available for a periodic transfer.
13364+ *
13365+ * @return 0 if successful, negative error code otherise.
13366+ */
13367+static int periodic_channel_available(dwc_otg_hcd_t *hcd)
13368+{
13369+ /*
13370+ * Currently assuming that there is a dedicated host channnel for each
13371+ * periodic transaction plus at least one host channel for
13372+ * non-periodic transactions.
13373+ */
13374+ int status;
13375+ int num_channels;
13376+
13377+ num_channels = hcd->core_if->core_params->host_channels;
13378+ if ((hcd->periodic_channels + hcd->non_periodic_channels < num_channels) &&
13379+ (hcd->periodic_channels < num_channels - 1)) {
13380+ status = 0;
13381+ }
13382+ else {
13383+ DWC_NOTICE("%s: Total channels: %d, Periodic: %d, Non-periodic: %d\n",
13384+ __func__, num_channels, hcd->periodic_channels,
13385+ hcd->non_periodic_channels);
13386+ status = -ENOSPC;
13387+ }
13388+
13389+ return status;
13390+}
13391+
13392+/**
13393+ * Checks that there is sufficient bandwidth for the specified QH in the
13394+ * periodic schedule. For simplicity, this calculation assumes that all the
13395+ * transfers in the periodic schedule may occur in the same (micro)frame.
13396+ *
13397+ * @param hcd The HCD state structure for the DWC OTG controller.
13398+ * @param qh QH containing periodic bandwidth required.
13399+ *
13400+ * @return 0 if successful, negative error code otherwise.
13401+ */
13402+static int check_periodic_bandwidth(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh)
13403+{
13404+ int status;
13405+ uint16_t max_claimed_usecs;
13406+
13407+ status = 0;
13408+
13409+ if (hcd->core_if->core_params->speed == DWC_SPEED_PARAM_HIGH) {
13410+ /*
13411+ * High speed mode.
13412+ * Max periodic usecs is 80% x 125 usec = 100 usec.
13413+ */
13414+ max_claimed_usecs = 100 - qh->usecs;
13415+ } else {
13416+ /*
13417+ * Full speed mode.
13418+ * Max periodic usecs is 90% x 1000 usec = 900 usec.
13419+ */
13420+ max_claimed_usecs = 900 - qh->usecs;
13421+ }
13422+
13423+ if (hcd->periodic_usecs > max_claimed_usecs) {
13424+ DWC_NOTICE("%s: already claimed usecs %d, required usecs %d\n",
13425+ __func__, hcd->periodic_usecs, qh->usecs);
13426+ status = -ENOSPC;
13427+ }
13428+
13429+ return status;
13430+}
13431+
13432+/**
13433+ * Checks that the max transfer size allowed in a host channel is large enough
13434+ * to handle the maximum data transfer in a single (micro)frame for a periodic
13435+ * transfer.
13436+ *
13437+ * @param hcd The HCD state structure for the DWC OTG controller.
13438+ * @param qh QH for a periodic endpoint.
13439+ *
13440+ * @return 0 if successful, negative error code otherwise.
13441+ */
13442+static int check_max_xfer_size(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh)
13443+{
13444+ int status;
13445+ uint32_t max_xfer_size;
13446+ uint32_t max_channel_xfer_size;
13447+
13448+ status = 0;
13449+
13450+ max_xfer_size = dwc_max_packet(qh->maxp) * dwc_hb_mult(qh->maxp);
13451+ max_channel_xfer_size = hcd->core_if->core_params->max_transfer_size;
13452+
13453+ if (max_xfer_size > max_channel_xfer_size) {
13454+ DWC_NOTICE("%s: Periodic xfer length %d > "
13455+ "max xfer length for channel %d\n",
13456+ __func__, max_xfer_size, max_channel_xfer_size);
13457+ status = -ENOSPC;
13458+ }
13459+
13460+ return status;
13461+}
13462+
13463+/**
13464+ * Schedules an interrupt or isochronous transfer in the periodic schedule.
13465+ *
13466+ * @param hcd The HCD state structure for the DWC OTG controller.
13467+ * @param qh QH for the periodic transfer. The QH should already contain the
13468+ * scheduling information.
13469+ *
13470+ * @return 0 if successful, negative error code otherwise.
13471+ */
13472+static int schedule_periodic(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh)
13473+{
13474+ int status = 0;
13475+
13476+ status = periodic_channel_available(hcd);
13477+ if (status) {
13478+ DWC_NOTICE("%s: No host channel available for periodic "
13479+ "transfer.\n", __func__);
13480+ return status;
13481+ }
13482+
13483+ status = check_periodic_bandwidth(hcd, qh);
13484+ if (status) {
13485+ DWC_NOTICE("%s: Insufficient periodic bandwidth for "
13486+ "periodic transfer.\n", __func__);
13487+ return status;
13488+ }
13489+
13490+ status = check_max_xfer_size(hcd, qh);
13491+ if (status) {
13492+ DWC_NOTICE("%s: Channel max transfer size too small "
13493+ "for periodic transfer.\n", __func__);
13494+ return status;
13495+ }
13496+
13497+ /* Always start in the inactive schedule. */
13498+ list_add_tail(&qh->qh_list_entry, &hcd->periodic_sched_inactive);
13499+
13500+ /* Reserve the periodic channel. */
13501+ hcd->periodic_channels++;
13502+
13503+ /* Update claimed usecs per (micro)frame. */
13504+ hcd->periodic_usecs += qh->usecs;
13505+
13506+ /* Update average periodic bandwidth claimed and # periodic reqs for usbfs. */
13507+ hcd_to_bus(dwc_otg_hcd_to_hcd(hcd))->bandwidth_allocated += qh->usecs / qh->interval;
13508+ if (qh->ep_type == USB_ENDPOINT_XFER_INT) {
13509+ hcd_to_bus(dwc_otg_hcd_to_hcd(hcd))->bandwidth_int_reqs++;
13510+ DWC_DEBUGPL(DBG_HCD, "Scheduled intr: qh %p, usecs %d, period %d\n",
13511+ qh, qh->usecs, qh->interval);
13512+ } else {
13513+ hcd_to_bus(dwc_otg_hcd_to_hcd(hcd))->bandwidth_isoc_reqs++;
13514+ DWC_DEBUGPL(DBG_HCD, "Scheduled isoc: qh %p, usecs %d, period %d\n",
13515+ qh, qh->usecs, qh->interval);
13516+ }
13517+
13518+ return status;
13519+}
13520+
13521+/**
13522+ * This function adds a QH to either the non periodic or periodic schedule if
13523+ * it is not already in the schedule. If the QH is already in the schedule, no
13524+ * action is taken.
13525+ *
13526+ * @return 0 if successful, negative error code otherwise.
13527+ */
13528+int dwc_otg_hcd_qh_add (dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh)
13529+{
13530+ //unsigned long flags;
13531+ int status = 0;
13532+
13533+#ifdef CONFIG_SMP
13534+ //the spinlock is locked before this function get called,
13535+ //but in case the lock is needed, the check function is preserved
13536+ //but in non-SMP mode, all spinlock is lockable.
13537+ //don't do the test in non-SMP mode
13538+
13539+ if(spin_trylock(&hcd->lock)) {
13540+ printk("%s: It is not supposed to be lockable!!\n",__func__);
13541+ BUG();
13542+ }
13543+#endif
13544+// SPIN_LOCK_IRQSAVE(&hcd->lock, flags)
13545+
13546+ if (!list_empty(&qh->qh_list_entry)) {
13547+ /* QH already in a schedule. */
13548+ goto done;
13549+ }
13550+
13551+ /* Add the new QH to the appropriate schedule */
13552+ if (dwc_qh_is_non_per(qh)) {
13553+ /* Always start in the inactive schedule. */
13554+ list_add_tail(&qh->qh_list_entry, &hcd->non_periodic_sched_inactive);
13555+ } else {
13556+ status = schedule_periodic(hcd, qh);
13557+ }
13558+
13559+ done:
13560+// SPIN_UNLOCK_IRQRESTORE(&hcd->lock, flags)
13561+
13562+ return status;
13563+}
13564+
13565+/**
13566+ * Removes an interrupt or isochronous transfer from the periodic schedule.
13567+ *
13568+ * @param hcd The HCD state structure for the DWC OTG controller.
13569+ * @param qh QH for the periodic transfer.
13570+ */
13571+static void deschedule_periodic(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh)
13572+{
13573+ list_del_init(&qh->qh_list_entry);
13574+
13575+ /* Release the periodic channel reservation. */
13576+ hcd->periodic_channels--;
13577+
13578+ /* Update claimed usecs per (micro)frame. */
13579+ hcd->periodic_usecs -= qh->usecs;
13580+
13581+ /* Update average periodic bandwidth claimed and # periodic reqs for usbfs. */
13582+ hcd_to_bus(dwc_otg_hcd_to_hcd(hcd))->bandwidth_allocated -= qh->usecs / qh->interval;
13583+
13584+ if (qh->ep_type == USB_ENDPOINT_XFER_INT) {
13585+ hcd_to_bus(dwc_otg_hcd_to_hcd(hcd))->bandwidth_int_reqs--;
13586+ DWC_DEBUGPL(DBG_HCD, "Descheduled intr: qh %p, usecs %d, period %d\n",
13587+ qh, qh->usecs, qh->interval);
13588+ } else {
13589+ hcd_to_bus(dwc_otg_hcd_to_hcd(hcd))->bandwidth_isoc_reqs--;
13590+ DWC_DEBUGPL(DBG_HCD, "Descheduled isoc: qh %p, usecs %d, period %d\n",
13591+ qh, qh->usecs, qh->interval);
13592+ }
13593+}
13594+
13595+/**
13596+ * Removes a QH from either the non-periodic or periodic schedule. Memory is
13597+ * not freed.
13598+ *
13599+ * @param[in] hcd The HCD state structure.
13600+ * @param[in] qh QH to remove from schedule. */
13601+void dwc_otg_hcd_qh_remove (dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh)
13602+{
13603+ //unsigned long flags;
13604+
13605+#ifdef CONFIG_SMP
13606+ //the spinlock is locked before this function get called,
13607+ //but in case the lock is needed, the check function is preserved
13608+ //but in non-SMP mode, all spinlock is lockable.
13609+ //don't do the test in non-SMP mode
13610+
13611+ if(spin_trylock(&hcd->lock)) {
13612+ printk("%s: It is not supposed to be lockable!!\n",__func__);
13613+ BUG();
13614+ }
13615+#endif
13616+// SPIN_LOCK_IRQSAVE(&hcd->lock, flags);
13617+
13618+ if (list_empty(&qh->qh_list_entry)) {
13619+ /* QH is not in a schedule. */
13620+ goto done;
13621+ }
13622+
13623+ if (dwc_qh_is_non_per(qh)) {
13624+ if (hcd->non_periodic_qh_ptr == &qh->qh_list_entry) {
13625+ hcd->non_periodic_qh_ptr = hcd->non_periodic_qh_ptr->next;
13626+ }
13627+ list_del_init(&qh->qh_list_entry);
13628+ } else {
13629+ deschedule_periodic(hcd, qh);
13630+ }
13631+
13632+ done:
13633+// SPIN_UNLOCK_IRQRESTORE(&hcd->lock, flags);
13634+ return;
13635+}
13636+
13637+/**
13638+ * Deactivates a QH. For non-periodic QHs, removes the QH from the active
13639+ * non-periodic schedule. The QH is added to the inactive non-periodic
13640+ * schedule if any QTDs are still attached to the QH.
13641+ *
13642+ * For periodic QHs, the QH is removed from the periodic queued schedule. If
13643+ * there are any QTDs still attached to the QH, the QH is added to either the
13644+ * periodic inactive schedule or the periodic ready schedule and its next
13645+ * scheduled frame is calculated. The QH is placed in the ready schedule if
13646+ * the scheduled frame has been reached already. Otherwise it's placed in the
13647+ * inactive schedule. If there are no QTDs attached to the QH, the QH is
13648+ * completely removed from the periodic schedule.
13649+ */
13650+void dwc_otg_hcd_qh_deactivate(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh, int sched_next_periodic_split)
13651+{
13652+ unsigned long flags;
13653+ SPIN_LOCK_IRQSAVE(&hcd->lock, flags);
13654+
13655+ if (dwc_qh_is_non_per(qh)) {
13656+ dwc_otg_hcd_qh_remove(hcd, qh);
13657+ if (!list_empty(&qh->qtd_list)) {
13658+ /* Add back to inactive non-periodic schedule. */
13659+ dwc_otg_hcd_qh_add(hcd, qh);
13660+ }
13661+ } else {
13662+ uint16_t frame_number = dwc_otg_hcd_get_frame_number(dwc_otg_hcd_to_hcd(hcd));
13663+
13664+ if (qh->do_split) {
13665+ /* Schedule the next continuing periodic split transfer */
13666+ if (sched_next_periodic_split) {
13667+
13668+ qh->sched_frame = frame_number;
13669+ if (dwc_frame_num_le(frame_number,
13670+ dwc_frame_num_inc(qh->start_split_frame, 1))) {
13671+ /*
13672+ * Allow one frame to elapse after start
13673+ * split microframe before scheduling
13674+ * complete split, but DONT if we are
13675+ * doing the next start split in the
13676+ * same frame for an ISOC out.
13677+ */
13678+ if ((qh->ep_type != USB_ENDPOINT_XFER_ISOC) || (qh->ep_is_in != 0)) {
13679+ qh->sched_frame = dwc_frame_num_inc(qh->sched_frame, 1);
13680+ }
13681+ }
13682+ } else {
13683+ qh->sched_frame = dwc_frame_num_inc(qh->start_split_frame,
13684+ qh->interval);
13685+ if (dwc_frame_num_le(qh->sched_frame, frame_number)) {
13686+ qh->sched_frame = frame_number;
13687+ }
13688+ qh->sched_frame |= 0x7;
13689+ qh->start_split_frame = qh->sched_frame;
13690+ }
13691+ } else {
13692+ qh->sched_frame = dwc_frame_num_inc(qh->sched_frame, qh->interval);
13693+ if (dwc_frame_num_le(qh->sched_frame, frame_number)) {
13694+ qh->sched_frame = frame_number;
13695+ }
13696+ }
13697+
13698+ if (list_empty(&qh->qtd_list)) {
13699+ dwc_otg_hcd_qh_remove(hcd, qh);
13700+ } else {
13701+ /*
13702+ * Remove from periodic_sched_queued and move to
13703+ * appropriate queue.
13704+ */
13705+ if (qh->sched_frame == frame_number) {
13706+ list_move(&qh->qh_list_entry,
13707+ &hcd->periodic_sched_ready);
13708+ } else {
13709+ list_move(&qh->qh_list_entry,
13710+ &hcd->periodic_sched_inactive);
13711+ }
13712+ }
13713+ }
13714+
13715+ SPIN_UNLOCK_IRQRESTORE(&hcd->lock, flags);
13716+}
13717+
13718+/**
13719+ * This function allocates and initializes a QTD.
13720+ *
13721+ * @param[in] urb The URB to create a QTD from. Each URB-QTD pair will end up
13722+ * pointing to each other so each pair should have a unique correlation.
13723+ *
13724+ * @return Returns pointer to the newly allocated QTD, or NULL on error. */
13725+dwc_otg_qtd_t *dwc_otg_hcd_qtd_create (struct urb *urb)
13726+{
13727+ dwc_otg_qtd_t *qtd;
13728+
13729+ qtd = dwc_otg_hcd_qtd_alloc ();
13730+ if (qtd == NULL) {
13731+ return NULL;
13732+ }
13733+
13734+ dwc_otg_hcd_qtd_init (qtd, urb);
13735+ return qtd;
13736+}
13737+
13738+/**
13739+ * Initializes a QTD structure.
13740+ *
13741+ * @param[in] qtd The QTD to initialize.
13742+ * @param[in] urb The URB to use for initialization. */
13743+void dwc_otg_hcd_qtd_init (dwc_otg_qtd_t *qtd, struct urb *urb)
13744+{
13745+ memset (qtd, 0, sizeof (dwc_otg_qtd_t));
13746+ qtd->urb = urb;
13747+ if (usb_pipecontrol(urb->pipe)) {
13748+ /*
13749+ * The only time the QTD data toggle is used is on the data
13750+ * phase of control transfers. This phase always starts with
13751+ * DATA1.
13752+ */
13753+ qtd->data_toggle = DWC_OTG_HC_PID_DATA1;
13754+ qtd->control_phase = DWC_OTG_CONTROL_SETUP;
13755+ }
13756+
13757+ /* start split */
13758+ qtd->complete_split = 0;
13759+ qtd->isoc_split_pos = DWC_HCSPLIT_XACTPOS_ALL;
13760+ qtd->isoc_split_offset = 0;
13761+
13762+ /* Store the qtd ptr in the urb to reference what QTD. */
13763+ urb->hcpriv = qtd;
13764+ return;
13765+}
13766+
13767+/**
13768+ * This function adds a QTD to the QTD-list of a QH. It will find the correct
13769+ * QH to place the QTD into. If it does not find a QH, then it will create a
13770+ * new QH. If the QH to which the QTD is added is not currently scheduled, it
13771+ * is placed into the proper schedule based on its EP type.
13772+ *
13773+ * @param[in] qtd The QTD to add
13774+ * @param[in] dwc_otg_hcd The DWC HCD structure
13775+ *
13776+ * @return 0 if successful, negative error code otherwise.
13777+ */
13778+int dwc_otg_hcd_qtd_add (dwc_otg_qtd_t *qtd,
13779+ dwc_otg_hcd_t *dwc_otg_hcd)
13780+{
13781+ struct usb_host_endpoint *ep;
13782+ dwc_otg_qh_t *qh;
13783+ unsigned long flags;
13784+ int retval = 0;
13785+
13786+ struct urb *urb = qtd->urb;
13787+
13788+ SPIN_LOCK_IRQSAVE(&dwc_otg_hcd->lock, flags);
13789+
13790+ /*
13791+ * Get the QH which holds the QTD-list to insert to. Create QH if it
13792+ * doesn't exist.
13793+ */
13794+ ep = dwc_urb_to_endpoint(urb);
13795+ qh = (dwc_otg_qh_t *)ep->hcpriv;
13796+ if (qh == NULL) {
13797+ qh = dwc_otg_hcd_qh_create (dwc_otg_hcd, urb);
13798+ if (qh == NULL) {
13799+ goto done;
13800+ }
13801+ ep->hcpriv = qh;
13802+ }
13803+
13804+ retval = dwc_otg_hcd_qh_add(dwc_otg_hcd, qh);
13805+ if (retval == 0) {
13806+ list_add_tail(&qtd->qtd_list_entry, &qh->qtd_list);
13807+ }
13808+
13809+ done:
13810+ SPIN_UNLOCK_IRQRESTORE(&dwc_otg_hcd->lock, flags);
13811+
13812+ return retval;
13813+}
13814+
13815+#endif /* DWC_DEVICE_ONLY */
13816--- /dev/null
13817+++ b/drivers/usb/dwc/otg_pcd.c
13818@@ -0,0 +1,2502 @@
13819+/* ==========================================================================
13820+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_pcd.c $
13821+ * $Revision: #70 $
13822+ * $Date: 2008/10/14 $
13823+ * $Change: 1115682 $
13824+ *
13825+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
13826+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
13827+ * otherwise expressly agreed to in writing between Synopsys and you.
13828+ *
13829+ * The Software IS NOT an item of Licensed Software or Licensed Product under
13830+ * any End User Software License Agreement or Agreement for Licensed Product
13831+ * with Synopsys or any supplement thereto. You are permitted to use and
13832+ * redistribute this Software in source and binary forms, with or without
13833+ * modification, provided that redistributions of source code must retain this
13834+ * notice. You may not view, use, disclose, copy or distribute this file or
13835+ * any information contained herein except pursuant to this license grant from
13836+ * Synopsys. If you do not agree with this notice, including the disclaimer
13837+ * below, then you are not authorized to use the Software.
13838+ *
13839+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
13840+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
13841+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
13842+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
13843+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
13844+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
13845+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
13846+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
13847+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
13848+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
13849+ * DAMAGE.
13850+ * ========================================================================== */
13851+#ifndef DWC_HOST_ONLY
13852+
13853+/** @file
13854+ * This file implements the Peripheral Controller Driver.
13855+ *
13856+ * The Peripheral Controller Driver (PCD) is responsible for
13857+ * translating requests from the Function Driver into the appropriate
13858+ * actions on the DWC_otg controller. It isolates the Function Driver
13859+ * from the specifics of the controller by providing an API to the
13860+ * Function Driver.
13861+ *
13862+ * The Peripheral Controller Driver for Linux will implement the
13863+ * Gadget API, so that the existing Gadget drivers can be used.
13864+ * (Gadget Driver is the Linux terminology for a Function Driver.)
13865+ *
13866+ * The Linux Gadget API is defined in the header file
13867+ * <code><linux/usb_gadget.h></code>. The USB EP operations API is
13868+ * defined in the structure <code>usb_ep_ops</code> and the USB
13869+ * Controller API is defined in the structure
13870+ * <code>usb_gadget_ops</code>.
13871+ *
13872+ * An important function of the PCD is managing interrupts generated
13873+ * by the DWC_otg controller. The implementation of the DWC_otg device
13874+ * mode interrupt service routines is in dwc_otg_pcd_intr.c.
13875+ *
13876+ * @todo Add Device Mode test modes (Test J mode, Test K mode, etc).
13877+ * @todo Does it work when the request size is greater than DEPTSIZ
13878+ * transfer size
13879+ *
13880+ */
13881+
13882+
13883+#include <linux/kernel.h>
13884+#include <linux/module.h>
13885+#include <linux/moduleparam.h>
13886+#include <linux/init.h>
13887+#include <linux/device.h>
13888+#include <linux/platform_device.h>
13889+#include <linux/errno.h>
13890+#include <linux/list.h>
13891+#include <linux/interrupt.h>
13892+#include <linux/string.h>
13893+#include <linux/dma-mapping.h>
13894+#include <linux/version.h>
13895+
13896+#include <mach/irqs.h>
13897+#include <linux/usb/ch9.h>
13898+
13899+//#include <linux/usb_gadget.h>
13900+
13901+#include "otg_driver.h"
13902+#include "otg_pcd.h"
13903+
13904+
13905+
13906+/**
13907+ * Static PCD pointer for use in usb_gadget_register_driver and
13908+ * usb_gadget_unregister_driver. Initialized in dwc_otg_pcd_init.
13909+ */
13910+static dwc_otg_pcd_t *s_pcd = 0;
13911+
13912+
13913+/* Display the contents of the buffer */
13914+extern void dump_msg(const u8 *buf, unsigned int length);
13915+
13916+
13917+/**
13918+ * This function completes a request. It call's the request call back.
13919+ */
13920+void dwc_otg_request_done(dwc_otg_pcd_ep_t *ep, dwc_otg_pcd_request_t *req,
13921+ int status)
13922+{
13923+ unsigned stopped = ep->stopped;
13924+
13925+ DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, ep);
13926+ list_del_init(&req->queue);
13927+
13928+ if (req->req.status == -EINPROGRESS) {
13929+ req->req.status = status;
13930+ } else {
13931+ status = req->req.status;
13932+ }
13933+
13934+ /* don't modify queue heads during completion callback */
13935+ ep->stopped = 1;
13936+ SPIN_UNLOCK(&ep->pcd->lock);
13937+ req->req.complete(&ep->ep, &req->req);
13938+ SPIN_LOCK(&ep->pcd->lock);
13939+
13940+ if (ep->pcd->request_pending > 0) {
13941+ --ep->pcd->request_pending;
13942+ }
13943+
13944+ ep->stopped = stopped;
13945+}
13946+
13947+/**
13948+ * This function terminates all the requsts in the EP request queue.
13949+ */
13950+void dwc_otg_request_nuke(dwc_otg_pcd_ep_t *ep)
13951+{
13952+ dwc_otg_pcd_request_t *req;
13953+
13954+ ep->stopped = 1;
13955+
13956+ /* called with irqs blocked?? */
13957+ while (!list_empty(&ep->queue)) {
13958+ req = list_entry(ep->queue.next, dwc_otg_pcd_request_t,
13959+ queue);
13960+ dwc_otg_request_done(ep, req, -ESHUTDOWN);
13961+ }
13962+}
13963+
13964+/* USB Endpoint Operations */
13965+/*
13966+ * The following sections briefly describe the behavior of the Gadget
13967+ * API endpoint operations implemented in the DWC_otg driver
13968+ * software. Detailed descriptions of the generic behavior of each of
13969+ * these functions can be found in the Linux header file
13970+ * include/linux/usb_gadget.h.
13971+ *
13972+ * The Gadget API provides wrapper functions for each of the function
13973+ * pointers defined in usb_ep_ops. The Gadget Driver calls the wrapper
13974+ * function, which then calls the underlying PCD function. The
13975+ * following sections are named according to the wrapper
13976+ * functions. Within each section, the corresponding DWC_otg PCD
13977+ * function name is specified.
13978+ *
13979+ */
13980+
13981+/**
13982+ * This function assigns periodic Tx FIFO to an periodic EP
13983+ * in shared Tx FIFO mode
13984+ */
13985+static uint32_t assign_perio_tx_fifo(dwc_otg_core_if_t *core_if)
13986+{
13987+ uint32_t PerTxMsk = 1;
13988+ int i;
13989+ for(i = 0; i < core_if->hwcfg4.b.num_dev_perio_in_ep; ++i)
13990+ {
13991+ if((PerTxMsk & core_if->p_tx_msk) == 0) {
13992+ core_if->p_tx_msk |= PerTxMsk;
13993+ return i + 1;
13994+ }
13995+ PerTxMsk <<= 1;
13996+ }
13997+ return 0;
13998+}
13999+/**
14000+ * This function releases periodic Tx FIFO
14001+ * in shared Tx FIFO mode
14002+ */
14003+static void release_perio_tx_fifo(dwc_otg_core_if_t *core_if, uint32_t fifo_num)
14004+{
14005+ core_if->p_tx_msk = (core_if->p_tx_msk & (1 << (fifo_num - 1))) ^ core_if->p_tx_msk;
14006+}
14007+/**
14008+ * This function assigns periodic Tx FIFO to an periodic EP
14009+ * in shared Tx FIFO mode
14010+ */
14011+static uint32_t assign_tx_fifo(dwc_otg_core_if_t *core_if)
14012+{
14013+ uint32_t TxMsk = 1;
14014+ int i;
14015+
14016+ for(i = 0; i < core_if->hwcfg4.b.num_in_eps; ++i)
14017+ {
14018+ if((TxMsk & core_if->tx_msk) == 0) {
14019+ core_if->tx_msk |= TxMsk;
14020+ return i + 1;
14021+ }
14022+ TxMsk <<= 1;
14023+ }
14024+ return 0;
14025+}
14026+/**
14027+ * This function releases periodic Tx FIFO
14028+ * in shared Tx FIFO mode
14029+ */
14030+static void release_tx_fifo(dwc_otg_core_if_t *core_if, uint32_t fifo_num)
14031+{
14032+ core_if->tx_msk = (core_if->tx_msk & (1 << (fifo_num - 1))) ^ core_if->tx_msk;
14033+}
14034+
14035+/**
14036+ * This function is called by the Gadget Driver for each EP to be
14037+ * configured for the current configuration (SET_CONFIGURATION).
14038+ *
14039+ * This function initializes the dwc_otg_ep_t data structure, and then
14040+ * calls dwc_otg_ep_activate.
14041+ */
14042+static int dwc_otg_pcd_ep_enable(struct usb_ep *usb_ep,
14043+ const struct usb_endpoint_descriptor *ep_desc)
14044+{
14045+ dwc_otg_pcd_ep_t *ep = 0;
14046+ dwc_otg_pcd_t *pcd = 0;
14047+ unsigned long flags;
14048+
14049+ DWC_DEBUGPL(DBG_PCDV,"%s(%p,%p)\n", __func__, usb_ep, ep_desc);
14050+
14051+ ep = container_of(usb_ep, dwc_otg_pcd_ep_t, ep);
14052+ if (!usb_ep || !ep_desc || ep->desc ||
14053+ ep_desc->bDescriptorType != USB_DT_ENDPOINT) {
14054+ DWC_WARN("%s, bad ep or descriptor\n", __func__);
14055+ return -EINVAL;
14056+ }
14057+ if (ep == &ep->pcd->ep0) {
14058+ DWC_WARN("%s, bad ep(0)\n", __func__);
14059+ return -EINVAL;
14060+ }
14061+
14062+ /* Check FIFO size? */
14063+ if (!ep_desc->wMaxPacketSize) {
14064+ DWC_WARN("%s, bad %s maxpacket\n", __func__, usb_ep->name);
14065+ return -ERANGE;
14066+ }
14067+
14068+ pcd = ep->pcd;
14069+ if (!pcd->driver || pcd->gadget.speed == USB_SPEED_UNKNOWN) {
14070+ DWC_WARN("%s, bogus device state\n", __func__);
14071+ return -ESHUTDOWN;
14072+ }
14073+
14074+ SPIN_LOCK_IRQSAVE(&pcd->lock, flags);
14075+
14076+ ep->desc = ep_desc;
14077+ ep->ep.maxpacket = le16_to_cpu (ep_desc->wMaxPacketSize);
14078+
14079+ /*
14080+ * Activate the EP
14081+ */
14082+ ep->stopped = 0;
14083+
14084+ ep->dwc_ep.is_in = (USB_DIR_IN & ep_desc->bEndpointAddress) != 0;
14085+ ep->dwc_ep.maxpacket = ep->ep.maxpacket;
14086+
14087+ ep->dwc_ep.type = ep_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
14088+
14089+ if(ep->dwc_ep.is_in) {
14090+ if(!pcd->otg_dev->core_if->en_multiple_tx_fifo) {
14091+ ep->dwc_ep.tx_fifo_num = 0;
14092+
14093+ if (ep->dwc_ep.type == USB_ENDPOINT_XFER_ISOC) {
14094+ /*
14095+ * if ISOC EP then assign a Periodic Tx FIFO.
14096+ */
14097+ ep->dwc_ep.tx_fifo_num = assign_perio_tx_fifo(pcd->otg_dev->core_if);
14098+ }
14099+ } else {
14100+ /*
14101+ * if Dedicated FIFOs mode is on then assign a Tx FIFO.
14102+ */
14103+ ep->dwc_ep.tx_fifo_num = assign_tx_fifo(pcd->otg_dev->core_if);
14104+
14105+ }
14106+ }
14107+ /* Set initial data PID. */
14108+ if (ep->dwc_ep.type == USB_ENDPOINT_XFER_BULK) {
14109+ ep->dwc_ep.data_pid_start = 0;
14110+ }
14111+
14112+ DWC_DEBUGPL(DBG_PCD, "Activate %s-%s: type=%d, mps=%d desc=%p\n",
14113+ ep->ep.name, (ep->dwc_ep.is_in ?"IN":"OUT"),
14114+ ep->dwc_ep.type, ep->dwc_ep.maxpacket, ep->desc);
14115+
14116+ if(ep->dwc_ep.type != USB_ENDPOINT_XFER_ISOC) {
14117+ ep->dwc_ep.desc_addr = dwc_otg_ep_alloc_desc_chain(&ep->dwc_ep.dma_desc_addr, MAX_DMA_DESC_CNT);
14118+ }
14119+
14120+ dwc_otg_ep_activate(GET_CORE_IF(pcd), &ep->dwc_ep);
14121+ SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
14122+
14123+ return 0;
14124+}
14125+
14126+/**
14127+ * This function is called when an EP is disabled due to disconnect or
14128+ * change in configuration. Any pending requests will terminate with a
14129+ * status of -ESHUTDOWN.
14130+ *
14131+ * This function modifies the dwc_otg_ep_t data structure for this EP,
14132+ * and then calls dwc_otg_ep_deactivate.
14133+ */
14134+static int dwc_otg_pcd_ep_disable(struct usb_ep *usb_ep)
14135+{
14136+ dwc_otg_pcd_ep_t *ep;
14137+ dwc_otg_pcd_t *pcd = 0;
14138+ unsigned long flags;
14139+
14140+ DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, usb_ep);
14141+ ep = container_of(usb_ep, dwc_otg_pcd_ep_t, ep);
14142+ if (!usb_ep || !ep->desc) {
14143+ DWC_DEBUGPL(DBG_PCD, "%s, %s not enabled\n", __func__,
14144+ usb_ep ? ep->ep.name : NULL);
14145+ return -EINVAL;
14146+ }
14147+
14148+ SPIN_LOCK_IRQSAVE(&ep->pcd->lock, flags);
14149+
14150+ dwc_otg_request_nuke(ep);
14151+
14152+ dwc_otg_ep_deactivate(GET_CORE_IF(ep->pcd), &ep->dwc_ep);
14153+ ep->desc = 0;
14154+ ep->stopped = 1;
14155+
14156+ if(ep->dwc_ep.is_in) {
14157+ dwc_otg_flush_tx_fifo(GET_CORE_IF(ep->pcd), ep->dwc_ep.tx_fifo_num);
14158+ release_perio_tx_fifo(GET_CORE_IF(ep->pcd), ep->dwc_ep.tx_fifo_num);
14159+ release_tx_fifo(GET_CORE_IF(ep->pcd), ep->dwc_ep.tx_fifo_num);
14160+ }
14161+
14162+ /* Free DMA Descriptors */
14163+ pcd = ep->pcd;
14164+
14165+ SPIN_UNLOCK_IRQRESTORE(&ep->pcd->lock, flags);
14166+
14167+ if(ep->dwc_ep.type != USB_ENDPOINT_XFER_ISOC && ep->dwc_ep.desc_addr) {
14168+ dwc_otg_ep_free_desc_chain(ep->dwc_ep.desc_addr, ep->dwc_ep.dma_desc_addr, MAX_DMA_DESC_CNT);
14169+ }
14170+
14171+ DWC_DEBUGPL(DBG_PCD, "%s disabled\n", usb_ep->name);
14172+ return 0;
14173+}
14174+
14175+
14176+/**
14177+ * This function allocates a request object to use with the specified
14178+ * endpoint.
14179+ *
14180+ * @param ep The endpoint to be used with with the request
14181+ * @param gfp_flags the GFP_* flags to use.
14182+ */
14183+static struct usb_request *dwc_otg_pcd_alloc_request(struct usb_ep *ep,
14184+ gfp_t gfp_flags)
14185+{
14186+ dwc_otg_pcd_request_t *req;
14187+
14188+ DWC_DEBUGPL(DBG_PCDV,"%s(%p,%d)\n", __func__, ep, gfp_flags);
14189+ if (0 == ep) {
14190+ DWC_WARN("%s() %s\n", __func__, "Invalid EP!\n");
14191+ return 0;
14192+ }
14193+ req = kmalloc(sizeof(dwc_otg_pcd_request_t), gfp_flags);
14194+ if (0 == req) {
14195+ DWC_WARN("%s() %s\n", __func__,
14196+ "request allocation failed!\n");
14197+ return 0;
14198+ }
14199+ memset(req, 0, sizeof(dwc_otg_pcd_request_t));
14200+ req->req.dma = DMA_ADDR_INVALID;
14201+ INIT_LIST_HEAD(&req->queue);
14202+ return &req->req;
14203+}
14204+
14205+/**
14206+ * This function frees a request object.
14207+ *
14208+ * @param ep The endpoint associated with the request
14209+ * @param req The request being freed
14210+ */
14211+static void dwc_otg_pcd_free_request(struct usb_ep *ep,
14212+ struct usb_request *req)
14213+{
14214+ dwc_otg_pcd_request_t *request;
14215+ DWC_DEBUGPL(DBG_PCDV,"%s(%p,%p)\n", __func__, ep, req);
14216+
14217+ if (0 == ep || 0 == req) {
14218+ DWC_WARN("%s() %s\n", __func__,
14219+ "Invalid ep or req argument!\n");
14220+ return;
14221+ }
14222+
14223+ request = container_of(req, dwc_otg_pcd_request_t, req);
14224+ kfree(request);
14225+}
14226+
14227+#if 0
14228+/**
14229+ * This function allocates an I/O buffer to be used for a transfer
14230+ * to/from the specified endpoint.
14231+ *
14232+ * @param usb_ep The endpoint to be used with with the request
14233+ * @param bytes The desired number of bytes for the buffer
14234+ * @param dma Pointer to the buffer's DMA address; must be valid
14235+ * @param gfp_flags the GFP_* flags to use.
14236+ * @return address of a new buffer or null is buffer could not be allocated.
14237+ */
14238+static void *dwc_otg_pcd_alloc_buffer(struct usb_ep *usb_ep, unsigned bytes,
14239+ dma_addr_t *dma,
14240+ gfp_t gfp_flags)
14241+{
14242+ void *buf;
14243+ dwc_otg_pcd_ep_t *ep;
14244+ dwc_otg_pcd_t *pcd = 0;
14245+
14246+ ep = container_of(usb_ep, dwc_otg_pcd_ep_t, ep);
14247+ pcd = ep->pcd;
14248+
14249+ DWC_DEBUGPL(DBG_PCDV,"%s(%p,%d,%p,%0x)\n", __func__, usb_ep, bytes,
14250+ dma, gfp_flags);
14251+
14252+ /* Check dword alignment */
14253+ if ((bytes & 0x3UL) != 0) {
14254+ DWC_WARN("%s() Buffer size is not a multiple of"
14255+ "DWORD size (%d)",__func__, bytes);
14256+ }
14257+
14258+ if (GET_CORE_IF(pcd)->dma_enable) {
14259+ buf = dma_alloc_coherent (NULL, bytes, dma, gfp_flags);
14260+ }
14261+ else {
14262+ buf = kmalloc(bytes, gfp_flags);
14263+ }
14264+
14265+ /* Check dword alignment */
14266+ if (((int)buf & 0x3UL) != 0) {
14267+ DWC_WARN("%s() Buffer is not DWORD aligned (%p)",
14268+ __func__, buf);
14269+ }
14270+
14271+ return buf;
14272+}
14273+
14274+/**
14275+ * This function frees an I/O buffer that was allocated by alloc_buffer.
14276+ *
14277+ * @param usb_ep the endpoint associated with the buffer
14278+ * @param buf address of the buffer
14279+ * @param dma The buffer's DMA address
14280+ * @param bytes The number of bytes of the buffer
14281+ */
14282+static void dwc_otg_pcd_free_buffer(struct usb_ep *usb_ep, void *buf,
14283+ dma_addr_t dma, unsigned bytes)
14284+{
14285+ dwc_otg_pcd_ep_t *ep;
14286+ dwc_otg_pcd_t *pcd = 0;
14287+
14288+ ep = container_of(usb_ep, dwc_otg_pcd_ep_t, ep);
14289+ pcd = ep->pcd;
14290+
14291+ DWC_DEBUGPL(DBG_PCDV,"%s(%p,%p,%0x,%d)\n", __func__, ep, buf, dma, bytes);
14292+
14293+ if (GET_CORE_IF(pcd)->dma_enable) {
14294+ dma_free_coherent (NULL, bytes, buf, dma);
14295+ }
14296+ else {
14297+ kfree(buf);
14298+ }
14299+}
14300+#endif
14301+
14302+/**
14303+ * This function is used to submit an I/O Request to an EP.
14304+ *
14305+ * - When the request completes the request's completion callback
14306+ * is called to return the request to the driver.
14307+ * - An EP, except control EPs, may have multiple requests
14308+ * pending.
14309+ * - Once submitted the request cannot be examined or modified.
14310+ * - Each request is turned into one or more packets.
14311+ * - A BULK EP can queue any amount of data; the transfer is
14312+ * packetized.
14313+ * - Zero length Packets are specified with the request 'zero'
14314+ * flag.
14315+ */
14316+static int dwc_otg_pcd_ep_queue(struct usb_ep *usb_ep,
14317+ struct usb_request *usb_req,
14318+ gfp_t gfp_flags)
14319+{
14320+ int prevented = 0;
14321+ dwc_otg_pcd_request_t *req;
14322+ dwc_otg_pcd_ep_t *ep;
14323+ dwc_otg_pcd_t *pcd;
14324+ unsigned long flags = 0;
14325+
14326+ DWC_DEBUGPL(DBG_PCDV,"%s(%p,%p,%d)\n",
14327+ __func__, usb_ep, usb_req, gfp_flags);
14328+
14329+ req = container_of(usb_req, dwc_otg_pcd_request_t, req);
14330+ if (!usb_req || !usb_req->complete || !usb_req->buf ||
14331+ !list_empty(&req->queue)) {
14332+ DWC_WARN("%s, bad params\n", __func__);
14333+ return -EINVAL;
14334+ }
14335+
14336+ ep = container_of(usb_ep, dwc_otg_pcd_ep_t, ep);
14337+ if (!usb_ep || (!ep->desc && ep->dwc_ep.num != 0)/* || ep->stopped != 0*/) {
14338+ DWC_WARN("%s, bad ep\n", __func__);
14339+ return -EINVAL;
14340+ }
14341+
14342+ pcd = ep->pcd;
14343+ if (!pcd->driver || pcd->gadget.speed == USB_SPEED_UNKNOWN) {
14344+ DWC_DEBUGPL(DBG_PCDV, "gadget.speed=%d\n", pcd->gadget.speed);
14345+ DWC_WARN("%s, bogus device state\n", __func__);
14346+ return -ESHUTDOWN;
14347+ }
14348+
14349+
14350+ DWC_DEBUGPL(DBG_PCD, "%s queue req %p, len %d buf %p\n",
14351+ usb_ep->name, usb_req, usb_req->length, usb_req->buf);
14352+
14353+ if (!GET_CORE_IF(pcd)->core_params->opt) {
14354+ if (ep->dwc_ep.num != 0) {
14355+ DWC_ERROR("%s queue req %p, len %d buf %p\n",
14356+ usb_ep->name, usb_req, usb_req->length, usb_req->buf);
14357+ }
14358+ }
14359+
14360+ SPIN_LOCK_IRQSAVE(&ep->pcd->lock, flags);
14361+
14362+#if defined(DEBUG) & defined(VERBOSE)
14363+ dump_msg(usb_req->buf, usb_req->length);
14364+#endif
14365+
14366+ usb_req->status = -EINPROGRESS;
14367+ usb_req->actual = 0;
14368+
14369+ /*
14370+ * For EP0 IN without premature status, zlp is required?
14371+ */
14372+ if (ep->dwc_ep.num == 0 && ep->dwc_ep.is_in) {
14373+ DWC_DEBUGPL(DBG_PCDV, "%s-OUT ZLP\n", usb_ep->name);
14374+ //_req->zero = 1;
14375+ }
14376+
14377+ /* Start the transfer */
14378+ if (list_empty(&ep->queue) && !ep->stopped) {
14379+ /* EP0 Transfer? */
14380+ if (ep->dwc_ep.num == 0) {
14381+ switch (pcd->ep0state) {
14382+ case EP0_IN_DATA_PHASE:
14383+ DWC_DEBUGPL(DBG_PCD,
14384+ "%s ep0: EP0_IN_DATA_PHASE\n",
14385+ __func__);
14386+ break;
14387+
14388+ case EP0_OUT_DATA_PHASE:
14389+ DWC_DEBUGPL(DBG_PCD,
14390+ "%s ep0: EP0_OUT_DATA_PHASE\n",
14391+ __func__);
14392+ if (pcd->request_config) {
14393+ /* Complete STATUS PHASE */
14394+ ep->dwc_ep.is_in = 1;
14395+ pcd->ep0state = EP0_IN_STATUS_PHASE;
14396+ }
14397+ break;
14398+
14399+ case EP0_IN_STATUS_PHASE:
14400+ DWC_DEBUGPL(DBG_PCD,
14401+ "%s ep0: EP0_IN_STATUS_PHASE\n",
14402+ __func__);
14403+ break;
14404+
14405+ default:
14406+ DWC_DEBUGPL(DBG_ANY, "ep0: odd state %d\n",
14407+ pcd->ep0state);
14408+ SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
14409+ return -EL2HLT;
14410+ }
14411+ ep->dwc_ep.dma_addr = usb_req->dma;
14412+ ep->dwc_ep.start_xfer_buff = usb_req->buf;
14413+ ep->dwc_ep.xfer_buff = usb_req->buf;
14414+ ep->dwc_ep.xfer_len = usb_req->length;
14415+ ep->dwc_ep.xfer_count = 0;
14416+ ep->dwc_ep.sent_zlp = 0;
14417+ ep->dwc_ep.total_len = ep->dwc_ep.xfer_len;
14418+
14419+ if(usb_req->zero) {
14420+ if((ep->dwc_ep.xfer_len % ep->dwc_ep.maxpacket == 0)
14421+ && (ep->dwc_ep.xfer_len != 0)) {
14422+ ep->dwc_ep.sent_zlp = 1;
14423+ }
14424+
14425+ }
14426+
14427+ ep_check_and_patch_dma_addr(ep);
14428+ dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep->dwc_ep);
14429+ }
14430+ else {
14431+
14432+ uint32_t max_transfer = GET_CORE_IF(ep->pcd)->core_params->max_transfer_size;
14433+
14434+ /* Setup and start the Transfer */
14435+ ep->dwc_ep.dma_addr = usb_req->dma;
14436+ ep->dwc_ep.start_xfer_buff = usb_req->buf;
14437+ ep->dwc_ep.xfer_buff = usb_req->buf;
14438+ ep->dwc_ep.sent_zlp = 0;
14439+ ep->dwc_ep.total_len = usb_req->length;
14440+ ep->dwc_ep.xfer_len = 0;
14441+ ep->dwc_ep.xfer_count = 0;
14442+
14443+ if(max_transfer > MAX_TRANSFER_SIZE) {
14444+ ep->dwc_ep.maxxfer = max_transfer - (max_transfer % ep->dwc_ep.maxpacket);
14445+ } else {
14446+ ep->dwc_ep.maxxfer = max_transfer;
14447+ }
14448+
14449+ if(usb_req->zero) {
14450+ if((ep->dwc_ep.total_len % ep->dwc_ep.maxpacket == 0)
14451+ && (ep->dwc_ep.total_len != 0)) {
14452+ ep->dwc_ep.sent_zlp = 1;
14453+ }
14454+
14455+ }
14456+
14457+ ep_check_and_patch_dma_addr(ep);
14458+ dwc_otg_ep_start_transfer(GET_CORE_IF(pcd), &ep->dwc_ep);
14459+ }
14460+ }
14461+
14462+ if ((req != 0) || prevented) {
14463+ ++pcd->request_pending;
14464+ list_add_tail(&req->queue, &ep->queue);
14465+ if (ep->dwc_ep.is_in && ep->stopped && !(GET_CORE_IF(pcd)->dma_enable)) {
14466+ /** @todo NGS Create a function for this. */
14467+ diepmsk_data_t diepmsk = { .d32 = 0};
14468+ diepmsk.b.intktxfemp = 1;
14469+ if(&GET_CORE_IF(pcd)->multiproc_int_enable) {
14470+ dwc_modify_reg32(&GET_CORE_IF(pcd)->dev_if->dev_global_regs->diepeachintmsk[ep->dwc_ep.num],
14471+ 0, diepmsk.d32);
14472+ } else {
14473+ dwc_modify_reg32(&GET_CORE_IF(pcd)->dev_if->dev_global_regs->diepmsk, 0, diepmsk.d32);
14474+ }
14475+ }
14476+ }
14477+
14478+ SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
14479+ return 0;
14480+}
14481+
14482+/**
14483+ * This function cancels an I/O request from an EP.
14484+ */
14485+static int dwc_otg_pcd_ep_dequeue(struct usb_ep *usb_ep,
14486+ struct usb_request *usb_req)
14487+{
14488+ dwc_otg_pcd_request_t *req;
14489+ dwc_otg_pcd_ep_t *ep;
14490+ dwc_otg_pcd_t *pcd;
14491+ unsigned long flags;
14492+
14493+ DWC_DEBUGPL(DBG_PCDV,"%s(%p,%p)\n", __func__, usb_ep, usb_req);
14494+
14495+ ep = container_of(usb_ep, dwc_otg_pcd_ep_t, ep);
14496+ if (!usb_ep || !usb_req || (!ep->desc && ep->dwc_ep.num != 0)) {
14497+ DWC_WARN("%s, bad argument\n", __func__);
14498+ return -EINVAL;
14499+ }
14500+ pcd = ep->pcd;
14501+ if (!pcd->driver || pcd->gadget.speed == USB_SPEED_UNKNOWN) {
14502+ DWC_WARN("%s, bogus device state\n", __func__);
14503+ return -ESHUTDOWN;
14504+ }
14505+
14506+ SPIN_LOCK_IRQSAVE(&pcd->lock, flags);
14507+ DWC_DEBUGPL(DBG_PCDV, "%s %s %s %p\n", __func__, usb_ep->name,
14508+ ep->dwc_ep.is_in ? "IN" : "OUT",
14509+ usb_req);
14510+
14511+ /* make sure it's actually queued on this endpoint */
14512+ list_for_each_entry(req, &ep->queue, queue)
14513+ {
14514+ if (&req->req == usb_req) {
14515+ break;
14516+ }
14517+ }
14518+
14519+ if (&req->req != usb_req) {
14520+ SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
14521+ return -EINVAL;
14522+ }
14523+
14524+ if (!list_empty(&req->queue)) {
14525+ dwc_otg_request_done(ep, req, -ECONNRESET);
14526+ }
14527+ else {
14528+ req = 0;
14529+ }
14530+
14531+ SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
14532+
14533+ return req ? 0 : -EOPNOTSUPP;
14534+}
14535+
14536+/**
14537+ * usb_ep_set_halt stalls an endpoint.
14538+ *
14539+ * usb_ep_clear_halt clears an endpoint halt and resets its data
14540+ * toggle.
14541+ *
14542+ * Both of these functions are implemented with the same underlying
14543+ * function. The behavior depends on the value argument.
14544+ *
14545+ * @param[in] usb_ep the Endpoint to halt or clear halt.
14546+ * @param[in] value
14547+ * - 0 means clear_halt.
14548+ * - 1 means set_halt,
14549+ * - 2 means clear stall lock flag.
14550+ * - 3 means set stall lock flag.
14551+ */
14552+static int dwc_otg_pcd_ep_set_halt(struct usb_ep *usb_ep, int value)
14553+{
14554+ int retval = 0;
14555+ unsigned long flags;
14556+ dwc_otg_pcd_ep_t *ep = 0;
14557+
14558+
14559+ DWC_DEBUGPL(DBG_PCD,"HALT %s %d\n", usb_ep->name, value);
14560+
14561+ ep = container_of(usb_ep, dwc_otg_pcd_ep_t, ep);
14562+
14563+ if (!usb_ep || (!ep->desc && ep != &ep->pcd->ep0) ||
14564+ ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
14565+ DWC_WARN("%s, bad ep\n", __func__);
14566+ return -EINVAL;
14567+ }
14568+
14569+ SPIN_LOCK_IRQSAVE(&ep->pcd->lock, flags);
14570+ if (!list_empty(&ep->queue)) {
14571+ DWC_WARN("%s() %s XFer In process\n", __func__, usb_ep->name);
14572+ retval = -EAGAIN;
14573+ }
14574+ else if (value == 0) {
14575+ dwc_otg_ep_clear_stall(ep->pcd->otg_dev->core_if,
14576+ &ep->dwc_ep);
14577+ }
14578+ else if(value == 1) {
14579+ if (ep->dwc_ep.is_in == 1 && ep->pcd->otg_dev->core_if->dma_desc_enable) {
14580+ dtxfsts_data_t txstatus;
14581+ fifosize_data_t txfifosize;
14582+
14583+ txfifosize.d32 = dwc_read_reg32(&ep->pcd->otg_dev->core_if->core_global_regs->dptxfsiz_dieptxf[ep->dwc_ep.tx_fifo_num]);
14584+ txstatus.d32 = dwc_read_reg32(&ep->pcd->otg_dev->core_if->dev_if->in_ep_regs[ep->dwc_ep.num]->dtxfsts);
14585+
14586+ if(txstatus.b.txfspcavail < txfifosize.b.depth) {
14587+ DWC_WARN("%s() %s Data In Tx Fifo\n", __func__, usb_ep->name);
14588+ retval = -EAGAIN;
14589+ }
14590+ else {
14591+ if (ep->dwc_ep.num == 0) {
14592+ ep->pcd->ep0state = EP0_STALL;
14593+ }
14594+
14595+ ep->stopped = 1;
14596+ dwc_otg_ep_set_stall(ep->pcd->otg_dev->core_if,
14597+ &ep->dwc_ep);
14598+ }
14599+ }
14600+ else {
14601+ if (ep->dwc_ep.num == 0) {
14602+ ep->pcd->ep0state = EP0_STALL;
14603+ }
14604+
14605+ ep->stopped = 1;
14606+ dwc_otg_ep_set_stall(ep->pcd->otg_dev->core_if,
14607+ &ep->dwc_ep);
14608+ }
14609+ }
14610+ else if (value == 2) {
14611+ ep->dwc_ep.stall_clear_flag = 0;
14612+ }
14613+ else if (value == 3) {
14614+ ep->dwc_ep.stall_clear_flag = 1;
14615+ }
14616+
14617+ SPIN_UNLOCK_IRQRESTORE(&ep->pcd->lock, flags);
14618+ return retval;
14619+}
14620+
14621+/**
14622+ * This function allocates a DMA Descriptor chain for the Endpoint
14623+ * buffer to be used for a transfer to/from the specified endpoint.
14624+ */
14625+dwc_otg_dma_desc_t* dwc_otg_ep_alloc_desc_chain(uint32_t * dma_desc_addr, uint32_t count)
14626+{
14627+
14628+ return dma_alloc_coherent(NULL, count * sizeof(dwc_otg_dma_desc_t), dma_desc_addr, GFP_KERNEL);
14629+}
14630+
14631+LIST_HEAD(tofree_list);
14632+DEFINE_SPINLOCK(tofree_list_lock);
14633+
14634+struct free_param {
14635+ struct list_head list;
14636+
14637+ void* addr;
14638+ dma_addr_t dma_addr;
14639+ uint32_t size;
14640+};
14641+void free_list_agent_fn(void *data){
14642+ struct list_head free_list;
14643+ struct free_param *cur,*next;
14644+
14645+ spin_lock(&tofree_list_lock);
14646+ list_add(&free_list,&tofree_list);
14647+ list_del_init(&tofree_list);
14648+ spin_unlock(&tofree_list_lock);
14649+
14650+ list_for_each_entry_safe(cur,next,&free_list,list){
14651+ if(cur==&free_list) break;
14652+ dma_free_coherent(NULL,cur->size,cur->addr,cur->dma_addr);
14653+ list_del(&cur->list);
14654+ kfree(cur);
14655+ }
14656+}
14657+DECLARE_WORK(free_list_agent,free_list_agent_fn);
14658+/**
14659+ * This function frees a DMA Descriptor chain that was allocated by ep_alloc_desc.
14660+ */
14661+void dwc_otg_ep_free_desc_chain(dwc_otg_dma_desc_t* desc_addr, uint32_t dma_desc_addr, uint32_t count)
14662+{
14663+ if(irqs_disabled()){
14664+ struct free_param* fp=kmalloc(sizeof(struct free_param),GFP_KERNEL);
14665+ fp->addr=desc_addr;
14666+ fp->dma_addr=dma_desc_addr;
14667+ fp->size=count*sizeof(dwc_otg_dma_desc_t);
14668+
14669+ spin_lock(&tofree_list_lock);
14670+ list_add(&fp->list,&tofree_list);
14671+ spin_unlock(&tofree_list_lock);
14672+
14673+ schedule_work(&free_list_agent);
14674+ return ;
14675+ }
14676+ dma_free_coherent(NULL, count * sizeof(dwc_otg_dma_desc_t), desc_addr, dma_desc_addr);
14677+}
14678+
14679+#ifdef DWC_EN_ISOC
14680+
14681+/**
14682+ * This function initializes a descriptor chain for Isochronous transfer
14683+ *
14684+ * @param core_if Programming view of DWC_otg controller.
14685+ * @param dwc_ep The EP to start the transfer on.
14686+ *
14687+ */
14688+void dwc_otg_iso_ep_start_ddma_transfer(dwc_otg_core_if_t *core_if, dwc_ep_t *dwc_ep)
14689+{
14690+
14691+ dsts_data_t dsts = { .d32 = 0};
14692+ depctl_data_t depctl = { .d32 = 0 };
14693+ volatile uint32_t *addr;
14694+ int i, j;
14695+
14696+ if(dwc_ep->is_in)
14697+ dwc_ep->desc_cnt = dwc_ep->buf_proc_intrvl / dwc_ep->bInterval;
14698+ else
14699+ dwc_ep->desc_cnt = dwc_ep->buf_proc_intrvl * dwc_ep->pkt_per_frm / dwc_ep->bInterval;
14700+
14701+
14702+ /** Allocate descriptors for double buffering */
14703+ dwc_ep->iso_desc_addr = dwc_otg_ep_alloc_desc_chain(&dwc_ep->iso_dma_desc_addr,dwc_ep->desc_cnt*2);
14704+ if(dwc_ep->desc_addr) {
14705+ DWC_WARN("%s, can't allocate DMA descriptor chain\n", __func__);
14706+ return;
14707+ }
14708+
14709+ dsts.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts);
14710+
14711+ /** ISO OUT EP */
14712+ if(dwc_ep->is_in == 0) {
14713+ desc_sts_data_t sts = { .d32 =0 };
14714+ dwc_otg_dma_desc_t* dma_desc = dwc_ep->iso_desc_addr;
14715+ dma_addr_t dma_ad;
14716+ uint32_t data_per_desc;
14717+ dwc_otg_dev_out_ep_regs_t *out_regs =
14718+ core_if->dev_if->out_ep_regs[dwc_ep->num];
14719+ int offset;
14720+
14721+ addr = &core_if->dev_if->out_ep_regs[dwc_ep->num]->doepctl;
14722+ dma_ad = (dma_addr_t)dwc_read_reg32(&(out_regs->doepdma));
14723+
14724+ /** Buffer 0 descriptors setup */
14725+ dma_ad = dwc_ep->dma_addr0;
14726+
14727+ sts.b_iso_out.bs = BS_HOST_READY;
14728+ sts.b_iso_out.rxsts = 0;
14729+ sts.b_iso_out.l = 0;
14730+ sts.b_iso_out.sp = 0;
14731+ sts.b_iso_out.ioc = 0;
14732+ sts.b_iso_out.pid = 0;
14733+ sts.b_iso_out.framenum = 0;
14734+
14735+ offset = 0;
14736+ for(i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm; i+= dwc_ep->pkt_per_frm)
14737+ {
14738+
14739+ for(j = 0; j < dwc_ep->pkt_per_frm; ++j)
14740+ {
14741+ data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
14742+ dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
14743+
14744+ data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
14745+ sts.b_iso_out.rxbytes = data_per_desc;
14746+ writel((uint32_t)dma_ad, &dma_desc->buf);
14747+ writel(sts.d32, &dma_desc->status);
14748+
14749+ offset += data_per_desc;
14750+ dma_desc ++;
14751+ //(uint32_t)dma_ad += data_per_desc;
14752+ dma_ad = (uint32_t)dma_ad + data_per_desc;
14753+ }
14754+ }
14755+
14756+ for(j = 0; j < dwc_ep->pkt_per_frm - 1; ++j)
14757+ {
14758+ data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
14759+ dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
14760+ data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
14761+ sts.b_iso_out.rxbytes = data_per_desc;
14762+ writel((uint32_t)dma_ad, &dma_desc->buf);
14763+ writel(sts.d32, &dma_desc->status);
14764+
14765+ offset += data_per_desc;
14766+ dma_desc ++;
14767+ //(uint32_t)dma_ad += data_per_desc;
14768+ dma_ad = (uint32_t)dma_ad + data_per_desc;
14769+ }
14770+
14771+ sts.b_iso_out.ioc = 1;
14772+ data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
14773+ dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
14774+ data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
14775+ sts.b_iso_out.rxbytes = data_per_desc;
14776+
14777+ writel((uint32_t)dma_ad, &dma_desc->buf);
14778+ writel(sts.d32, &dma_desc->status);
14779+ dma_desc ++;
14780+
14781+ /** Buffer 1 descriptors setup */
14782+ sts.b_iso_out.ioc = 0;
14783+ dma_ad = dwc_ep->dma_addr1;
14784+
14785+ offset = 0;
14786+ for(i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm; i+= dwc_ep->pkt_per_frm)
14787+ {
14788+ for(j = 0; j < dwc_ep->pkt_per_frm; ++j)
14789+ {
14790+ data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
14791+ dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
14792+ data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
14793+ sts.b_iso_out.rxbytes = data_per_desc;
14794+ writel((uint32_t)dma_ad, &dma_desc->buf);
14795+ writel(sts.d32, &dma_desc->status);
14796+
14797+ offset += data_per_desc;
14798+ dma_desc ++;
14799+ //(uint32_t)dma_ad += data_per_desc;
14800+ dma_ad = (uint32_t)dma_ad + data_per_desc;
14801+ }
14802+ }
14803+ for(j = 0; j < dwc_ep->pkt_per_frm - 1; ++j)
14804+ {
14805+ data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
14806+ dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
14807+ data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
14808+ sts.b_iso_out.rxbytes = data_per_desc;
14809+ writel((uint32_t)dma_ad, &dma_desc->buf);
14810+ writel(sts.d32, &dma_desc->status);
14811+
14812+ offset += data_per_desc;
14813+ dma_desc ++;
14814+ //(uint32_t)dma_ad += data_per_desc;
14815+ dma_ad = (uint32_t)dma_ad + data_per_desc;
14816+ }
14817+
14818+ sts.b_iso_out.ioc = 1;
14819+ sts.b_iso_out.l = 1;
14820+ data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
14821+ dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
14822+ data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
14823+ sts.b_iso_out.rxbytes = data_per_desc;
14824+
14825+ writel((uint32_t)dma_ad, &dma_desc->buf);
14826+ writel(sts.d32, &dma_desc->status);
14827+
14828+ dwc_ep->next_frame = 0;
14829+
14830+ /** Write dma_ad into DOEPDMA register */
14831+ dwc_write_reg32(&(out_regs->doepdma),(uint32_t)dwc_ep->iso_dma_desc_addr);
14832+
14833+ }
14834+ /** ISO IN EP */
14835+ else {
14836+ desc_sts_data_t sts = { .d32 =0 };
14837+ dwc_otg_dma_desc_t* dma_desc = dwc_ep->iso_desc_addr;
14838+ dma_addr_t dma_ad;
14839+ dwc_otg_dev_in_ep_regs_t *in_regs =
14840+ core_if->dev_if->in_ep_regs[dwc_ep->num];
14841+ unsigned int frmnumber;
14842+ fifosize_data_t txfifosize,rxfifosize;
14843+
14844+ txfifosize.d32 = dwc_read_reg32(&core_if->dev_if->in_ep_regs[dwc_ep->num]->dtxfsts);
14845+ rxfifosize.d32 = dwc_read_reg32(&core_if->core_global_regs->grxfsiz);
14846+
14847+
14848+ addr = &core_if->dev_if->in_ep_regs[dwc_ep->num]->diepctl;
14849+
14850+ dma_ad = dwc_ep->dma_addr0;
14851+
14852+ dsts.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts);
14853+
14854+ sts.b_iso_in.bs = BS_HOST_READY;
14855+ sts.b_iso_in.txsts = 0;
14856+ sts.b_iso_in.sp = (dwc_ep->data_per_frame % dwc_ep->maxpacket)? 1 : 0;
14857+ sts.b_iso_in.ioc = 0;
14858+ sts.b_iso_in.pid = dwc_ep->pkt_per_frm;
14859+
14860+
14861+ frmnumber = dwc_ep->next_frame;
14862+
14863+ sts.b_iso_in.framenum = frmnumber;
14864+ sts.b_iso_in.txbytes = dwc_ep->data_per_frame;
14865+ sts.b_iso_in.l = 0;
14866+
14867+ /** Buffer 0 descriptors setup */
14868+ for(i = 0; i < dwc_ep->desc_cnt - 1; i++)
14869+ {
14870+ writel((uint32_t)dma_ad, &dma_desc->buf);
14871+ writel(sts.d32, &dma_desc->status);
14872+ dma_desc ++;
14873+
14874+ //(uint32_t)dma_ad += dwc_ep->data_per_frame;
14875+ dma_ad = (uint32_t)dma_ad + dwc_ep->data_per_frame;
14876+ sts.b_iso_in.framenum += dwc_ep->bInterval;
14877+ }
14878+
14879+ sts.b_iso_in.ioc = 1;
14880+ writel((uint32_t)dma_ad, &dma_desc->buf);
14881+ writel(sts.d32, &dma_desc->status);
14882+ ++dma_desc;
14883+
14884+ /** Buffer 1 descriptors setup */
14885+ sts.b_iso_in.ioc = 0;
14886+ dma_ad = dwc_ep->dma_addr1;
14887+
14888+ for(i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm; i+= dwc_ep->pkt_per_frm)
14889+ {
14890+ writel((uint32_t)dma_ad, &dma_desc->buf);
14891+ writel(sts.d32, &dma_desc->status);
14892+ dma_desc ++;
14893+
14894+ //(uint32_t)dma_ad += dwc_ep->data_per_frame;
14895+ dma_ad = (uint32_t)dma_ad + dwc_ep->data_per_frame;
14896+ sts.b_iso_in.framenum += dwc_ep->bInterval;
14897+
14898+ sts.b_iso_in.ioc = 0;
14899+ }
14900+ sts.b_iso_in.ioc = 1;
14901+ sts.b_iso_in.l = 1;
14902+
14903+ writel((uint32_t)dma_ad, &dma_desc->buf);
14904+ writel(sts.d32, &dma_desc->status);
14905+
14906+ dwc_ep->next_frame = sts.b_iso_in.framenum + dwc_ep->bInterval;
14907+
14908+ /** Write dma_ad into diepdma register */
14909+ dwc_write_reg32(&(in_regs->diepdma),(uint32_t)dwc_ep->iso_dma_desc_addr);
14910+ }
14911+ /** Enable endpoint, clear nak */
14912+ depctl.d32 = 0;
14913+ depctl.b.epena = 1;
14914+ depctl.b.usbactep = 1;
14915+ depctl.b.cnak = 1;
14916+
14917+ dwc_modify_reg32(addr, depctl.d32,depctl.d32);
14918+ depctl.d32 = dwc_read_reg32(addr);
14919+}
14920+
14921+/**
14922+ * This function initializes a descriptor chain for Isochronous transfer
14923+ *
14924+ * @param core_if Programming view of DWC_otg controller.
14925+ * @param ep The EP to start the transfer on.
14926+ *
14927+ */
14928+
14929+void dwc_otg_iso_ep_start_buf_transfer(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
14930+{
14931+ depctl_data_t depctl = { .d32 = 0 };
14932+ volatile uint32_t *addr;
14933+
14934+
14935+ if(ep->is_in) {
14936+ addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl;
14937+ } else {
14938+ addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl;
14939+ }
14940+
14941+
14942+ if(core_if->dma_enable == 0 || core_if->dma_desc_enable!= 0) {
14943+ return;
14944+ } else {
14945+ deptsiz_data_t deptsiz = { .d32 = 0 };
14946+
14947+ ep->xfer_len = ep->data_per_frame * ep->buf_proc_intrvl / ep->bInterval;
14948+ ep->pkt_cnt = (ep->xfer_len - 1 + ep->maxpacket) /
14949+ ep->maxpacket;
14950+ ep->xfer_count = 0;
14951+ ep->xfer_buff = (ep->proc_buf_num) ? ep->xfer_buff1 : ep->xfer_buff0;
14952+ ep->dma_addr = (ep->proc_buf_num) ? ep->dma_addr1 : ep->dma_addr0;
14953+
14954+ if(ep->is_in) {
14955+ /* Program the transfer size and packet count
14956+ * as follows: xfersize = N * maxpacket +
14957+ * short_packet pktcnt = N + (short_packet
14958+ * exist ? 1 : 0)
14959+ */
14960+ deptsiz.b.mc = ep->pkt_per_frm;
14961+ deptsiz.b.xfersize = ep->xfer_len;
14962+ deptsiz.b.pktcnt =
14963+ (ep->xfer_len - 1 + ep->maxpacket) /
14964+ ep->maxpacket;
14965+ dwc_write_reg32(&core_if->dev_if->in_ep_regs[ep->num]->dieptsiz, deptsiz.d32);
14966+
14967+ /* Write the DMA register */
14968+ dwc_write_reg32 (&(core_if->dev_if->in_ep_regs[ep->num]->diepdma), (uint32_t)ep->dma_addr);
14969+
14970+ } else {
14971+ deptsiz.b.pktcnt =
14972+ (ep->xfer_len + (ep->maxpacket - 1)) /
14973+ ep->maxpacket;
14974+ deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket;
14975+
14976+ dwc_write_reg32(&core_if->dev_if->out_ep_regs[ep->num]->doeptsiz, deptsiz.d32);
14977+
14978+ /* Write the DMA register */
14979+ dwc_write_reg32 (&(core_if->dev_if->out_ep_regs[ep->num]->doepdma), (uint32_t)ep->dma_addr);
14980+
14981+ }
14982+ /** Enable endpoint, clear nak */
14983+ depctl.d32 = 0;
14984+ dwc_modify_reg32(addr, depctl.d32,depctl.d32);
14985+
14986+ depctl.b.epena = 1;
14987+ depctl.b.cnak = 1;
14988+
14989+ dwc_modify_reg32(addr, depctl.d32,depctl.d32);
14990+ }
14991+}
14992+
14993+
14994+/**
14995+ * This function does the setup for a data transfer for an EP and
14996+ * starts the transfer. For an IN transfer, the packets will be
14997+ * loaded into the appropriate Tx FIFO in the ISR. For OUT transfers,
14998+ * the packets are unloaded from the Rx FIFO in the ISR. the ISR.
14999+ *
15000+ * @param core_if Programming view of DWC_otg controller.
15001+ * @param ep The EP to start the transfer on.
15002+ */
15003+
15004+void dwc_otg_iso_ep_start_transfer(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
15005+{
15006+ if(core_if->dma_enable) {
15007+ if(core_if->dma_desc_enable) {
15008+ if(ep->is_in) {
15009+ ep->desc_cnt = ep->pkt_cnt / ep->pkt_per_frm;
15010+ } else {
15011+ ep->desc_cnt = ep->pkt_cnt;
15012+ }
15013+ dwc_otg_iso_ep_start_ddma_transfer(core_if, ep);
15014+ } else {
15015+ if(core_if->pti_enh_enable) {
15016+ dwc_otg_iso_ep_start_buf_transfer(core_if, ep);
15017+ } else {
15018+ ep->cur_pkt_addr = (ep->proc_buf_num) ? ep->xfer_buff1 : ep->xfer_buff0;
15019+ ep->cur_pkt_dma_addr = (ep->proc_buf_num) ? ep->dma_addr1 : ep->dma_addr0;
15020+ dwc_otg_iso_ep_start_frm_transfer(core_if, ep);
15021+ }
15022+ }
15023+ } else {
15024+ ep->cur_pkt_addr = (ep->proc_buf_num) ? ep->xfer_buff1 : ep->xfer_buff0;
15025+ ep->cur_pkt_dma_addr = (ep->proc_buf_num) ? ep->dma_addr1 : ep->dma_addr0;
15026+ dwc_otg_iso_ep_start_frm_transfer(core_if, ep);
15027+ }
15028+}
15029+
15030+/**
15031+ * This function does the setup for a data transfer for an EP and
15032+ * starts the transfer. For an IN transfer, the packets will be
15033+ * loaded into the appropriate Tx FIFO in the ISR. For OUT transfers,
15034+ * the packets are unloaded from the Rx FIFO in the ISR. the ISR.
15035+ *
15036+ * @param core_if Programming view of DWC_otg controller.
15037+ * @param ep The EP to start the transfer on.
15038+ */
15039+
15040+void dwc_otg_iso_ep_stop_transfer(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
15041+{
15042+ depctl_data_t depctl = { .d32 = 0 };
15043+ volatile uint32_t *addr;
15044+
15045+ if(ep->is_in == 1) {
15046+ addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl;
15047+ }
15048+ else {
15049+ addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl;
15050+ }
15051+
15052+ /* disable the ep */
15053+ depctl.d32 = dwc_read_reg32(addr);
15054+
15055+ depctl.b.epdis = 1;
15056+ depctl.b.snak = 1;
15057+
15058+ dwc_write_reg32(addr, depctl.d32);
15059+
15060+ if(core_if->dma_desc_enable &&
15061+ ep->iso_desc_addr && ep->iso_dma_desc_addr) {
15062+ dwc_otg_ep_free_desc_chain(ep->iso_desc_addr,ep->iso_dma_desc_addr,ep->desc_cnt * 2);
15063+ }
15064+
15065+ /* reset varibales */
15066+ ep->dma_addr0 = 0;
15067+ ep->dma_addr1 = 0;
15068+ ep->xfer_buff0 = 0;
15069+ ep->xfer_buff1 = 0;
15070+ ep->data_per_frame = 0;
15071+ ep->data_pattern_frame = 0;
15072+ ep->sync_frame = 0;
15073+ ep->buf_proc_intrvl = 0;
15074+ ep->bInterval = 0;
15075+ ep->proc_buf_num = 0;
15076+ ep->pkt_per_frm = 0;
15077+ ep->pkt_per_frm = 0;
15078+ ep->desc_cnt = 0;
15079+ ep->iso_desc_addr = 0;
15080+ ep->iso_dma_desc_addr = 0;
15081+}
15082+
15083+
15084+/**
15085+ * This function is used to submit an ISOC Transfer Request to an EP.
15086+ *
15087+ * - Every time a sync period completes the request's completion callback
15088+ * is called to provide data to the gadget driver.
15089+ * - Once submitted the request cannot be modified.
15090+ * - Each request is turned into periodic data packets untill ISO
15091+ * Transfer is stopped..
15092+ */
15093+static int dwc_otg_pcd_iso_ep_start(struct usb_ep *usb_ep, struct usb_iso_request *req,
15094+ gfp_t gfp_flags)
15095+{
15096+ dwc_otg_pcd_ep_t *ep;
15097+ dwc_otg_pcd_t *pcd;
15098+ dwc_ep_t *dwc_ep;
15099+ unsigned long flags = 0;
15100+ int32_t frm_data;
15101+ dwc_otg_core_if_t *core_if;
15102+ dcfg_data_t dcfg;
15103+ dsts_data_t dsts;
15104+
15105+
15106+ if (!req || !req->process_buffer || !req->buf0 || !req->buf1) {
15107+ DWC_WARN("%s, bad params\n", __func__);
15108+ return -EINVAL;
15109+ }
15110+
15111+ ep = container_of(usb_ep, dwc_otg_pcd_ep_t, ep);
15112+
15113+ if (!usb_ep || !ep->desc || ep->dwc_ep.num == 0) {
15114+ DWC_WARN("%s, bad ep\n", __func__);
15115+ return -EINVAL;
15116+ }
15117+
15118+ pcd = ep->pcd;
15119+ core_if = GET_CORE_IF(pcd);
15120+
15121+ dcfg.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dcfg);
15122+
15123+ if (!pcd->driver || pcd->gadget.speed == USB_SPEED_UNKNOWN) {
15124+ DWC_DEBUGPL(DBG_PCDV, "gadget.speed=%d\n", pcd->gadget.speed);
15125+ DWC_WARN("%s, bogus device state\n", __func__);
15126+ return -ESHUTDOWN;
15127+ }
15128+
15129+ SPIN_LOCK_IRQSAVE(&ep->pcd->lock, flags);
15130+
15131+ dwc_ep = &ep->dwc_ep;
15132+
15133+ if(ep->iso_req) {
15134+ DWC_WARN("%s, iso request in progress\n", __func__);
15135+ }
15136+ req->status = -EINPROGRESS;
15137+
15138+ dwc_ep->dma_addr0 = req->dma0;
15139+ dwc_ep->dma_addr1 = req->dma1;
15140+
15141+ dwc_ep->xfer_buff0 = req->buf0;
15142+ dwc_ep->xfer_buff1 = req->buf1;
15143+
15144+ ep->iso_req = req;
15145+
15146+ dwc_ep->data_per_frame = req->data_per_frame;
15147+
15148+ /** @todo - pattern data support is to be implemented in the future */
15149+ dwc_ep->data_pattern_frame = req->data_pattern_frame;
15150+ dwc_ep->sync_frame = req->sync_frame;
15151+
15152+ dwc_ep->buf_proc_intrvl = req->buf_proc_intrvl;
15153+
15154+ dwc_ep->bInterval = 1 << (ep->desc->bInterval - 1);
15155+
15156+ dwc_ep->proc_buf_num = 0;
15157+
15158+ dwc_ep->pkt_per_frm = 0;
15159+ frm_data = ep->dwc_ep.data_per_frame;
15160+ while(frm_data > 0) {
15161+ dwc_ep->pkt_per_frm++;
15162+ frm_data -= ep->dwc_ep.maxpacket;
15163+ }
15164+
15165+ dsts.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts);
15166+
15167+ if(req->flags & USB_REQ_ISO_ASAP) {
15168+ dwc_ep->next_frame = dsts.b.soffn + 1;
15169+ if(dwc_ep->bInterval != 1){
15170+ dwc_ep->next_frame = dwc_ep->next_frame + (dwc_ep->bInterval - 1 - dwc_ep->next_frame % dwc_ep->bInterval);
15171+ }
15172+ } else {
15173+ dwc_ep->next_frame = req->start_frame;
15174+ }
15175+
15176+
15177+ if(!core_if->pti_enh_enable) {
15178+ dwc_ep->pkt_cnt = dwc_ep->buf_proc_intrvl * dwc_ep->pkt_per_frm / dwc_ep->bInterval;
15179+ } else {
15180+ dwc_ep->pkt_cnt =
15181+ (dwc_ep->data_per_frame * (dwc_ep->buf_proc_intrvl / dwc_ep->bInterval)
15182+ - 1 + dwc_ep->maxpacket) / dwc_ep->maxpacket;
15183+ }
15184+
15185+ if(core_if->dma_desc_enable) {
15186+ dwc_ep->desc_cnt =
15187+ dwc_ep->buf_proc_intrvl * dwc_ep->pkt_per_frm / dwc_ep->bInterval;
15188+ }
15189+
15190+ dwc_ep->pkt_info = kmalloc(sizeof(iso_pkt_info_t) * dwc_ep->pkt_cnt, GFP_KERNEL);
15191+ if(!dwc_ep->pkt_info) {
15192+ return -ENOMEM;
15193+ }
15194+ if(core_if->pti_enh_enable) {
15195+ memset(dwc_ep->pkt_info, 0, sizeof(iso_pkt_info_t) * dwc_ep->pkt_cnt);
15196+ }
15197+
15198+ dwc_ep->cur_pkt = 0;
15199+
15200+ SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
15201+
15202+ dwc_otg_iso_ep_start_transfer(core_if, dwc_ep);
15203+
15204+ return 0;
15205+}
15206+
15207+/**
15208+ * This function stops ISO EP Periodic Data Transfer.
15209+ */
15210+static int dwc_otg_pcd_iso_ep_stop(struct usb_ep *usb_ep, struct usb_iso_request *req)
15211+{
15212+ dwc_otg_pcd_ep_t *ep;
15213+ dwc_otg_pcd_t *pcd;
15214+ dwc_ep_t *dwc_ep;
15215+ unsigned long flags;
15216+
15217+ ep = container_of(usb_ep, dwc_otg_pcd_ep_t, ep);
15218+
15219+ if (!usb_ep || !ep->desc || ep->dwc_ep.num == 0) {
15220+ DWC_WARN("%s, bad ep\n", __func__);
15221+ return -EINVAL;
15222+ }
15223+
15224+ pcd = ep->pcd;
15225+
15226+ if (!pcd->driver || pcd->gadget.speed == USB_SPEED_UNKNOWN) {
15227+ DWC_DEBUGPL(DBG_PCDV, "gadget.speed=%d\n", pcd->gadget.speed);
15228+ DWC_WARN("%s, bogus device state\n", __func__);
15229+ return -ESHUTDOWN;
15230+ }
15231+
15232+ dwc_ep = &ep->dwc_ep;
15233+
15234+ dwc_otg_iso_ep_stop_transfer(GET_CORE_IF(pcd), dwc_ep);
15235+
15236+ kfree(dwc_ep->pkt_info);
15237+
15238+ SPIN_LOCK_IRQSAVE(&pcd->lock, flags);
15239+
15240+ if(ep->iso_req != req) {
15241+ return -EINVAL;
15242+ }
15243+
15244+ req->status = -ECONNRESET;
15245+
15246+ SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
15247+
15248+
15249+ ep->iso_req = 0;
15250+
15251+ return 0;
15252+}
15253+
15254+/**
15255+ * This function is used for perodical data exchnage between PCD and gadget drivers.
15256+ * for Isochronous EPs
15257+ *
15258+ * - Every time a sync period completes this function is called to
15259+ * perform data exchange between PCD and gadget
15260+ */
15261+void dwc_otg_iso_buffer_done(dwc_otg_pcd_ep_t *ep, dwc_otg_pcd_iso_request_t *req)
15262+{
15263+ int i;
15264+ struct usb_gadget_iso_packet_descriptor *iso_packet;
15265+ dwc_ep_t *dwc_ep;
15266+
15267+ dwc_ep = &ep->dwc_ep;
15268+
15269+ if(ep->iso_req->status == -ECONNRESET) {
15270+ DWC_PRINT("Device has already disconnected\n");
15271+ /*Device has been disconnected*/
15272+ return;
15273+ }
15274+
15275+ if(dwc_ep->proc_buf_num != 0) {
15276+ iso_packet = ep->iso_req->iso_packet_desc0;
15277+ }
15278+
15279+ else {
15280+ iso_packet = ep->iso_req->iso_packet_desc1;
15281+ }
15282+
15283+ /* Fill in ISOC packets descriptors & pass to gadget driver*/
15284+
15285+ for(i = 0; i < dwc_ep->pkt_cnt; ++i) {
15286+ iso_packet[i].status = dwc_ep->pkt_info[i].status;
15287+ iso_packet[i].offset = dwc_ep->pkt_info[i].offset;
15288+ iso_packet[i].actual_length = dwc_ep->pkt_info[i].length;
15289+ dwc_ep->pkt_info[i].status = 0;
15290+ dwc_ep->pkt_info[i].offset = 0;
15291+ dwc_ep->pkt_info[i].length = 0;
15292+ }
15293+
15294+ /* Call callback function to process data buffer */
15295+ ep->iso_req->status = 0;/* success */
15296+
15297+ SPIN_UNLOCK(&ep->pcd->lock);
15298+ ep->iso_req->process_buffer(&ep->ep, ep->iso_req);
15299+ SPIN_LOCK(&ep->pcd->lock);
15300+}
15301+
15302+
15303+static struct usb_iso_request *dwc_otg_pcd_alloc_iso_request(struct usb_ep *ep,int packets,
15304+ gfp_t gfp_flags)
15305+{
15306+ struct usb_iso_request *pReq = NULL;
15307+ uint32_t req_size;
15308+
15309+
15310+ req_size = sizeof(struct usb_iso_request);
15311+ req_size += (2 * packets * (sizeof(struct usb_gadget_iso_packet_descriptor)));
15312+
15313+
15314+ pReq = kmalloc(req_size, gfp_flags);
15315+ if (!pReq) {
15316+ DWC_WARN("%s, can't allocate Iso Request\n", __func__);
15317+ return 0;
15318+ }
15319+ pReq->iso_packet_desc0 = (void*) (pReq + 1);
15320+
15321+ pReq->iso_packet_desc1 = pReq->iso_packet_desc0 + packets;
15322+
15323+ return pReq;
15324+}
15325+
15326+static void dwc_otg_pcd_free_iso_request(struct usb_ep *ep, struct usb_iso_request *req)
15327+{
15328+ kfree(req);
15329+}
15330+
15331+static struct usb_isoc_ep_ops dwc_otg_pcd_ep_ops =
15332+{
15333+ .ep_ops =
15334+ {
15335+ .enable = dwc_otg_pcd_ep_enable,
15336+ .disable = dwc_otg_pcd_ep_disable,
15337+
15338+ .alloc_request = dwc_otg_pcd_alloc_request,
15339+ .free_request = dwc_otg_pcd_free_request,
15340+
15341+ //.alloc_buffer = dwc_otg_pcd_alloc_buffer,
15342+ //.free_buffer = dwc_otg_pcd_free_buffer,
15343+
15344+ .queue = dwc_otg_pcd_ep_queue,
15345+ .dequeue = dwc_otg_pcd_ep_dequeue,
15346+
15347+ .set_halt = dwc_otg_pcd_ep_set_halt,
15348+ .fifo_status = 0,
15349+ .fifo_flush = 0,
15350+ },
15351+ .iso_ep_start = dwc_otg_pcd_iso_ep_start,
15352+ .iso_ep_stop = dwc_otg_pcd_iso_ep_stop,
15353+ .alloc_iso_request = dwc_otg_pcd_alloc_iso_request,
15354+ .free_iso_request = dwc_otg_pcd_free_iso_request,
15355+};
15356+
15357+#else
15358+
15359+
15360+static struct usb_ep_ops dwc_otg_pcd_ep_ops =
15361+{
15362+ .enable = dwc_otg_pcd_ep_enable,
15363+ .disable = dwc_otg_pcd_ep_disable,
15364+
15365+ .alloc_request = dwc_otg_pcd_alloc_request,
15366+ .free_request = dwc_otg_pcd_free_request,
15367+
15368+// .alloc_buffer = dwc_otg_pcd_alloc_buffer,
15369+// .free_buffer = dwc_otg_pcd_free_buffer,
15370+
15371+ .queue = dwc_otg_pcd_ep_queue,
15372+ .dequeue = dwc_otg_pcd_ep_dequeue,
15373+
15374+ .set_halt = dwc_otg_pcd_ep_set_halt,
15375+ .fifo_status = 0,
15376+ .fifo_flush = 0,
15377+
15378+
15379+};
15380+
15381+#endif /* DWC_EN_ISOC */
15382+/* Gadget Operations */
15383+/**
15384+ * The following gadget operations will be implemented in the DWC_otg
15385+ * PCD. Functions in the API that are not described below are not
15386+ * implemented.
15387+ *
15388+ * The Gadget API provides wrapper functions for each of the function
15389+ * pointers defined in usb_gadget_ops. The Gadget Driver calls the
15390+ * wrapper function, which then calls the underlying PCD function. The
15391+ * following sections are named according to the wrapper functions
15392+ * (except for ioctl, which doesn't have a wrapper function). Within
15393+ * each section, the corresponding DWC_otg PCD function name is
15394+ * specified.
15395+ *
15396+ */
15397+
15398+/**
15399+ *Gets the USB Frame number of the last SOF.
15400+ */
15401+static int dwc_otg_pcd_get_frame(struct usb_gadget *gadget)
15402+{
15403+ dwc_otg_pcd_t *pcd;
15404+
15405+ DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, gadget);
15406+
15407+ if (gadget == 0) {
15408+ return -ENODEV;
15409+ }
15410+ else {
15411+ pcd = container_of(gadget, dwc_otg_pcd_t, gadget);
15412+ dwc_otg_get_frame_number(GET_CORE_IF(pcd));
15413+ }
15414+
15415+ return 0;
15416+}
15417+
15418+void dwc_otg_pcd_initiate_srp(dwc_otg_pcd_t *pcd)
15419+{
15420+ uint32_t *addr = (uint32_t *)&(GET_CORE_IF(pcd)->core_global_regs->gotgctl);
15421+ gotgctl_data_t mem;
15422+ gotgctl_data_t val;
15423+
15424+ val.d32 = dwc_read_reg32(addr);
15425+ if (val.b.sesreq) {
15426+ DWC_ERROR("Session Request Already active!\n");
15427+ return;
15428+ }
15429+
15430+ DWC_NOTICE("Session Request Initated\n");
15431+ mem.d32 = dwc_read_reg32(addr);
15432+ mem.b.sesreq = 1;
15433+ dwc_write_reg32(addr, mem.d32);
15434+
15435+ /* Start the SRP timer */
15436+ dwc_otg_pcd_start_srp_timer(pcd);
15437+ return;
15438+}
15439+
15440+void dwc_otg_pcd_remote_wakeup(dwc_otg_pcd_t *pcd, int set)
15441+{
15442+ dctl_data_t dctl = {.d32=0};
15443+ volatile uint32_t *addr = &(GET_CORE_IF(pcd)->dev_if->dev_global_regs->dctl);
15444+
15445+ if (dwc_otg_is_device_mode(GET_CORE_IF(pcd))) {
15446+ if (pcd->remote_wakeup_enable) {
15447+ if (set) {
15448+ dctl.b.rmtwkupsig = 1;
15449+ dwc_modify_reg32(addr, 0, dctl.d32);
15450+ DWC_DEBUGPL(DBG_PCD, "Set Remote Wakeup\n");
15451+ mdelay(1);
15452+ dwc_modify_reg32(addr, dctl.d32, 0);
15453+ DWC_DEBUGPL(DBG_PCD, "Clear Remote Wakeup\n");
15454+ }
15455+ else {
15456+ }
15457+ }
15458+ else {
15459+ DWC_DEBUGPL(DBG_PCD, "Remote Wakeup is disabled\n");
15460+ }
15461+ }
15462+ return;
15463+}
15464+
15465+/**
15466+ * Initiates Session Request Protocol (SRP) to wakeup the host if no
15467+ * session is in progress. If a session is already in progress, but
15468+ * the device is suspended, remote wakeup signaling is started.
15469+ *
15470+ */
15471+static int dwc_otg_pcd_wakeup(struct usb_gadget *gadget)
15472+{
15473+ unsigned long flags;
15474+ dwc_otg_pcd_t *pcd;
15475+ dsts_data_t dsts;
15476+ gotgctl_data_t gotgctl;
15477+
15478+ DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, gadget);
15479+
15480+ if (gadget == 0) {
15481+ return -ENODEV;
15482+ }
15483+ else {
15484+ pcd = container_of(gadget, dwc_otg_pcd_t, gadget);
15485+ }
15486+ SPIN_LOCK_IRQSAVE(&pcd->lock, flags);
15487+
15488+ /*
15489+ * This function starts the Protocol if no session is in progress. If
15490+ * a session is already in progress, but the device is suspended,
15491+ * remote wakeup signaling is started.
15492+ */
15493+
15494+ /* Check if valid session */
15495+ gotgctl.d32 = dwc_read_reg32(&(GET_CORE_IF(pcd)->core_global_regs->gotgctl));
15496+ if (gotgctl.b.bsesvld) {
15497+ /* Check if suspend state */
15498+ dsts.d32 = dwc_read_reg32(&(GET_CORE_IF(pcd)->dev_if->dev_global_regs->dsts));
15499+ if (dsts.b.suspsts) {
15500+ dwc_otg_pcd_remote_wakeup(pcd, 1);
15501+ }
15502+ }
15503+ else {
15504+ dwc_otg_pcd_initiate_srp(pcd);
15505+ }
15506+
15507+ SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
15508+ return 0;
15509+}
15510+
15511+static const struct usb_gadget_ops dwc_otg_pcd_ops =
15512+{
15513+ .get_frame = dwc_otg_pcd_get_frame,
15514+ .wakeup = dwc_otg_pcd_wakeup,
15515+ // current versions must always be self-powered
15516+};
15517+
15518+/**
15519+ * This function updates the otg values in the gadget structure.
15520+ */
15521+void dwc_otg_pcd_update_otg(dwc_otg_pcd_t *pcd, const unsigned reset)
15522+{
15523+
15524+ if (!pcd->gadget.is_otg)
15525+ return;
15526+
15527+ if (reset) {
15528+ pcd->b_hnp_enable = 0;
15529+ pcd->a_hnp_support = 0;
15530+ pcd->a_alt_hnp_support = 0;
15531+ }
15532+
15533+ pcd->gadget.b_hnp_enable = pcd->b_hnp_enable;
15534+ pcd->gadget.a_hnp_support = pcd->a_hnp_support;
15535+ pcd->gadget.a_alt_hnp_support = pcd->a_alt_hnp_support;
15536+}
15537+
15538+/**
15539+ * This function is the top level PCD interrupt handler.
15540+ */
15541+static irqreturn_t dwc_otg_pcd_irq(int irq, void *dev)
15542+{
15543+ dwc_otg_pcd_t *pcd = dev;
15544+ int32_t retval = IRQ_NONE;
15545+
15546+ retval = dwc_otg_pcd_handle_intr(pcd);
15547+ return IRQ_RETVAL(retval);
15548+}
15549+
15550+/**
15551+ * PCD Callback function for initializing the PCD when switching to
15552+ * device mode.
15553+ *
15554+ * @param p void pointer to the <code>dwc_otg_pcd_t</code>
15555+ */
15556+static int32_t dwc_otg_pcd_start_cb(void *p)
15557+{
15558+ dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *)p;
15559+
15560+ /*
15561+ * Initialized the Core for Device mode.
15562+ */
15563+ if (dwc_otg_is_device_mode(GET_CORE_IF(pcd))) {
15564+ dwc_otg_core_dev_init(GET_CORE_IF(pcd));
15565+ }
15566+ return 1;
15567+}
15568+
15569+/**
15570+ * PCD Callback function for stopping the PCD when switching to Host
15571+ * mode.
15572+ *
15573+ * @param p void pointer to the <code>dwc_otg_pcd_t</code>
15574+ */
15575+static int32_t dwc_otg_pcd_stop_cb(void *p)
15576+{
15577+ dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *)p;
15578+ extern void dwc_otg_pcd_stop(dwc_otg_pcd_t *_pcd);
15579+
15580+ dwc_otg_pcd_stop(pcd);
15581+ return 1;
15582+}
15583+
15584+
15585+/**
15586+ * PCD Callback function for notifying the PCD when resuming from
15587+ * suspend.
15588+ *
15589+ * @param p void pointer to the <code>dwc_otg_pcd_t</code>
15590+ */
15591+static int32_t dwc_otg_pcd_suspend_cb(void *p)
15592+{
15593+ dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *)p;
15594+
15595+ if (pcd->driver && pcd->driver->resume) {
15596+ SPIN_UNLOCK(&pcd->lock);
15597+ pcd->driver->suspend(&pcd->gadget);
15598+ SPIN_LOCK(&pcd->lock);
15599+ }
15600+
15601+ return 1;
15602+}
15603+
15604+
15605+/**
15606+ * PCD Callback function for notifying the PCD when resuming from
15607+ * suspend.
15608+ *
15609+ * @param p void pointer to the <code>dwc_otg_pcd_t</code>
15610+ */
15611+static int32_t dwc_otg_pcd_resume_cb(void *p)
15612+{
15613+ dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *)p;
15614+
15615+ if (pcd->driver && pcd->driver->resume) {
15616+ SPIN_UNLOCK(&pcd->lock);
15617+ pcd->driver->resume(&pcd->gadget);
15618+ SPIN_LOCK(&pcd->lock);
15619+ }
15620+
15621+ /* Stop the SRP timeout timer. */
15622+ if ((GET_CORE_IF(pcd)->core_params->phy_type != DWC_PHY_TYPE_PARAM_FS) ||
15623+ (!GET_CORE_IF(pcd)->core_params->i2c_enable)) {
15624+ if (GET_CORE_IF(pcd)->srp_timer_started) {
15625+ GET_CORE_IF(pcd)->srp_timer_started = 0;
15626+ del_timer(&pcd->srp_timer);
15627+ }
15628+ }
15629+ return 1;
15630+}
15631+
15632+
15633+/**
15634+ * PCD Callback structure for handling mode switching.
15635+ */
15636+static dwc_otg_cil_callbacks_t pcd_callbacks =
15637+{
15638+ .start = dwc_otg_pcd_start_cb,
15639+ .stop = dwc_otg_pcd_stop_cb,
15640+ .suspend = dwc_otg_pcd_suspend_cb,
15641+ .resume_wakeup = dwc_otg_pcd_resume_cb,
15642+ .p = 0, /* Set at registration */
15643+};
15644+
15645+/**
15646+ * This function is called when the SRP timer expires. The SRP should
15647+ * complete within 6 seconds.
15648+ */
15649+static void srp_timeout(unsigned long ptr)
15650+{
15651+ gotgctl_data_t gotgctl;
15652+ dwc_otg_core_if_t *core_if = (dwc_otg_core_if_t *)ptr;
15653+ volatile uint32_t *addr = &core_if->core_global_regs->gotgctl;
15654+
15655+ gotgctl.d32 = dwc_read_reg32(addr);
15656+
15657+ core_if->srp_timer_started = 0;
15658+
15659+ if ((core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS) &&
15660+ (core_if->core_params->i2c_enable)) {
15661+ DWC_PRINT("SRP Timeout\n");
15662+
15663+ if ((core_if->srp_success) &&
15664+ (gotgctl.b.bsesvld)) {
15665+ if (core_if->pcd_cb && core_if->pcd_cb->resume_wakeup) {
15666+ core_if->pcd_cb->resume_wakeup(core_if->pcd_cb->p);
15667+ }
15668+
15669+ /* Clear Session Request */
15670+ gotgctl.d32 = 0;
15671+ gotgctl.b.sesreq = 1;
15672+ dwc_modify_reg32(&core_if->core_global_regs->gotgctl,
15673+ gotgctl.d32, 0);
15674+
15675+ core_if->srp_success = 0;
15676+ }
15677+ else {
15678+ DWC_ERROR("Device not connected/responding\n");
15679+ gotgctl.b.sesreq = 0;
15680+ dwc_write_reg32(addr, gotgctl.d32);
15681+ }
15682+ }
15683+ else if (gotgctl.b.sesreq) {
15684+ DWC_PRINT("SRP Timeout\n");
15685+
15686+ DWC_ERROR("Device not connected/responding\n");
15687+ gotgctl.b.sesreq = 0;
15688+ dwc_write_reg32(addr, gotgctl.d32);
15689+ }
15690+ else {
15691+ DWC_PRINT(" SRP GOTGCTL=%0x\n", gotgctl.d32);
15692+ }
15693+}
15694+
15695+/**
15696+ * Start the SRP timer to detect when the SRP does not complete within
15697+ * 6 seconds.
15698+ *
15699+ * @param pcd the pcd structure.
15700+ */
15701+void dwc_otg_pcd_start_srp_timer(dwc_otg_pcd_t *pcd)
15702+{
15703+ struct timer_list *srp_timer = &pcd->srp_timer;
15704+ GET_CORE_IF(pcd)->srp_timer_started = 1;
15705+ init_timer(srp_timer);
15706+ srp_timer->function = srp_timeout;
15707+ srp_timer->data = (unsigned long)GET_CORE_IF(pcd);
15708+ srp_timer->expires = jiffies + (HZ*6);
15709+ add_timer(srp_timer);
15710+}
15711+
15712+/**
15713+ * Tasklet
15714+ *
15715+ */
15716+extern void start_next_request(dwc_otg_pcd_ep_t *ep);
15717+
15718+static void start_xfer_tasklet_func (unsigned long data)
15719+{
15720+ dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t*)data;
15721+ dwc_otg_core_if_t *core_if = pcd->otg_dev->core_if;
15722+
15723+ int i;
15724+ depctl_data_t diepctl;
15725+
15726+ DWC_DEBUGPL(DBG_PCDV, "Start xfer tasklet\n");
15727+
15728+ diepctl.d32 = dwc_read_reg32(&core_if->dev_if->in_ep_regs[0]->diepctl);
15729+
15730+ if (pcd->ep0.queue_sof) {
15731+ pcd->ep0.queue_sof = 0;
15732+ start_next_request (&pcd->ep0);
15733+ // break;
15734+ }
15735+
15736+ for (i=0; i<core_if->dev_if->num_in_eps; i++)
15737+ {
15738+ depctl_data_t diepctl;
15739+ diepctl.d32 = dwc_read_reg32(&core_if->dev_if->in_ep_regs[i]->diepctl);
15740+
15741+ if (pcd->in_ep[i].queue_sof) {
15742+ pcd->in_ep[i].queue_sof = 0;
15743+ start_next_request (&pcd->in_ep[i]);
15744+ // break;
15745+ }
15746+ }
15747+
15748+ return;
15749+}
15750+
15751+
15752+
15753+
15754+
15755+
15756+
15757+static struct tasklet_struct start_xfer_tasklet = {
15758+ .next = NULL,
15759+ .state = 0,
15760+ .count = ATOMIC_INIT(0),
15761+ .func = start_xfer_tasklet_func,
15762+ .data = 0,
15763+};
15764+/**
15765+ * This function initialized the pcd Dp structures to there default
15766+ * state.
15767+ *
15768+ * @param pcd the pcd structure.
15769+ */
15770+void dwc_otg_pcd_reinit(dwc_otg_pcd_t *pcd)
15771+{
15772+ static const char * names[] =
15773+ {
15774+
15775+ "ep0",
15776+ "ep1in",
15777+ "ep2in",
15778+ "ep3in",
15779+ "ep4in",
15780+ "ep5in",
15781+ "ep6in",
15782+ "ep7in",
15783+ "ep8in",
15784+ "ep9in",
15785+ "ep10in",
15786+ "ep11in",
15787+ "ep12in",
15788+ "ep13in",
15789+ "ep14in",
15790+ "ep15in",
15791+ "ep1out",
15792+ "ep2out",
15793+ "ep3out",
15794+ "ep4out",
15795+ "ep5out",
15796+ "ep6out",
15797+ "ep7out",
15798+ "ep8out",
15799+ "ep9out",
15800+ "ep10out",
15801+ "ep11out",
15802+ "ep12out",
15803+ "ep13out",
15804+ "ep14out",
15805+ "ep15out"
15806+
15807+ };
15808+
15809+ int i;
15810+ int in_ep_cntr, out_ep_cntr;
15811+ uint32_t hwcfg1;
15812+ uint32_t num_in_eps = (GET_CORE_IF(pcd))->dev_if->num_in_eps;
15813+ uint32_t num_out_eps = (GET_CORE_IF(pcd))->dev_if->num_out_eps;
15814+ dwc_otg_pcd_ep_t *ep;
15815+
15816+ DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, pcd);
15817+
15818+ INIT_LIST_HEAD (&pcd->gadget.ep_list);
15819+ pcd->gadget.ep0 = &pcd->ep0.ep;
15820+ pcd->gadget.speed = USB_SPEED_UNKNOWN;
15821+
15822+ INIT_LIST_HEAD (&pcd->gadget.ep0->ep_list);
15823+
15824+ /**
15825+ * Initialize the EP0 structure.
15826+ */
15827+ ep = &pcd->ep0;
15828+
15829+ /* Init EP structure */
15830+ ep->desc = 0;
15831+ ep->pcd = pcd;
15832+ ep->stopped = 1;
15833+
15834+ /* Init DWC ep structure */
15835+ ep->dwc_ep.num = 0;
15836+ ep->dwc_ep.active = 0;
15837+ ep->dwc_ep.tx_fifo_num = 0;
15838+ /* Control until ep is actvated */
15839+ ep->dwc_ep.type = DWC_OTG_EP_TYPE_CONTROL;
15840+ ep->dwc_ep.maxpacket = MAX_PACKET_SIZE;
15841+ ep->dwc_ep.dma_addr = 0;
15842+ ep->dwc_ep.start_xfer_buff = 0;
15843+ ep->dwc_ep.xfer_buff = 0;
15844+ ep->dwc_ep.xfer_len = 0;
15845+ ep->dwc_ep.xfer_count = 0;
15846+ ep->dwc_ep.sent_zlp = 0;
15847+ ep->dwc_ep.total_len = 0;
15848+ ep->queue_sof = 0;
15849+ ep->dwc_ep.desc_addr = 0;
15850+ ep->dwc_ep.dma_desc_addr = 0;
15851+
15852+ ep->dwc_ep.aligned_buf=NULL;
15853+ ep->dwc_ep.aligned_buf_size=0;
15854+ ep->dwc_ep.aligned_dma_addr=0;
15855+
15856+
15857+ /* Init the usb_ep structure. */
15858+ ep->ep.name = names[0];
15859+ ep->ep.ops = (struct usb_ep_ops*)&dwc_otg_pcd_ep_ops;
15860+
15861+ /**
15862+ * @todo NGS: What should the max packet size be set to
15863+ * here? Before EP type is set?
15864+ */
15865+ ep->ep.maxpacket = MAX_PACKET_SIZE;
15866+
15867+ list_add_tail (&ep->ep.ep_list, &pcd->gadget.ep_list);
15868+
15869+ INIT_LIST_HEAD (&ep->queue);
15870+ /**
15871+ * Initialize the EP structures.
15872+ */
15873+ in_ep_cntr = 0;
15874+ hwcfg1 = (GET_CORE_IF(pcd))->hwcfg1.d32 >> 3;
15875+
15876+ for (i = 1; in_ep_cntr < num_in_eps; i++)
15877+ {
15878+ if((hwcfg1 & 0x1) == 0) {
15879+ dwc_otg_pcd_ep_t *ep = &pcd->in_ep[in_ep_cntr];
15880+ in_ep_cntr ++;
15881+
15882+ /* Init EP structure */
15883+ ep->desc = 0;
15884+ ep->pcd = pcd;
15885+ ep->stopped = 1;
15886+
15887+ /* Init DWC ep structure */
15888+ ep->dwc_ep.is_in = 1;
15889+ ep->dwc_ep.num = i;
15890+ ep->dwc_ep.active = 0;
15891+ ep->dwc_ep.tx_fifo_num = 0;
15892+
15893+ /* Control until ep is actvated */
15894+ ep->dwc_ep.type = DWC_OTG_EP_TYPE_CONTROL;
15895+ ep->dwc_ep.maxpacket = MAX_PACKET_SIZE;
15896+ ep->dwc_ep.dma_addr = 0;
15897+ ep->dwc_ep.start_xfer_buff = 0;
15898+ ep->dwc_ep.xfer_buff = 0;
15899+ ep->dwc_ep.xfer_len = 0;
15900+ ep->dwc_ep.xfer_count = 0;
15901+ ep->dwc_ep.sent_zlp = 0;
15902+ ep->dwc_ep.total_len = 0;
15903+ ep->queue_sof = 0;
15904+ ep->dwc_ep.desc_addr = 0;
15905+ ep->dwc_ep.dma_desc_addr = 0;
15906+
15907+ /* Init the usb_ep structure. */
15908+ ep->ep.name = names[i];
15909+ ep->ep.ops = (struct usb_ep_ops*)&dwc_otg_pcd_ep_ops;
15910+
15911+ /**
15912+ * @todo NGS: What should the max packet size be set to
15913+ * here? Before EP type is set?
15914+ */
15915+ ep->ep.maxpacket = MAX_PACKET_SIZE;
15916+
15917+ //add only even number ep as in
15918+ if((i%2)==1)
15919+ list_add_tail (&ep->ep.ep_list, &pcd->gadget.ep_list);
15920+
15921+ INIT_LIST_HEAD (&ep->queue);
15922+ }
15923+ hwcfg1 >>= 2;
15924+ }
15925+
15926+ out_ep_cntr = 0;
15927+ hwcfg1 = (GET_CORE_IF(pcd))->hwcfg1.d32 >> 2;
15928+
15929+ for (i = 1; out_ep_cntr < num_out_eps; i++)
15930+ {
15931+ if((hwcfg1 & 0x1) == 0) {
15932+ dwc_otg_pcd_ep_t *ep = &pcd->out_ep[out_ep_cntr];
15933+ out_ep_cntr++;
15934+
15935+ /* Init EP structure */
15936+ ep->desc = 0;
15937+ ep->pcd = pcd;
15938+ ep->stopped = 1;
15939+
15940+ /* Init DWC ep structure */
15941+ ep->dwc_ep.is_in = 0;
15942+ ep->dwc_ep.num = i;
15943+ ep->dwc_ep.active = 0;
15944+ ep->dwc_ep.tx_fifo_num = 0;
15945+ /* Control until ep is actvated */
15946+ ep->dwc_ep.type = DWC_OTG_EP_TYPE_CONTROL;
15947+ ep->dwc_ep.maxpacket = MAX_PACKET_SIZE;
15948+ ep->dwc_ep.dma_addr = 0;
15949+ ep->dwc_ep.start_xfer_buff = 0;
15950+ ep->dwc_ep.xfer_buff = 0;
15951+ ep->dwc_ep.xfer_len = 0;
15952+ ep->dwc_ep.xfer_count = 0;
15953+ ep->dwc_ep.sent_zlp = 0;
15954+ ep->dwc_ep.total_len = 0;
15955+ ep->queue_sof = 0;
15956+
15957+ /* Init the usb_ep structure. */
15958+ ep->ep.name = names[15 + i];
15959+ ep->ep.ops = (struct usb_ep_ops*)&dwc_otg_pcd_ep_ops;
15960+ /**
15961+ * @todo NGS: What should the max packet size be set to
15962+ * here? Before EP type is set?
15963+ */
15964+ ep->ep.maxpacket = MAX_PACKET_SIZE;
15965+
15966+ //add only odd number ep as out
15967+ if((i%2)==0)
15968+ list_add_tail (&ep->ep.ep_list, &pcd->gadget.ep_list);
15969+
15970+ INIT_LIST_HEAD (&ep->queue);
15971+ }
15972+ hwcfg1 >>= 2;
15973+ }
15974+
15975+ /* remove ep0 from the list. There is a ep0 pointer.*/
15976+ list_del_init (&pcd->ep0.ep.ep_list);
15977+
15978+ pcd->ep0state = EP0_DISCONNECT;
15979+ pcd->ep0.ep.maxpacket = MAX_EP0_SIZE;
15980+ pcd->ep0.dwc_ep.maxpacket = MAX_EP0_SIZE;
15981+ pcd->ep0.dwc_ep.type = DWC_OTG_EP_TYPE_CONTROL;
15982+}
15983+
15984+/**
15985+ * This function releases the Gadget device.
15986+ * required by device_unregister().
15987+ *
15988+ * @todo Should this do something? Should it free the PCD?
15989+ */
15990+static void dwc_otg_pcd_gadget_release(struct device *dev)
15991+{
15992+ DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, dev);
15993+}
15994+
15995+
15996+
15997+/**
15998+ * This function initialized the PCD portion of the driver.
15999+ *
16000+ */
16001+u8 dev_id[]="gadget";
16002+int dwc_otg_pcd_init(struct platform_device *pdev)
16003+{
16004+ static char pcd_name[] = "dwc_otg_pcd";
16005+ dwc_otg_pcd_t *pcd;
16006+ dwc_otg_core_if_t* core_if;
16007+ dwc_otg_dev_if_t* dev_if;
16008+ dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev);
16009+ int retval = 0;
16010+
16011+
16012+ DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n",__func__, pdev);
16013+ /*
16014+ * Allocate PCD structure
16015+ */
16016+ pcd = kmalloc(sizeof(dwc_otg_pcd_t), GFP_KERNEL);
16017+
16018+ if (pcd == 0) {
16019+ return -ENOMEM;
16020+ }
16021+
16022+ memset(pcd, 0, sizeof(dwc_otg_pcd_t));
16023+ spin_lock_init(&pcd->lock);
16024+
16025+ otg_dev->pcd = pcd;
16026+ s_pcd = pcd;
16027+ pcd->gadget.name = pcd_name;
16028+
16029+ pcd->gadget.dev.init_name = dev_id;
16030+ pcd->otg_dev = platform_get_drvdata(pdev);
16031+
16032+ pcd->gadget.dev.parent = &pdev->dev;
16033+ pcd->gadget.dev.release = dwc_otg_pcd_gadget_release;
16034+ pcd->gadget.ops = &dwc_otg_pcd_ops;
16035+
16036+ core_if = GET_CORE_IF(pcd);
16037+ dev_if = core_if->dev_if;
16038+
16039+ if(core_if->hwcfg4.b.ded_fifo_en) {
16040+ DWC_PRINT("Dedicated Tx FIFOs mode\n");
16041+ }
16042+ else {
16043+ DWC_PRINT("Shared Tx FIFO mode\n");
16044+ }
16045+
16046+ /* If the module is set to FS or if the PHY_TYPE is FS then the gadget
16047+ * should not report as dual-speed capable. replace the following line
16048+ * with the block of code below it once the software is debugged for
16049+ * this. If is_dualspeed = 0 then the gadget driver should not report
16050+ * a device qualifier descriptor when queried. */
16051+ if ((GET_CORE_IF(pcd)->core_params->speed == DWC_SPEED_PARAM_FULL) ||
16052+ ((GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type == 2) &&
16053+ (GET_CORE_IF(pcd)->hwcfg2.b.fs_phy_type == 1) &&
16054+ (GET_CORE_IF(pcd)->core_params->ulpi_fs_ls))) {
16055+ pcd->gadget.is_dualspeed = 0;
16056+ }
16057+ else {
16058+ pcd->gadget.is_dualspeed = 1;
16059+ }
16060+
16061+ if ((otg_dev->core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE) ||
16062+ (otg_dev->core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST) ||
16063+ (otg_dev->core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE) ||
16064+ (otg_dev->core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)) {
16065+ pcd->gadget.is_otg = 0;
16066+ }
16067+ else {
16068+ pcd->gadget.is_otg = 1;
16069+ }
16070+
16071+
16072+ pcd->driver = 0;
16073+ /* Register the gadget device */
16074+printk("%s: 1\n",__func__);
16075+ retval = device_register(&pcd->gadget.dev);
16076+ if (retval != 0) {
16077+ kfree (pcd);
16078+printk("%s: 2\n",__func__);
16079+ return retval;
16080+ }
16081+
16082+
16083+ /*
16084+ * Initialized the Core for Device mode.
16085+ */
16086+ if (dwc_otg_is_device_mode(core_if)) {
16087+ dwc_otg_core_dev_init(core_if);
16088+ }
16089+
16090+ /*
16091+ * Initialize EP structures
16092+ */
16093+ dwc_otg_pcd_reinit(pcd);
16094+
16095+ /*
16096+ * Register the PCD Callbacks.
16097+ */
16098+ dwc_otg_cil_register_pcd_callbacks(otg_dev->core_if, &pcd_callbacks,
16099+ pcd);
16100+ /*
16101+ * Setup interupt handler
16102+ */
16103+ DWC_DEBUGPL(DBG_ANY, "registering handler for irq%d\n", otg_dev->irq);
16104+ retval = request_irq(otg_dev->irq, dwc_otg_pcd_irq,
16105+ IRQF_SHARED, pcd->gadget.name, pcd);
16106+ if (retval != 0) {
16107+ DWC_ERROR("request of irq%d failed\n", otg_dev->irq);
16108+ device_unregister(&pcd->gadget.dev);
16109+ kfree (pcd);
16110+ return -EBUSY;
16111+ }
16112+
16113+ /*
16114+ * Initialize the DMA buffer for SETUP packets
16115+ */
16116+ if (GET_CORE_IF(pcd)->dma_enable) {
16117+ pcd->setup_pkt = dma_alloc_coherent (NULL, sizeof (*pcd->setup_pkt) * 5, &pcd->setup_pkt_dma_handle, 0);
16118+ if (pcd->setup_pkt == 0) {
16119+ free_irq(otg_dev->irq, pcd);
16120+ device_unregister(&pcd->gadget.dev);
16121+ kfree (pcd);
16122+ return -ENOMEM;
16123+ }
16124+
16125+ pcd->status_buf = dma_alloc_coherent (NULL, sizeof (uint16_t), &pcd->status_buf_dma_handle, 0);
16126+ if (pcd->status_buf == 0) {
16127+ dma_free_coherent(NULL, sizeof(*pcd->setup_pkt), pcd->setup_pkt, pcd->setup_pkt_dma_handle);
16128+ free_irq(otg_dev->irq, pcd);
16129+ device_unregister(&pcd->gadget.dev);
16130+ kfree (pcd);
16131+ return -ENOMEM;
16132+ }
16133+
16134+ if (GET_CORE_IF(pcd)->dma_desc_enable) {
16135+ dev_if->setup_desc_addr[0] = dwc_otg_ep_alloc_desc_chain(&dev_if->dma_setup_desc_addr[0], 1);
16136+ dev_if->setup_desc_addr[1] = dwc_otg_ep_alloc_desc_chain(&dev_if->dma_setup_desc_addr[1], 1);
16137+ dev_if->in_desc_addr = dwc_otg_ep_alloc_desc_chain(&dev_if->dma_in_desc_addr, 1);
16138+ dev_if->out_desc_addr = dwc_otg_ep_alloc_desc_chain(&dev_if->dma_out_desc_addr, 1);
16139+
16140+ if(dev_if->setup_desc_addr[0] == 0
16141+ || dev_if->setup_desc_addr[1] == 0
16142+ || dev_if->in_desc_addr == 0
16143+ || dev_if->out_desc_addr == 0 ) {
16144+
16145+ if(dev_if->out_desc_addr)
16146+ dwc_otg_ep_free_desc_chain(dev_if->out_desc_addr, dev_if->dma_out_desc_addr, 1);
16147+ if(dev_if->in_desc_addr)
16148+ dwc_otg_ep_free_desc_chain(dev_if->in_desc_addr, dev_if->dma_in_desc_addr, 1);
16149+ if(dev_if->setup_desc_addr[1])
16150+ dwc_otg_ep_free_desc_chain(dev_if->setup_desc_addr[1], dev_if->dma_setup_desc_addr[1], 1);
16151+ if(dev_if->setup_desc_addr[0])
16152+ dwc_otg_ep_free_desc_chain(dev_if->setup_desc_addr[0], dev_if->dma_setup_desc_addr[0], 1);
16153+
16154+
16155+ dma_free_coherent(NULL, sizeof(*pcd->status_buf), pcd->status_buf, pcd->setup_pkt_dma_handle);
16156+ dma_free_coherent(NULL, sizeof(*pcd->setup_pkt), pcd->setup_pkt, pcd->setup_pkt_dma_handle);
16157+
16158+ free_irq(otg_dev->irq, pcd);
16159+ device_unregister(&pcd->gadget.dev);
16160+ kfree (pcd);
16161+
16162+ return -ENOMEM;
16163+ }
16164+ }
16165+ }
16166+ else {
16167+ pcd->setup_pkt = kmalloc (sizeof (*pcd->setup_pkt) * 5, GFP_KERNEL);
16168+ if (pcd->setup_pkt == 0) {
16169+ free_irq(otg_dev->irq, pcd);
16170+ device_unregister(&pcd->gadget.dev);
16171+ kfree (pcd);
16172+ return -ENOMEM;
16173+ }
16174+
16175+ pcd->status_buf = kmalloc (sizeof (uint16_t), GFP_KERNEL);
16176+ if (pcd->status_buf == 0) {
16177+ kfree(pcd->setup_pkt);
16178+ free_irq(otg_dev->irq, pcd);
16179+ device_unregister(&pcd->gadget.dev);
16180+ kfree (pcd);
16181+ return -ENOMEM;
16182+ }
16183+ }
16184+
16185+
16186+ /* Initialize tasklet */
16187+ start_xfer_tasklet.data = (unsigned long)pcd;
16188+ pcd->start_xfer_tasklet = &start_xfer_tasklet;
16189+
16190+ return 0;
16191+}
16192+
16193+/**
16194+ * Cleanup the PCD.
16195+ */
16196+void dwc_otg_pcd_remove(struct platform_device *pdev)
16197+{
16198+ dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev);
16199+ dwc_otg_pcd_t *pcd = otg_dev->pcd;
16200+ dwc_otg_dev_if_t* dev_if = GET_CORE_IF(pcd)->dev_if;
16201+
16202+ DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, pdev);
16203+
16204+ /*
16205+ * Free the IRQ
16206+ */
16207+ free_irq(otg_dev->irq, pcd);
16208+
16209+ /* start with the driver above us */
16210+ if (pcd->driver) {
16211+ /* should have been done already by driver model core */
16212+ DWC_WARN("driver '%s' is still registered\n",
16213+ pcd->driver->driver.name);
16214+ usb_gadget_unregister_driver(pcd->driver);
16215+ }
16216+ device_unregister(&pcd->gadget.dev);
16217+
16218+ if (GET_CORE_IF(pcd)->dma_enable) {
16219+ dma_free_coherent (NULL, sizeof (*pcd->setup_pkt) * 5, pcd->setup_pkt, pcd->setup_pkt_dma_handle);
16220+ dma_free_coherent (NULL, sizeof (uint16_t), pcd->status_buf, pcd->status_buf_dma_handle);
16221+ if (GET_CORE_IF(pcd)->dma_desc_enable) {
16222+ dwc_otg_ep_free_desc_chain(dev_if->setup_desc_addr[0], dev_if->dma_setup_desc_addr[0], 1);
16223+ dwc_otg_ep_free_desc_chain(dev_if->setup_desc_addr[1], dev_if->dma_setup_desc_addr[1], 1);
16224+ dwc_otg_ep_free_desc_chain(dev_if->in_desc_addr, dev_if->dma_in_desc_addr, 1);
16225+ dwc_otg_ep_free_desc_chain(dev_if->out_desc_addr, dev_if->dma_out_desc_addr, 1);
16226+ }
16227+ }
16228+ else {
16229+ kfree (pcd->setup_pkt);
16230+ kfree (pcd->status_buf);
16231+ }
16232+
16233+ kfree(pcd);
16234+ otg_dev->pcd = 0;
16235+}
16236+
16237+/**
16238+ * This function registers a gadget driver with the PCD.
16239+ *
16240+ * When a driver is successfully registered, it will receive control
16241+ * requests including set_configuration(), which enables non-control
16242+ * requests. then usb traffic follows until a disconnect is reported.
16243+ * then a host may connect again, or the driver might get unbound.
16244+ *
16245+ * @param driver The driver being registered
16246+ */
16247+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
16248+ int (*bind)(struct usb_gadget *))
16249+{
16250+ int retval;
16251+
16252+ DWC_DEBUGPL(DBG_PCD, "registering gadget driver '%s'\n", driver->driver.name);
16253+
16254+ if (!driver || driver->speed == USB_SPEED_UNKNOWN ||
16255+ !bind ||
16256+ !driver->unbind ||
16257+ !driver->disconnect ||
16258+ !driver->setup) {
16259+ DWC_DEBUGPL(DBG_PCDV,"EINVAL\n");
16260+ return -EINVAL;
16261+ }
16262+ if (s_pcd == 0) {
16263+ DWC_DEBUGPL(DBG_PCDV,"ENODEV\n");
16264+ return -ENODEV;
16265+ }
16266+ if (s_pcd->driver != 0) {
16267+ DWC_DEBUGPL(DBG_PCDV,"EBUSY (%p)\n", s_pcd->driver);
16268+ return -EBUSY;
16269+ }
16270+
16271+ /* hook up the driver */
16272+ s_pcd->driver = driver;
16273+ s_pcd->gadget.dev.driver = &driver->driver;
16274+
16275+ DWC_DEBUGPL(DBG_PCD, "bind to driver %s\n", driver->driver.name);
16276+ retval = bind(&s_pcd->gadget);
16277+ if (retval) {
16278+ DWC_ERROR("bind to driver %s --> error %d\n",
16279+ driver->driver.name, retval);
16280+ s_pcd->driver = 0;
16281+ s_pcd->gadget.dev.driver = 0;
16282+ return retval;
16283+ }
16284+ DWC_DEBUGPL(DBG_ANY, "registered gadget driver '%s'\n",
16285+ driver->driver.name);
16286+ return 0;
16287+}
16288+
16289+EXPORT_SYMBOL(usb_gadget_probe_driver);
16290+
16291+/**
16292+ * This function unregisters a gadget driver
16293+ *
16294+ * @param driver The driver being unregistered
16295+ */
16296+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
16297+{
16298+ //DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, _driver);
16299+
16300+ if (s_pcd == 0) {
16301+ DWC_DEBUGPL(DBG_ANY, "%s Return(%d): s_pcd==0\n", __func__,
16302+ -ENODEV);
16303+ return -ENODEV;
16304+ }
16305+ if (driver == 0 || driver != s_pcd->driver) {
16306+ DWC_DEBUGPL(DBG_ANY, "%s Return(%d): driver?\n", __func__,
16307+ -EINVAL);
16308+ return -EINVAL;
16309+ }
16310+
16311+ driver->unbind(&s_pcd->gadget);
16312+ s_pcd->driver = 0;
16313+
16314+ DWC_DEBUGPL(DBG_ANY, "unregistered driver '%s'\n",
16315+ driver->driver.name);
16316+ return 0;
16317+}
16318+EXPORT_SYMBOL(usb_gadget_unregister_driver);
16319+
16320+#endif /* DWC_HOST_ONLY */
16321--- /dev/null
16322+++ b/drivers/usb/dwc/otg_pcd.h
16323@@ -0,0 +1,292 @@
16324+/* ==========================================================================
16325+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_pcd.h $
16326+ * $Revision: #36 $
16327+ * $Date: 2008/09/26 $
16328+ * $Change: 1103515 $
16329+ *
16330+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
16331+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
16332+ * otherwise expressly agreed to in writing between Synopsys and you.
16333+ *
16334+ * The Software IS NOT an item of Licensed Software or Licensed Product under
16335+ * any End User Software License Agreement or Agreement for Licensed Product
16336+ * with Synopsys or any supplement thereto. You are permitted to use and
16337+ * redistribute this Software in source and binary forms, with or without
16338+ * modification, provided that redistributions of source code must retain this
16339+ * notice. You may not view, use, disclose, copy or distribute this file or
16340+ * any information contained herein except pursuant to this license grant from
16341+ * Synopsys. If you do not agree with this notice, including the disclaimer
16342+ * below, then you are not authorized to use the Software.
16343+ *
16344+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
16345+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16346+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16347+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
16348+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16349+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
16350+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
16351+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
16352+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
16353+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
16354+ * DAMAGE.
16355+ * ========================================================================== */
16356+#ifndef DWC_HOST_ONLY
16357+#if !defined(__DWC_PCD_H__)
16358+#define __DWC_PCD_H__
16359+
16360+#include <linux/types.h>
16361+#include <linux/list.h>
16362+#include <linux/errno.h>
16363+#include <linux/device.h>
16364+#include <linux/platform_device.h>
16365+
16366+#include <linux/usb/ch9.h>
16367+#include <linux/usb/gadget.h>
16368+
16369+#include <linux/interrupt.h>
16370+#include <linux/dma-mapping.h>
16371+
16372+struct dwc_otg_device;
16373+
16374+#include "otg_cil.h"
16375+
16376+/**
16377+ * @file
16378+ *
16379+ * This file contains the structures, constants, and interfaces for
16380+ * the Perpherial Contoller Driver (PCD).
16381+ *
16382+ * The Peripheral Controller Driver (PCD) for Linux will implement the
16383+ * Gadget API, so that the existing Gadget drivers can be used. For
16384+ * the Mass Storage Function driver the File-backed USB Storage Gadget
16385+ * (FBS) driver will be used. The FBS driver supports the
16386+ * Control-Bulk (CB), Control-Bulk-Interrupt (CBI), and Bulk-Only
16387+ * transports.
16388+ *
16389+ */
16390+
16391+/** Invalid DMA Address */
16392+#define DMA_ADDR_INVALID (~(dma_addr_t)0)
16393+/** Maxpacket size for EP0 */
16394+#define MAX_EP0_SIZE 64
16395+/** Maxpacket size for any EP */
16396+#define MAX_PACKET_SIZE 1024
16397+
16398+/** Max Transfer size for any EP */
16399+#define MAX_TRANSFER_SIZE 65535
16400+
16401+/** Max DMA Descriptor count for any EP */
16402+#define MAX_DMA_DESC_CNT 64
16403+
16404+/**
16405+ * Get the pointer to the core_if from the pcd pointer.
16406+ */
16407+#define GET_CORE_IF( _pcd ) (_pcd->otg_dev->core_if)
16408+
16409+/**
16410+ * States of EP0.
16411+ */
16412+typedef enum ep0_state
16413+{
16414+ EP0_DISCONNECT, /* no host */
16415+ EP0_IDLE,
16416+ EP0_IN_DATA_PHASE,
16417+ EP0_OUT_DATA_PHASE,
16418+ EP0_IN_STATUS_PHASE,
16419+ EP0_OUT_STATUS_PHASE,
16420+ EP0_STALL,
16421+} ep0state_e;
16422+
16423+/** Fordward declaration.*/
16424+struct dwc_otg_pcd;
16425+
16426+/** DWC_otg iso request structure.
16427+ *
16428+ */
16429+typedef struct usb_iso_request dwc_otg_pcd_iso_request_t;
16430+
16431+/** PCD EP structure.
16432+ * This structure describes an EP, there is an array of EPs in the PCD
16433+ * structure.
16434+ */
16435+typedef struct dwc_otg_pcd_ep
16436+{
16437+ /** USB EP data */
16438+ struct usb_ep ep;
16439+ /** USB EP Descriptor */
16440+ const struct usb_endpoint_descriptor *desc;
16441+
16442+ /** queue of dwc_otg_pcd_requests. */
16443+ struct list_head queue;
16444+ unsigned stopped : 1;
16445+ unsigned disabling : 1;
16446+ unsigned dma : 1;
16447+ unsigned queue_sof : 1;
16448+
16449+#ifdef DWC_EN_ISOC
16450+ /** DWC_otg Isochronous Transfer */
16451+ struct usb_iso_request* iso_req;
16452+#endif //DWC_EN_ISOC
16453+
16454+ /** DWC_otg ep data. */
16455+ dwc_ep_t dwc_ep;
16456+
16457+ /** Pointer to PCD */
16458+ struct dwc_otg_pcd *pcd;
16459+}dwc_otg_pcd_ep_t;
16460+
16461+
16462+
16463+/** DWC_otg PCD Structure.
16464+ * This structure encapsulates the data for the dwc_otg PCD.
16465+ */
16466+typedef struct dwc_otg_pcd
16467+{
16468+ /** USB gadget */
16469+ struct usb_gadget gadget;
16470+ /** USB gadget driver pointer*/
16471+ struct usb_gadget_driver *driver;
16472+ /** The DWC otg device pointer. */
16473+ struct dwc_otg_device *otg_dev;
16474+
16475+ /** State of EP0 */
16476+ ep0state_e ep0state;
16477+ /** EP0 Request is pending */
16478+ unsigned ep0_pending : 1;
16479+ /** Indicates when SET CONFIGURATION Request is in process */
16480+ unsigned request_config : 1;
16481+ /** The state of the Remote Wakeup Enable. */
16482+ unsigned remote_wakeup_enable : 1;
16483+ /** The state of the B-Device HNP Enable. */
16484+ unsigned b_hnp_enable : 1;
16485+ /** The state of A-Device HNP Support. */
16486+ unsigned a_hnp_support : 1;
16487+ /** The state of the A-Device Alt HNP support. */
16488+ unsigned a_alt_hnp_support : 1;
16489+ /** Count of pending Requests */
16490+ unsigned request_pending;
16491+
16492+ /** SETUP packet for EP0
16493+ * This structure is allocated as a DMA buffer on PCD initialization
16494+ * with enough space for up to 3 setup packets.
16495+ */
16496+ union
16497+ {
16498+ struct usb_ctrlrequest req;
16499+ uint32_t d32[2];
16500+ } *setup_pkt;
16501+
16502+ dma_addr_t setup_pkt_dma_handle;
16503+
16504+ /** 2-byte dma buffer used to return status from GET_STATUS */
16505+ uint16_t *status_buf;
16506+ dma_addr_t status_buf_dma_handle;
16507+
16508+ /** EP0 */
16509+ dwc_otg_pcd_ep_t ep0;
16510+
16511+ /** Array of IN EPs. */
16512+ dwc_otg_pcd_ep_t in_ep[ MAX_EPS_CHANNELS - 1];
16513+ /** Array of OUT EPs. */
16514+ dwc_otg_pcd_ep_t out_ep[ MAX_EPS_CHANNELS - 1];
16515+ /** number of valid EPs in the above array. */
16516+// unsigned num_eps : 4;
16517+ spinlock_t lock;
16518+ /** Timer for SRP. If it expires before SRP is successful
16519+ * clear the SRP. */
16520+ struct timer_list srp_timer;
16521+
16522+ /** Tasklet to defer starting of TEST mode transmissions until
16523+ * Status Phase has been completed.
16524+ */
16525+ struct tasklet_struct test_mode_tasklet;
16526+
16527+ /** Tasklet to delay starting of xfer in DMA mode */
16528+ struct tasklet_struct *start_xfer_tasklet;
16529+
16530+ /** The test mode to enter when the tasklet is executed. */
16531+ unsigned test_mode;
16532+
16533+} dwc_otg_pcd_t;
16534+
16535+
16536+/** DWC_otg request structure.
16537+ * This structure is a list of requests.
16538+ */
16539+typedef struct
16540+{
16541+ struct usb_request req; /**< USB Request. */
16542+ struct list_head queue; /**< queue of these requests. */
16543+} dwc_otg_pcd_request_t;
16544+
16545+
16546+extern int dwc_otg_pcd_init(struct platform_device *pdev);
16547+
16548+//extern void dwc_otg_pcd_remove( struct dwc_otg_device *_otg_dev );
16549+extern void dwc_otg_pcd_remove( struct platform_device *pdev );
16550+extern int32_t dwc_otg_pcd_handle_intr( dwc_otg_pcd_t *pcd );
16551+extern void dwc_otg_pcd_start_srp_timer(dwc_otg_pcd_t *pcd );
16552+
16553+extern void dwc_otg_pcd_initiate_srp(dwc_otg_pcd_t *pcd);
16554+extern void dwc_otg_pcd_remote_wakeup(dwc_otg_pcd_t *pcd, int set);
16555+
16556+extern void dwc_otg_iso_buffer_done(dwc_otg_pcd_ep_t *ep, dwc_otg_pcd_iso_request_t *req);
16557+extern void dwc_otg_request_done(dwc_otg_pcd_ep_t *_ep, dwc_otg_pcd_request_t *req,
16558+ int status);
16559+extern void dwc_otg_request_nuke(dwc_otg_pcd_ep_t *_ep);
16560+extern void dwc_otg_pcd_update_otg(dwc_otg_pcd_t *_pcd,
16561+ const unsigned reset);
16562+#ifndef VERBOSE
16563+#define VERIFY_PCD_DMA_ADDR(_addr_) BUG_ON(((_addr_)==DMA_ADDR_INVALID)||\
16564+ ((_addr_)==0)||\
16565+ ((_addr_)&0x3))
16566+#else
16567+#define VERIFY_PCD_DMA_ADDR(_addr_) {\
16568+ if(((_addr_)==DMA_ADDR_INVALID)||\
16569+ ((_addr_)==0)||\
16570+ ((_addr_)&0x3)) {\
16571+ printk("%s: Invalid DMA address "#_addr_"(%.8x)\n",__func__,_addr_);\
16572+ BUG();\
16573+ }\
16574+ }
16575+#endif
16576+
16577+
16578+static inline void ep_check_and_patch_dma_addr(dwc_otg_pcd_ep_t *ep){
16579+//void ep_check_and_patch_dma_addr(dwc_otg_pcd_ep_t *ep){
16580+ dwc_ep_t *dwc_ep=&ep->dwc_ep;
16581+
16582+DWC_DEBUGPL(DBG_PCDV,"%s: dwc_ep xfer_buf=%.8x, total_len=%d, dma_addr=%.8x\n",__func__,(u32)dwc_ep->xfer_buff,(dwc_ep->total_len),dwc_ep->dma_addr);
16583+ if (/*(core_if->dma_enable)&&*/(dwc_ep->dma_addr==DMA_ADDR_INVALID)) {
16584+ if((((u32)dwc_ep->xfer_buff)&0x3)==0){
16585+ dwc_ep->dma_addr=dma_map_single(NULL,(void *)(dwc_ep->start_xfer_buff),(dwc_ep->total_len), DMA_TO_DEVICE);
16586+DWC_DEBUGPL(DBG_PCDV," got dma_addr=%.8x\n",dwc_ep->dma_addr);
16587+ }else{
16588+DWC_DEBUGPL(DBG_PCDV," buf not aligned, use aligned_buf instead. xfer_buf=%.8x, total_len=%d, aligned_buf_size=%d\n",(u32)dwc_ep->xfer_buff,(dwc_ep->total_len),dwc_ep->aligned_buf_size);
16589+ if(dwc_ep->aligned_buf_size<dwc_ep->total_len){
16590+ if(dwc_ep->aligned_buf){
16591+//printk(" free buff dwc_ep aligned_buf_size=%d, aligned_buf(%.8x), aligned_dma_addr(%.8x));\n",dwc_ep->aligned_buf_size,dwc_ep->aligned_buf,dwc_ep->aligned_dma_addr);
16592+ //dma_free_coherent(NULL,dwc_ep->aligned_buf_size,dwc_ep->aligned_buf,dwc_ep->aligned_dma_addr);
16593+ kfree(dwc_ep->aligned_buf);
16594+ }
16595+ dwc_ep->aligned_buf_size=((1<<20)>(dwc_ep->total_len<<1))?(dwc_ep->total_len<<1):(1<<20);
16596+ //dwc_ep->aligned_buf = dma_alloc_coherent (NULL, dwc_ep->aligned_buf_size, &dwc_ep->aligned_dma_addr, GFP_KERNEL|GFP_DMA);
16597+ dwc_ep->aligned_buf=kmalloc(dwc_ep->aligned_buf_size,GFP_KERNEL|GFP_DMA|GFP_ATOMIC);
16598+ dwc_ep->aligned_dma_addr=dma_map_single(NULL,(void *)(dwc_ep->aligned_buf),(dwc_ep->aligned_buf_size),DMA_FROM_DEVICE);
16599+ if(!dwc_ep->aligned_buf){
16600+ DWC_ERROR("Cannot alloc required buffer!!\n");
16601+ BUG();
16602+ }
16603+DWC_DEBUGPL(DBG_PCDV," dwc_ep allocated aligned buf=%.8x, dma_addr=%.8x, size=%d(0x%x)\n", (u32)dwc_ep->aligned_buf, dwc_ep->aligned_dma_addr, dwc_ep->aligned_buf_size, dwc_ep->aligned_buf_size);
16604+ }
16605+ dwc_ep->dma_addr=dwc_ep->aligned_dma_addr;
16606+ if(dwc_ep->is_in) {
16607+ memcpy(dwc_ep->aligned_buf,dwc_ep->xfer_buff,dwc_ep->total_len);
16608+ dma_sync_single_for_device(NULL,dwc_ep->dma_addr,dwc_ep->total_len,DMA_TO_DEVICE);
16609+ }
16610+ }
16611+ }
16612+}
16613+
16614+#endif
16615+#endif /* DWC_HOST_ONLY */
16616--- /dev/null
16617+++ b/drivers/usb/dwc/otg_pcd_intr.c
16618@@ -0,0 +1,3682 @@
16619+/* ==========================================================================
16620+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_pcd_intr.c $
16621+ * $Revision: #83 $
16622+ * $Date: 2008/10/14 $
16623+ * $Change: 1115682 $
16624+ *
16625+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
16626+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
16627+ * otherwise expressly agreed to in writing between Synopsys and you.
16628+ *
16629+ * The Software IS NOT an item of Licensed Software or Licensed Product under
16630+ * any End User Software License Agreement or Agreement for Licensed Product
16631+ * with Synopsys or any supplement thereto. You are permitted to use and
16632+ * redistribute this Software in source and binary forms, with or without
16633+ * modification, provided that redistributions of source code must retain this
16634+ * notice. You may not view, use, disclose, copy or distribute this file or
16635+ * any information contained herein except pursuant to this license grant from
16636+ * Synopsys. If you do not agree with this notice, including the disclaimer
16637+ * below, then you are not authorized to use the Software.
16638+ *
16639+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
16640+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16641+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16642+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
16643+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16644+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
16645+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
16646+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
16647+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
16648+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
16649+ * DAMAGE.
16650+ * ========================================================================== */
16651+#ifndef DWC_HOST_ONLY
16652+#include <linux/interrupt.h>
16653+#include <linux/dma-mapping.h>
16654+#include <linux/version.h>
16655+#include <linux/pci.h>
16656+
16657+#include "otg_driver.h"
16658+#include "otg_pcd.h"
16659+
16660+
16661+#define DEBUG_EP0
16662+
16663+
16664+/* request functions defined in "dwc_otg_pcd.c" */
16665+
16666+/** @file
16667+ * This file contains the implementation of the PCD Interrupt handlers.
16668+ *
16669+ * The PCD handles the device interrupts. Many conditions can cause a
16670+ * device interrupt. When an interrupt occurs, the device interrupt
16671+ * service routine determines the cause of the interrupt and
16672+ * dispatches handling to the appropriate function. These interrupt
16673+ * handling functions are described below.
16674+ * All interrupt registers are processed from LSB to MSB.
16675+ */
16676+
16677+
16678+/**
16679+ * This function prints the ep0 state for debug purposes.
16680+ */
16681+static inline void print_ep0_state(dwc_otg_pcd_t *pcd)
16682+{
16683+#ifdef DEBUG
16684+ char str[40];
16685+
16686+ switch (pcd->ep0state) {
16687+ case EP0_DISCONNECT:
16688+ strcpy(str, "EP0_DISCONNECT");
16689+ break;
16690+ case EP0_IDLE:
16691+ strcpy(str, "EP0_IDLE");
16692+ break;
16693+ case EP0_IN_DATA_PHASE:
16694+ strcpy(str, "EP0_IN_DATA_PHASE");
16695+ break;
16696+ case EP0_OUT_DATA_PHASE:
16697+ strcpy(str, "EP0_OUT_DATA_PHASE");
16698+ break;
16699+ case EP0_IN_STATUS_PHASE:
16700+ strcpy(str,"EP0_IN_STATUS_PHASE");
16701+ break;
16702+ case EP0_OUT_STATUS_PHASE:
16703+ strcpy(str,"EP0_OUT_STATUS_PHASE");
16704+ break;
16705+ case EP0_STALL:
16706+ strcpy(str,"EP0_STALL");
16707+ break;
16708+ default:
16709+ strcpy(str,"EP0_INVALID");
16710+ }
16711+
16712+ DWC_DEBUGPL(DBG_ANY, "%s(%d)\n", str, pcd->ep0state);
16713+#endif
16714+}
16715+
16716+/**
16717+ * This function returns pointer to in ep struct with number ep_num
16718+ */
16719+static inline dwc_otg_pcd_ep_t* get_in_ep(dwc_otg_pcd_t *pcd, uint32_t ep_num)
16720+{
16721+ int i;
16722+ int num_in_eps = GET_CORE_IF(pcd)->dev_if->num_in_eps;
16723+ if(ep_num == 0) {
16724+ return &pcd->ep0;
16725+ }
16726+ else {
16727+ for(i = 0; i < num_in_eps; ++i)
16728+ {
16729+ if(pcd->in_ep[i].dwc_ep.num == ep_num)
16730+ return &pcd->in_ep[i];
16731+ }
16732+ return 0;
16733+ }
16734+}
16735+/**
16736+ * This function returns pointer to out ep struct with number ep_num
16737+ */
16738+static inline dwc_otg_pcd_ep_t* get_out_ep(dwc_otg_pcd_t *pcd, uint32_t ep_num)
16739+{
16740+ int i;
16741+ int num_out_eps = GET_CORE_IF(pcd)->dev_if->num_out_eps;
16742+ if(ep_num == 0) {
16743+ return &pcd->ep0;
16744+ }
16745+ else {
16746+ for(i = 0; i < num_out_eps; ++i)
16747+ {
16748+ if(pcd->out_ep[i].dwc_ep.num == ep_num)
16749+ return &pcd->out_ep[i];
16750+ }
16751+ return 0;
16752+ }
16753+}
16754+/**
16755+ * This functions gets a pointer to an EP from the wIndex address
16756+ * value of the control request.
16757+ */
16758+static dwc_otg_pcd_ep_t *get_ep_by_addr (dwc_otg_pcd_t *pcd, u16 wIndex)
16759+{
16760+ dwc_otg_pcd_ep_t *ep;
16761+
16762+ if ((wIndex & USB_ENDPOINT_NUMBER_MASK) == 0)
16763+ return &pcd->ep0;
16764+ list_for_each_entry(ep, &pcd->gadget.ep_list, ep.ep_list)
16765+ {
16766+ u8 bEndpointAddress;
16767+
16768+ if (!ep->desc)
16769+ continue;
16770+
16771+ bEndpointAddress = ep->desc->bEndpointAddress;
16772+ if((wIndex & (USB_DIR_IN | USB_ENDPOINT_NUMBER_MASK))
16773+ == (bEndpointAddress & (USB_DIR_IN | USB_ENDPOINT_NUMBER_MASK)))
16774+ return ep;
16775+ }
16776+ return NULL;
16777+}
16778+
16779+/**
16780+ * This function checks the EP request queue, if the queue is not
16781+ * empty the next request is started.
16782+ */
16783+void start_next_request(dwc_otg_pcd_ep_t *ep)
16784+{
16785+ dwc_otg_pcd_request_t *req = 0;
16786+ uint32_t max_transfer = GET_CORE_IF(ep->pcd)->core_params->max_transfer_size;
16787+ if (!list_empty(&ep->queue)) {
16788+ req = list_entry(ep->queue.next,
16789+ dwc_otg_pcd_request_t, queue);
16790+
16791+ /* Setup and start the Transfer */
16792+ ep->dwc_ep.dma_addr = req->req.dma;
16793+ ep->dwc_ep.start_xfer_buff = req->req.buf;
16794+ ep->dwc_ep.xfer_buff = req->req.buf;
16795+ ep->dwc_ep.sent_zlp = 0;
16796+ ep->dwc_ep.total_len = req->req.length;
16797+ ep->dwc_ep.xfer_len = 0;
16798+ ep->dwc_ep.xfer_count = 0;
16799+
16800+ if(max_transfer > MAX_TRANSFER_SIZE) {
16801+ ep->dwc_ep.maxxfer = max_transfer - (max_transfer % ep->dwc_ep.maxpacket);
16802+ } else {
16803+ ep->dwc_ep.maxxfer = max_transfer;
16804+ }
16805+
16806+ if(req->req.zero) {
16807+ if((ep->dwc_ep.total_len % ep->dwc_ep.maxpacket == 0)
16808+ && (ep->dwc_ep.total_len != 0)) {
16809+ ep->dwc_ep.sent_zlp = 1;
16810+ }
16811+
16812+ }
16813+ ep_check_and_patch_dma_addr(ep);
16814+ dwc_otg_ep_start_transfer(GET_CORE_IF(ep->pcd), &ep->dwc_ep);
16815+ }
16816+}
16817+
16818+/**
16819+ * This function handles the SOF Interrupts. At this time the SOF
16820+ * Interrupt is disabled.
16821+ */
16822+int32_t dwc_otg_pcd_handle_sof_intr(dwc_otg_pcd_t *pcd)
16823+{
16824+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
16825+
16826+ gintsts_data_t gintsts;
16827+
16828+ DWC_DEBUGPL(DBG_PCD, "SOF\n");
16829+
16830+ /* Clear interrupt */
16831+ gintsts.d32 = 0;
16832+ gintsts.b.sofintr = 1;
16833+ dwc_write_reg32 (&core_if->core_global_regs->gintsts, gintsts.d32);
16834+
16835+ return 1;
16836+}
16837+
16838+
16839+/**
16840+ * This function handles the Rx Status Queue Level Interrupt, which
16841+ * indicates that there is a least one packet in the Rx FIFO. The
16842+ * packets are moved from the FIFO to memory, where they will be
16843+ * processed when the Endpoint Interrupt Register indicates Transfer
16844+ * Complete or SETUP Phase Done.
16845+ *
16846+ * Repeat the following until the Rx Status Queue is empty:
16847+ * -# Read the Receive Status Pop Register (GRXSTSP) to get Packet
16848+ * info
16849+ * -# If Receive FIFO is empty then skip to step Clear the interrupt
16850+ * and exit
16851+ * -# If SETUP Packet call dwc_otg_read_setup_packet to copy the
16852+ * SETUP data to the buffer
16853+ * -# If OUT Data Packet call dwc_otg_read_packet to copy the data
16854+ * to the destination buffer
16855+ */
16856+int32_t dwc_otg_pcd_handle_rx_status_q_level_intr(dwc_otg_pcd_t *pcd)
16857+{
16858+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
16859+ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
16860+ gintmsk_data_t gintmask = {.d32=0};
16861+ device_grxsts_data_t status;
16862+ dwc_otg_pcd_ep_t *ep;
16863+ gintsts_data_t gintsts;
16864+#ifdef DEBUG
16865+ static char *dpid_str[] ={ "D0", "D2", "D1", "MDATA" };
16866+#endif
16867+
16868+ //DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, _pcd);
16869+ /* Disable the Rx Status Queue Level interrupt */
16870+ gintmask.b.rxstsqlvl= 1;
16871+ dwc_modify_reg32(&global_regs->gintmsk, gintmask.d32, 0);
16872+
16873+ /* Get the Status from the top of the FIFO */
16874+ status.d32 = dwc_read_reg32(&global_regs->grxstsp);
16875+
16876+ DWC_DEBUGPL(DBG_PCD, "EP:%d BCnt:%d DPID:%s "
16877+ "pktsts:%x Frame:%d(0x%0x)\n",
16878+ status.b.epnum, status.b.bcnt,
16879+ dpid_str[status.b.dpid],
16880+ status.b.pktsts, status.b.fn, status.b.fn);
16881+ /* Get pointer to EP structure */
16882+ ep = get_out_ep(pcd, status.b.epnum);
16883+
16884+ switch (status.b.pktsts) {
16885+ case DWC_DSTS_GOUT_NAK:
16886+ DWC_DEBUGPL(DBG_PCDV, "Global OUT NAK\n");
16887+ break;
16888+ case DWC_STS_DATA_UPDT:
16889+ DWC_DEBUGPL(DBG_PCDV, "OUT Data Packet\n");
16890+ if (status.b.bcnt && ep->dwc_ep.xfer_buff) {
16891+ /** @todo NGS Check for buffer overflow? */
16892+ dwc_otg_read_packet(core_if,
16893+ ep->dwc_ep.xfer_buff,
16894+ status.b.bcnt);
16895+ ep->dwc_ep.xfer_count += status.b.bcnt;
16896+ ep->dwc_ep.xfer_buff += status.b.bcnt;
16897+ }
16898+ break;
16899+ case DWC_STS_XFER_COMP:
16900+ DWC_DEBUGPL(DBG_PCDV, "OUT Complete\n");
16901+ break;
16902+ case DWC_DSTS_SETUP_COMP:
16903+#ifdef DEBUG_EP0
16904+ DWC_DEBUGPL(DBG_PCDV, "Setup Complete\n");
16905+#endif
16906+ break;
16907+case DWC_DSTS_SETUP_UPDT:
16908+ dwc_otg_read_setup_packet(core_if, pcd->setup_pkt->d32);
16909+#ifdef DEBUG_EP0
16910+ DWC_DEBUGPL(DBG_PCD,
16911+ "SETUP PKT: %02x.%02x v%04x i%04x l%04x\n",
16912+ pcd->setup_pkt->req.bRequestType,
16913+ pcd->setup_pkt->req.bRequest,
16914+ pcd->setup_pkt->req.wValue,
16915+ pcd->setup_pkt->req.wIndex,
16916+ pcd->setup_pkt->req.wLength);
16917+#endif
16918+ ep->dwc_ep.xfer_count += status.b.bcnt;
16919+ break;
16920+ default:
16921+ DWC_DEBUGPL(DBG_PCDV, "Invalid Packet Status (0x%0x)\n",
16922+ status.b.pktsts);
16923+ break;
16924+ }
16925+
16926+ /* Enable the Rx Status Queue Level interrupt */
16927+ dwc_modify_reg32(&global_regs->gintmsk, 0, gintmask.d32);
16928+ /* Clear interrupt */
16929+ gintsts.d32 = 0;
16930+ gintsts.b.rxstsqlvl = 1;
16931+ dwc_write_reg32 (&global_regs->gintsts, gintsts.d32);
16932+
16933+ //DWC_DEBUGPL(DBG_PCDV, "EXIT: %s\n", __func__);
16934+ return 1;
16935+}
16936+/**
16937+ * This function examines the Device IN Token Learning Queue to
16938+ * determine the EP number of the last IN token received. This
16939+ * implementation is for the Mass Storage device where there are only
16940+ * 2 IN EPs (Control-IN and BULK-IN).
16941+ *
16942+ * The EP numbers for the first six IN Tokens are in DTKNQR1 and there
16943+ * are 8 EP Numbers in each of the other possible DTKNQ Registers.
16944+ *
16945+ * @param core_if Programming view of DWC_otg controller.
16946+ *
16947+ */
16948+static inline int get_ep_of_last_in_token(dwc_otg_core_if_t *core_if)
16949+{
16950+ dwc_otg_device_global_regs_t *dev_global_regs =
16951+ core_if->dev_if->dev_global_regs;
16952+ const uint32_t TOKEN_Q_DEPTH = core_if->hwcfg2.b.dev_token_q_depth;
16953+ /* Number of Token Queue Registers */
16954+ const int DTKNQ_REG_CNT = (TOKEN_Q_DEPTH + 7) / 8;
16955+ dtknq1_data_t dtknqr1;
16956+ uint32_t in_tkn_epnums[4];
16957+ int ndx = 0;
16958+ int i = 0;
16959+ volatile uint32_t *addr = &dev_global_regs->dtknqr1;
16960+ int epnum = 0;
16961+
16962+ //DWC_DEBUGPL(DBG_PCD,"dev_token_q_depth=%d\n",TOKEN_Q_DEPTH);
16963+
16964+ /* Read the DTKNQ Registers */
16965+ for (i = 0; i < DTKNQ_REG_CNT; i++)
16966+ {
16967+ in_tkn_epnums[ i ] = dwc_read_reg32(addr);
16968+ DWC_DEBUGPL(DBG_PCDV, "DTKNQR%d=0x%08x\n", i+1,
16969+ in_tkn_epnums[i]);
16970+ if (addr == &dev_global_regs->dvbusdis) {
16971+ addr = &dev_global_regs->dtknqr3_dthrctl;
16972+ }
16973+ else {
16974+ ++addr;
16975+ }
16976+ }
16977+
16978+ /* Copy the DTKNQR1 data to the bit field. */
16979+ dtknqr1.d32 = in_tkn_epnums[0];
16980+ /* Get the EP numbers */
16981+ in_tkn_epnums[0] = dtknqr1.b.epnums0_5;
16982+ ndx = dtknqr1.b.intknwptr - 1;
16983+
16984+ //DWC_DEBUGPL(DBG_PCDV,"ndx=%d\n",ndx);
16985+ if (ndx == -1) {
16986+ /** @todo Find a simpler way to calculate the max
16987+ * queue position.*/
16988+ int cnt = TOKEN_Q_DEPTH;
16989+ if (TOKEN_Q_DEPTH <= 6) {
16990+ cnt = TOKEN_Q_DEPTH - 1;
16991+ }
16992+ else if (TOKEN_Q_DEPTH <= 14) {
16993+ cnt = TOKEN_Q_DEPTH - 7;
16994+ }
16995+ else if (TOKEN_Q_DEPTH <= 22) {
16996+ cnt = TOKEN_Q_DEPTH - 15;
16997+ }
16998+ else {
16999+ cnt = TOKEN_Q_DEPTH - 23;
17000+ }
17001+ epnum = (in_tkn_epnums[ DTKNQ_REG_CNT - 1 ] >> (cnt * 4)) & 0xF;
17002+ }
17003+ else {
17004+ if (ndx <= 5) {
17005+ epnum = (in_tkn_epnums[0] >> (ndx * 4)) & 0xF;
17006+ }
17007+ else if (ndx <= 13) {
17008+ ndx -= 6;
17009+ epnum = (in_tkn_epnums[1] >> (ndx * 4)) & 0xF;
17010+ }
17011+ else if (ndx <= 21) {
17012+ ndx -= 14;
17013+ epnum = (in_tkn_epnums[2] >> (ndx * 4)) & 0xF;
17014+ }
17015+ else if (ndx <= 29) {
17016+ ndx -= 22;
17017+ epnum = (in_tkn_epnums[3] >> (ndx * 4)) & 0xF;
17018+ }
17019+ }
17020+ //DWC_DEBUGPL(DBG_PCD,"epnum=%d\n",epnum);
17021+ return epnum;
17022+}
17023+
17024+/**
17025+ * This interrupt occurs when the non-periodic Tx FIFO is half-empty.
17026+ * The active request is checked for the next packet to be loaded into
17027+ * the non-periodic Tx FIFO.
17028+ */
17029+int32_t dwc_otg_pcd_handle_np_tx_fifo_empty_intr(dwc_otg_pcd_t *pcd)
17030+{
17031+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
17032+ dwc_otg_core_global_regs_t *global_regs =
17033+ core_if->core_global_regs;
17034+ dwc_otg_dev_in_ep_regs_t *ep_regs;
17035+ gnptxsts_data_t txstatus = {.d32 = 0};
17036+ gintsts_data_t gintsts;
17037+
17038+ int epnum = 0;
17039+ dwc_otg_pcd_ep_t *ep = 0;
17040+ uint32_t len = 0;
17041+ int dwords;
17042+
17043+ /* Get the epnum from the IN Token Learning Queue. */
17044+ epnum = get_ep_of_last_in_token(core_if);
17045+ ep = get_in_ep(pcd, epnum);
17046+
17047+ DWC_DEBUGPL(DBG_PCD, "NP TxFifo Empty: %s(%d) \n", ep->ep.name, epnum);
17048+ ep_regs = core_if->dev_if->in_ep_regs[epnum];
17049+
17050+ len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
17051+ if (len > ep->dwc_ep.maxpacket) {
17052+ len = ep->dwc_ep.maxpacket;
17053+ }
17054+ dwords = (len + 3)/4;
17055+
17056+ /* While there is space in the queue and space in the FIFO and
17057+ * More data to tranfer, Write packets to the Tx FIFO */
17058+ txstatus.d32 = dwc_read_reg32(&global_regs->gnptxsts);
17059+ DWC_DEBUGPL(DBG_PCDV, "b4 GNPTXSTS=0x%08x\n",txstatus.d32);
17060+
17061+ while (txstatus.b.nptxqspcavail > 0 &&
17062+ txstatus.b.nptxfspcavail > dwords &&
17063+ ep->dwc_ep.xfer_count < ep->dwc_ep.xfer_len) {
17064+ /* Write the FIFO */
17065+ dwc_otg_ep_write_packet(core_if, &ep->dwc_ep, 0);
17066+ len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
17067+
17068+ if (len > ep->dwc_ep.maxpacket) {
17069+ len = ep->dwc_ep.maxpacket;
17070+ }
17071+
17072+ dwords = (len + 3)/4;
17073+ txstatus.d32 = dwc_read_reg32(&global_regs->gnptxsts);
17074+ DWC_DEBUGPL(DBG_PCDV,"GNPTXSTS=0x%08x\n",txstatus.d32);
17075+ }
17076+
17077+ DWC_DEBUGPL(DBG_PCDV, "GNPTXSTS=0x%08x\n",
17078+ dwc_read_reg32(&global_regs->gnptxsts));
17079+
17080+ /* Clear interrupt */
17081+ gintsts.d32 = 0;
17082+ gintsts.b.nptxfempty = 1;
17083+ dwc_write_reg32 (&global_regs->gintsts, gintsts.d32);
17084+
17085+ return 1;
17086+}
17087+
17088+/**
17089+ * This function is called when dedicated Tx FIFO Empty interrupt occurs.
17090+ * The active request is checked for the next packet to be loaded into
17091+ * apropriate Tx FIFO.
17092+ */
17093+static int32_t write_empty_tx_fifo(dwc_otg_pcd_t *pcd, uint32_t epnum)
17094+{
17095+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
17096+ dwc_otg_dev_if_t* dev_if = core_if->dev_if;
17097+ dwc_otg_dev_in_ep_regs_t *ep_regs;
17098+ dtxfsts_data_t txstatus = {.d32 = 0};
17099+ dwc_otg_pcd_ep_t *ep = 0;
17100+ uint32_t len = 0;
17101+ int dwords;
17102+
17103+ ep = get_in_ep(pcd, epnum);
17104+
17105+ DWC_DEBUGPL(DBG_PCD, "Dedicated TxFifo Empty: %s(%d) \n", ep->ep.name, epnum);
17106+
17107+ ep_regs = core_if->dev_if->in_ep_regs[epnum];
17108+
17109+ len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
17110+
17111+ if (len > ep->dwc_ep.maxpacket) {
17112+ len = ep->dwc_ep.maxpacket;
17113+ }
17114+
17115+ dwords = (len + 3)/4;
17116+
17117+ /* While there is space in the queue and space in the FIFO and
17118+ * More data to tranfer, Write packets to the Tx FIFO */
17119+ txstatus.d32 = dwc_read_reg32(&dev_if->in_ep_regs[epnum]->dtxfsts);
17120+ DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n",epnum,txstatus.d32);
17121+
17122+ while (txstatus.b.txfspcavail > dwords &&
17123+ ep->dwc_ep.xfer_count < ep->dwc_ep.xfer_len &&
17124+ ep->dwc_ep.xfer_len != 0) {
17125+ /* Write the FIFO */
17126+ dwc_otg_ep_write_packet(core_if, &ep->dwc_ep, 0);
17127+
17128+ len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
17129+ if (len > ep->dwc_ep.maxpacket) {
17130+ len = ep->dwc_ep.maxpacket;
17131+ }
17132+
17133+ dwords = (len + 3)/4;
17134+ txstatus.d32 = dwc_read_reg32(&dev_if->in_ep_regs[epnum]->dtxfsts);
17135+ DWC_DEBUGPL(DBG_PCDV,"dtxfsts[%d]=0x%08x\n", epnum, txstatus.d32);
17136+ }
17137+
17138+ DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n",epnum,dwc_read_reg32(&dev_if->in_ep_regs[epnum]->dtxfsts));
17139+
17140+ return 1;
17141+}
17142+
17143+/**
17144+ * This function is called when the Device is disconnected. It stops
17145+ * any active requests and informs the Gadget driver of the
17146+ * disconnect.
17147+ */
17148+void dwc_otg_pcd_stop(dwc_otg_pcd_t *pcd)
17149+{
17150+ int i, num_in_eps, num_out_eps;
17151+ dwc_otg_pcd_ep_t *ep;
17152+
17153+ gintmsk_data_t intr_mask = {.d32 = 0};
17154+
17155+ num_in_eps = GET_CORE_IF(pcd)->dev_if->num_in_eps;
17156+ num_out_eps = GET_CORE_IF(pcd)->dev_if->num_out_eps;
17157+
17158+ DWC_DEBUGPL(DBG_PCDV, "%s() \n", __func__);
17159+ /* don't disconnect drivers more than once */
17160+ if (pcd->ep0state == EP0_DISCONNECT) {
17161+ DWC_DEBUGPL(DBG_ANY, "%s() Already Disconnected\n", __func__);
17162+ return;
17163+ }
17164+ pcd->ep0state = EP0_DISCONNECT;
17165+
17166+ /* Reset the OTG state. */
17167+ dwc_otg_pcd_update_otg(pcd, 1);
17168+
17169+ /* Disable the NP Tx Fifo Empty Interrupt. */
17170+ intr_mask.b.nptxfempty = 1;
17171+ dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
17172+ intr_mask.d32, 0);
17173+
17174+ /* Flush the FIFOs */
17175+ /**@todo NGS Flush Periodic FIFOs */
17176+ dwc_otg_flush_tx_fifo(GET_CORE_IF(pcd), 0x10);
17177+ dwc_otg_flush_rx_fifo(GET_CORE_IF(pcd));
17178+
17179+ /* prevent new request submissions, kill any outstanding requests */
17180+ ep = &pcd->ep0;
17181+ dwc_otg_request_nuke(ep);
17182+ /* prevent new request submissions, kill any outstanding requests */
17183+ for (i = 0; i < num_in_eps; i++)
17184+ {
17185+ dwc_otg_pcd_ep_t *ep = &pcd->in_ep[i];
17186+ dwc_otg_request_nuke(ep);
17187+ }
17188+ /* prevent new request submissions, kill any outstanding requests */
17189+ for (i = 0; i < num_out_eps; i++)
17190+ {
17191+ dwc_otg_pcd_ep_t *ep = &pcd->out_ep[i];
17192+ dwc_otg_request_nuke(ep);
17193+ }
17194+
17195+ /* report disconnect; the driver is already quiesced */
17196+ if (pcd->driver && pcd->driver->disconnect) {
17197+ SPIN_UNLOCK(&pcd->lock);
17198+ pcd->driver->disconnect(&pcd->gadget);
17199+ SPIN_LOCK(&pcd->lock);
17200+ }
17201+}
17202+
17203+/**
17204+ * This interrupt indicates that ...
17205+ */
17206+int32_t dwc_otg_pcd_handle_i2c_intr(dwc_otg_pcd_t *pcd)
17207+{
17208+ gintmsk_data_t intr_mask = { .d32 = 0};
17209+ gintsts_data_t gintsts;
17210+
17211+ DWC_PRINT("INTERRUPT Handler not implemented for %s\n", "i2cintr");
17212+ intr_mask.b.i2cintr = 1;
17213+ dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
17214+ intr_mask.d32, 0);
17215+
17216+ /* Clear interrupt */
17217+ gintsts.d32 = 0;
17218+ gintsts.b.i2cintr = 1;
17219+ dwc_write_reg32 (&GET_CORE_IF(pcd)->core_global_regs->gintsts,
17220+ gintsts.d32);
17221+ return 1;
17222+}
17223+
17224+
17225+/**
17226+ * This interrupt indicates that ...
17227+ */
17228+int32_t dwc_otg_pcd_handle_early_suspend_intr(dwc_otg_pcd_t *pcd)
17229+{
17230+ gintsts_data_t gintsts;
17231+#if defined(VERBOSE)
17232+ DWC_PRINT("Early Suspend Detected\n");
17233+#endif
17234+ /* Clear interrupt */
17235+ gintsts.d32 = 0;
17236+ gintsts.b.erlysuspend = 1;
17237+ dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
17238+ gintsts.d32);
17239+ return 1;
17240+}
17241+
17242+/**
17243+ * This function configures EPO to receive SETUP packets.
17244+ *
17245+ * @todo NGS: Update the comments from the HW FS.
17246+ *
17247+ * -# Program the following fields in the endpoint specific registers
17248+ * for Control OUT EP 0, in order to receive a setup packet
17249+ * - DOEPTSIZ0.Packet Count = 3 (To receive up to 3 back to back
17250+ * setup packets)
17251+ * - DOEPTSIZE0.Transfer Size = 24 Bytes (To receive up to 3 back
17252+ * to back setup packets)
17253+ * - In DMA mode, DOEPDMA0 Register with a memory address to
17254+ * store any setup packets received
17255+ *
17256+ * @param core_if Programming view of DWC_otg controller.
17257+ * @param pcd Programming view of the PCD.
17258+ */
17259+static inline void ep0_out_start(dwc_otg_core_if_t *core_if, dwc_otg_pcd_t *pcd)
17260+{
17261+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
17262+ deptsiz0_data_t doeptsize0 = { .d32 = 0};
17263+ dwc_otg_dma_desc_t* dma_desc;
17264+ depctl_data_t doepctl = { .d32 = 0 };
17265+
17266+#ifdef VERBOSE
17267+ DWC_DEBUGPL(DBG_PCDV,"%s() doepctl0=%0x\n", __func__,
17268+ dwc_read_reg32(&dev_if->out_ep_regs[0]->doepctl));
17269+#endif
17270+
17271+ doeptsize0.b.supcnt = 3;
17272+ doeptsize0.b.pktcnt = 1;
17273+ doeptsize0.b.xfersize = 8*3;
17274+
17275+ if (core_if->dma_enable) {
17276+ if (!core_if->dma_desc_enable) {
17277+ /** put here as for Hermes mode deptisz register should not be written */
17278+ dwc_write_reg32(&dev_if->out_ep_regs[0]->doeptsiz,
17279+ doeptsize0.d32);
17280+
17281+ /** @todo dma needs to handle multiple setup packets (up to 3) */
17282+ VERIFY_PCD_DMA_ADDR(pcd->setup_pkt_dma_handle);
17283+
17284+ dwc_write_reg32(&dev_if->out_ep_regs[0]->doepdma,
17285+ pcd->setup_pkt_dma_handle);
17286+ } else {
17287+ dev_if->setup_desc_index = (dev_if->setup_desc_index + 1) & 1;
17288+ dma_desc = dev_if->setup_desc_addr[dev_if->setup_desc_index];
17289+
17290+ /** DMA Descriptor Setup */
17291+ dma_desc->status.b.bs = BS_HOST_BUSY;
17292+ dma_desc->status.b.l = 1;
17293+ dma_desc->status.b.ioc = 1;
17294+ dma_desc->status.b.bytes = pcd->ep0.dwc_ep.maxpacket;
17295+ dma_desc->buf = pcd->setup_pkt_dma_handle;
17296+ dma_desc->status.b.bs = BS_HOST_READY;
17297+
17298+ /** DOEPDMA0 Register write */
17299+ VERIFY_PCD_DMA_ADDR(dev_if->dma_setup_desc_addr[dev_if->setup_desc_index]);
17300+ dwc_write_reg32(&dev_if->out_ep_regs[0]->doepdma, dev_if->dma_setup_desc_addr[dev_if->setup_desc_index]);
17301+ }
17302+
17303+ } else {
17304+ /** put here as for Hermes mode deptisz register should not be written */
17305+ dwc_write_reg32(&dev_if->out_ep_regs[0]->doeptsiz,
17306+ doeptsize0.d32);
17307+ }
17308+
17309+ /** DOEPCTL0 Register write */
17310+ doepctl.b.epena = 1;
17311+ doepctl.b.cnak = 1;
17312+ dwc_write_reg32(&dev_if->out_ep_regs[0]->doepctl, doepctl.d32);
17313+
17314+#ifdef VERBOSE
17315+ DWC_DEBUGPL(DBG_PCDV,"doepctl0=%0x\n",
17316+ dwc_read_reg32(&dev_if->out_ep_regs[0]->doepctl));
17317+ DWC_DEBUGPL(DBG_PCDV,"diepctl0=%0x\n",
17318+ dwc_read_reg32(&dev_if->in_ep_regs[0]->diepctl));
17319+#endif
17320+}
17321+
17322+/**
17323+ * This interrupt occurs when a USB Reset is detected. When the USB
17324+ * Reset Interrupt occurs the device state is set to DEFAULT and the
17325+ * EP0 state is set to IDLE.
17326+ * -# Set the NAK bit for all OUT endpoints (DOEPCTLn.SNAK = 1)
17327+ * -# Unmask the following interrupt bits
17328+ * - DAINTMSK.INEP0 = 1 (Control 0 IN endpoint)
17329+ * - DAINTMSK.OUTEP0 = 1 (Control 0 OUT endpoint)
17330+ * - DOEPMSK.SETUP = 1
17331+ * - DOEPMSK.XferCompl = 1
17332+ * - DIEPMSK.XferCompl = 1
17333+ * - DIEPMSK.TimeOut = 1
17334+ * -# Program the following fields in the endpoint specific registers
17335+ * for Control OUT EP 0, in order to receive a setup packet
17336+ * - DOEPTSIZ0.Packet Count = 3 (To receive up to 3 back to back
17337+ * setup packets)
17338+ * - DOEPTSIZE0.Transfer Size = 24 Bytes (To receive up to 3 back
17339+ * to back setup packets)
17340+ * - In DMA mode, DOEPDMA0 Register with a memory address to
17341+ * store any setup packets received
17342+ * At this point, all the required initialization, except for enabling
17343+ * the control 0 OUT endpoint is done, for receiving SETUP packets.
17344+ */
17345+int32_t dwc_otg_pcd_handle_usb_reset_intr(dwc_otg_pcd_t * pcd)
17346+{
17347+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
17348+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
17349+ depctl_data_t doepctl = { .d32 = 0};
17350+
17351+ daint_data_t daintmsk = { .d32 = 0};
17352+ doepmsk_data_t doepmsk = { .d32 = 0};
17353+ diepmsk_data_t diepmsk = { .d32 = 0};
17354+
17355+ dcfg_data_t dcfg = { .d32=0 };
17356+ grstctl_t resetctl = { .d32=0 };
17357+ dctl_data_t dctl = {.d32=0};
17358+ int i = 0;
17359+ gintsts_data_t gintsts;
17360+
17361+ DWC_PRINT("USB RESET\n");
17362+#ifdef DWC_EN_ISOC
17363+ for(i = 1;i < 16; ++i)
17364+ {
17365+ dwc_otg_pcd_ep_t *ep;
17366+ dwc_ep_t *dwc_ep;
17367+ ep = get_in_ep(pcd,i);
17368+ if(ep != 0){
17369+ dwc_ep = &ep->dwc_ep;
17370+ dwc_ep->next_frame = 0xffffffff;
17371+ }
17372+ }
17373+#endif /* DWC_EN_ISOC */
17374+
17375+ /* reset the HNP settings */
17376+ dwc_otg_pcd_update_otg(pcd, 1);
17377+
17378+ /* Clear the Remote Wakeup Signalling */
17379+ dctl.b.rmtwkupsig = 1;
17380+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->dctl,
17381+ dctl.d32, 0);
17382+
17383+ /* Set NAK for all OUT EPs */
17384+ doepctl.b.snak = 1;
17385+ for (i=0; i <= dev_if->num_out_eps; i++)
17386+ {
17387+ dwc_write_reg32(&dev_if->out_ep_regs[i]->doepctl,
17388+ doepctl.d32);
17389+ }
17390+
17391+ /* Flush the NP Tx FIFO */
17392+ dwc_otg_flush_tx_fifo(core_if, 0x10);
17393+ /* Flush the Learning Queue */
17394+ resetctl.b.intknqflsh = 1;
17395+ dwc_write_reg32(&core_if->core_global_regs->grstctl, resetctl.d32);
17396+
17397+ if(core_if->multiproc_int_enable) {
17398+ daintmsk.b.inep0 = 1;
17399+ daintmsk.b.outep0 = 1;
17400+ dwc_write_reg32(&dev_if->dev_global_regs->deachintmsk, daintmsk.d32);
17401+
17402+ doepmsk.b.setup = 1;
17403+ doepmsk.b.xfercompl = 1;
17404+ doepmsk.b.ahberr = 1;
17405+ doepmsk.b.epdisabled = 1;
17406+
17407+ if(core_if->dma_desc_enable) {
17408+ doepmsk.b.stsphsercvd = 1;
17409+ doepmsk.b.bna = 1;
17410+ }
17411+/*
17412+ doepmsk.b.babble = 1;
17413+ doepmsk.b.nyet = 1;
17414+
17415+ if(core_if->dma_enable) {
17416+ doepmsk.b.nak = 1;
17417+ }
17418+*/
17419+ dwc_write_reg32(&dev_if->dev_global_regs->doepeachintmsk[0], doepmsk.d32);
17420+
17421+ diepmsk.b.xfercompl = 1;
17422+ diepmsk.b.timeout = 1;
17423+ diepmsk.b.epdisabled = 1;
17424+ diepmsk.b.ahberr = 1;
17425+ diepmsk.b.intknepmis = 1;
17426+
17427+ if(core_if->dma_desc_enable) {
17428+ diepmsk.b.bna = 1;
17429+ }
17430+/*
17431+ if(core_if->dma_enable) {
17432+ diepmsk.b.nak = 1;
17433+ }
17434+*/
17435+ dwc_write_reg32(&dev_if->dev_global_regs->diepeachintmsk[0], diepmsk.d32);
17436+ } else{
17437+ daintmsk.b.inep0 = 1;
17438+ daintmsk.b.outep0 = 1;
17439+ dwc_write_reg32(&dev_if->dev_global_regs->daintmsk, daintmsk.d32);
17440+
17441+ doepmsk.b.setup = 1;
17442+ doepmsk.b.xfercompl = 1;
17443+ doepmsk.b.ahberr = 1;
17444+ doepmsk.b.epdisabled = 1;
17445+
17446+ if(core_if->dma_desc_enable) {
17447+ doepmsk.b.stsphsercvd = 1;
17448+ doepmsk.b.bna = 1;
17449+ }
17450+/*
17451+ doepmsk.b.babble = 1;
17452+ doepmsk.b.nyet = 1;
17453+ doepmsk.b.nak = 1;
17454+*/
17455+ dwc_write_reg32(&dev_if->dev_global_regs->doepmsk, doepmsk.d32);
17456+
17457+ diepmsk.b.xfercompl = 1;
17458+ diepmsk.b.timeout = 1;
17459+ diepmsk.b.epdisabled = 1;
17460+ diepmsk.b.ahberr = 1;
17461+ diepmsk.b.intknepmis = 1;
17462+
17463+ if(core_if->dma_desc_enable) {
17464+ diepmsk.b.bna = 1;
17465+ }
17466+
17467+// diepmsk.b.nak = 1;
17468+
17469+ dwc_write_reg32(&dev_if->dev_global_regs->diepmsk, diepmsk.d32);
17470+ }
17471+
17472+ /* Reset Device Address */
17473+ dcfg.d32 = dwc_read_reg32(&dev_if->dev_global_regs->dcfg);
17474+ dcfg.b.devaddr = 0;
17475+ dwc_write_reg32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
17476+
17477+ /* setup EP0 to receive SETUP packets */
17478+ ep0_out_start(core_if, pcd);
17479+
17480+ /* Clear interrupt */
17481+ gintsts.d32 = 0;
17482+ gintsts.b.usbreset = 1;
17483+ dwc_write_reg32 (&core_if->core_global_regs->gintsts, gintsts.d32);
17484+
17485+ return 1;
17486+}
17487+
17488+/**
17489+ * Get the device speed from the device status register and convert it
17490+ * to USB speed constant.
17491+ *
17492+ * @param core_if Programming view of DWC_otg controller.
17493+ */
17494+static int get_device_speed(dwc_otg_core_if_t *core_if)
17495+{
17496+ dsts_data_t dsts;
17497+ enum usb_device_speed speed = USB_SPEED_UNKNOWN;
17498+ dsts.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts);
17499+
17500+ switch (dsts.b.enumspd) {
17501+ case DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
17502+ speed = USB_SPEED_HIGH;
17503+ break;
17504+ case DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
17505+ case DWC_DSTS_ENUMSPD_FS_PHY_48MHZ:
17506+ speed = USB_SPEED_FULL;
17507+ break;
17508+
17509+ case DWC_DSTS_ENUMSPD_LS_PHY_6MHZ:
17510+ speed = USB_SPEED_LOW;
17511+ break;
17512+ }
17513+
17514+ return speed;
17515+}
17516+
17517+/**
17518+ * Read the device status register and set the device speed in the
17519+ * data structure.
17520+ * Set up EP0 to receive SETUP packets by calling dwc_ep0_activate.
17521+ */
17522+int32_t dwc_otg_pcd_handle_enum_done_intr(dwc_otg_pcd_t *pcd)
17523+{
17524+ dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
17525+ gintsts_data_t gintsts;
17526+ gusbcfg_data_t gusbcfg;
17527+ dwc_otg_core_global_regs_t *global_regs =
17528+ GET_CORE_IF(pcd)->core_global_regs;
17529+ uint8_t utmi16b, utmi8b;
17530+// DWC_DEBUGPL(DBG_PCD, "SPEED ENUM\n");
17531+ DWC_PRINT("SPEED ENUM\n");
17532+
17533+ if (GET_CORE_IF(pcd)->snpsid >= 0x4F54260A) {
17534+ utmi16b = 6;
17535+ utmi8b = 9;
17536+ } else {
17537+ utmi16b = 4;
17538+ utmi8b = 8;
17539+ }
17540+ dwc_otg_ep0_activate(GET_CORE_IF(pcd), &ep0->dwc_ep);
17541+
17542+#ifdef DEBUG_EP0
17543+ print_ep0_state(pcd);
17544+#endif
17545+
17546+ if (pcd->ep0state == EP0_DISCONNECT) {
17547+ pcd->ep0state = EP0_IDLE;
17548+ }
17549+ else if (pcd->ep0state == EP0_STALL) {
17550+ pcd->ep0state = EP0_IDLE;
17551+ }
17552+
17553+ pcd->ep0state = EP0_IDLE;
17554+
17555+ ep0->stopped = 0;
17556+
17557+ pcd->gadget.speed = get_device_speed(GET_CORE_IF(pcd));
17558+
17559+ /* Set USB turnaround time based on device speed and PHY interface. */
17560+ gusbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
17561+ if (pcd->gadget.speed == USB_SPEED_HIGH) {
17562+ if (GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type == DWC_HWCFG2_HS_PHY_TYPE_ULPI) {
17563+ /* ULPI interface */
17564+ gusbcfg.b.usbtrdtim = 9;
17565+ }
17566+ if (GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type == DWC_HWCFG2_HS_PHY_TYPE_UTMI) {
17567+ /* UTMI+ interface */
17568+ if (GET_CORE_IF(pcd)->hwcfg4.b.utmi_phy_data_width == 0) {
17569+ gusbcfg.b.usbtrdtim = utmi8b;
17570+ }
17571+ else if (GET_CORE_IF(pcd)->hwcfg4.b.utmi_phy_data_width == 1) {
17572+ gusbcfg.b.usbtrdtim = utmi16b;
17573+ }
17574+ else if (GET_CORE_IF(pcd)->core_params->phy_utmi_width == 8) {
17575+ gusbcfg.b.usbtrdtim = utmi8b;
17576+ }
17577+ else {
17578+ gusbcfg.b.usbtrdtim = utmi16b;
17579+ }
17580+ }
17581+ if (GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type == DWC_HWCFG2_HS_PHY_TYPE_UTMI_ULPI) {
17582+ /* UTMI+ OR ULPI interface */
17583+ if (gusbcfg.b.ulpi_utmi_sel == 1) {
17584+ /* ULPI interface */
17585+ gusbcfg.b.usbtrdtim = 9;
17586+ }
17587+ else {
17588+ /* UTMI+ interface */
17589+ if (GET_CORE_IF(pcd)->core_params->phy_utmi_width == 16) {
17590+ gusbcfg.b.usbtrdtim = utmi16b;
17591+ }
17592+ else {
17593+ gusbcfg.b.usbtrdtim = utmi8b;
17594+ }
17595+ }
17596+ }
17597+ }
17598+ else {
17599+ /* Full or low speed */
17600+ gusbcfg.b.usbtrdtim = 9;
17601+ }
17602+ dwc_write_reg32(&global_regs->gusbcfg, gusbcfg.d32);
17603+
17604+ /* Clear interrupt */
17605+ gintsts.d32 = 0;
17606+ gintsts.b.enumdone = 1;
17607+ dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
17608+ gintsts.d32);
17609+ return 1;
17610+}
17611+
17612+/**
17613+ * This interrupt indicates that the ISO OUT Packet was dropped due to
17614+ * Rx FIFO full or Rx Status Queue Full. If this interrupt occurs
17615+ * read all the data from the Rx FIFO.
17616+ */
17617+int32_t dwc_otg_pcd_handle_isoc_out_packet_dropped_intr(dwc_otg_pcd_t *pcd)
17618+{
17619+ gintmsk_data_t intr_mask = { .d32 = 0};
17620+ gintsts_data_t gintsts;
17621+
17622+ DWC_PRINT("INTERRUPT Handler not implemented for %s\n",
17623+ "ISOC Out Dropped");
17624+
17625+ intr_mask.b.isooutdrop = 1;
17626+ dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
17627+ intr_mask.d32, 0);
17628+
17629+ /* Clear interrupt */
17630+
17631+ gintsts.d32 = 0;
17632+ gintsts.b.isooutdrop = 1;
17633+ dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
17634+ gintsts.d32);
17635+
17636+ return 1;
17637+}
17638+
17639+/**
17640+ * This interrupt indicates the end of the portion of the micro-frame
17641+ * for periodic transactions. If there is a periodic transaction for
17642+ * the next frame, load the packets into the EP periodic Tx FIFO.
17643+ */
17644+int32_t dwc_otg_pcd_handle_end_periodic_frame_intr(dwc_otg_pcd_t *pcd)
17645+{
17646+ gintmsk_data_t intr_mask = { .d32 = 0};
17647+ gintsts_data_t gintsts;
17648+ DWC_PRINT("INTERRUPT Handler not implemented for %s\n", "EOP");
17649+
17650+ intr_mask.b.eopframe = 1;
17651+ dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
17652+ intr_mask.d32, 0);
17653+
17654+ /* Clear interrupt */
17655+ gintsts.d32 = 0;
17656+ gintsts.b.eopframe = 1;
17657+ dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts, gintsts.d32);
17658+
17659+ return 1;
17660+}
17661+
17662+/**
17663+ * This interrupt indicates that EP of the packet on the top of the
17664+ * non-periodic Tx FIFO does not match EP of the IN Token received.
17665+ *
17666+ * The "Device IN Token Queue" Registers are read to determine the
17667+ * order the IN Tokens have been received. The non-periodic Tx FIFO
17668+ * is flushed, so it can be reloaded in the order seen in the IN Token
17669+ * Queue.
17670+ */
17671+int32_t dwc_otg_pcd_handle_ep_mismatch_intr(dwc_otg_core_if_t *core_if)
17672+{
17673+ gintsts_data_t gintsts;
17674+ DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, core_if);
17675+
17676+ /* Clear interrupt */
17677+ gintsts.d32 = 0;
17678+ gintsts.b.epmismatch = 1;
17679+ dwc_write_reg32 (&core_if->core_global_regs->gintsts, gintsts.d32);
17680+
17681+ return 1;
17682+}
17683+
17684+/**
17685+ * This funcion stalls EP0.
17686+ */
17687+static inline void ep0_do_stall(dwc_otg_pcd_t *pcd, const int err_val)
17688+{
17689+ dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
17690+ struct usb_ctrlrequest *ctrl = &pcd->setup_pkt->req;
17691+ DWC_WARN("req %02x.%02x protocol STALL; err %d\n",
17692+ ctrl->bRequestType, ctrl->bRequest, err_val);
17693+
17694+ ep0->dwc_ep.is_in = 1;
17695+ dwc_otg_ep_set_stall(pcd->otg_dev->core_if, &ep0->dwc_ep);
17696+ pcd->ep0.stopped = 1;
17697+ pcd->ep0state = EP0_IDLE;
17698+ ep0_out_start(GET_CORE_IF(pcd), pcd);
17699+}
17700+
17701+/**
17702+ * This functions delegates the setup command to the gadget driver.
17703+ */
17704+static inline void do_gadget_setup(dwc_otg_pcd_t *pcd,
17705+ struct usb_ctrlrequest * ctrl)
17706+{
17707+ int ret = 0;
17708+ if (pcd->driver && pcd->driver->setup) {
17709+ SPIN_UNLOCK(&pcd->lock);
17710+ ret = pcd->driver->setup(&pcd->gadget, ctrl);
17711+ SPIN_LOCK(&pcd->lock);
17712+ if (ret < 0) {
17713+ ep0_do_stall(pcd, ret);
17714+ }
17715+
17716+ /** @todo This is a g_file_storage gadget driver specific
17717+ * workaround: a DELAYED_STATUS result from the fsg_setup
17718+ * routine will result in the gadget queueing a EP0 IN status
17719+ * phase for a two-stage control transfer. Exactly the same as
17720+ * a SET_CONFIGURATION/SET_INTERFACE except that this is a class
17721+ * specific request. Need a generic way to know when the gadget
17722+ * driver will queue the status phase. Can we assume when we
17723+ * call the gadget driver setup() function that it will always
17724+ * queue and require the following flag? Need to look into
17725+ * this.
17726+ */
17727+
17728+ if (ret == 256 + 999) {
17729+ pcd->request_config = 1;
17730+ }
17731+ }
17732+}
17733+
17734+/**
17735+ * This function starts the Zero-Length Packet for the IN status phase
17736+ * of a 2 stage control transfer.
17737+ */
17738+static inline void do_setup_in_status_phase(dwc_otg_pcd_t *pcd)
17739+{
17740+ dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
17741+ if (pcd->ep0state == EP0_STALL) {
17742+ return;
17743+ }
17744+
17745+ pcd->ep0state = EP0_IN_STATUS_PHASE;
17746+
17747+ /* Prepare for more SETUP Packets */
17748+ DWC_DEBUGPL(DBG_PCD, "EP0 IN ZLP\n");
17749+ ep0->dwc_ep.xfer_len = 0;
17750+ ep0->dwc_ep.xfer_count = 0;
17751+ ep0->dwc_ep.is_in = 1;
17752+ ep0->dwc_ep.dma_addr = pcd->setup_pkt_dma_handle;
17753+ dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
17754+
17755+ /* Prepare for more SETUP Packets */
17756+// if(GET_CORE_IF(pcd)->dma_enable == 0) ep0_out_start(GET_CORE_IF(pcd), pcd);
17757+}
17758+
17759+/**
17760+ * This function starts the Zero-Length Packet for the OUT status phase
17761+ * of a 2 stage control transfer.
17762+ */
17763+static inline void do_setup_out_status_phase(dwc_otg_pcd_t *pcd)
17764+{
17765+ dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
17766+ if (pcd->ep0state == EP0_STALL) {
17767+ DWC_DEBUGPL(DBG_PCD, "EP0 STALLED\n");
17768+ return;
17769+ }
17770+ pcd->ep0state = EP0_OUT_STATUS_PHASE;
17771+
17772+ DWC_DEBUGPL(DBG_PCD, "EP0 OUT ZLP\n");
17773+ ep0->dwc_ep.xfer_len = 0;
17774+ ep0->dwc_ep.xfer_count = 0;
17775+ ep0->dwc_ep.is_in = 0;
17776+ ep0->dwc_ep.dma_addr = pcd->setup_pkt_dma_handle;
17777+ dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
17778+
17779+ /* Prepare for more SETUP Packets */
17780+ if(GET_CORE_IF(pcd)->dma_enable == 0) {
17781+ ep0_out_start(GET_CORE_IF(pcd), pcd);
17782+ }
17783+}
17784+
17785+/**
17786+ * Clear the EP halt (STALL) and if pending requests start the
17787+ * transfer.
17788+ */
17789+static inline void pcd_clear_halt(dwc_otg_pcd_t *pcd, dwc_otg_pcd_ep_t *ep)
17790+{
17791+ if(ep->dwc_ep.stall_clear_flag == 0)
17792+ dwc_otg_ep_clear_stall(GET_CORE_IF(pcd), &ep->dwc_ep);
17793+
17794+ /* Reactive the EP */
17795+ dwc_otg_ep_activate(GET_CORE_IF(pcd), &ep->dwc_ep);
17796+ if (ep->stopped) {
17797+ ep->stopped = 0;
17798+ /* If there is a request in the EP queue start it */
17799+
17800+ /** @todo FIXME: this causes an EP mismatch in DMA mode.
17801+ * epmismatch not yet implemented. */
17802+
17803+ /*
17804+ * Above fixme is solved by implmenting a tasklet to call the
17805+ * start_next_request(), outside of interrupt context at some
17806+ * time after the current time, after a clear-halt setup packet.
17807+ * Still need to implement ep mismatch in the future if a gadget
17808+ * ever uses more than one endpoint at once
17809+ */
17810+ ep->queue_sof = 1;
17811+ tasklet_schedule (pcd->start_xfer_tasklet);
17812+ }
17813+ /* Start Control Status Phase */
17814+ do_setup_in_status_phase(pcd);
17815+}
17816+
17817+/**
17818+ * This function is called when the SET_FEATURE TEST_MODE Setup packet
17819+ * is sent from the host. The Device Control register is written with
17820+ * the Test Mode bits set to the specified Test Mode. This is done as
17821+ * a tasklet so that the "Status" phase of the control transfer
17822+ * completes before transmitting the TEST packets.
17823+ *
17824+ * @todo This has not been tested since the tasklet struct was put
17825+ * into the PCD struct!
17826+ *
17827+ */
17828+static void do_test_mode(unsigned long data)
17829+{
17830+ dctl_data_t dctl;
17831+ dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *)data;
17832+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
17833+ int test_mode = pcd->test_mode;
17834+
17835+
17836+// DWC_WARN("%s() has not been tested since being rewritten!\n", __func__);
17837+
17838+ dctl.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dctl);
17839+ switch (test_mode) {
17840+ case 1: // TEST_J
17841+ dctl.b.tstctl = 1;
17842+ break;
17843+
17844+ case 2: // TEST_K
17845+ dctl.b.tstctl = 2;
17846+ break;
17847+
17848+ case 3: // TEST_SE0_NAK
17849+ dctl.b.tstctl = 3;
17850+ break;
17851+
17852+ case 4: // TEST_PACKET
17853+ dctl.b.tstctl = 4;
17854+ break;
17855+
17856+ case 5: // TEST_FORCE_ENABLE
17857+ dctl.b.tstctl = 5;
17858+ break;
17859+ }
17860+ dwc_write_reg32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32);
17861+}
17862+
17863+/**
17864+ * This function process the GET_STATUS Setup Commands.
17865+ */
17866+static inline void do_get_status(dwc_otg_pcd_t *pcd)
17867+{
17868+ struct usb_ctrlrequest ctrl = pcd->setup_pkt->req;
17869+ dwc_otg_pcd_ep_t *ep;
17870+ dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
17871+ uint16_t *status = pcd->status_buf;
17872+
17873+#ifdef DEBUG_EP0
17874+ DWC_DEBUGPL(DBG_PCD,
17875+ "GET_STATUS %02x.%02x v%04x i%04x l%04x\n",
17876+ ctrl.bRequestType, ctrl.bRequest,
17877+ ctrl.wValue, ctrl.wIndex, ctrl.wLength);
17878+#endif
17879+
17880+ switch (ctrl.bRequestType & USB_RECIP_MASK) {
17881+ case USB_RECIP_DEVICE:
17882+ *status = 0x1; /* Self powered */
17883+ *status |= pcd->remote_wakeup_enable << 1;
17884+ break;
17885+
17886+ case USB_RECIP_INTERFACE:
17887+ *status = 0;
17888+ break;
17889+
17890+ case USB_RECIP_ENDPOINT:
17891+ ep = get_ep_by_addr(pcd, ctrl.wIndex);
17892+ if (ep == 0 || ctrl.wLength > 2) {
17893+ ep0_do_stall(pcd, -EOPNOTSUPP);
17894+ return;
17895+ }
17896+ /** @todo check for EP stall */
17897+ *status = ep->stopped;
17898+ break;
17899+ }
17900+ pcd->ep0_pending = 1;
17901+ ep0->dwc_ep.start_xfer_buff = (uint8_t *)status;
17902+ ep0->dwc_ep.xfer_buff = (uint8_t *)status;
17903+ ep0->dwc_ep.dma_addr = pcd->status_buf_dma_handle;
17904+ ep0->dwc_ep.xfer_len = 2;
17905+ ep0->dwc_ep.xfer_count = 0;
17906+ ep0->dwc_ep.total_len = ep0->dwc_ep.xfer_len;
17907+ dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
17908+}
17909+/**
17910+ * This function process the SET_FEATURE Setup Commands.
17911+ */
17912+static inline void do_set_feature(dwc_otg_pcd_t *pcd)
17913+{
17914+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
17915+ dwc_otg_core_global_regs_t *global_regs =
17916+ core_if->core_global_regs;
17917+ struct usb_ctrlrequest ctrl = pcd->setup_pkt->req;
17918+ dwc_otg_pcd_ep_t *ep = 0;
17919+ int32_t otg_cap_param = core_if->core_params->otg_cap;
17920+ gotgctl_data_t gotgctl = { .d32 = 0 };
17921+
17922+ DWC_DEBUGPL(DBG_PCD, "SET_FEATURE:%02x.%02x v%04x i%04x l%04x\n",
17923+ ctrl.bRequestType, ctrl.bRequest,
17924+ ctrl.wValue, ctrl.wIndex, ctrl.wLength);
17925+ DWC_DEBUGPL(DBG_PCD,"otg_cap=%d\n", otg_cap_param);
17926+
17927+
17928+ switch (ctrl.bRequestType & USB_RECIP_MASK) {
17929+ case USB_RECIP_DEVICE:
17930+ switch (ctrl.wValue) {
17931+ case USB_DEVICE_REMOTE_WAKEUP:
17932+ pcd->remote_wakeup_enable = 1;
17933+ break;
17934+
17935+ case USB_DEVICE_TEST_MODE:
17936+ /* Setup the Test Mode tasklet to do the Test
17937+ * Packet generation after the SETUP Status
17938+ * phase has completed. */
17939+
17940+ /** @todo This has not been tested since the
17941+ * tasklet struct was put into the PCD
17942+ * struct! */
17943+ pcd->test_mode_tasklet.next = 0;
17944+ pcd->test_mode_tasklet.state = 0;
17945+ atomic_set(&pcd->test_mode_tasklet.count, 0);
17946+ pcd->test_mode_tasklet.func = do_test_mode;
17947+ pcd->test_mode_tasklet.data = (unsigned long)pcd;
17948+ pcd->test_mode = ctrl.wIndex >> 8;
17949+ tasklet_schedule(&pcd->test_mode_tasklet);
17950+ break;
17951+
17952+ case USB_DEVICE_B_HNP_ENABLE:
17953+ DWC_DEBUGPL(DBG_PCDV, "SET_FEATURE: USB_DEVICE_B_HNP_ENABLE\n");
17954+
17955+ /* dev may initiate HNP */
17956+ if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) {
17957+ pcd->b_hnp_enable = 1;
17958+ dwc_otg_pcd_update_otg(pcd, 0);
17959+ DWC_DEBUGPL(DBG_PCD, "Request B HNP\n");
17960+ /**@todo Is the gotgctl.devhnpen cleared
17961+ * by a USB Reset? */
17962+ gotgctl.b.devhnpen = 1;
17963+ gotgctl.b.hnpreq = 1;
17964+ dwc_write_reg32(&global_regs->gotgctl, gotgctl.d32);
17965+ }
17966+ else {
17967+ ep0_do_stall(pcd, -EOPNOTSUPP);
17968+ }
17969+ break;
17970+
17971+ case USB_DEVICE_A_HNP_SUPPORT:
17972+ /* RH port supports HNP */
17973+ DWC_DEBUGPL(DBG_PCDV, "SET_FEATURE: USB_DEVICE_A_HNP_SUPPORT\n");
17974+ if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) {
17975+ pcd->a_hnp_support = 1;
17976+ dwc_otg_pcd_update_otg(pcd, 0);
17977+ }
17978+ else {
17979+ ep0_do_stall(pcd, -EOPNOTSUPP);
17980+ }
17981+ break;
17982+
17983+ case USB_DEVICE_A_ALT_HNP_SUPPORT:
17984+ /* other RH port does */
17985+ DWC_DEBUGPL(DBG_PCDV, "SET_FEATURE: USB_DEVICE_A_ALT_HNP_SUPPORT\n");
17986+ if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) {
17987+ pcd->a_alt_hnp_support = 1;
17988+ dwc_otg_pcd_update_otg(pcd, 0);
17989+ }
17990+ else {
17991+ ep0_do_stall(pcd, -EOPNOTSUPP);
17992+ }
17993+ break;
17994+ }
17995+ do_setup_in_status_phase(pcd);
17996+ break;
17997+
17998+ case USB_RECIP_INTERFACE:
17999+ do_gadget_setup(pcd, &ctrl);
18000+ break;
18001+
18002+ case USB_RECIP_ENDPOINT:
18003+ if (ctrl.wValue == USB_ENDPOINT_HALT) {
18004+ ep = get_ep_by_addr(pcd, ctrl.wIndex);
18005+ if (ep == 0) {
18006+ ep0_do_stall(pcd, -EOPNOTSUPP);
18007+ return;
18008+ }
18009+ ep->stopped = 1;
18010+ dwc_otg_ep_set_stall(core_if, &ep->dwc_ep);
18011+ }
18012+ do_setup_in_status_phase(pcd);
18013+ break;
18014+ }
18015+}
18016+
18017+/**
18018+ * This function process the CLEAR_FEATURE Setup Commands.
18019+ */
18020+static inline void do_clear_feature(dwc_otg_pcd_t *pcd)
18021+{
18022+ struct usb_ctrlrequest ctrl = pcd->setup_pkt->req;
18023+ dwc_otg_pcd_ep_t *ep = 0;
18024+
18025+ DWC_DEBUGPL(DBG_PCD,
18026+ "CLEAR_FEATURE:%02x.%02x v%04x i%04x l%04x\n",
18027+ ctrl.bRequestType, ctrl.bRequest,
18028+ ctrl.wValue, ctrl.wIndex, ctrl.wLength);
18029+
18030+ switch (ctrl.bRequestType & USB_RECIP_MASK) {
18031+ case USB_RECIP_DEVICE:
18032+ switch (ctrl.wValue) {
18033+ case USB_DEVICE_REMOTE_WAKEUP:
18034+ pcd->remote_wakeup_enable = 0;
18035+ break;
18036+
18037+ case USB_DEVICE_TEST_MODE:
18038+ /** @todo Add CLEAR_FEATURE for TEST modes. */
18039+ break;
18040+ }
18041+ do_setup_in_status_phase(pcd);
18042+ break;
18043+
18044+ case USB_RECIP_ENDPOINT:
18045+ ep = get_ep_by_addr(pcd, ctrl.wIndex);
18046+ if (ep == 0) {
18047+ ep0_do_stall(pcd, -EOPNOTSUPP);
18048+ return;
18049+ }
18050+
18051+ pcd_clear_halt(pcd, ep);
18052+
18053+ break;
18054+ }
18055+}
18056+
18057+/**
18058+ * This function process the SET_ADDRESS Setup Commands.
18059+ */
18060+static inline void do_set_address(dwc_otg_pcd_t *pcd)
18061+{
18062+ dwc_otg_dev_if_t *dev_if = GET_CORE_IF(pcd)->dev_if;
18063+ struct usb_ctrlrequest ctrl = pcd->setup_pkt->req;
18064+
18065+ if (ctrl.bRequestType == USB_RECIP_DEVICE) {
18066+ dcfg_data_t dcfg = {.d32=0};
18067+
18068+#ifdef DEBUG_EP0
18069+// DWC_DEBUGPL(DBG_PCDV, "SET_ADDRESS:%d\n", ctrl.wValue);
18070+#endif
18071+ dcfg.b.devaddr = ctrl.wValue;
18072+ dwc_modify_reg32(&dev_if->dev_global_regs->dcfg, 0, dcfg.d32);
18073+ do_setup_in_status_phase(pcd);
18074+ }
18075+}
18076+
18077+/**
18078+ * This function processes SETUP commands. In Linux, the USB Command
18079+ * processing is done in two places - the first being the PCD and the
18080+ * second in the Gadget Driver (for example, the File-Backed Storage
18081+ * Gadget Driver).
18082+ *
18083+ * <table>
18084+ * <tr><td>Command </td><td>Driver </td><td>Description</td></tr>
18085+ *
18086+ * <tr><td>GET_STATUS </td><td>PCD </td><td>Command is processed as
18087+ * defined in chapter 9 of the USB 2.0 Specification chapter 9
18088+ * </td></tr>
18089+ *
18090+ * <tr><td>CLEAR_FEATURE </td><td>PCD </td><td>The Device and Endpoint
18091+ * requests are the ENDPOINT_HALT feature is procesed, all others the
18092+ * interface requests are ignored.</td></tr>
18093+ *
18094+ * <tr><td>SET_FEATURE </td><td>PCD </td><td>The Device and Endpoint
18095+ * requests are processed by the PCD. Interface requests are passed
18096+ * to the Gadget Driver.</td></tr>
18097+ *
18098+ * <tr><td>SET_ADDRESS </td><td>PCD </td><td>Program the DCFG reg,
18099+ * with device address received </td></tr>
18100+ *
18101+ * <tr><td>GET_DESCRIPTOR </td><td>Gadget Driver </td><td>Return the
18102+ * requested descriptor</td></tr>
18103+ *
18104+ * <tr><td>SET_DESCRIPTOR </td><td>Gadget Driver </td><td>Optional -
18105+ * not implemented by any of the existing Gadget Drivers.</td></tr>
18106+ *
18107+ * <tr><td>SET_CONFIGURATION </td><td>Gadget Driver </td><td>Disable
18108+ * all EPs and enable EPs for new configuration.</td></tr>
18109+ *
18110+ * <tr><td>GET_CONFIGURATION </td><td>Gadget Driver </td><td>Return
18111+ * the current configuration</td></tr>
18112+ *
18113+ * <tr><td>SET_INTERFACE </td><td>Gadget Driver </td><td>Disable all
18114+ * EPs and enable EPs for new configuration.</td></tr>
18115+ *
18116+ * <tr><td>GET_INTERFACE </td><td>Gadget Driver </td><td>Return the
18117+ * current interface.</td></tr>
18118+ *
18119+ * <tr><td>SYNC_FRAME </td><td>PCD </td><td>Display debug
18120+ * message.</td></tr>
18121+ * </table>
18122+ *
18123+ * When the SETUP Phase Done interrupt occurs, the PCD SETUP commands are
18124+ * processed by pcd_setup. Calling the Function Driver's setup function from
18125+ * pcd_setup processes the gadget SETUP commands.
18126+ */
18127+static inline void pcd_setup(dwc_otg_pcd_t *pcd)
18128+{
18129+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
18130+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
18131+ struct usb_ctrlrequest ctrl = pcd->setup_pkt->req;
18132+ dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
18133+
18134+ deptsiz0_data_t doeptsize0 = { .d32 = 0};
18135+
18136+#ifdef DEBUG_EP0
18137+ DWC_DEBUGPL(DBG_PCD, "SETUP %02x.%02x v%04x i%04x l%04x\n",
18138+ ctrl.bRequestType, ctrl.bRequest,
18139+ ctrl.wValue, ctrl.wIndex, ctrl.wLength);
18140+#endif
18141+
18142+ doeptsize0.d32 = dwc_read_reg32(&dev_if->out_ep_regs[0]->doeptsiz);
18143+
18144+ /** @todo handle > 1 setup packet , assert error for now */
18145+
18146+ if (core_if->dma_enable && core_if->dma_desc_enable == 0 && (doeptsize0.b.supcnt < 2)) {
18147+ DWC_ERROR ("\n\n----------- CANNOT handle > 1 setup packet in DMA mode\n\n");
18148+ }
18149+
18150+ /* Clean up the request queue */
18151+ dwc_otg_request_nuke(ep0);
18152+ ep0->stopped = 0;
18153+
18154+ if (ctrl.bRequestType & USB_DIR_IN) {
18155+ ep0->dwc_ep.is_in = 1;
18156+ pcd->ep0state = EP0_IN_DATA_PHASE;
18157+ }
18158+ else {
18159+ ep0->dwc_ep.is_in = 0;
18160+ pcd->ep0state = EP0_OUT_DATA_PHASE;
18161+ }
18162+
18163+ if(ctrl.wLength == 0) {
18164+ ep0->dwc_ep.is_in = 1;
18165+ pcd->ep0state = EP0_IN_STATUS_PHASE;
18166+ }
18167+
18168+ if ((ctrl.bRequestType & USB_TYPE_MASK) != USB_TYPE_STANDARD) {
18169+ /* handle non-standard (class/vendor) requests in the gadget driver */
18170+ do_gadget_setup(pcd, &ctrl);
18171+ return;
18172+ }
18173+
18174+ /** @todo NGS: Handle bad setup packet? */
18175+
18176+///////////////////////////////////////////
18177+//// --- Standard Request handling --- ////
18178+
18179+ switch (ctrl.bRequest) {
18180+ case USB_REQ_GET_STATUS:
18181+ do_get_status(pcd);
18182+ break;
18183+
18184+ case USB_REQ_CLEAR_FEATURE:
18185+ do_clear_feature(pcd);
18186+ break;
18187+
18188+ case USB_REQ_SET_FEATURE:
18189+ do_set_feature(pcd);
18190+ break;
18191+
18192+ case USB_REQ_SET_ADDRESS:
18193+ do_set_address(pcd);
18194+ break;
18195+
18196+ case USB_REQ_SET_INTERFACE:
18197+ case USB_REQ_SET_CONFIGURATION:
18198+// _pcd->request_config = 1; /* Configuration changed */
18199+ do_gadget_setup(pcd, &ctrl);
18200+ break;
18201+
18202+ case USB_REQ_SYNCH_FRAME:
18203+ do_gadget_setup(pcd, &ctrl);
18204+ break;
18205+
18206+ default:
18207+ /* Call the Gadget Driver's setup functions */
18208+ do_gadget_setup(pcd, &ctrl);
18209+ break;
18210+ }
18211+}
18212+
18213+/**
18214+ * This function completes the ep0 control transfer.
18215+ */
18216+static int32_t ep0_complete_request(dwc_otg_pcd_ep_t *ep)
18217+{
18218+ dwc_otg_core_if_t *core_if = GET_CORE_IF(ep->pcd);
18219+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
18220+ dwc_otg_dev_in_ep_regs_t *in_ep_regs =
18221+ dev_if->in_ep_regs[ep->dwc_ep.num];
18222+#ifdef DEBUG_EP0
18223+ dwc_otg_dev_out_ep_regs_t *out_ep_regs =
18224+ dev_if->out_ep_regs[ep->dwc_ep.num];
18225+#endif
18226+ deptsiz0_data_t deptsiz;
18227+ desc_sts_data_t desc_sts;
18228+ dwc_otg_pcd_request_t *req;
18229+ int is_last = 0;
18230+ dwc_otg_pcd_t *pcd = ep->pcd;
18231+
18232+ //DWC_DEBUGPL(DBG_PCDV, "%s() %s\n", __func__, _ep->ep.name);
18233+
18234+ if (pcd->ep0_pending && list_empty(&ep->queue)) {
18235+ if (ep->dwc_ep.is_in) {
18236+#ifdef DEBUG_EP0
18237+ DWC_DEBUGPL(DBG_PCDV, "Do setup OUT status phase\n");
18238+#endif
18239+ do_setup_out_status_phase(pcd);
18240+ }
18241+ else {
18242+#ifdef DEBUG_EP0
18243+ DWC_DEBUGPL(DBG_PCDV, "Do setup IN status phase\n");
18244+#endif
18245+ do_setup_in_status_phase(pcd);
18246+ }
18247+ pcd->ep0_pending = 0;
18248+ return 1;
18249+ }
18250+
18251+ if (list_empty(&ep->queue)) {
18252+ return 0;
18253+ }
18254+ req = list_entry(ep->queue.next, dwc_otg_pcd_request_t, queue);
18255+
18256+
18257+ if (pcd->ep0state == EP0_OUT_STATUS_PHASE || pcd->ep0state == EP0_IN_STATUS_PHASE) {
18258+ is_last = 1;
18259+ }
18260+ else if (ep->dwc_ep.is_in) {
18261+ deptsiz.d32 = dwc_read_reg32(&in_ep_regs->dieptsiz);
18262+ if(core_if->dma_desc_enable != 0)
18263+ desc_sts.d32 = readl(dev_if->in_desc_addr);
18264+#ifdef DEBUG_EP0
18265+ DWC_DEBUGPL(DBG_PCDV, "%s len=%d xfersize=%d pktcnt=%d\n",
18266+ ep->ep.name, ep->dwc_ep.xfer_len,
18267+ deptsiz.b.xfersize, deptsiz.b.pktcnt);
18268+#endif
18269+
18270+ if (((core_if->dma_desc_enable == 0) && (deptsiz.b.xfersize == 0)) ||
18271+ ((core_if->dma_desc_enable != 0) && (desc_sts.b.bytes == 0))) {
18272+ req->req.actual = ep->dwc_ep.xfer_count;
18273+ /* Is a Zero Len Packet needed? */
18274+ if (req->req.zero) {
18275+#ifdef DEBUG_EP0
18276+ DWC_DEBUGPL(DBG_PCD, "Setup Rx ZLP\n");
18277+#endif
18278+ req->req.zero = 0;
18279+ }
18280+ do_setup_out_status_phase(pcd);
18281+ }
18282+ }
18283+ else {
18284+ /* ep0-OUT */
18285+#ifdef DEBUG_EP0
18286+ deptsiz.d32 = dwc_read_reg32(&out_ep_regs->doeptsiz);
18287+ DWC_DEBUGPL(DBG_PCDV, "%s len=%d xsize=%d pktcnt=%d\n",
18288+ ep->ep.name, ep->dwc_ep.xfer_len,
18289+ deptsiz.b.xfersize,
18290+ deptsiz.b.pktcnt);
18291+#endif
18292+ req->req.actual = ep->dwc_ep.xfer_count;
18293+ /* Is a Zero Len Packet needed? */
18294+ if (req->req.zero) {
18295+#ifdef DEBUG_EP0
18296+ DWC_DEBUGPL(DBG_PCDV, "Setup Tx ZLP\n");
18297+#endif
18298+ req->req.zero = 0;
18299+ }
18300+ if(core_if->dma_desc_enable == 0)
18301+ do_setup_in_status_phase(pcd);
18302+ }
18303+
18304+ /* Complete the request */
18305+ if (is_last) {
18306+ dwc_otg_request_done(ep, req, 0);
18307+ ep->dwc_ep.start_xfer_buff = 0;
18308+ ep->dwc_ep.xfer_buff = 0;
18309+ ep->dwc_ep.xfer_len = 0;
18310+ return 1;
18311+ }
18312+ return 0;
18313+}
18314+
18315+inline void aligned_buf_patch_on_buf_dma_oep_completion(dwc_otg_pcd_ep_t *ep, uint32_t byte_count)
18316+{
18317+ dwc_ep_t *dwc_ep = &ep->dwc_ep;
18318+ if(byte_count && dwc_ep->aligned_buf &&
18319+ dwc_ep->dma_addr>=dwc_ep->aligned_dma_addr &&
18320+ dwc_ep->dma_addr<=(dwc_ep->aligned_dma_addr+dwc_ep->aligned_buf_size))\
18321+ {
18322+ //aligned buf used, apply complete patch
18323+ u32 offset=(dwc_ep->dma_addr-dwc_ep->aligned_dma_addr);
18324+ memcpy(dwc_ep->start_xfer_buff+offset, dwc_ep->aligned_buf+offset, byte_count);
18325+ }
18326+}
18327+
18328+/**
18329+ * This function completes the request for the EP. If there are
18330+ * additional requests for the EP in the queue they will be started.
18331+ */
18332+static void complete_ep(dwc_otg_pcd_ep_t *ep)
18333+{
18334+ dwc_otg_core_if_t *core_if = GET_CORE_IF(ep->pcd);
18335+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
18336+ dwc_otg_dev_in_ep_regs_t *in_ep_regs =
18337+ dev_if->in_ep_regs[ep->dwc_ep.num];
18338+ deptsiz_data_t deptsiz;
18339+ desc_sts_data_t desc_sts;
18340+ dwc_otg_pcd_request_t *req = 0;
18341+ dwc_otg_dma_desc_t* dma_desc;
18342+ uint32_t byte_count = 0;
18343+ int is_last = 0;
18344+ int i;
18345+
18346+ DWC_DEBUGPL(DBG_PCDV,"%s() %s-%s\n", __func__, ep->ep.name,
18347+ (ep->dwc_ep.is_in?"IN":"OUT"));
18348+
18349+ /* Get any pending requests */
18350+ if (!list_empty(&ep->queue)) {
18351+ req = list_entry(ep->queue.next, dwc_otg_pcd_request_t,
18352+ queue);
18353+ if (!req) {
18354+ printk("complete_ep 0x%p, req = NULL!\n", ep);
18355+ return;
18356+ }
18357+ }
18358+ else {
18359+ printk("complete_ep 0x%p, ep->queue empty!\n", ep);
18360+ return;
18361+ }
18362+ DWC_DEBUGPL(DBG_PCD, "Requests %d\n", ep->pcd->request_pending);
18363+
18364+ if (ep->dwc_ep.is_in) {
18365+ deptsiz.d32 = dwc_read_reg32(&in_ep_regs->dieptsiz);
18366+
18367+ if (core_if->dma_enable) {
18368+ //dma_unmap_single(NULL,ep->dwc_ep.dma_addr,ep->dwc_ep.xfer_count,DMA_NONE);
18369+ if(core_if->dma_desc_enable == 0) {
18370+ //dma_unmap_single(NULL,ep->dwc_ep.dma_addr,ep->dwc_ep.xfer_count,DMA_NONE);
18371+ if (deptsiz.b.xfersize == 0 && deptsiz.b.pktcnt == 0) {
18372+ byte_count = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
18373+DWC_DEBUGPL(DBG_PCDV,"byte_count(%.8x) = (ep->dwc_ep.xfer_len(%.8x) - ep->dwc_ep.xfer_count(%.8x)\n", byte_count ,ep->dwc_ep.xfer_len , ep->dwc_ep.xfer_count );
18374+
18375+ ep->dwc_ep.xfer_buff += byte_count;
18376+ ep->dwc_ep.dma_addr += byte_count;
18377+ ep->dwc_ep.xfer_count += byte_count;
18378+
18379+ DWC_DEBUGPL(DBG_PCDV, "%s len=%d xfersize=%d pktcnt=%d\n",
18380+ ep->ep.name, ep->dwc_ep.xfer_len,
18381+ deptsiz.b.xfersize, deptsiz.b.pktcnt);
18382+
18383+ if(ep->dwc_ep.xfer_len < ep->dwc_ep.total_len) {
18384+ //dwc_otg_ep_start_transfer(core_if, &ep->dwc_ep);
18385+printk("Warning: transfer ended, but specified len is not accomplished!! ep->total_len=%.x,ep->dwc_ep.sent_zlp=%d, byte_count(%.8x) = (ep->dwc_ep.xfer_len(%.8x) - ep->dwc_ep.xfer_count(%.8x) - deptsiz.b.xfersize(%.8x)\n", ep->dwc_ep.total_len, ep->dwc_ep.sent_zlp, byte_count ,ep->dwc_ep.xfer_len , ep->dwc_ep.xfer_count , deptsiz.b.xfersize);
18386+ } else if(ep->dwc_ep.sent_zlp) {
18387+ /*
18388+ * This fragment of code should initiate 0
18389+ * length trasfer in case if it is queued
18390+ * a trasfer with size divisible to EPs max
18391+ * packet size and with usb_request zero field
18392+ * is set, which means that after data is transfered,
18393+ * it is also should be transfered
18394+ * a 0 length packet at the end. For Slave and
18395+ * Buffer DMA modes in this case SW has
18396+ * to initiate 2 transfers one with transfer size,
18397+ * and the second with 0 size. For Desriptor
18398+ * DMA mode SW is able to initiate a transfer,
18399+ * which will handle all the packets including
18400+ * the last 0 legth.
18401+ */
18402+ ep->dwc_ep.sent_zlp = 0;
18403+ dwc_otg_ep_start_zl_transfer(core_if, &ep->dwc_ep);
18404+ } else {
18405+ is_last = 1;
18406+ }
18407+ } else {
18408+ DWC_WARN("Incomplete transfer (%s-%s [siz=%d pkt=%d])\n",
18409+ ep->ep.name, (ep->dwc_ep.is_in?"IN":"OUT"),
18410+ deptsiz.b.xfersize, deptsiz.b.pktcnt);
18411+ }
18412+ } else {
18413+
18414+ dma_desc = ep->dwc_ep.desc_addr;
18415+ byte_count = 0;
18416+ ep->dwc_ep.sent_zlp = 0;
18417+
18418+ for(i = 0; i < ep->dwc_ep.desc_cnt; ++i) {
18419+ desc_sts.d32 = readl(dma_desc);
18420+ byte_count += desc_sts.b.bytes;
18421+ dma_desc++;
18422+ }
18423+
18424+ if(byte_count == 0) {
18425+ ep->dwc_ep.xfer_count = ep->dwc_ep.total_len;
18426+ is_last = 1;
18427+ } else {
18428+ DWC_WARN("Incomplete transfer\n");
18429+ }
18430+ }
18431+ } else {
18432+ if (deptsiz.b.xfersize == 0 && deptsiz.b.pktcnt == 0) {
18433+ /* Check if the whole transfer was completed,
18434+ * if no, setup transfer for next portion of data
18435+ */
18436+ DWC_DEBUGPL(DBG_PCDV, "%s len=%d xfersize=%d pktcnt=%d\n",
18437+ ep->ep.name, ep->dwc_ep.xfer_len,
18438+ deptsiz.b.xfersize, deptsiz.b.pktcnt);
18439+ if(ep->dwc_ep.xfer_len < ep->dwc_ep.total_len) {
18440+ //dwc_otg_ep_start_transfer(core_if, &ep->dwc_ep);
18441+printk("Warning: transfer ended, but specified len is not accomplished!! ep->total_len=%.x,ep->dwc_ep.sent_zlp=%d, ep->dwc_ep.xfer_len(%.8x) \n", ep->dwc_ep.total_len, ep->dwc_ep.sent_zlp, ep->dwc_ep.xfer_len );
18442+ } else if(ep->dwc_ep.sent_zlp) {
18443+ /*
18444+ * This fragment of code should initiate 0
18445+ * length trasfer in case if it is queued
18446+ * a trasfer with size divisible to EPs max
18447+ * packet size and with usb_request zero field
18448+ * is set, which means that after data is transfered,
18449+ * it is also should be transfered
18450+ * a 0 length packet at the end. For Slave and
18451+ * Buffer DMA modes in this case SW has
18452+ * to initiate 2 transfers one with transfer size,
18453+ * and the second with 0 size. For Desriptor
18454+ * DMA mode SW is able to initiate a transfer,
18455+ * which will handle all the packets including
18456+ * the last 0 legth.
18457+ */
18458+ ep->dwc_ep.sent_zlp = 0;
18459+ dwc_otg_ep_start_zl_transfer(core_if, &ep->dwc_ep);
18460+ } else {
18461+ is_last = 1;
18462+ }
18463+ }
18464+ else {
18465+ DWC_WARN("Incomplete transfer (%s-%s [siz=%d pkt=%d])\n",
18466+ ep->ep.name, (ep->dwc_ep.is_in?"IN":"OUT"),
18467+ deptsiz.b.xfersize, deptsiz.b.pktcnt);
18468+ }
18469+ }
18470+ } else {
18471+ dwc_otg_dev_out_ep_regs_t *out_ep_regs =
18472+ dev_if->out_ep_regs[ep->dwc_ep.num];
18473+ desc_sts.d32 = 0;
18474+ if(core_if->dma_enable) {
18475+ //dma_unmap_single(NULL,ep->dwc_ep.dma_addr,ep->dwc_ep.xfer_count,DMA_FROM_DEVICE);
18476+ if(core_if->dma_desc_enable) {
18477+ DWC_WARN("\n\n%s: we need a cache invalidation here!!\n\n",__func__);
18478+ dma_desc = ep->dwc_ep.desc_addr;
18479+ byte_count = 0;
18480+ ep->dwc_ep.sent_zlp = 0;
18481+ for(i = 0; i < ep->dwc_ep.desc_cnt; ++i) {
18482+ desc_sts.d32 = readl(dma_desc);
18483+ byte_count += desc_sts.b.bytes;
18484+ dma_desc++;
18485+ }
18486+
18487+ ep->dwc_ep.xfer_count = ep->dwc_ep.total_len
18488+ - byte_count + ((4 - (ep->dwc_ep.total_len & 0x3)) & 0x3);
18489+
18490+ //todo: invalidate cache & aligned buf patch on completion
18491+ //
18492+
18493+ is_last = 1;
18494+ } else {
18495+ deptsiz.d32 = 0;
18496+ deptsiz.d32 = dwc_read_reg32(&out_ep_regs->doeptsiz);
18497+
18498+ byte_count = (ep->dwc_ep.xfer_len -
18499+ ep->dwc_ep.xfer_count - deptsiz.b.xfersize);
18500+
18501+// dma_sync_single_for_device(NULL,ep->dwc_ep.dma_addr,byte_count,DMA_FROM_DEVICE);
18502+
18503+DWC_DEBUGPL(DBG_PCDV,"ep->total_len=%.x,ep->dwc_ep.sent_zlp=%d, byte_count(%.8x) = (ep->dwc_ep.xfer_len(%.8x) - ep->dwc_ep.xfer_count(%.8x) - deptsiz.b.xfersize(%.8x)\n", ep->dwc_ep.total_len, ep->dwc_ep.sent_zlp, byte_count ,ep->dwc_ep.xfer_len , ep->dwc_ep.xfer_count , deptsiz.b.xfersize);
18504+ //todo: invalidate cache & aligned buf patch on completion
18505+ dma_sync_single_for_device(NULL,ep->dwc_ep.dma_addr,byte_count,DMA_FROM_DEVICE);
18506+ aligned_buf_patch_on_buf_dma_oep_completion(ep,byte_count);
18507+
18508+ ep->dwc_ep.xfer_buff += byte_count;
18509+ ep->dwc_ep.dma_addr += byte_count;
18510+ ep->dwc_ep.xfer_count += byte_count;
18511+
18512+ /* Check if the whole transfer was completed,
18513+ * if no, setup transfer for next portion of data
18514+ */
18515+ if(ep->dwc_ep.xfer_len < ep->dwc_ep.total_len) {
18516+ //dwc_otg_ep_start_transfer(core_if, &ep->dwc_ep);
18517+printk("Warning: transfer ended, but specified len is not accomplished!! ep->total_len=%.x,ep->dwc_ep.sent_zlp=%d, byte_count(%.8x) = (ep->dwc_ep.xfer_len(%.8x) - ep->dwc_ep.xfer_count(%.8x) - deptsiz.b.xfersize(%.8x)\n", ep->dwc_ep.total_len, ep->dwc_ep.sent_zlp, byte_count ,ep->dwc_ep.xfer_len , ep->dwc_ep.xfer_count , deptsiz.b.xfersize);
18518+ }
18519+ else if(ep->dwc_ep.sent_zlp) {
18520+ /*
18521+ * This fragment of code should initiate 0
18522+ * length trasfer in case if it is queued
18523+ * a trasfer with size divisible to EPs max
18524+ * packet size and with usb_request zero field
18525+ * is set, which means that after data is transfered,
18526+ * it is also should be transfered
18527+ * a 0 length packet at the end. For Slave and
18528+ * Buffer DMA modes in this case SW has
18529+ * to initiate 2 transfers one with transfer size,
18530+ * and the second with 0 size. For Desriptor
18531+ * DMA mode SW is able to initiate a transfer,
18532+ * which will handle all the packets including
18533+ * the last 0 legth.
18534+ */
18535+ ep->dwc_ep.sent_zlp = 0;
18536+ dwc_otg_ep_start_zl_transfer(core_if, &ep->dwc_ep);
18537+ } else {
18538+ is_last = 1;
18539+ }
18540+ }
18541+ } else {
18542+ /* Check if the whole transfer was completed,
18543+ * if no, setup transfer for next portion of data
18544+ */
18545+ if(ep->dwc_ep.xfer_len < ep->dwc_ep.total_len) {
18546+ //dwc_otg_ep_start_transfer(core_if, &ep->dwc_ep);
18547+printk("Warning: transfer ended, but specified len is not accomplished!! ep->total_len=%.x,ep->dwc_ep.sent_zlp=%d, ep->dwc_ep.xfer_len(%.8x) \n", ep->dwc_ep.total_len, ep->dwc_ep.sent_zlp, ep->dwc_ep.xfer_len );
18548+ }
18549+ else if(ep->dwc_ep.sent_zlp) {
18550+ /*
18551+ * This fragment of code should initiate 0
18552+ * length trasfer in case if it is queued
18553+ * a trasfer with size divisible to EPs max
18554+ * packet size and with usb_request zero field
18555+ * is set, which means that after data is transfered,
18556+ * it is also should be transfered
18557+ * a 0 length packet at the end. For Slave and
18558+ * Buffer DMA modes in this case SW has
18559+ * to initiate 2 transfers one with transfer size,
18560+ * and the second with 0 size. For Desriptor
18561+ * DMA mode SW is able to initiate a transfer,
18562+ * which will handle all the packets including
18563+ * the last 0 legth.
18564+ */
18565+ ep->dwc_ep.sent_zlp = 0;
18566+ dwc_otg_ep_start_zl_transfer(core_if, &ep->dwc_ep);
18567+ } else {
18568+ is_last = 1;
18569+ }
18570+ }
18571+
18572+#ifdef DEBUG
18573+
18574+ DWC_DEBUGPL(DBG_PCDV, "addr %p, %s len=%d cnt=%d xsize=%d pktcnt=%d\n",
18575+ &out_ep_regs->doeptsiz, ep->ep.name, ep->dwc_ep.xfer_len,
18576+ ep->dwc_ep.xfer_count,
18577+ deptsiz.b.xfersize,
18578+ deptsiz.b.pktcnt);
18579+#endif
18580+ }
18581+
18582+ /* Complete the request */
18583+ if (is_last) {
18584+ req->req.actual = ep->dwc_ep.xfer_count;
18585+
18586+ dwc_otg_request_done(ep, req, 0);
18587+
18588+ ep->dwc_ep.start_xfer_buff = 0;
18589+ ep->dwc_ep.xfer_buff = 0;
18590+ ep->dwc_ep.xfer_len = 0;
18591+
18592+ /* If there is a request in the queue start it.*/
18593+ start_next_request(ep);
18594+ }
18595+}
18596+
18597+
18598+#ifdef DWC_EN_ISOC
18599+
18600+/**
18601+ * This function BNA interrupt for Isochronous EPs
18602+ *
18603+ */
18604+static void dwc_otg_pcd_handle_iso_bna(dwc_otg_pcd_ep_t *ep)
18605+{
18606+ dwc_ep_t *dwc_ep = &ep->dwc_ep;
18607+ volatile uint32_t *addr;
18608+ depctl_data_t depctl = {.d32 = 0};
18609+ dwc_otg_pcd_t *pcd = ep->pcd;
18610+ dwc_otg_dma_desc_t *dma_desc;
18611+ int i;
18612+
18613+ dma_desc = dwc_ep->iso_desc_addr + dwc_ep->desc_cnt * (dwc_ep->proc_buf_num);
18614+
18615+ if(dwc_ep->is_in) {
18616+ desc_sts_data_t sts = {.d32 = 0};
18617+ for(i = 0;i < dwc_ep->desc_cnt; ++i, ++dma_desc)
18618+ {
18619+ sts.d32 = readl(&dma_desc->status);
18620+ sts.b_iso_in.bs = BS_HOST_READY;
18621+ writel(sts.d32,&dma_desc->status);
18622+ }
18623+ }
18624+ else {
18625+ desc_sts_data_t sts = {.d32 = 0};
18626+ for(i = 0;i < dwc_ep->desc_cnt; ++i, ++dma_desc)
18627+ {
18628+ sts.d32 = readl(&dma_desc->status);
18629+ sts.b_iso_out.bs = BS_HOST_READY;
18630+ writel(sts.d32,&dma_desc->status);
18631+ }
18632+ }
18633+
18634+ if(dwc_ep->is_in == 0){
18635+ addr = &GET_CORE_IF(pcd)->dev_if->out_ep_regs[dwc_ep->num]->doepctl;
18636+ }
18637+ else{
18638+ addr = &GET_CORE_IF(pcd)->dev_if->in_ep_regs[dwc_ep->num]->diepctl;
18639+ }
18640+ depctl.b.epena = 1;
18641+ dwc_modify_reg32(addr,depctl.d32,depctl.d32);
18642+}
18643+
18644+/**
18645+ * This function sets latest iso packet information(non-PTI mode)
18646+ *
18647+ * @param core_if Programming view of DWC_otg controller.
18648+ * @param ep The EP to start the transfer on.
18649+ *
18650+ */
18651+void set_current_pkt_info(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
18652+{
18653+ deptsiz_data_t deptsiz = { .d32 = 0 };
18654+ dma_addr_t dma_addr;
18655+ uint32_t offset;
18656+
18657+ if(ep->proc_buf_num)
18658+ dma_addr = ep->dma_addr1;
18659+ else
18660+ dma_addr = ep->dma_addr0;
18661+
18662+ if(ep->is_in) {
18663+ deptsiz.d32 = dwc_read_reg32(&core_if->dev_if->in_ep_regs[ep->num]->dieptsiz);
18664+ offset = ep->data_per_frame;
18665+ } else {
18666+ deptsiz.d32 = dwc_read_reg32(&core_if->dev_if->out_ep_regs[ep->num]->doeptsiz);
18667+ offset = ep->data_per_frame + (0x4 & (0x4 - (ep->data_per_frame & 0x3)));
18668+ }
18669+
18670+ if(!deptsiz.b.xfersize) {
18671+ ep->pkt_info[ep->cur_pkt].length = ep->data_per_frame;
18672+ ep->pkt_info[ep->cur_pkt].offset = ep->cur_pkt_dma_addr - dma_addr;
18673+ ep->pkt_info[ep->cur_pkt].status = 0;
18674+ } else {
18675+ ep->pkt_info[ep->cur_pkt].length = ep->data_per_frame;
18676+ ep->pkt_info[ep->cur_pkt].offset = ep->cur_pkt_dma_addr - dma_addr;
18677+ ep->pkt_info[ep->cur_pkt].status = -ENODATA;
18678+ }
18679+ ep->cur_pkt_addr += offset;
18680+ ep->cur_pkt_dma_addr += offset;
18681+ ep->cur_pkt++;
18682+}
18683+
18684+/**
18685+ * This function sets latest iso packet information(DDMA mode)
18686+ *
18687+ * @param core_if Programming view of DWC_otg controller.
18688+ * @param dwc_ep The EP to start the transfer on.
18689+ *
18690+ */
18691+static void set_ddma_iso_pkts_info(dwc_otg_core_if_t *core_if, dwc_ep_t *dwc_ep)
18692+{
18693+ dwc_otg_dma_desc_t* dma_desc;
18694+ desc_sts_data_t sts = {.d32 = 0};
18695+ iso_pkt_info_t *iso_packet;
18696+ uint32_t data_per_desc;
18697+ uint32_t offset;
18698+ int i, j;
18699+
18700+ iso_packet = dwc_ep->pkt_info;
18701+
18702+ /** Reinit closed DMA Descriptors*/
18703+ /** ISO OUT EP */
18704+ if(dwc_ep->is_in == 0) {
18705+ dma_desc = dwc_ep->iso_desc_addr + dwc_ep->desc_cnt * dwc_ep->proc_buf_num;
18706+ offset = 0;
18707+
18708+ for(i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm; i+= dwc_ep->pkt_per_frm)
18709+ {
18710+ for(j = 0; j < dwc_ep->pkt_per_frm; ++j)
18711+ {
18712+ data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
18713+ dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
18714+ data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
18715+
18716+ sts.d32 = readl(&dma_desc->status);
18717+
18718+ /* Write status in iso_packet_decsriptor */
18719+ iso_packet->status = sts.b_iso_out.rxsts + (sts.b_iso_out.bs^BS_DMA_DONE);
18720+ if(iso_packet->status) {
18721+ iso_packet->status = -ENODATA;
18722+ }
18723+
18724+ /* Received data length */
18725+ if(!sts.b_iso_out.rxbytes){
18726+ iso_packet->length = data_per_desc - sts.b_iso_out.rxbytes;
18727+ } else {
18728+ iso_packet->length = data_per_desc - sts.b_iso_out.rxbytes +
18729+ (4 - dwc_ep->data_per_frame % 4);
18730+ }
18731+
18732+ iso_packet->offset = offset;
18733+
18734+ offset += data_per_desc;
18735+ dma_desc ++;
18736+ iso_packet ++;
18737+ }
18738+ }
18739+
18740+ for(j = 0; j < dwc_ep->pkt_per_frm - 1; ++j)
18741+ {
18742+ data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
18743+ dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
18744+ data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
18745+
18746+ sts.d32 = readl(&dma_desc->status);
18747+
18748+ /* Write status in iso_packet_decsriptor */
18749+ iso_packet->status = sts.b_iso_out.rxsts + (sts.b_iso_out.bs^BS_DMA_DONE);
18750+ if(iso_packet->status) {
18751+ iso_packet->status = -ENODATA;
18752+ }
18753+
18754+ /* Received data length */
18755+ iso_packet->length = dwc_ep->data_per_frame - sts.b_iso_out.rxbytes;
18756+
18757+ iso_packet->offset = offset;
18758+
18759+ offset += data_per_desc;
18760+ iso_packet++;
18761+ dma_desc++;
18762+ }
18763+
18764+ sts.d32 = readl(&dma_desc->status);
18765+
18766+ /* Write status in iso_packet_decsriptor */
18767+ iso_packet->status = sts.b_iso_out.rxsts + (sts.b_iso_out.bs^BS_DMA_DONE);
18768+ if(iso_packet->status) {
18769+ iso_packet->status = -ENODATA;
18770+ }
18771+ /* Received data length */
18772+ if(!sts.b_iso_out.rxbytes){
18773+ iso_packet->length = dwc_ep->data_per_frame - sts.b_iso_out.rxbytes;
18774+ } else {
18775+ iso_packet->length = dwc_ep->data_per_frame - sts.b_iso_out.rxbytes +
18776+ (4 - dwc_ep->data_per_frame % 4);
18777+ }
18778+
18779+ iso_packet->offset = offset;
18780+ }
18781+ else /** ISO IN EP */
18782+ {
18783+ dma_desc = dwc_ep->iso_desc_addr + dwc_ep->desc_cnt * dwc_ep->proc_buf_num;
18784+
18785+ for(i = 0; i < dwc_ep->desc_cnt - 1; i++)
18786+ {
18787+ sts.d32 = readl(&dma_desc->status);
18788+
18789+ /* Write status in iso packet descriptor */
18790+ iso_packet->status = sts.b_iso_in.txsts + (sts.b_iso_in.bs^BS_DMA_DONE);
18791+ if(iso_packet->status != 0) {
18792+ iso_packet->status = -ENODATA;
18793+
18794+ }
18795+ /* Bytes has been transfered */
18796+ iso_packet->length = dwc_ep->data_per_frame - sts.b_iso_in.txbytes;
18797+
18798+ dma_desc ++;
18799+ iso_packet++;
18800+ }
18801+
18802+ sts.d32 = readl(&dma_desc->status);
18803+ while(sts.b_iso_in.bs == BS_DMA_BUSY) {
18804+ sts.d32 = readl(&dma_desc->status);
18805+ }
18806+
18807+ /* Write status in iso packet descriptor ??? do be done with ERROR codes*/
18808+ iso_packet->status = sts.b_iso_in.txsts + (sts.b_iso_in.bs^BS_DMA_DONE);
18809+ if(iso_packet->status != 0) {
18810+ iso_packet->status = -ENODATA;
18811+ }
18812+
18813+ /* Bytes has been transfered */
18814+ iso_packet->length = dwc_ep->data_per_frame - sts.b_iso_in.txbytes;
18815+ }
18816+}
18817+
18818+/**
18819+ * This function reinitialize DMA Descriptors for Isochronous transfer
18820+ *
18821+ * @param core_if Programming view of DWC_otg controller.
18822+ * @param dwc_ep The EP to start the transfer on.
18823+ *
18824+ */
18825+static void reinit_ddma_iso_xfer(dwc_otg_core_if_t *core_if, dwc_ep_t *dwc_ep)
18826+{
18827+ int i, j;
18828+ dwc_otg_dma_desc_t* dma_desc;
18829+ dma_addr_t dma_ad;
18830+ volatile uint32_t *addr;
18831+ desc_sts_data_t sts = { .d32 =0 };
18832+ uint32_t data_per_desc;
18833+
18834+ if(dwc_ep->is_in == 0) {
18835+ addr = &core_if->dev_if->out_ep_regs[dwc_ep->num]->doepctl;
18836+ }
18837+ else {
18838+ addr = &core_if->dev_if->in_ep_regs[dwc_ep->num]->diepctl;
18839+ }
18840+
18841+
18842+ if(dwc_ep->proc_buf_num == 0) {
18843+ /** Buffer 0 descriptors setup */
18844+ dma_ad = dwc_ep->dma_addr0;
18845+ }
18846+ else {
18847+ /** Buffer 1 descriptors setup */
18848+ dma_ad = dwc_ep->dma_addr1;
18849+ }
18850+
18851+ /** Reinit closed DMA Descriptors*/
18852+ /** ISO OUT EP */
18853+ if(dwc_ep->is_in == 0) {
18854+ dma_desc = dwc_ep->iso_desc_addr + dwc_ep->desc_cnt * dwc_ep->proc_buf_num;
18855+
18856+ sts.b_iso_out.bs = BS_HOST_READY;
18857+ sts.b_iso_out.rxsts = 0;
18858+ sts.b_iso_out.l = 0;
18859+ sts.b_iso_out.sp = 0;
18860+ sts.b_iso_out.ioc = 0;
18861+ sts.b_iso_out.pid = 0;
18862+ sts.b_iso_out.framenum = 0;
18863+
18864+ for(i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm; i+= dwc_ep->pkt_per_frm)
18865+ {
18866+ for(j = 0; j < dwc_ep->pkt_per_frm; ++j)
18867+ {
18868+ data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
18869+ dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
18870+ data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
18871+ sts.b_iso_out.rxbytes = data_per_desc;
18872+ writel((uint32_t)dma_ad, &dma_desc->buf);
18873+ writel(sts.d32, &dma_desc->status);
18874+
18875+ //(uint32_t)dma_ad += data_per_desc;
18876+ dma_ad = (uint32_t)dma_ad + data_per_desc;
18877+ dma_desc ++;
18878+ }
18879+ }
18880+
18881+ for(j = 0; j < dwc_ep->pkt_per_frm - 1; ++j)
18882+ {
18883+
18884+ data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
18885+ dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
18886+ data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
18887+ sts.b_iso_out.rxbytes = data_per_desc;
18888+
18889+ writel((uint32_t)dma_ad, &dma_desc->buf);
18890+ writel(sts.d32, &dma_desc->status);
18891+
18892+ dma_desc++;
18893+ //(uint32_t)dma_ad += data_per_desc;
18894+ dma_ad = (uint32_t)dma_ad + data_per_desc;
18895+ }
18896+
18897+ sts.b_iso_out.ioc = 1;
18898+ sts.b_iso_out.l = dwc_ep->proc_buf_num;
18899+
18900+ data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
18901+ dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
18902+ data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
18903+ sts.b_iso_out.rxbytes = data_per_desc;
18904+
18905+ writel((uint32_t)dma_ad, &dma_desc->buf);
18906+ writel(sts.d32, &dma_desc->status);
18907+ }
18908+ else /** ISO IN EP */
18909+ {
18910+ dma_desc = dwc_ep->iso_desc_addr + dwc_ep->desc_cnt * dwc_ep->proc_buf_num;
18911+
18912+ sts.b_iso_in.bs = BS_HOST_READY;
18913+ sts.b_iso_in.txsts = 0;
18914+ sts.b_iso_in.sp = 0;
18915+ sts.b_iso_in.ioc = 0;
18916+ sts.b_iso_in.pid = dwc_ep->pkt_per_frm;
18917+ sts.b_iso_in.framenum = dwc_ep->next_frame;
18918+ sts.b_iso_in.txbytes = dwc_ep->data_per_frame;
18919+ sts.b_iso_in.l = 0;
18920+
18921+ for(i = 0; i < dwc_ep->desc_cnt - 1; i++)
18922+ {
18923+ writel((uint32_t)dma_ad, &dma_desc->buf);
18924+ writel(sts.d32, &dma_desc->status);
18925+
18926+ sts.b_iso_in.framenum += dwc_ep->bInterval;
18927+ //(uint32_t)dma_ad += dwc_ep->data_per_frame;
18928+ dma_ad = (uint32_t)dma_ad + dwc_ep->data_per_frame;
18929+ dma_desc ++;
18930+ }
18931+
18932+ sts.b_iso_in.ioc = 1;
18933+ sts.b_iso_in.l = dwc_ep->proc_buf_num;
18934+
18935+ writel((uint32_t)dma_ad, &dma_desc->buf);
18936+ writel(sts.d32, &dma_desc->status);
18937+
18938+ dwc_ep->next_frame = sts.b_iso_in.framenum + dwc_ep->bInterval * 1;
18939+ }
18940+ dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1;
18941+}
18942+
18943+
18944+/**
18945+ * This function is to handle Iso EP transfer complete interrupt
18946+ * in case Iso out packet was dropped
18947+ *
18948+ * @param core_if Programming view of DWC_otg controller.
18949+ * @param dwc_ep The EP for wihich transfer complete was asserted
18950+ *
18951+ */
18952+static uint32_t handle_iso_out_pkt_dropped(dwc_otg_core_if_t *core_if, dwc_ep_t *dwc_ep)
18953+{
18954+ uint32_t dma_addr;
18955+ uint32_t drp_pkt;
18956+ uint32_t drp_pkt_cnt;
18957+ deptsiz_data_t deptsiz = { .d32 = 0 };
18958+ depctl_data_t depctl = { .d32 = 0 };
18959+ int i;
18960+
18961+ deptsiz.d32 = dwc_read_reg32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doeptsiz);
18962+
18963+ drp_pkt = dwc_ep->pkt_cnt - deptsiz.b.pktcnt;
18964+ drp_pkt_cnt = dwc_ep->pkt_per_frm - (drp_pkt % dwc_ep->pkt_per_frm);
18965+
18966+ /* Setting dropped packets status */
18967+ for(i = 0; i < drp_pkt_cnt; ++i) {
18968+ dwc_ep->pkt_info[drp_pkt].status = -ENODATA;
18969+ drp_pkt ++;
18970+ deptsiz.b.pktcnt--;
18971+ }
18972+
18973+
18974+ if(deptsiz.b.pktcnt > 0) {
18975+ deptsiz.b.xfersize = dwc_ep->xfer_len - (dwc_ep->pkt_cnt - deptsiz.b.pktcnt) * dwc_ep->maxpacket;
18976+ } else {
18977+ deptsiz.b.xfersize = 0;
18978+ deptsiz.b.pktcnt = 0;
18979+ }
18980+
18981+ dwc_write_reg32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doeptsiz, deptsiz.d32);
18982+
18983+ if(deptsiz.b.pktcnt > 0) {
18984+ if(dwc_ep->proc_buf_num) {
18985+ dma_addr = dwc_ep->dma_addr1 + dwc_ep->xfer_len - deptsiz.b.xfersize;
18986+ } else {
18987+ dma_addr = dwc_ep->dma_addr0 + dwc_ep->xfer_len - deptsiz.b.xfersize;;
18988+ }
18989+
18990+ VERIFY_PCD_DMA_ADDR(dma_addr);
18991+ dwc_write_reg32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doepdma, dma_addr);
18992+
18993+ /** Re-enable endpoint, clear nak */
18994+ depctl.d32 = 0;
18995+ depctl.b.epena = 1;
18996+ depctl.b.cnak = 1;
18997+
18998+ dwc_modify_reg32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doepctl,
18999+ depctl.d32,depctl.d32);
19000+ return 0;
19001+ } else {
19002+ return 1;
19003+ }
19004+}
19005+
19006+/**
19007+ * This function sets iso packets information(PTI mode)
19008+ *
19009+ * @param core_if Programming view of DWC_otg controller.
19010+ * @param ep The EP to start the transfer on.
19011+ *
19012+ */
19013+static uint32_t set_iso_pkts_info(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
19014+{
19015+ int i, j;
19016+ dma_addr_t dma_ad;
19017+ iso_pkt_info_t *packet_info = ep->pkt_info;
19018+ uint32_t offset;
19019+ uint32_t frame_data;
19020+ deptsiz_data_t deptsiz;
19021+
19022+ if(ep->proc_buf_num == 0) {
19023+ /** Buffer 0 descriptors setup */
19024+ dma_ad = ep->dma_addr0;
19025+ }
19026+ else {
19027+ /** Buffer 1 descriptors setup */
19028+ dma_ad = ep->dma_addr1;
19029+ }
19030+
19031+ if(ep->is_in) {
19032+ deptsiz.d32 = dwc_read_reg32(&core_if->dev_if->in_ep_regs[ep->num]->dieptsiz);
19033+ } else {
19034+ deptsiz.d32 = dwc_read_reg32(&core_if->dev_if->out_ep_regs[ep->num]->doeptsiz);
19035+ }
19036+
19037+ if(!deptsiz.b.xfersize) {
19038+ offset = 0;
19039+ for(i = 0; i < ep->pkt_cnt; i += ep->pkt_per_frm)
19040+ {
19041+ frame_data = ep->data_per_frame;
19042+ for(j = 0; j < ep->pkt_per_frm; ++j) {
19043+
19044+ /* Packet status - is not set as initially
19045+ * it is set to 0 and if packet was sent
19046+ successfully, status field will remain 0*/
19047+
19048+ /* Bytes has been transfered */
19049+ packet_info->length = (ep->maxpacket < frame_data) ?
19050+ ep->maxpacket : frame_data;
19051+
19052+ /* Received packet offset */
19053+ packet_info->offset = offset;
19054+ offset += packet_info->length;
19055+ frame_data -= packet_info->length;
19056+
19057+ packet_info ++;
19058+ }
19059+ }
19060+ return 1;
19061+ } else {
19062+ /* This is a workaround for in case of Transfer Complete with
19063+ * PktDrpSts interrupts merging - in this case Transfer complete
19064+ * interrupt for Isoc Out Endpoint is asserted without PktDrpSts
19065+ * set and with DOEPTSIZ register non zero. Investigations showed,
19066+ * that this happens when Out packet is dropped, but because of
19067+ * interrupts merging during first interrupt handling PktDrpSts
19068+ * bit is cleared and for next merged interrupts it is not reset.
19069+ * In this case SW hadles the interrupt as if PktDrpSts bit is set.
19070+ */
19071+ if(ep->is_in) {
19072+ return 1;
19073+ } else {
19074+ return handle_iso_out_pkt_dropped(core_if, ep);
19075+ }
19076+ }
19077+}
19078+
19079+/**
19080+ * This function is to handle Iso EP transfer complete interrupt
19081+ *
19082+ * @param ep The EP for which transfer complete was asserted
19083+ *
19084+ */
19085+static void complete_iso_ep(dwc_otg_pcd_ep_t *ep)
19086+{
19087+ dwc_otg_core_if_t *core_if = GET_CORE_IF(ep->pcd);
19088+ dwc_ep_t *dwc_ep = &ep->dwc_ep;
19089+ uint8_t is_last = 0;
19090+
19091+ if(core_if->dma_enable) {
19092+ if(core_if->dma_desc_enable) {
19093+ set_ddma_iso_pkts_info(core_if, dwc_ep);
19094+ reinit_ddma_iso_xfer(core_if, dwc_ep);
19095+ is_last = 1;
19096+ } else {
19097+ if(core_if->pti_enh_enable) {
19098+ if(set_iso_pkts_info(core_if, dwc_ep)) {
19099+ dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1;
19100+ dwc_otg_iso_ep_start_buf_transfer(core_if, dwc_ep);
19101+ is_last = 1;
19102+ }
19103+ } else {
19104+ set_current_pkt_info(core_if, dwc_ep);
19105+ if(dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
19106+ is_last = 1;
19107+ dwc_ep->cur_pkt = 0;
19108+ dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1;
19109+ if(dwc_ep->proc_buf_num) {
19110+ dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff1;
19111+ dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr1;
19112+ } else {
19113+ dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff0;
19114+ dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr0;
19115+ }
19116+ }
19117+ dwc_otg_iso_ep_start_frm_transfer(core_if, dwc_ep);
19118+ }
19119+ }
19120+ } else {
19121+ set_current_pkt_info(core_if, dwc_ep);
19122+ if(dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
19123+ is_last = 1;
19124+ dwc_ep->cur_pkt = 0;
19125+ dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1;
19126+ if(dwc_ep->proc_buf_num) {
19127+ dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff1;
19128+ dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr1;
19129+ } else {
19130+ dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff0;
19131+ dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr0;
19132+ }
19133+ }
19134+ dwc_otg_iso_ep_start_frm_transfer(core_if, dwc_ep);
19135+ }
19136+ if(is_last)
19137+ dwc_otg_iso_buffer_done(ep, ep->iso_req);
19138+}
19139+
19140+#endif //DWC_EN_ISOC
19141+
19142+
19143+/**
19144+ * This function handles EP0 Control transfers.
19145+ *
19146+ * The state of the control tranfers are tracked in
19147+ * <code>ep0state</code>.
19148+ */
19149+static void handle_ep0(dwc_otg_pcd_t *pcd)
19150+{
19151+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
19152+ dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
19153+ desc_sts_data_t desc_sts;
19154+ deptsiz0_data_t deptsiz;
19155+ uint32_t byte_count;
19156+
19157+#ifdef DEBUG_EP0
19158+ DWC_DEBUGPL(DBG_PCDV, "%s()\n", __func__);
19159+ print_ep0_state(pcd);
19160+#endif
19161+
19162+ switch (pcd->ep0state) {
19163+ case EP0_DISCONNECT:
19164+ break;
19165+
19166+ case EP0_IDLE:
19167+ pcd->request_config = 0;
19168+
19169+ pcd_setup(pcd);
19170+ break;
19171+
19172+ case EP0_IN_DATA_PHASE:
19173+#ifdef DEBUG_EP0
19174+ DWC_DEBUGPL(DBG_PCD, "DATA_IN EP%d-%s: type=%d, mps=%d\n",
19175+ ep0->dwc_ep.num, (ep0->dwc_ep.is_in ?"IN":"OUT"),
19176+ ep0->dwc_ep.type, ep0->dwc_ep.maxpacket);
19177+#endif
19178+
19179+ if (core_if->dma_enable != 0) {
19180+ /*
19181+ * For EP0 we can only program 1 packet at a time so we
19182+ * need to do the make calculations after each complete.
19183+ * Call write_packet to make the calculations, as in
19184+ * slave mode, and use those values to determine if we
19185+ * can complete.
19186+ */
19187+ if(core_if->dma_desc_enable == 0) {
19188+ deptsiz.d32 = dwc_read_reg32(&core_if->dev_if->in_ep_regs[0]->dieptsiz);
19189+ byte_count = ep0->dwc_ep.xfer_len - deptsiz.b.xfersize;
19190+ }
19191+ else {
19192+ desc_sts.d32 = readl(core_if->dev_if->in_desc_addr);
19193+ byte_count = ep0->dwc_ep.xfer_len - desc_sts.b.bytes;
19194+ }
19195+
19196+ ep0->dwc_ep.xfer_count += byte_count;
19197+ ep0->dwc_ep.xfer_buff += byte_count;
19198+ ep0->dwc_ep.dma_addr += byte_count;
19199+ }
19200+ if (ep0->dwc_ep.xfer_count < ep0->dwc_ep.total_len) {
19201+ dwc_otg_ep0_continue_transfer (GET_CORE_IF(pcd), &ep0->dwc_ep);
19202+ DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");
19203+ }
19204+ else if(ep0->dwc_ep.sent_zlp) {
19205+ dwc_otg_ep0_continue_transfer (GET_CORE_IF(pcd), &ep0->dwc_ep);
19206+ ep0->dwc_ep.sent_zlp = 0;
19207+ DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");
19208+ }
19209+ else {
19210+ ep0_complete_request(ep0);
19211+ DWC_DEBUGPL(DBG_PCD, "COMPLETE TRANSFER\n");
19212+ }
19213+ break;
19214+ case EP0_OUT_DATA_PHASE:
19215+#ifdef DEBUG_EP0
19216+ DWC_DEBUGPL(DBG_PCD, "DATA_OUT EP%d-%s: type=%d, mps=%d\n",
19217+ ep0->dwc_ep.num, (ep0->dwc_ep.is_in ?"IN":"OUT"),
19218+ ep0->dwc_ep.type, ep0->dwc_ep.maxpacket);
19219+#endif
19220+ if (core_if->dma_enable != 0) {
19221+ if(core_if->dma_desc_enable == 0) {
19222+ deptsiz.d32 = dwc_read_reg32(&core_if->dev_if->out_ep_regs[0]->doeptsiz);
19223+ byte_count = ep0->dwc_ep.maxpacket - deptsiz.b.xfersize;
19224+
19225+ //todo: invalidate cache & aligned buf patch on completion
19226+ dma_sync_single_for_device(NULL,ep0->dwc_ep.dma_addr,byte_count,DMA_FROM_DEVICE);
19227+ aligned_buf_patch_on_buf_dma_oep_completion(ep0,byte_count);
19228+ }
19229+ else {
19230+ desc_sts.d32 = readl(core_if->dev_if->out_desc_addr);
19231+ byte_count = ep0->dwc_ep.maxpacket - desc_sts.b.bytes;
19232+
19233+ //todo: invalidate cache & aligned buf patch on completion
19234+ //
19235+
19236+ }
19237+ ep0->dwc_ep.xfer_count += byte_count;
19238+ ep0->dwc_ep.xfer_buff += byte_count;
19239+ ep0->dwc_ep.dma_addr += byte_count;
19240+ }
19241+ if (ep0->dwc_ep.xfer_count < ep0->dwc_ep.total_len) {
19242+ dwc_otg_ep0_continue_transfer (GET_CORE_IF(pcd), &ep0->dwc_ep);
19243+ DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");
19244+ }
19245+ else if(ep0->dwc_ep.sent_zlp) {
19246+ dwc_otg_ep0_continue_transfer (GET_CORE_IF(pcd), &ep0->dwc_ep);
19247+ ep0->dwc_ep.sent_zlp = 0;
19248+ DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");
19249+ }
19250+ else {
19251+ ep0_complete_request(ep0);
19252+ DWC_DEBUGPL(DBG_PCD, "COMPLETE TRANSFER\n");
19253+ }
19254+ break;
19255+
19256+ case EP0_IN_STATUS_PHASE:
19257+ case EP0_OUT_STATUS_PHASE:
19258+ DWC_DEBUGPL(DBG_PCD, "CASE: EP0_STATUS\n");
19259+ ep0_complete_request(ep0);
19260+ pcd->ep0state = EP0_IDLE;
19261+ ep0->stopped = 1;
19262+ ep0->dwc_ep.is_in = 0; /* OUT for next SETUP */
19263+
19264+ /* Prepare for more SETUP Packets */
19265+ if(core_if->dma_enable) {
19266+ ep0_out_start(core_if, pcd);
19267+ }
19268+ break;
19269+
19270+ case EP0_STALL:
19271+ DWC_ERROR("EP0 STALLed, should not get here pcd_setup()\n");
19272+ break;
19273+ }
19274+#ifdef DEBUG_EP0
19275+ print_ep0_state(pcd);
19276+#endif
19277+}
19278+
19279+
19280+/**
19281+ * Restart transfer
19282+ */
19283+static void restart_transfer(dwc_otg_pcd_t *pcd, const uint32_t epnum)
19284+{
19285+ dwc_otg_core_if_t *core_if;
19286+ dwc_otg_dev_if_t *dev_if;
19287+ deptsiz_data_t dieptsiz = {.d32=0};
19288+ dwc_otg_pcd_ep_t *ep;
19289+
19290+ ep = get_in_ep(pcd, epnum);
19291+
19292+#ifdef DWC_EN_ISOC
19293+ if(ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) {
19294+ return;
19295+ }
19296+#endif /* DWC_EN_ISOC */
19297+
19298+ core_if = GET_CORE_IF(pcd);
19299+ dev_if = core_if->dev_if;
19300+
19301+ dieptsiz.d32 = dwc_read_reg32(&dev_if->in_ep_regs[epnum]->dieptsiz);
19302+
19303+ DWC_DEBUGPL(DBG_PCD,"xfer_buff=%p xfer_count=%0x xfer_len=%0x"
19304+ " stopped=%d\n", ep->dwc_ep.xfer_buff,
19305+ ep->dwc_ep.xfer_count, ep->dwc_ep.xfer_len ,
19306+ ep->stopped);
19307+ /*
19308+ * If xfersize is 0 and pktcnt in not 0, resend the last packet.
19309+ */
19310+ if (dieptsiz.b.pktcnt && dieptsiz.b.xfersize == 0 &&
19311+ ep->dwc_ep.start_xfer_buff != 0) {
19312+ if (ep->dwc_ep.total_len <= ep->dwc_ep.maxpacket) {
19313+ ep->dwc_ep.xfer_count = 0;
19314+ ep->dwc_ep.xfer_buff = ep->dwc_ep.start_xfer_buff;
19315+ ep->dwc_ep.xfer_len = ep->dwc_ep.xfer_count;
19316+ }
19317+ else {
19318+ ep->dwc_ep.xfer_count -= ep->dwc_ep.maxpacket;
19319+ /* convert packet size to dwords. */
19320+ ep->dwc_ep.xfer_buff -= ep->dwc_ep.maxpacket;
19321+ ep->dwc_ep.xfer_len = ep->dwc_ep.xfer_count;
19322+ }
19323+ ep->stopped = 0;
19324+ DWC_DEBUGPL(DBG_PCD,"xfer_buff=%p xfer_count=%0x "
19325+ "xfer_len=%0x stopped=%d\n",
19326+ ep->dwc_ep.xfer_buff,
19327+ ep->dwc_ep.xfer_count, ep->dwc_ep.xfer_len ,
19328+ ep->stopped
19329+ );
19330+ if (epnum == 0) {
19331+ dwc_otg_ep0_start_transfer(core_if, &ep->dwc_ep);
19332+ }
19333+ else {
19334+ dwc_otg_ep_start_transfer(core_if, &ep->dwc_ep);
19335+ }
19336+ }
19337+}
19338+
19339+
19340+/**
19341+ * handle the IN EP disable interrupt.
19342+ */
19343+static inline void handle_in_ep_disable_intr(dwc_otg_pcd_t *pcd,
19344+ const uint32_t epnum)
19345+{
19346+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
19347+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
19348+ deptsiz_data_t dieptsiz = {.d32=0};
19349+ dctl_data_t dctl = {.d32=0};
19350+ dwc_otg_pcd_ep_t *ep;
19351+ dwc_ep_t *dwc_ep;
19352+
19353+ ep = get_in_ep(pcd, epnum);
19354+ dwc_ep = &ep->dwc_ep;
19355+
19356+ if(dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
19357+ dwc_otg_flush_tx_fifo(core_if, dwc_ep->tx_fifo_num);
19358+ return;
19359+ }
19360+
19361+ DWC_DEBUGPL(DBG_PCD,"diepctl%d=%0x\n", epnum,
19362+ dwc_read_reg32(&dev_if->in_ep_regs[epnum]->diepctl));
19363+ dieptsiz.d32 = dwc_read_reg32(&dev_if->in_ep_regs[epnum]->dieptsiz);
19364+
19365+ DWC_DEBUGPL(DBG_ANY, "pktcnt=%d size=%d\n",
19366+ dieptsiz.b.pktcnt,
19367+ dieptsiz.b.xfersize);
19368+
19369+ if (ep->stopped) {
19370+ /* Flush the Tx FIFO */
19371+ dwc_otg_flush_tx_fifo(core_if, dwc_ep->tx_fifo_num);
19372+ /* Clear the Global IN NP NAK */
19373+ dctl.d32 = 0;
19374+ dctl.b.cgnpinnak = 1;
19375+ dwc_modify_reg32(&dev_if->dev_global_regs->dctl,
19376+ dctl.d32, 0);
19377+ /* Restart the transaction */
19378+ if (dieptsiz.b.pktcnt != 0 ||
19379+ dieptsiz.b.xfersize != 0) {
19380+ restart_transfer(pcd, epnum);
19381+ }
19382+ }
19383+ else {
19384+ /* Restart the transaction */
19385+ if (dieptsiz.b.pktcnt != 0 ||
19386+ dieptsiz.b.xfersize != 0) {
19387+ restart_transfer(pcd, epnum);
19388+ }
19389+ DWC_DEBUGPL(DBG_ANY, "STOPPED!!!\n");
19390+ }
19391+}
19392+
19393+/**
19394+ * Handler for the IN EP timeout handshake interrupt.
19395+ */
19396+static inline void handle_in_ep_timeout_intr(dwc_otg_pcd_t *pcd,
19397+ const uint32_t epnum)
19398+{
19399+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
19400+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
19401+
19402+#ifdef DEBUG
19403+ deptsiz_data_t dieptsiz = {.d32=0};
19404+ uint32_t num = 0;
19405+#endif
19406+ dctl_data_t dctl = {.d32=0};
19407+ dwc_otg_pcd_ep_t *ep;
19408+
19409+ gintmsk_data_t intr_mask = {.d32 = 0};
19410+
19411+ ep = get_in_ep(pcd, epnum);
19412+
19413+ /* Disable the NP Tx Fifo Empty Interrrupt */
19414+ if (!core_if->dma_enable) {
19415+ intr_mask.b.nptxfempty = 1;
19416+ dwc_modify_reg32(&core_if->core_global_regs->gintmsk, intr_mask.d32, 0);
19417+ }
19418+ /** @todo NGS Check EP type.
19419+ * Implement for Periodic EPs */
19420+ /*
19421+ * Non-periodic EP
19422+ */
19423+ /* Enable the Global IN NAK Effective Interrupt */
19424+ intr_mask.b.ginnakeff = 1;
19425+ dwc_modify_reg32(&core_if->core_global_regs->gintmsk,
19426+ 0, intr_mask.d32);
19427+
19428+ /* Set Global IN NAK */
19429+ dctl.b.sgnpinnak = 1;
19430+ dwc_modify_reg32(&dev_if->dev_global_regs->dctl,
19431+ dctl.d32, dctl.d32);
19432+
19433+ ep->stopped = 1;
19434+
19435+#ifdef DEBUG
19436+ dieptsiz.d32 = dwc_read_reg32(&dev_if->in_ep_regs[num]->dieptsiz);
19437+ DWC_DEBUGPL(DBG_ANY, "pktcnt=%d size=%d\n",
19438+ dieptsiz.b.pktcnt,
19439+ dieptsiz.b.xfersize);
19440+#endif
19441+
19442+#ifdef DISABLE_PERIODIC_EP
19443+ /*
19444+ * Set the NAK bit for this EP to
19445+ * start the disable process.
19446+ */
19447+ diepctl.d32 = 0;
19448+ diepctl.b.snak = 1;
19449+ dwc_modify_reg32(&dev_if->in_ep_regs[num]->diepctl, diepctl.d32, diepctl.d32);
19450+ ep->disabling = 1;
19451+ ep->stopped = 1;
19452+#endif
19453+}
19454+
19455+/**
19456+ * Handler for the IN EP NAK interrupt.
19457+ */
19458+static inline int32_t handle_in_ep_nak_intr(dwc_otg_pcd_t *pcd,
19459+ const uint32_t epnum)
19460+{
19461+ /** @todo implement ISR */
19462+ dwc_otg_core_if_t* core_if;
19463+ diepmsk_data_t intr_mask = { .d32 = 0};
19464+
19465+ DWC_PRINT("INTERRUPT Handler not implemented for %s\n", "IN EP NAK");
19466+ core_if = GET_CORE_IF(pcd);
19467+ intr_mask.b.nak = 1;
19468+
19469+ if(core_if->multiproc_int_enable) {
19470+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->diepeachintmsk[epnum],
19471+ intr_mask.d32, 0);
19472+ } else {
19473+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->diepmsk,
19474+ intr_mask.d32, 0);
19475+ }
19476+
19477+ return 1;
19478+}
19479+
19480+/**
19481+ * Handler for the OUT EP Babble interrupt.
19482+ */
19483+static inline int32_t handle_out_ep_babble_intr(dwc_otg_pcd_t *pcd,
19484+ const uint32_t epnum)
19485+{
19486+ /** @todo implement ISR */
19487+ dwc_otg_core_if_t* core_if;
19488+ doepmsk_data_t intr_mask = { .d32 = 0};
19489+
19490+ DWC_PRINT("INTERRUPT Handler not implemented for %s\n", "OUT EP Babble");
19491+ core_if = GET_CORE_IF(pcd);
19492+ intr_mask.b.babble = 1;
19493+
19494+ if(core_if->multiproc_int_enable) {
19495+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->doepeachintmsk[epnum],
19496+ intr_mask.d32, 0);
19497+ } else {
19498+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->doepmsk,
19499+ intr_mask.d32, 0);
19500+ }
19501+
19502+ return 1;
19503+}
19504+
19505+/**
19506+ * Handler for the OUT EP NAK interrupt.
19507+ */
19508+static inline int32_t handle_out_ep_nak_intr(dwc_otg_pcd_t *pcd,
19509+ const uint32_t epnum)
19510+{
19511+ /** @todo implement ISR */
19512+ dwc_otg_core_if_t* core_if;
19513+ doepmsk_data_t intr_mask = { .d32 = 0};
19514+
19515+ DWC_PRINT("INTERRUPT Handler not implemented for %s\n", "OUT EP NAK");
19516+ core_if = GET_CORE_IF(pcd);
19517+ intr_mask.b.nak = 1;
19518+
19519+ if(core_if->multiproc_int_enable) {
19520+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->doepeachintmsk[epnum],
19521+ intr_mask.d32, 0);
19522+ } else {
19523+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->doepmsk,
19524+ intr_mask.d32, 0);
19525+ }
19526+
19527+ return 1;
19528+}
19529+
19530+/**
19531+ * Handler for the OUT EP NYET interrupt.
19532+ */
19533+static inline int32_t handle_out_ep_nyet_intr(dwc_otg_pcd_t *pcd,
19534+ const uint32_t epnum)
19535+{
19536+ /** @todo implement ISR */
19537+ dwc_otg_core_if_t* core_if;
19538+ doepmsk_data_t intr_mask = { .d32 = 0};
19539+
19540+ DWC_PRINT("INTERRUPT Handler not implemented for %s\n", "OUT EP NYET");
19541+ core_if = GET_CORE_IF(pcd);
19542+ intr_mask.b.nyet = 1;
19543+
19544+ if(core_if->multiproc_int_enable) {
19545+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->doepeachintmsk[epnum],
19546+ intr_mask.d32, 0);
19547+ } else {
19548+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->doepmsk,
19549+ intr_mask.d32, 0);
19550+ }
19551+
19552+ return 1;
19553+}
19554+
19555+/**
19556+ * This interrupt indicates that an IN EP has a pending Interrupt.
19557+ * The sequence for handling the IN EP interrupt is shown below:
19558+ * -# Read the Device All Endpoint Interrupt register
19559+ * -# Repeat the following for each IN EP interrupt bit set (from
19560+ * LSB to MSB).
19561+ * -# Read the Device Endpoint Interrupt (DIEPINTn) register
19562+ * -# If "Transfer Complete" call the request complete function
19563+ * -# If "Endpoint Disabled" complete the EP disable procedure.
19564+ * -# If "AHB Error Interrupt" log error
19565+ * -# If "Time-out Handshake" log error
19566+ * -# If "IN Token Received when TxFIFO Empty" write packet to Tx
19567+ * FIFO.
19568+ * -# If "IN Token EP Mismatch" (disable, this is handled by EP
19569+ * Mismatch Interrupt)
19570+ */
19571+static int32_t dwc_otg_pcd_handle_in_ep_intr(dwc_otg_pcd_t *pcd)
19572+{
19573+#define CLEAR_IN_EP_INTR(__core_if,__epnum,__intr) \
19574+do { \
19575+ diepint_data_t diepint = {.d32=0}; \
19576+ diepint.b.__intr = 1; \
19577+ dwc_write_reg32(&__core_if->dev_if->in_ep_regs[__epnum]->diepint, \
19578+ diepint.d32); \
19579+} while (0)
19580+
19581+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
19582+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
19583+ diepint_data_t diepint = {.d32=0};
19584+ dctl_data_t dctl = {.d32=0};
19585+ depctl_data_t depctl = {.d32=0};
19586+ uint32_t ep_intr;
19587+ uint32_t epnum = 0;
19588+ dwc_otg_pcd_ep_t *ep;
19589+ dwc_ep_t *dwc_ep;
19590+ gintmsk_data_t intr_mask = {.d32 = 0};
19591+
19592+ DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, pcd);
19593+
19594+ /* Read in the device interrupt bits */
19595+ ep_intr = dwc_otg_read_dev_all_in_ep_intr(core_if);
19596+
19597+ /* Service the Device IN interrupts for each endpoint */
19598+ while(ep_intr) {
19599+ if (ep_intr&0x1) {
19600+ uint32_t empty_msk;
19601+ /* Get EP pointer */
19602+ ep = get_in_ep(pcd, epnum);
19603+ dwc_ep = &ep->dwc_ep;
19604+
19605+ depctl.d32 = dwc_read_reg32(&dev_if->in_ep_regs[epnum]->diepctl);
19606+ empty_msk = dwc_read_reg32(&dev_if->dev_global_regs->dtknqr4_fifoemptymsk);
19607+
19608+ DWC_DEBUGPL(DBG_PCDV,
19609+ "IN EP INTERRUPT - %d\nepmty_msk - %8x diepctl - %8x\n",
19610+ epnum,
19611+ empty_msk,
19612+ depctl.d32);
19613+
19614+ DWC_DEBUGPL(DBG_PCD,
19615+ "EP%d-%s: type=%d, mps=%d\n",
19616+ dwc_ep->num, (dwc_ep->is_in ?"IN":"OUT"),
19617+ dwc_ep->type, dwc_ep->maxpacket);
19618+
19619+ diepint.d32 = dwc_otg_read_dev_in_ep_intr(core_if, dwc_ep);
19620+
19621+ DWC_DEBUGPL(DBG_PCDV, "EP %d Interrupt Register - 0x%x\n", epnum, diepint.d32);
19622+ /* Transfer complete */
19623+ if (diepint.b.xfercompl) {
19624+ /* Disable the NP Tx FIFO Empty
19625+ * Interrrupt */
19626+ if(core_if->en_multiple_tx_fifo == 0) {
19627+ intr_mask.b.nptxfempty = 1;
19628+ dwc_modify_reg32(&core_if->core_global_regs->gintmsk, intr_mask.d32, 0);
19629+ }
19630+ else {
19631+ /* Disable the Tx FIFO Empty Interrupt for this EP */
19632+ uint32_t fifoemptymsk = 0x1 << dwc_ep->num;
19633+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
19634+ fifoemptymsk, 0);
19635+ }
19636+ /* Clear the bit in DIEPINTn for this interrupt */
19637+ CLEAR_IN_EP_INTR(core_if,epnum,xfercompl);
19638+
19639+ /* Complete the transfer */
19640+ if (epnum == 0) {
19641+ handle_ep0(pcd);
19642+ }
19643+#ifdef DWC_EN_ISOC
19644+ else if(dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
19645+ if(!ep->stopped)
19646+ complete_iso_ep(ep);
19647+ }
19648+#endif //DWC_EN_ISOC
19649+ else {
19650+
19651+ complete_ep(ep);
19652+ }
19653+ }
19654+ /* Endpoint disable */
19655+ if (diepint.b.epdisabled) {
19656+ DWC_DEBUGPL(DBG_ANY,"EP%d IN disabled\n", epnum);
19657+ handle_in_ep_disable_intr(pcd, epnum);
19658+
19659+ /* Clear the bit in DIEPINTn for this interrupt */
19660+ CLEAR_IN_EP_INTR(core_if,epnum,epdisabled);
19661+ }
19662+ /* AHB Error */
19663+ if (diepint.b.ahberr) {
19664+ DWC_DEBUGPL(DBG_ANY,"EP%d IN AHB Error\n", epnum);
19665+ /* Clear the bit in DIEPINTn for this interrupt */
19666+ CLEAR_IN_EP_INTR(core_if,epnum,ahberr);
19667+ }
19668+ /* TimeOUT Handshake (non-ISOC IN EPs) */
19669+ if (diepint.b.timeout) {
19670+ DWC_DEBUGPL(DBG_ANY,"EP%d IN Time-out\n", epnum);
19671+ handle_in_ep_timeout_intr(pcd, epnum);
19672+
19673+ CLEAR_IN_EP_INTR(core_if,epnum,timeout);
19674+ }
19675+ /** IN Token received with TxF Empty */
19676+ if (diepint.b.intktxfemp) {
19677+ DWC_DEBUGPL(DBG_ANY,"EP%d IN TKN TxFifo Empty\n",
19678+ epnum);
19679+ if (!ep->stopped && epnum != 0) {
19680+
19681+ diepmsk_data_t diepmsk = { .d32 = 0};
19682+ diepmsk.b.intktxfemp = 1;
19683+
19684+ if(core_if->multiproc_int_enable) {
19685+ dwc_modify_reg32(&dev_if->dev_global_regs->diepeachintmsk[epnum],
19686+ diepmsk.d32, 0);
19687+ } else {
19688+ dwc_modify_reg32(&dev_if->dev_global_regs->diepmsk, diepmsk.d32, 0);
19689+ }
19690+ start_next_request(ep);
19691+ }
19692+ else if(core_if->dma_desc_enable && epnum == 0 &&
19693+ pcd->ep0state == EP0_OUT_STATUS_PHASE) {
19694+ // EP0 IN set STALL
19695+ depctl.d32 = dwc_read_reg32(&dev_if->in_ep_regs[epnum]->diepctl);
19696+
19697+ /* set the disable and stall bits */
19698+ if (depctl.b.epena) {
19699+ depctl.b.epdis = 1;
19700+ }
19701+ depctl.b.stall = 1;
19702+ dwc_write_reg32(&dev_if->in_ep_regs[epnum]->diepctl, depctl.d32);
19703+ }
19704+ CLEAR_IN_EP_INTR(core_if,epnum,intktxfemp);
19705+ }
19706+ /** IN Token Received with EP mismatch */
19707+ if (diepint.b.intknepmis) {
19708+ DWC_DEBUGPL(DBG_ANY,"EP%d IN TKN EP Mismatch\n", epnum);
19709+ CLEAR_IN_EP_INTR(core_if,epnum,intknepmis);
19710+ }
19711+ /** IN Endpoint NAK Effective */
19712+ if (diepint.b.inepnakeff) {
19713+ DWC_DEBUGPL(DBG_ANY,"EP%d IN EP NAK Effective\n", epnum);
19714+ /* Periodic EP */
19715+ if (ep->disabling) {
19716+ depctl.d32 = 0;
19717+ depctl.b.snak = 1;
19718+ depctl.b.epdis = 1;
19719+ dwc_modify_reg32(&dev_if->in_ep_regs[epnum]->diepctl, depctl.d32, depctl.d32);
19720+ }
19721+ CLEAR_IN_EP_INTR(core_if,epnum,inepnakeff);
19722+
19723+ }
19724+
19725+ /** IN EP Tx FIFO Empty Intr */
19726+ if (diepint.b.emptyintr) {
19727+ DWC_DEBUGPL(DBG_ANY,"EP%d Tx FIFO Empty Intr \n", epnum);
19728+ write_empty_tx_fifo(pcd, epnum);
19729+
19730+ CLEAR_IN_EP_INTR(core_if,epnum,emptyintr);
19731+ }
19732+
19733+ /** IN EP BNA Intr */
19734+ if (diepint.b.bna) {
19735+ CLEAR_IN_EP_INTR(core_if,epnum,bna);
19736+ if(core_if->dma_desc_enable) {
19737+#ifdef DWC_EN_ISOC
19738+ if(dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
19739+ /*
19740+ * This checking is performed to prevent first "false" BNA
19741+ * handling occuring right after reconnect
19742+ */
19743+ if(dwc_ep->next_frame != 0xffffffff)
19744+ dwc_otg_pcd_handle_iso_bna(ep);
19745+ }
19746+ else
19747+#endif //DWC_EN_ISOC
19748+ {
19749+ dctl.d32 = dwc_read_reg32(&dev_if->dev_global_regs->dctl);
19750+
19751+ /* If Global Continue on BNA is disabled - disable EP */
19752+ if(!dctl.b.gcontbna) {
19753+ depctl.d32 = 0;
19754+ depctl.b.snak = 1;
19755+ depctl.b.epdis = 1;
19756+ dwc_modify_reg32(&dev_if->in_ep_regs[epnum]->diepctl, depctl.d32, depctl.d32);
19757+ } else {
19758+ start_next_request(ep);
19759+ }
19760+ }
19761+ }
19762+ }
19763+ /* NAK Interrutp */
19764+ if (diepint.b.nak) {
19765+ DWC_DEBUGPL(DBG_ANY,"EP%d IN NAK Interrupt\n", epnum);
19766+ handle_in_ep_nak_intr(pcd, epnum);
19767+
19768+ CLEAR_IN_EP_INTR(core_if,epnum,nak);
19769+ }
19770+ }
19771+ epnum++;
19772+ ep_intr >>=1;
19773+ }
19774+
19775+ return 1;
19776+#undef CLEAR_IN_EP_INTR
19777+}
19778+
19779+/**
19780+ * This interrupt indicates that an OUT EP has a pending Interrupt.
19781+ * The sequence for handling the OUT EP interrupt is shown below:
19782+ * -# Read the Device All Endpoint Interrupt register
19783+ * -# Repeat the following for each OUT EP interrupt bit set (from
19784+ * LSB to MSB).
19785+ * -# Read the Device Endpoint Interrupt (DOEPINTn) register
19786+ * -# If "Transfer Complete" call the request complete function
19787+ * -# If "Endpoint Disabled" complete the EP disable procedure.
19788+ * -# If "AHB Error Interrupt" log error
19789+ * -# If "Setup Phase Done" process Setup Packet (See Standard USB
19790+ * Command Processing)
19791+ */
19792+static int32_t dwc_otg_pcd_handle_out_ep_intr(dwc_otg_pcd_t *pcd)
19793+{
19794+#define CLEAR_OUT_EP_INTR(__core_if,__epnum,__intr) \
19795+do { \
19796+ doepint_data_t doepint = {.d32=0}; \
19797+ doepint.b.__intr = 1; \
19798+ dwc_write_reg32(&__core_if->dev_if->out_ep_regs[__epnum]->doepint, \
19799+ doepint.d32); \
19800+} while (0)
19801+
19802+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
19803+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
19804+ uint32_t ep_intr;
19805+ doepint_data_t doepint = {.d32=0};
19806+ dctl_data_t dctl = {.d32=0};
19807+ depctl_data_t doepctl = {.d32=0};
19808+ uint32_t epnum = 0;
19809+ dwc_otg_pcd_ep_t *ep;
19810+ dwc_ep_t *dwc_ep;
19811+
19812+ DWC_DEBUGPL(DBG_PCDV, "%s()\n", __func__);
19813+
19814+ /* Read in the device interrupt bits */
19815+ ep_intr = dwc_otg_read_dev_all_out_ep_intr(core_if);
19816+
19817+ while(ep_intr) {
19818+ if (ep_intr&0x1) {
19819+ /* Get EP pointer */
19820+ ep = get_out_ep(pcd, epnum);
19821+ dwc_ep = &ep->dwc_ep;
19822+
19823+#ifdef VERBOSE
19824+ DWC_DEBUGPL(DBG_PCDV,
19825+ "EP%d-%s: type=%d, mps=%d\n",
19826+ dwc_ep->num, (dwc_ep->is_in ?"IN":"OUT"),
19827+ dwc_ep->type, dwc_ep->maxpacket);
19828+#endif
19829+ doepint.d32 = dwc_otg_read_dev_out_ep_intr(core_if, dwc_ep);
19830+
19831+ /* Transfer complete */
19832+ if (doepint.b.xfercompl) {
19833+ if (epnum == 0) {
19834+ /* Clear the bit in DOEPINTn for this interrupt */
19835+ CLEAR_OUT_EP_INTR(core_if,epnum,xfercompl);
19836+ if(core_if->dma_desc_enable == 0 || pcd->ep0state != EP0_IDLE)
19837+ handle_ep0(pcd);
19838+#ifdef DWC_EN_ISOC
19839+ } else if(dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
19840+ if (doepint.b.pktdrpsts == 0) {
19841+ /* Clear the bit in DOEPINTn for this interrupt */
19842+ CLEAR_OUT_EP_INTR(core_if,epnum,xfercompl);
19843+ complete_iso_ep(ep);
19844+ } else {
19845+ doepint_data_t doepint = {.d32=0};
19846+ doepint.b.xfercompl = 1;
19847+ doepint.b.pktdrpsts = 1;
19848+ dwc_write_reg32(&core_if->dev_if->out_ep_regs[epnum]->doepint,
19849+ doepint.d32);
19850+ if(handle_iso_out_pkt_dropped(core_if,dwc_ep)) {
19851+ complete_iso_ep(ep);
19852+ }
19853+ }
19854+#endif //DWC_EN_ISOC
19855+ } else {
19856+ /* Clear the bit in DOEPINTn for this interrupt */
19857+ CLEAR_OUT_EP_INTR(core_if,epnum,xfercompl);
19858+ complete_ep(ep);
19859+ }
19860+
19861+ }
19862+
19863+ /* Endpoint disable */
19864+ if (doepint.b.epdisabled) {
19865+ /* Clear the bit in DOEPINTn for this interrupt */
19866+ CLEAR_OUT_EP_INTR(core_if,epnum,epdisabled);
19867+ }
19868+ /* AHB Error */
19869+ if (doepint.b.ahberr) {
19870+ DWC_DEBUGPL(DBG_PCD,"EP%d OUT AHB Error\n", epnum);
19871+ DWC_DEBUGPL(DBG_PCD,"EP DMA REG %d \n", core_if->dev_if->out_ep_regs[epnum]->doepdma);
19872+ CLEAR_OUT_EP_INTR(core_if,epnum,ahberr);
19873+ }
19874+ /* Setup Phase Done (contorl EPs) */
19875+ if (doepint.b.setup) {
19876+#ifdef DEBUG_EP0
19877+ DWC_DEBUGPL(DBG_PCD,"EP%d SETUP Done\n",
19878+ epnum);
19879+#endif
19880+ CLEAR_OUT_EP_INTR(core_if,epnum,setup);
19881+ handle_ep0(pcd);
19882+ }
19883+
19884+ /** OUT EP BNA Intr */
19885+ if (doepint.b.bna) {
19886+ CLEAR_OUT_EP_INTR(core_if,epnum,bna);
19887+ if(core_if->dma_desc_enable) {
19888+#ifdef DWC_EN_ISOC
19889+ if(dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
19890+ /*
19891+ * This checking is performed to prevent first "false" BNA
19892+ * handling occuring right after reconnect
19893+ */
19894+ if(dwc_ep->next_frame != 0xffffffff)
19895+ dwc_otg_pcd_handle_iso_bna(ep);
19896+ }
19897+ else
19898+#endif //DWC_EN_ISOC
19899+ {
19900+ dctl.d32 = dwc_read_reg32(&dev_if->dev_global_regs->dctl);
19901+
19902+ /* If Global Continue on BNA is disabled - disable EP*/
19903+ if(!dctl.b.gcontbna) {
19904+ doepctl.d32 = 0;
19905+ doepctl.b.snak = 1;
19906+ doepctl.b.epdis = 1;
19907+ dwc_modify_reg32(&dev_if->out_ep_regs[epnum]->doepctl, doepctl.d32, doepctl.d32);
19908+ } else {
19909+ start_next_request(ep);
19910+ }
19911+ }
19912+ }
19913+ }
19914+ if (doepint.b.stsphsercvd) {
19915+ CLEAR_OUT_EP_INTR(core_if,epnum,stsphsercvd);
19916+ if(core_if->dma_desc_enable) {
19917+ do_setup_in_status_phase(pcd);
19918+ }
19919+ }
19920+ /* Babble Interrutp */
19921+ if (doepint.b.babble) {
19922+ DWC_DEBUGPL(DBG_ANY,"EP%d OUT Babble\n", epnum);
19923+ handle_out_ep_babble_intr(pcd, epnum);
19924+
19925+ CLEAR_OUT_EP_INTR(core_if,epnum,babble);
19926+ }
19927+ /* NAK Interrutp */
19928+ if (doepint.b.nak) {
19929+ DWC_DEBUGPL(DBG_ANY,"EP%d OUT NAK\n", epnum);
19930+ handle_out_ep_nak_intr(pcd, epnum);
19931+
19932+ CLEAR_OUT_EP_INTR(core_if,epnum,nak);
19933+ }
19934+ /* NYET Interrutp */
19935+ if (doepint.b.nyet) {
19936+ DWC_DEBUGPL(DBG_ANY,"EP%d OUT NYET\n", epnum);
19937+ handle_out_ep_nyet_intr(pcd, epnum);
19938+
19939+ CLEAR_OUT_EP_INTR(core_if,epnum,nyet);
19940+ }
19941+ }
19942+
19943+ epnum++;
19944+ ep_intr >>=1;
19945+ }
19946+
19947+ return 1;
19948+
19949+#undef CLEAR_OUT_EP_INTR
19950+}
19951+
19952+
19953+/**
19954+ * Incomplete ISO IN Transfer Interrupt.
19955+ * This interrupt indicates one of the following conditions occurred
19956+ * while transmitting an ISOC transaction.
19957+ * - Corrupted IN Token for ISOC EP.
19958+ * - Packet not complete in FIFO.
19959+ * The follow actions will be taken:
19960+ * -# Determine the EP
19961+ * -# Set incomplete flag in dwc_ep structure
19962+ * -# Disable EP; when "Endpoint Disabled" interrupt is received
19963+ * Flush FIFO
19964+ */
19965+int32_t dwc_otg_pcd_handle_incomplete_isoc_in_intr(dwc_otg_pcd_t *pcd)
19966+{
19967+ gintsts_data_t gintsts;
19968+
19969+
19970+#ifdef DWC_EN_ISOC
19971+ dwc_otg_dev_if_t *dev_if;
19972+ deptsiz_data_t deptsiz = { .d32 = 0};
19973+ depctl_data_t depctl = { .d32 = 0};
19974+ dsts_data_t dsts = { .d32 = 0};
19975+ dwc_ep_t *dwc_ep;
19976+ int i;
19977+
19978+ dev_if = GET_CORE_IF(pcd)->dev_if;
19979+
19980+ for(i = 1; i <= dev_if->num_in_eps; ++i) {
19981+ dwc_ep = &pcd->in_ep[i].dwc_ep;
19982+ if(dwc_ep->active &&
19983+ dwc_ep->type == USB_ENDPOINT_XFER_ISOC)
19984+ {
19985+ deptsiz.d32 = dwc_read_reg32(&dev_if->in_ep_regs[i]->dieptsiz);
19986+ depctl.d32 = dwc_read_reg32(&dev_if->in_ep_regs[i]->diepctl);
19987+
19988+ if(depctl.b.epdis && deptsiz.d32) {
19989+ set_current_pkt_info(GET_CORE_IF(pcd), dwc_ep);
19990+ if(dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
19991+ dwc_ep->cur_pkt = 0;
19992+ dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1;
19993+
19994+ if(dwc_ep->proc_buf_num) {
19995+ dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff1;
19996+ dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr1;
19997+ } else {
19998+ dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff0;
19999+ dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr0;
20000+ }
20001+ }
20002+
20003+ dsts.d32 = dwc_read_reg32(&GET_CORE_IF(pcd)->dev_if->dev_global_regs->dsts);
20004+ dwc_ep->next_frame = dsts.b.soffn;
20005+
20006+ dwc_otg_iso_ep_start_frm_transfer(GET_CORE_IF(pcd), dwc_ep);
20007+ }
20008+ }
20009+ }
20010+
20011+#else
20012+ gintmsk_data_t intr_mask = { .d32 = 0};
20013+ DWC_PRINT("INTERRUPT Handler not implemented for %s\n",
20014+ "IN ISOC Incomplete");
20015+
20016+ intr_mask.b.incomplisoin = 1;
20017+ dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
20018+ intr_mask.d32, 0);
20019+#endif //DWC_EN_ISOC
20020+
20021+ /* Clear interrupt */
20022+ gintsts.d32 = 0;
20023+ gintsts.b.incomplisoin = 1;
20024+ dwc_write_reg32 (&GET_CORE_IF(pcd)->core_global_regs->gintsts,
20025+ gintsts.d32);
20026+
20027+ return 1;
20028+}
20029+
20030+/**
20031+ * Incomplete ISO OUT Transfer Interrupt.
20032+ *
20033+ * This interrupt indicates that the core has dropped an ISO OUT
20034+ * packet. The following conditions can be the cause:
20035+ * - FIFO Full, the entire packet would not fit in the FIFO.
20036+ * - CRC Error
20037+ * - Corrupted Token
20038+ * The follow actions will be taken:
20039+ * -# Determine the EP
20040+ * -# Set incomplete flag in dwc_ep structure
20041+ * -# Read any data from the FIFO
20042+ * -# Disable EP. when "Endpoint Disabled" interrupt is received
20043+ * re-enable EP.
20044+ */
20045+int32_t dwc_otg_pcd_handle_incomplete_isoc_out_intr(dwc_otg_pcd_t *pcd)
20046+{
20047+ /* @todo implement ISR */
20048+ gintsts_data_t gintsts;
20049+
20050+#ifdef DWC_EN_ISOC
20051+ dwc_otg_dev_if_t *dev_if;
20052+ deptsiz_data_t deptsiz = { .d32 = 0};
20053+ depctl_data_t depctl = { .d32 = 0};
20054+ dsts_data_t dsts = { .d32 = 0};
20055+ dwc_ep_t *dwc_ep;
20056+ int i;
20057+
20058+ dev_if = GET_CORE_IF(pcd)->dev_if;
20059+
20060+ for(i = 1; i <= dev_if->num_out_eps; ++i) {
20061+ dwc_ep = &pcd->in_ep[i].dwc_ep;
20062+ if(pcd->out_ep[i].dwc_ep.active &&
20063+ pcd->out_ep[i].dwc_ep.type == USB_ENDPOINT_XFER_ISOC)
20064+ {
20065+ deptsiz.d32 = dwc_read_reg32(&dev_if->out_ep_regs[i]->doeptsiz);
20066+ depctl.d32 = dwc_read_reg32(&dev_if->out_ep_regs[i]->doepctl);
20067+
20068+ if(depctl.b.epdis && deptsiz.d32) {
20069+ set_current_pkt_info(GET_CORE_IF(pcd), &pcd->out_ep[i].dwc_ep);
20070+ if(dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
20071+ dwc_ep->cur_pkt = 0;
20072+ dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1;
20073+
20074+ if(dwc_ep->proc_buf_num) {
20075+ dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff1;
20076+ dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr1;
20077+ } else {
20078+ dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff0;
20079+ dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr0;
20080+ }
20081+ }
20082+
20083+ dsts.d32 = dwc_read_reg32(&GET_CORE_IF(pcd)->dev_if->dev_global_regs->dsts);
20084+ dwc_ep->next_frame = dsts.b.soffn;
20085+
20086+ dwc_otg_iso_ep_start_frm_transfer(GET_CORE_IF(pcd), dwc_ep);
20087+ }
20088+ }
20089+ }
20090+#else
20091+ /** @todo implement ISR */
20092+ gintmsk_data_t intr_mask = { .d32 = 0};
20093+
20094+ DWC_PRINT("INTERRUPT Handler not implemented for %s\n",
20095+ "OUT ISOC Incomplete");
20096+
20097+ intr_mask.b.incomplisoout = 1;
20098+ dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
20099+ intr_mask.d32, 0);
20100+
20101+#endif // DWC_EN_ISOC
20102+
20103+ /* Clear interrupt */
20104+ gintsts.d32 = 0;
20105+ gintsts.b.incomplisoout = 1;
20106+ dwc_write_reg32 (&GET_CORE_IF(pcd)->core_global_regs->gintsts,
20107+ gintsts.d32);
20108+
20109+ return 1;
20110+}
20111+
20112+/**
20113+ * This function handles the Global IN NAK Effective interrupt.
20114+ *
20115+ */
20116+int32_t dwc_otg_pcd_handle_in_nak_effective(dwc_otg_pcd_t *pcd)
20117+{
20118+ dwc_otg_dev_if_t *dev_if = GET_CORE_IF(pcd)->dev_if;
20119+ depctl_data_t diepctl = { .d32 = 0};
20120+ depctl_data_t diepctl_rd = { .d32 = 0};
20121+ gintmsk_data_t intr_mask = { .d32 = 0};
20122+ gintsts_data_t gintsts;
20123+ int i;
20124+
20125+ DWC_DEBUGPL(DBG_PCD, "Global IN NAK Effective\n");
20126+
20127+ /* Disable all active IN EPs */
20128+ diepctl.b.epdis = 1;
20129+ diepctl.b.snak = 1;
20130+
20131+ for (i=0; i <= dev_if->num_in_eps; i++)
20132+ {
20133+ diepctl_rd.d32 = dwc_read_reg32(&dev_if->in_ep_regs[i]->diepctl);
20134+ if (diepctl_rd.b.epena) {
20135+ dwc_write_reg32(&dev_if->in_ep_regs[i]->diepctl,
20136+ diepctl.d32);
20137+ }
20138+ }
20139+ /* Disable the Global IN NAK Effective Interrupt */
20140+ intr_mask.b.ginnakeff = 1;
20141+ dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
20142+ intr_mask.d32, 0);
20143+
20144+ /* Clear interrupt */
20145+ gintsts.d32 = 0;
20146+ gintsts.b.ginnakeff = 1;
20147+ dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
20148+ gintsts.d32);
20149+
20150+ return 1;
20151+}
20152+
20153+/**
20154+ * OUT NAK Effective.
20155+ *
20156+ */
20157+int32_t dwc_otg_pcd_handle_out_nak_effective(dwc_otg_pcd_t *pcd)
20158+{
20159+ gintmsk_data_t intr_mask = { .d32 = 0};
20160+ gintsts_data_t gintsts;
20161+
20162+ DWC_PRINT("INTERRUPT Handler not implemented for %s\n",
20163+ "Global IN NAK Effective\n");
20164+ /* Disable the Global IN NAK Effective Interrupt */
20165+ intr_mask.b.goutnakeff = 1;
20166+ dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
20167+ intr_mask.d32, 0);
20168+
20169+ /* Clear interrupt */
20170+ gintsts.d32 = 0;
20171+ gintsts.b.goutnakeff = 1;
20172+ dwc_write_reg32 (&GET_CORE_IF(pcd)->core_global_regs->gintsts,
20173+ gintsts.d32);
20174+
20175+ return 1;
20176+}
20177+
20178+
20179+/**
20180+ * PCD interrupt handler.
20181+ *
20182+ * The PCD handles the device interrupts. Many conditions can cause a
20183+ * device interrupt. When an interrupt occurs, the device interrupt
20184+ * service routine determines the cause of the interrupt and
20185+ * dispatches handling to the appropriate function. These interrupt
20186+ * handling functions are described below.
20187+ *
20188+ * All interrupt registers are processed from LSB to MSB.
20189+ *
20190+ */
20191+int32_t dwc_otg_pcd_handle_intr(dwc_otg_pcd_t *pcd)
20192+{
20193+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
20194+#ifdef VERBOSE
20195+ dwc_otg_core_global_regs_t *global_regs =
20196+ core_if->core_global_regs;
20197+#endif
20198+ gintsts_data_t gintr_status;
20199+ int32_t retval = 0;
20200+
20201+
20202+#ifdef VERBOSE
20203+ DWC_DEBUGPL(DBG_ANY, "%s() gintsts=%08x gintmsk=%08x\n",
20204+ __func__,
20205+ dwc_read_reg32(&global_regs->gintsts),
20206+ dwc_read_reg32(&global_regs->gintmsk));
20207+#endif
20208+
20209+ if (dwc_otg_is_device_mode(core_if)) {
20210+ SPIN_LOCK(&pcd->lock);
20211+#ifdef VERBOSE
20212+ DWC_DEBUGPL(DBG_PCDV, "%s() gintsts=%08x gintmsk=%08x\n",
20213+ __func__,
20214+ dwc_read_reg32(&global_regs->gintsts),
20215+ dwc_read_reg32(&global_regs->gintmsk));
20216+#endif
20217+
20218+ gintr_status.d32 = dwc_otg_read_core_intr(core_if);
20219+/*
20220+ if (!gintr_status.d32) {
20221+ SPIN_UNLOCK(&pcd->lock);
20222+ return 0;
20223+ }
20224+*/
20225+ DWC_DEBUGPL(DBG_PCDV, "%s: gintsts&gintmsk=%08x\n",
20226+ __func__, gintr_status.d32);
20227+
20228+ if (gintr_status.b.sofintr) {
20229+ retval |= dwc_otg_pcd_handle_sof_intr(pcd);
20230+ }
20231+ if (gintr_status.b.rxstsqlvl) {
20232+ retval |= dwc_otg_pcd_handle_rx_status_q_level_intr(pcd);
20233+ }
20234+ if (gintr_status.b.nptxfempty) {
20235+ retval |= dwc_otg_pcd_handle_np_tx_fifo_empty_intr(pcd);
20236+ }
20237+ if (gintr_status.b.ginnakeff) {
20238+ retval |= dwc_otg_pcd_handle_in_nak_effective(pcd);
20239+ }
20240+ if (gintr_status.b.goutnakeff) {
20241+ retval |= dwc_otg_pcd_handle_out_nak_effective(pcd);
20242+ }
20243+ if (gintr_status.b.i2cintr) {
20244+ retval |= dwc_otg_pcd_handle_i2c_intr(pcd);
20245+ }
20246+ if (gintr_status.b.erlysuspend) {
20247+ retval |= dwc_otg_pcd_handle_early_suspend_intr(pcd);
20248+ }
20249+ if (gintr_status.b.usbreset) {
20250+ retval |= dwc_otg_pcd_handle_usb_reset_intr(pcd);
20251+ }
20252+ if (gintr_status.b.enumdone) {
20253+ retval |= dwc_otg_pcd_handle_enum_done_intr(pcd);
20254+ }
20255+ if (gintr_status.b.isooutdrop) {
20256+ retval |= dwc_otg_pcd_handle_isoc_out_packet_dropped_intr(pcd);
20257+ }
20258+ if (gintr_status.b.eopframe) {
20259+ retval |= dwc_otg_pcd_handle_end_periodic_frame_intr(pcd);
20260+ }
20261+ if (gintr_status.b.epmismatch) {
20262+ retval |= dwc_otg_pcd_handle_ep_mismatch_intr(core_if);
20263+ }
20264+ if (gintr_status.b.inepint) {
20265+ if(!core_if->multiproc_int_enable) {
20266+ retval |= dwc_otg_pcd_handle_in_ep_intr(pcd);
20267+ }
20268+ }
20269+ if (gintr_status.b.outepintr) {
20270+ if(!core_if->multiproc_int_enable) {
20271+ retval |= dwc_otg_pcd_handle_out_ep_intr(pcd);
20272+ }
20273+ }
20274+ if (gintr_status.b.incomplisoin) {
20275+ retval |= dwc_otg_pcd_handle_incomplete_isoc_in_intr(pcd);
20276+ }
20277+ if (gintr_status.b.incomplisoout) {
20278+ retval |= dwc_otg_pcd_handle_incomplete_isoc_out_intr(pcd);
20279+ }
20280+
20281+ /* In MPI mode De vice Endpoints intterrupts are asserted
20282+ * without setting outepintr and inepint bits set, so these
20283+ * Interrupt handlers are called without checking these bit-fields
20284+ */
20285+ if(core_if->multiproc_int_enable) {
20286+ retval |= dwc_otg_pcd_handle_in_ep_intr(pcd);
20287+ retval |= dwc_otg_pcd_handle_out_ep_intr(pcd);
20288+ }
20289+#ifdef VERBOSE
20290+ DWC_DEBUGPL(DBG_PCDV, "%s() gintsts=%0x\n", __func__,
20291+ dwc_read_reg32(&global_regs->gintsts));
20292+#endif
20293+ SPIN_UNLOCK(&pcd->lock);
20294+ }
20295+ S3C2410X_CLEAR_EINTPEND();
20296+
20297+ return retval;
20298+}
20299+
20300+#endif /* DWC_HOST_ONLY */
20301--- /dev/null
20302+++ b/drivers/usb/dwc/otg_plat.h
20303@@ -0,0 +1,266 @@
20304+/* ==========================================================================
20305+ * $File: //dwh/usb_iip/dev/software/otg/linux/platform/dwc_otg_plat.h $
20306+ * $Revision: #23 $
20307+ * $Date: 2008/07/15 $
20308+ * $Change: 1064915 $
20309+ *
20310+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
20311+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
20312+ * otherwise expressly agreed to in writing between Synopsys and you.
20313+ *
20314+ * The Software IS NOT an item of Licensed Software or Licensed Product under
20315+ * any End User Software License Agreement or Agreement for Licensed Product
20316+ * with Synopsys or any supplement thereto. You are permitted to use and
20317+ * redistribute this Software in source and binary forms, with or without
20318+ * modification, provided that redistributions of source code must retain this
20319+ * notice. You may not view, use, disclose, copy or distribute this file or
20320+ * any information contained herein except pursuant to this license grant from
20321+ * Synopsys. If you do not agree with this notice, including the disclaimer
20322+ * below, then you are not authorized to use the Software.
20323+ *
20324+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
20325+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20326+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20327+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
20328+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20329+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20330+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
20331+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20332+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
20333+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
20334+ * DAMAGE.
20335+ * ========================================================================== */
20336+
20337+#if !defined(__DWC_OTG_PLAT_H__)
20338+#define __DWC_OTG_PLAT_H__
20339+
20340+#include <linux/types.h>
20341+#include <linux/slab.h>
20342+#include <linux/list.h>
20343+#include <linux/delay.h>
20344+#include <asm/io.h>
20345+
20346+/* Changed all readl and writel to __raw_readl, __raw_writel */
20347+
20348+/**
20349+ * @file
20350+ *
20351+ * This file contains the Platform Specific constants, interfaces
20352+ * (functions and macros) for Linux.
20353+ *
20354+ */
20355+//#if !defined(__LINUX_ARM_ARCH__)
20356+//#error "The contents of this file is Linux specific!!!"
20357+//#endif
20358+
20359+/**
20360+ * Reads the content of a register.
20361+ *
20362+ * @param reg address of register to read.
20363+ * @return contents of the register.
20364+ *
20365+
20366+ * Usage:<br>
20367+ * <code>uint32_t dev_ctl = dwc_read_reg32(&dev_regs->dctl);</code>
20368+ */
20369+static __inline__ uint32_t dwc_read_reg32( volatile uint32_t *reg)
20370+{
20371+ return __raw_readl(reg);
20372+ // return readl(reg);
20373+};
20374+
20375+/**
20376+ * Writes a register with a 32 bit value.
20377+ *
20378+ * @param reg address of register to read.
20379+ * @param value to write to _reg.
20380+ *
20381+ * Usage:<br>
20382+ * <code>dwc_write_reg32(&dev_regs->dctl, 0); </code>
20383+ */
20384+static __inline__ void dwc_write_reg32( volatile uint32_t *reg, const uint32_t value)
20385+{
20386+ // writel( value, reg );
20387+ __raw_writel(value, reg);
20388+
20389+};
20390+
20391+/**
20392+ * This function modifies bit values in a register. Using the
20393+ * algorithm: (reg_contents & ~clear_mask) | set_mask.
20394+ *
20395+ * @param reg address of register to read.
20396+ * @param clear_mask bit mask to be cleared.
20397+ * @param set_mask bit mask to be set.
20398+ *
20399+ * Usage:<br>
20400+ * <code> // Clear the SOF Interrupt Mask bit and <br>
20401+ * // set the OTG Interrupt mask bit, leaving all others as they were.
20402+ * dwc_modify_reg32(&dev_regs->gintmsk, DWC_SOF_INT, DWC_OTG_INT);</code>
20403+ */
20404+static __inline__
20405+ void dwc_modify_reg32( volatile uint32_t *reg, const uint32_t clear_mask, const uint32_t set_mask)
20406+{
20407+ // writel( (readl(reg) & ~clear_mask) | set_mask, reg );
20408+ __raw_writel( (__raw_readl(reg) & ~clear_mask) | set_mask, reg );
20409+};
20410+
20411+
20412+/**
20413+ * Wrapper for the OS micro-second delay function.
20414+ * @param[in] usecs Microseconds of delay
20415+ */
20416+static __inline__ void UDELAY( const uint32_t usecs )
20417+{
20418+ udelay( usecs );
20419+}
20420+
20421+/**
20422+ * Wrapper for the OS milli-second delay function.
20423+ * @param[in] msecs milliseconds of delay
20424+ */
20425+static __inline__ void MDELAY( const uint32_t msecs )
20426+{
20427+ mdelay( msecs );
20428+}
20429+
20430+/**
20431+ * Wrapper for the Linux spin_lock. On the ARM (Integrator)
20432+ * spin_lock() is a nop.
20433+ *
20434+ * @param lock Pointer to the spinlock.
20435+ */
20436+static __inline__ void SPIN_LOCK( spinlock_t *lock )
20437+{
20438+ spin_lock(lock);
20439+}
20440+
20441+/**
20442+ * Wrapper for the Linux spin_unlock. On the ARM (Integrator)
20443+ * spin_lock() is a nop.
20444+ *
20445+ * @param lock Pointer to the spinlock.
20446+ */
20447+static __inline__ void SPIN_UNLOCK( spinlock_t *lock )
20448+{
20449+ spin_unlock(lock);
20450+}
20451+
20452+/**
20453+ * Wrapper (macro) for the Linux spin_lock_irqsave. On the ARM
20454+ * (Integrator) spin_lock() is a nop.
20455+ *
20456+ * @param l Pointer to the spinlock.
20457+ * @param f unsigned long for irq flags storage.
20458+ */
20459+#define SPIN_LOCK_IRQSAVE( l, f ) spin_lock_irqsave(l,f);
20460+
20461+/**
20462+ * Wrapper (macro) for the Linux spin_unlock_irqrestore. On the ARM
20463+ * (Integrator) spin_lock() is a nop.
20464+ *
20465+ * @param l Pointer to the spinlock.
20466+ * @param f unsigned long for irq flags storage.
20467+ */
20468+#define SPIN_UNLOCK_IRQRESTORE( l,f ) spin_unlock_irqrestore(l,f);
20469+
20470+/*
20471+ * Debugging support vanishes in non-debug builds.
20472+ */
20473+
20474+
20475+/**
20476+ * The Debug Level bit-mask variable.
20477+ */
20478+extern uint32_t g_dbg_lvl;
20479+/**
20480+ * Set the Debug Level variable.
20481+ */
20482+static inline uint32_t SET_DEBUG_LEVEL( const uint32_t new )
20483+{
20484+ uint32_t old = g_dbg_lvl;
20485+ g_dbg_lvl = new;
20486+ return old;
20487+}
20488+
20489+/** When debug level has the DBG_CIL bit set, display CIL Debug messages. */
20490+#define DBG_CIL (0x2)
20491+/** When debug level has the DBG_CILV bit set, display CIL Verbose debug
20492+ * messages */
20493+#define DBG_CILV (0x20)
20494+/** When debug level has the DBG_PCD bit set, display PCD (Device) debug
20495+ * messages */
20496+#define DBG_PCD (0x4)
20497+/** When debug level has the DBG_PCDV set, display PCD (Device) Verbose debug
20498+ * messages */
20499+#define DBG_PCDV (0x40)
20500+/** When debug level has the DBG_HCD bit set, display Host debug messages */
20501+#define DBG_HCD (0x8)
20502+/** When debug level has the DBG_HCDV bit set, display Verbose Host debug
20503+ * messages */
20504+#define DBG_HCDV (0x80)
20505+/** When debug level has the DBG_HCD_URB bit set, display enqueued URBs in host
20506+ * mode. */
20507+#define DBG_HCD_URB (0x800)
20508+
20509+/** When debug level has any bit set, display debug messages */
20510+#define DBG_ANY (0xFF)
20511+
20512+/** All debug messages off */
20513+#define DBG_OFF 0
20514+
20515+/** Prefix string for DWC_DEBUG print macros. */
20516+#define USB_DWC "DWC_otg: "
20517+
20518+/**
20519+ * Print a debug message when the Global debug level variable contains
20520+ * the bit defined in <code>lvl</code>.
20521+ *
20522+ * @param[in] lvl - Debug level, use one of the DBG_ constants above.
20523+ * @param[in] x - like printf
20524+ *
20525+ * Example:<p>
20526+ * <code>
20527+ * DWC_DEBUGPL( DBG_ANY, "%s(%p)\n", __func__, _reg_base_addr);
20528+ * </code>
20529+ * <br>
20530+ * results in:<br>
20531+ * <code>
20532+ * usb-DWC_otg: dwc_otg_cil_init(ca867000)
20533+ * </code>
20534+ */
20535+#ifdef DEBUG
20536+
20537+# define DWC_DEBUGPL(lvl, x...) do{ if ((lvl)&g_dbg_lvl)printk( KERN_DEBUG USB_DWC x ); }while(0)
20538+# define DWC_DEBUGP(x...) DWC_DEBUGPL(DBG_ANY, x )
20539+
20540+# define CHK_DEBUG_LEVEL(level) ((level) & g_dbg_lvl)
20541+
20542+#else
20543+
20544+# define DWC_DEBUGPL(lvl, x...) do{}while(0)
20545+# define DWC_DEBUGP(x...)
20546+
20547+# define CHK_DEBUG_LEVEL(level) (0)
20548+
20549+#endif /*DEBUG*/
20550+
20551+/**
20552+ * Print an Error message.
20553+ */
20554+#define DWC_ERROR(x...) printk( KERN_ERR USB_DWC x )
20555+/**
20556+ * Print a Warning message.
20557+ */
20558+#define DWC_WARN(x...) printk( KERN_WARNING USB_DWC x )
20559+/**
20560+ * Print a notice (normal but significant message).
20561+ */
20562+#define DWC_NOTICE(x...) printk( KERN_NOTICE USB_DWC x )
20563+/**
20564+ * Basic message printing.
20565+ */
20566+#define DWC_PRINT(x...) printk( KERN_INFO USB_DWC x )
20567+
20568+#endif
20569+
20570--- /dev/null
20571+++ b/drivers/usb/dwc/otg_regs.h
20572@@ -0,0 +1,2059 @@
20573+/* ==========================================================================
20574+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_regs.h $
20575+ * $Revision: #72 $
20576+ * $Date: 2008/09/19 $
20577+ * $Change: 1099526 $
20578+ *
20579+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
20580+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
20581+ * otherwise expressly agreed to in writing between Synopsys and you.
20582+ *
20583+ * The Software IS NOT an item of Licensed Software or Licensed Product under
20584+ * any End User Software License Agreement or Agreement for Licensed Product
20585+ * with Synopsys or any supplement thereto. You are permitted to use and
20586+ * redistribute this Software in source and binary forms, with or without
20587+ * modification, provided that redistributions of source code must retain this
20588+ * notice. You may not view, use, disclose, copy or distribute this file or
20589+ * any information contained herein except pursuant to this license grant from
20590+ * Synopsys. If you do not agree with this notice, including the disclaimer
20591+ * below, then you are not authorized to use the Software.
20592+ *
20593+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
20594+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20595+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20596+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
20597+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20598+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20599+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
20600+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20601+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
20602+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
20603+ * DAMAGE.
20604+ * ========================================================================== */
20605+
20606+#ifndef __DWC_OTG_REGS_H__
20607+#define __DWC_OTG_REGS_H__
20608+
20609+/**
20610+ * @file
20611+ *
20612+ * This file contains the data structures for accessing the DWC_otg core registers.
20613+ *
20614+ * The application interfaces with the HS OTG core by reading from and
20615+ * writing to the Control and Status Register (CSR) space through the
20616+ * AHB Slave interface. These registers are 32 bits wide, and the
20617+ * addresses are 32-bit-block aligned.
20618+ * CSRs are classified as follows:
20619+ * - Core Global Registers
20620+ * - Device Mode Registers
20621+ * - Device Global Registers
20622+ * - Device Endpoint Specific Registers
20623+ * - Host Mode Registers
20624+ * - Host Global Registers
20625+ * - Host Port CSRs
20626+ * - Host Channel Specific Registers
20627+ *
20628+ * Only the Core Global registers can be accessed in both Device and
20629+ * Host modes. When the HS OTG core is operating in one mode, either
20630+ * Device or Host, the application must not access registers from the
20631+ * other mode. When the core switches from one mode to another, the
20632+ * registers in the new mode of operation must be reprogrammed as they
20633+ * would be after a power-on reset.
20634+ */
20635+
20636+/** Maximum number of Periodic FIFOs */
20637+#define MAX_PERIO_FIFOS 15
20638+/** Maximum number of Transmit FIFOs */
20639+#define MAX_TX_FIFOS 15
20640+
20641+/** Maximum number of Endpoints/HostChannels */
20642+#define MAX_EPS_CHANNELS 16
20643+
20644+/****************************************************************************/
20645+/** DWC_otg Core registers .
20646+ * The dwc_otg_core_global_regs structure defines the size
20647+ * and relative field offsets for the Core Global registers.
20648+ */
20649+typedef struct dwc_otg_core_global_regs
20650+{
20651+ /** OTG Control and Status Register. <i>Offset: 000h</i> */
20652+ volatile uint32_t gotgctl;
20653+ /** OTG Interrupt Register. <i>Offset: 004h</i> */
20654+ volatile uint32_t gotgint;
20655+ /**Core AHB Configuration Register. <i>Offset: 008h</i> */
20656+ volatile uint32_t gahbcfg;
20657+
20658+#define DWC_GLBINTRMASK 0x0001
20659+#define DWC_DMAENABLE 0x0020
20660+#define DWC_NPTXEMPTYLVL_EMPTY 0x0080
20661+#define DWC_NPTXEMPTYLVL_HALFEMPTY 0x0000
20662+#define DWC_PTXEMPTYLVL_EMPTY 0x0100
20663+#define DWC_PTXEMPTYLVL_HALFEMPTY 0x0000
20664+
20665+ /**Core USB Configuration Register. <i>Offset: 00Ch</i> */
20666+ volatile uint32_t gusbcfg;
20667+ /**Core Reset Register. <i>Offset: 010h</i> */
20668+ volatile uint32_t grstctl;
20669+ /**Core Interrupt Register. <i>Offset: 014h</i> */
20670+ volatile uint32_t gintsts;
20671+ /**Core Interrupt Mask Register. <i>Offset: 018h</i> */
20672+ volatile uint32_t gintmsk;
20673+ /**Receive Status Queue Read Register (Read Only). <i>Offset: 01Ch</i> */
20674+ volatile uint32_t grxstsr;
20675+ /**Receive Status Queue Read & POP Register (Read Only). <i>Offset: 020h</i>*/
20676+ volatile uint32_t grxstsp;
20677+ /**Receive FIFO Size Register. <i>Offset: 024h</i> */
20678+ volatile uint32_t grxfsiz;
20679+ /**Non Periodic Transmit FIFO Size Register. <i>Offset: 028h</i> */
20680+ volatile uint32_t gnptxfsiz;
20681+ /**Non Periodic Transmit FIFO/Queue Status Register (Read
20682+ * Only). <i>Offset: 02Ch</i> */
20683+ volatile uint32_t gnptxsts;
20684+ /**I2C Access Register. <i>Offset: 030h</i> */
20685+ volatile uint32_t gi2cctl;
20686+ /**PHY Vendor Control Register. <i>Offset: 034h</i> */
20687+ volatile uint32_t gpvndctl;
20688+ /**General Purpose Input/Output Register. <i>Offset: 038h</i> */
20689+ volatile uint32_t ggpio;
20690+ /**User ID Register. <i>Offset: 03Ch</i> */
20691+ volatile uint32_t guid;
20692+ /**Synopsys ID Register (Read Only). <i>Offset: 040h</i> */
20693+ volatile uint32_t gsnpsid;
20694+ /**User HW Config1 Register (Read Only). <i>Offset: 044h</i> */
20695+ volatile uint32_t ghwcfg1;
20696+ /**User HW Config2 Register (Read Only). <i>Offset: 048h</i> */
20697+ volatile uint32_t ghwcfg2;
20698+#define DWC_SLAVE_ONLY_ARCH 0
20699+#define DWC_EXT_DMA_ARCH 1
20700+#define DWC_INT_DMA_ARCH 2
20701+
20702+#define DWC_MODE_HNP_SRP_CAPABLE 0
20703+#define DWC_MODE_SRP_ONLY_CAPABLE 1
20704+#define DWC_MODE_NO_HNP_SRP_CAPABLE 2
20705+#define DWC_MODE_SRP_CAPABLE_DEVICE 3
20706+#define DWC_MODE_NO_SRP_CAPABLE_DEVICE 4
20707+#define DWC_MODE_SRP_CAPABLE_HOST 5
20708+#define DWC_MODE_NO_SRP_CAPABLE_HOST 6
20709+
20710+ /**User HW Config3 Register (Read Only). <i>Offset: 04Ch</i> */
20711+ volatile uint32_t ghwcfg3;
20712+ /**User HW Config4 Register (Read Only). <i>Offset: 050h</i>*/
20713+ volatile uint32_t ghwcfg4;
20714+ /** Reserved <i>Offset: 054h-0FFh</i> */
20715+ volatile uint32_t reserved[43];
20716+ /** Host Periodic Transmit FIFO Size Register. <i>Offset: 100h</i> */
20717+ volatile uint32_t hptxfsiz;
20718+ /** Device Periodic Transmit FIFO#n Register if dedicated fifos are disabled,
20719+ otherwise Device Transmit FIFO#n Register.
20720+ * <i>Offset: 104h + (FIFO_Number-1)*04h, 1 <= FIFO Number <= 15 (1<=n<=15).</i> */
20721+ volatile uint32_t dptxfsiz_dieptxf[15];
20722+} dwc_otg_core_global_regs_t;
20723+
20724+/**
20725+ * This union represents the bit fields of the Core OTG Control
20726+ * and Status Register (GOTGCTL). Set the bits using the bit
20727+ * fields then write the <i>d32</i> value to the register.
20728+ */
20729+typedef union gotgctl_data
20730+{
20731+ /** raw register data */
20732+ uint32_t d32;
20733+ /** register bits */
20734+ struct
20735+ {
20736+ unsigned sesreqscs : 1;
20737+ unsigned sesreq : 1;
20738+ unsigned reserved2_7 : 6;
20739+ unsigned hstnegscs : 1;
20740+ unsigned hnpreq : 1;
20741+ unsigned hstsethnpen : 1;
20742+ unsigned devhnpen : 1;
20743+ unsigned reserved12_15 : 4;
20744+ unsigned conidsts : 1;
20745+ unsigned reserved17 : 1;
20746+ unsigned asesvld : 1;
20747+ unsigned bsesvld : 1;
20748+ unsigned currmod : 1;
20749+ unsigned reserved21_31 : 11;
20750+ } b;
20751+} gotgctl_data_t;
20752+
20753+/**
20754+ * This union represents the bit fields of the Core OTG Interrupt Register
20755+ * (GOTGINT). Set/clear the bits using the bit fields then write the <i>d32</i>
20756+ * value to the register.
20757+ */
20758+typedef union gotgint_data
20759+{
20760+ /** raw register data */
20761+ uint32_t d32;
20762+ /** register bits */
20763+ struct
20764+ {
20765+ /** Current Mode */
20766+ unsigned reserved0_1 : 2;
20767+
20768+ /** Session End Detected */
20769+ unsigned sesenddet : 1;
20770+
20771+ unsigned reserved3_7 : 5;
20772+
20773+ /** Session Request Success Status Change */
20774+ unsigned sesreqsucstschng : 1;
20775+ /** Host Negotiation Success Status Change */
20776+ unsigned hstnegsucstschng : 1;
20777+
20778+ unsigned reserver10_16 : 7;
20779+
20780+ /** Host Negotiation Detected */
20781+ unsigned hstnegdet : 1;
20782+ /** A-Device Timeout Change */
20783+ unsigned adevtoutchng : 1;
20784+ /** Debounce Done */
20785+ unsigned debdone : 1;
20786+
20787+ unsigned reserved31_20 : 12;
20788+
20789+ } b;
20790+} gotgint_data_t;
20791+
20792+
20793+/**
20794+ * This union represents the bit fields of the Core AHB Configuration
20795+ * Register (GAHBCFG). Set/clear the bits using the bit fields then
20796+ * write the <i>d32</i> value to the register.
20797+ */
20798+typedef union gahbcfg_data
20799+{
20800+ /** raw register data */
20801+ uint32_t d32;
20802+ /** register bits */
20803+ struct
20804+ {
20805+ unsigned glblintrmsk : 1;
20806+#define DWC_GAHBCFG_GLBINT_ENABLE 1
20807+
20808+ unsigned hburstlen : 4;
20809+#define DWC_GAHBCFG_INT_DMA_BURST_SINGLE 0
20810+#define DWC_GAHBCFG_INT_DMA_BURST_INCR 1
20811+#define DWC_GAHBCFG_INT_DMA_BURST_INCR4 3
20812+#define DWC_GAHBCFG_INT_DMA_BURST_INCR8 5
20813+#define DWC_GAHBCFG_INT_DMA_BURST_INCR16 7
20814+
20815+ unsigned dmaenable : 1;
20816+#define DWC_GAHBCFG_DMAENABLE 1
20817+ unsigned reserved : 1;
20818+ unsigned nptxfemplvl_txfemplvl : 1;
20819+ unsigned ptxfemplvl : 1;
20820+#define DWC_GAHBCFG_TXFEMPTYLVL_EMPTY 1
20821+#define DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY 0
20822+ unsigned reserved9_31 : 23;
20823+ } b;
20824+} gahbcfg_data_t;
20825+
20826+/**
20827+ * This union represents the bit fields of the Core USB Configuration
20828+ * Register (GUSBCFG). Set the bits using the bit fields then write
20829+ * the <i>d32</i> value to the register.
20830+ */
20831+typedef union gusbcfg_data
20832+{
20833+ /** raw register data */
20834+ uint32_t d32;
20835+ /** register bits */
20836+ struct
20837+ {
20838+ unsigned toutcal : 3;
20839+ unsigned phyif : 1;
20840+ unsigned ulpi_utmi_sel : 1;
20841+ unsigned fsintf : 1;
20842+ unsigned physel : 1;
20843+ unsigned ddrsel : 1;
20844+ unsigned srpcap : 1;
20845+ unsigned hnpcap : 1;
20846+ unsigned usbtrdtim : 4;
20847+ unsigned nptxfrwnden : 1;
20848+ unsigned phylpwrclksel : 1;
20849+ unsigned otgutmifssel : 1;
20850+ unsigned ulpi_fsls : 1;
20851+ unsigned ulpi_auto_res : 1;
20852+ unsigned ulpi_clk_sus_m : 1;
20853+ unsigned ulpi_ext_vbus_drv : 1;
20854+ unsigned ulpi_int_vbus_indicator : 1;
20855+ unsigned term_sel_dl_pulse : 1;
20856+ unsigned reserved23_27 : 5;
20857+ unsigned tx_end_delay : 1;
20858+ unsigned reserved29_31 : 3;
20859+ } b;
20860+} gusbcfg_data_t;
20861+
20862+/**
20863+ * This union represents the bit fields of the Core Reset Register
20864+ * (GRSTCTL). Set/clear the bits using the bit fields then write the
20865+ * <i>d32</i> value to the register.
20866+ */
20867+typedef union grstctl_data
20868+{
20869+ /** raw register data */
20870+ uint32_t d32;
20871+ /** register bits */
20872+ struct
20873+ {
20874+ /** Core Soft Reset (CSftRst) (Device and Host)
20875+ *
20876+ * The application can flush the control logic in the
20877+ * entire core using this bit. This bit resets the
20878+ * pipelines in the AHB Clock domain as well as the
20879+ * PHY Clock domain.
20880+ *
20881+ * The state machines are reset to an IDLE state, the
20882+ * control bits in the CSRs are cleared, all the
20883+ * transmit FIFOs and the receive FIFO are flushed.
20884+ *
20885+ * The status mask bits that control the generation of
20886+ * the interrupt, are cleared, to clear the
20887+ * interrupt. The interrupt status bits are not
20888+ * cleared, so the application can get the status of
20889+ * any events that occurred in the core after it has
20890+ * set this bit.
20891+ *
20892+ * Any transactions on the AHB are terminated as soon
20893+ * as possible following the protocol. Any
20894+ * transactions on the USB are terminated immediately.
20895+ *
20896+ * The configuration settings in the CSRs are
20897+ * unchanged, so the software doesn't have to
20898+ * reprogram these registers (Device
20899+ * Configuration/Host Configuration/Core System
20900+ * Configuration/Core PHY Configuration).
20901+ *
20902+ * The application can write to this bit, any time it
20903+ * wants to reset the core. This is a self clearing
20904+ * bit and the core clears this bit after all the
20905+ * necessary logic is reset in the core, which may
20906+ * take several clocks, depending on the current state
20907+ * of the core.
20908+ */
20909+ unsigned csftrst : 1;
20910+ /** Hclk Soft Reset
20911+ *
20912+ * The application uses this bit to reset the control logic in
20913+ * the AHB clock domain. Only AHB clock domain pipelines are
20914+ * reset.
20915+ */
20916+ unsigned hsftrst : 1;
20917+ /** Host Frame Counter Reset (Host Only)<br>
20918+ *
20919+ * The application can reset the (micro)frame number
20920+ * counter inside the core, using this bit. When the
20921+ * (micro)frame counter is reset, the subsequent SOF
20922+ * sent out by the core, will have a (micro)frame
20923+ * number of 0.
20924+ */
20925+ unsigned hstfrm : 1;
20926+ /** In Token Sequence Learning Queue Flush
20927+ * (INTknQFlsh) (Device Only)
20928+ */
20929+ unsigned intknqflsh : 1;
20930+ /** RxFIFO Flush (RxFFlsh) (Device and Host)
20931+ *
20932+ * The application can flush the entire Receive FIFO
20933+ * using this bit. <p>The application must first
20934+ * ensure that the core is not in the middle of a
20935+ * transaction. <p>The application should write into
20936+ * this bit, only after making sure that neither the
20937+ * DMA engine is reading from the RxFIFO nor the MAC
20938+ * is writing the data in to the FIFO. <p>The
20939+ * application should wait until the bit is cleared
20940+ * before performing any other operations. This bit
20941+ * will takes 8 clocks (slowest of PHY or AHB clock)
20942+ * to clear.
20943+ */
20944+ unsigned rxfflsh : 1;
20945+ /** TxFIFO Flush (TxFFlsh) (Device and Host).
20946+ *
20947+ * This bit is used to selectively flush a single or
20948+ * all transmit FIFOs. The application must first
20949+ * ensure that the core is not in the middle of a
20950+ * transaction. <p>The application should write into
20951+ * this bit, only after making sure that neither the
20952+ * DMA engine is writing into the TxFIFO nor the MAC
20953+ * is reading the data out of the FIFO. <p>The
20954+ * application should wait until the core clears this
20955+ * bit, before performing any operations. This bit
20956+ * will takes 8 clocks (slowest of PHY or AHB clock)
20957+ * to clear.
20958+ */
20959+ unsigned txfflsh : 1;
20960+ /** TxFIFO Number (TxFNum) (Device and Host).
20961+ *
20962+ * This is the FIFO number which needs to be flushed,
20963+ * using the TxFIFO Flush bit. This field should not
20964+ * be changed until the TxFIFO Flush bit is cleared by
20965+ * the core.
20966+ * - 0x0 : Non Periodic TxFIFO Flush
20967+ * - 0x1 : Periodic TxFIFO #1 Flush in device mode
20968+ * or Periodic TxFIFO in host mode
20969+ * - 0x2 : Periodic TxFIFO #2 Flush in device mode.
20970+ * - ...
20971+ * - 0xF : Periodic TxFIFO #15 Flush in device mode
20972+ * - 0x10: Flush all the Transmit NonPeriodic and
20973+ * Transmit Periodic FIFOs in the core
20974+ */
20975+ unsigned txfnum : 5;
20976+ /** Reserved */
20977+ unsigned reserved11_29 : 19;
20978+ /** DMA Request Signal. Indicated DMA request is in
20979+ * probress. Used for debug purpose. */
20980+ unsigned dmareq : 1;
20981+ /** AHB Master Idle. Indicates the AHB Master State
20982+ * Machine is in IDLE condition. */
20983+ unsigned ahbidle : 1;
20984+ } b;
20985+} grstctl_t;
20986+
20987+
20988+/**
20989+ * This union represents the bit fields of the Core Interrupt Mask
20990+ * Register (GINTMSK). Set/clear the bits using the bit fields then
20991+ * write the <i>d32</i> value to the register.
20992+ */
20993+typedef union gintmsk_data
20994+{
20995+ /** raw register data */
20996+ uint32_t d32;
20997+ /** register bits */
20998+ struct
20999+ {
21000+ unsigned reserved0 : 1;
21001+ unsigned modemismatch : 1;
21002+ unsigned otgintr : 1;
21003+ unsigned sofintr : 1;
21004+ unsigned rxstsqlvl : 1;
21005+ unsigned nptxfempty : 1;
21006+ unsigned ginnakeff : 1;
21007+ unsigned goutnakeff : 1;
21008+ unsigned reserved8 : 1;
21009+ unsigned i2cintr : 1;
21010+ unsigned erlysuspend : 1;
21011+ unsigned usbsuspend : 1;
21012+ unsigned usbreset : 1;
21013+ unsigned enumdone : 1;
21014+ unsigned isooutdrop : 1;
21015+ unsigned eopframe : 1;
21016+ unsigned reserved16 : 1;
21017+ unsigned epmismatch : 1;
21018+ unsigned inepintr : 1;
21019+ unsigned outepintr : 1;
21020+ unsigned incomplisoin : 1;
21021+ unsigned incomplisoout : 1;
21022+ unsigned reserved22_23 : 2;
21023+ unsigned portintr : 1;
21024+ unsigned hcintr : 1;
21025+ unsigned ptxfempty : 1;
21026+ unsigned reserved27 : 1;
21027+ unsigned conidstschng : 1;
21028+ unsigned disconnect : 1;
21029+ unsigned sessreqintr : 1;
21030+ unsigned wkupintr : 1;
21031+ } b;
21032+} gintmsk_data_t;
21033+/**
21034+ * This union represents the bit fields of the Core Interrupt Register
21035+ * (GINTSTS). Set/clear the bits using the bit fields then write the
21036+ * <i>d32</i> value to the register.
21037+ */
21038+typedef union gintsts_data
21039+{
21040+ /** raw register data */
21041+ uint32_t d32;
21042+#define DWC_SOF_INTR_MASK 0x0008
21043+ /** register bits */
21044+ struct
21045+ {
21046+#define DWC_HOST_MODE 1
21047+ unsigned curmode : 1;
21048+ unsigned modemismatch : 1;
21049+ unsigned otgintr : 1;
21050+ unsigned sofintr : 1;
21051+ unsigned rxstsqlvl : 1;
21052+ unsigned nptxfempty : 1;
21053+ unsigned ginnakeff : 1;
21054+ unsigned goutnakeff : 1;
21055+ unsigned reserved8 : 1;
21056+ unsigned i2cintr : 1;
21057+ unsigned erlysuspend : 1;
21058+ unsigned usbsuspend : 1;
21059+ unsigned usbreset : 1;
21060+ unsigned enumdone : 1;
21061+ unsigned isooutdrop : 1;
21062+ unsigned eopframe : 1;
21063+ unsigned intokenrx : 1;
21064+ unsigned epmismatch : 1;
21065+ unsigned inepint: 1;
21066+ unsigned outepintr : 1;
21067+ unsigned incomplisoin : 1;
21068+ unsigned incomplisoout : 1;
21069+ unsigned reserved22_23 : 2;
21070+ unsigned portintr : 1;
21071+ unsigned hcintr : 1;
21072+ unsigned ptxfempty : 1;
21073+ unsigned reserved27 : 1;
21074+ unsigned conidstschng : 1;
21075+ unsigned disconnect : 1;
21076+ unsigned sessreqintr : 1;
21077+ unsigned wkupintr : 1;
21078+ } b;
21079+} gintsts_data_t;
21080+
21081+
21082+/**
21083+ * This union represents the bit fields in the Device Receive Status Read and
21084+ * Pop Registers (GRXSTSR, GRXSTSP) Read the register into the <i>d32</i>
21085+ * element then read out the bits using the <i>b</i>it elements.
21086+ */
21087+typedef union device_grxsts_data
21088+{
21089+ /** raw register data */
21090+ uint32_t d32;
21091+ /** register bits */
21092+ struct
21093+ {
21094+ unsigned epnum : 4;
21095+ unsigned bcnt : 11;
21096+ unsigned dpid : 2;
21097+#define DWC_STS_DATA_UPDT 0x2 // OUT Data Packet
21098+#define DWC_STS_XFER_COMP 0x3 // OUT Data Transfer Complete
21099+
21100+#define DWC_DSTS_GOUT_NAK 0x1 // Global OUT NAK
21101+#define DWC_DSTS_SETUP_COMP 0x4 // Setup Phase Complete
21102+#define DWC_DSTS_SETUP_UPDT 0x6 // SETUP Packet
21103+ unsigned pktsts : 4;
21104+ unsigned fn : 4;
21105+ unsigned reserved : 7;
21106+ } b;
21107+} device_grxsts_data_t;
21108+
21109+/**
21110+ * This union represents the bit fields in the Host Receive Status Read and
21111+ * Pop Registers (GRXSTSR, GRXSTSP) Read the register into the <i>d32</i>
21112+ * element then read out the bits using the <i>b</i>it elements.
21113+ */
21114+typedef union host_grxsts_data
21115+{
21116+ /** raw register data */
21117+ uint32_t d32;
21118+ /** register bits */
21119+ struct
21120+ {
21121+ unsigned chnum : 4;
21122+ unsigned bcnt : 11;
21123+ unsigned dpid : 2;
21124+ unsigned pktsts : 4;
21125+#define DWC_GRXSTS_PKTSTS_IN 0x2
21126+#define DWC_GRXSTS_PKTSTS_IN_XFER_COMP 0x3
21127+#define DWC_GRXSTS_PKTSTS_DATA_TOGGLE_ERR 0x5
21128+#define DWC_GRXSTS_PKTSTS_CH_HALTED 0x7
21129+ unsigned reserved : 11;
21130+ } b;
21131+} host_grxsts_data_t;
21132+
21133+/**
21134+ * This union represents the bit fields in the FIFO Size Registers (HPTXFSIZ,
21135+ * GNPTXFSIZ, DPTXFSIZn, DIEPTXFn). Read the register into the <i>d32</i> element then
21136+ * read out the bits using the <i>b</i>it elements.
21137+ */
21138+typedef union fifosize_data
21139+{
21140+ /** raw register data */
21141+ uint32_t d32;
21142+ /** register bits */
21143+ struct
21144+ {
21145+ unsigned startaddr : 16;
21146+ unsigned depth : 16;
21147+ } b;
21148+} fifosize_data_t;
21149+
21150+/**
21151+ * This union represents the bit fields in the Non-Periodic Transmit
21152+ * FIFO/Queue Status Register (GNPTXSTS). Read the register into the
21153+ * <i>d32</i> element then read out the bits using the <i>b</i>it
21154+ * elements.
21155+ */
21156+typedef union gnptxsts_data
21157+{
21158+ /** raw register data */
21159+ uint32_t d32;
21160+ /** register bits */
21161+ struct
21162+ {
21163+ unsigned nptxfspcavail : 16;
21164+ unsigned nptxqspcavail : 8;
21165+ /** Top of the Non-Periodic Transmit Request Queue
21166+ * - bit 24 - Terminate (Last entry for the selected
21167+ * channel/EP)
21168+ * - bits 26:25 - Token Type
21169+ * - 2'b00 - IN/OUT
21170+ * - 2'b01 - Zero Length OUT
21171+ * - 2'b10 - PING/Complete Split
21172+ * - 2'b11 - Channel Halt
21173+ * - bits 30:27 - Channel/EP Number
21174+ */
21175+ unsigned nptxqtop_terminate : 1;
21176+ unsigned nptxqtop_token : 2;
21177+ unsigned nptxqtop_chnep : 4;
21178+ unsigned reserved : 1;
21179+ } b;
21180+} gnptxsts_data_t;
21181+
21182+/**
21183+ * This union represents the bit fields in the Transmit
21184+ * FIFO Status Register (DTXFSTS). Read the register into the
21185+ * <i>d32</i> element then read out the bits using the <i>b</i>it
21186+ * elements.
21187+ */
21188+typedef union dtxfsts_data
21189+{
21190+ /** raw register data */
21191+ uint32_t d32;
21192+ /** register bits */
21193+ struct
21194+ {
21195+ unsigned txfspcavail : 16;
21196+ unsigned reserved : 16;
21197+ } b;
21198+} dtxfsts_data_t;
21199+
21200+/**
21201+ * This union represents the bit fields in the I2C Control Register
21202+ * (I2CCTL). Read the register into the <i>d32</i> element then read out the
21203+ * bits using the <i>b</i>it elements.
21204+ */
21205+typedef union gi2cctl_data
21206+{
21207+ /** raw register data */
21208+ uint32_t d32;
21209+ /** register bits */
21210+ struct
21211+ {
21212+ unsigned rwdata : 8;
21213+ unsigned regaddr : 8;
21214+ unsigned addr : 7;
21215+ unsigned i2cen : 1;
21216+ unsigned ack : 1;
21217+ unsigned i2csuspctl : 1;
21218+ unsigned i2cdevaddr : 2;
21219+ unsigned reserved : 2;
21220+ unsigned rw : 1;
21221+ unsigned bsydne : 1;
21222+ } b;
21223+} gi2cctl_data_t;
21224+
21225+/**
21226+ * This union represents the bit fields in the User HW Config1
21227+ * Register. Read the register into the <i>d32</i> element then read
21228+ * out the bits using the <i>b</i>it elements.
21229+ */
21230+typedef union hwcfg1_data
21231+{
21232+ /** raw register data */
21233+ uint32_t d32;
21234+ /** register bits */
21235+ struct
21236+ {
21237+ unsigned ep_dir0 : 2;
21238+ unsigned ep_dir1 : 2;
21239+ unsigned ep_dir2 : 2;
21240+ unsigned ep_dir3 : 2;
21241+ unsigned ep_dir4 : 2;
21242+ unsigned ep_dir5 : 2;
21243+ unsigned ep_dir6 : 2;
21244+ unsigned ep_dir7 : 2;
21245+ unsigned ep_dir8 : 2;
21246+ unsigned ep_dir9 : 2;
21247+ unsigned ep_dir10 : 2;
21248+ unsigned ep_dir11 : 2;
21249+ unsigned ep_dir12 : 2;
21250+ unsigned ep_dir13 : 2;
21251+ unsigned ep_dir14 : 2;
21252+ unsigned ep_dir15 : 2;
21253+ } b;
21254+} hwcfg1_data_t;
21255+
21256+/**
21257+ * This union represents the bit fields in the User HW Config2
21258+ * Register. Read the register into the <i>d32</i> element then read
21259+ * out the bits using the <i>b</i>it elements.
21260+ */
21261+typedef union hwcfg2_data
21262+{
21263+ /** raw register data */
21264+ uint32_t d32;
21265+ /** register bits */
21266+ struct
21267+ {
21268+ /* GHWCFG2 */
21269+ unsigned op_mode : 3;
21270+#define DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG 0
21271+#define DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG 1
21272+#define DWC_HWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE_OTG 2
21273+#define DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE 3
21274+#define DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE 4
21275+#define DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST 5
21276+#define DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST 6
21277+
21278+ unsigned architecture : 2;
21279+ unsigned point2point : 1;
21280+ unsigned hs_phy_type : 2;
21281+#define DWC_HWCFG2_HS_PHY_TYPE_NOT_SUPPORTED 0
21282+#define DWC_HWCFG2_HS_PHY_TYPE_UTMI 1
21283+#define DWC_HWCFG2_HS_PHY_TYPE_ULPI 2
21284+#define DWC_HWCFG2_HS_PHY_TYPE_UTMI_ULPI 3
21285+
21286+ unsigned fs_phy_type : 2;
21287+ unsigned num_dev_ep : 4;
21288+ unsigned num_host_chan : 4;
21289+ unsigned perio_ep_supported : 1;
21290+ unsigned dynamic_fifo : 1;
21291+ unsigned multi_proc_int : 1;
21292+ unsigned reserved21 : 1;
21293+ unsigned nonperio_tx_q_depth : 2;
21294+ unsigned host_perio_tx_q_depth : 2;
21295+ unsigned dev_token_q_depth : 5;
21296+ unsigned reserved31 : 1;
21297+ } b;
21298+} hwcfg2_data_t;
21299+
21300+/**
21301+ * This union represents the bit fields in the User HW Config3
21302+ * Register. Read the register into the <i>d32</i> element then read
21303+ * out the bits using the <i>b</i>it elements.
21304+ */
21305+typedef union hwcfg3_data
21306+{
21307+ /** raw register data */
21308+ uint32_t d32;
21309+ /** register bits */
21310+ struct
21311+ {
21312+ /* GHWCFG3 */
21313+ unsigned xfer_size_cntr_width : 4;
21314+ unsigned packet_size_cntr_width : 3;
21315+ unsigned otg_func : 1;
21316+ unsigned i2c : 1;
21317+ unsigned vendor_ctrl_if : 1;
21318+ unsigned optional_features : 1;
21319+ unsigned synch_reset_type : 1;
21320+ unsigned ahb_phy_clock_synch : 1;
21321+ unsigned reserved15_13 : 3;
21322+ unsigned dfifo_depth : 16;
21323+ } b;
21324+} hwcfg3_data_t;
21325+
21326+/**
21327+ * This union represents the bit fields in the User HW Config4
21328+ * Register. Read the register into the <i>d32</i> element then read
21329+ * out the bits using the <i>b</i>it elements.
21330+ */
21331+typedef union hwcfg4_data
21332+{
21333+ /** raw register data */
21334+ uint32_t d32;
21335+ /** register bits */
21336+ struct
21337+ {
21338+ unsigned num_dev_perio_in_ep : 4;
21339+ unsigned power_optimiz : 1;
21340+ unsigned min_ahb_freq : 9;
21341+ unsigned utmi_phy_data_width : 2;
21342+ unsigned num_dev_mode_ctrl_ep : 4;
21343+ unsigned iddig_filt_en : 1;
21344+ unsigned vbus_valid_filt_en : 1;
21345+ unsigned a_valid_filt_en : 1;
21346+ unsigned b_valid_filt_en : 1;
21347+ unsigned session_end_filt_en : 1;
21348+ unsigned ded_fifo_en : 1;
21349+ unsigned num_in_eps : 4;
21350+ unsigned desc_dma : 1;
21351+ unsigned desc_dma_dyn : 1;
21352+ } b;
21353+} hwcfg4_data_t;
21354+
21355+////////////////////////////////////////////
21356+// Device Registers
21357+/**
21358+ * Device Global Registers. <i>Offsets 800h-BFFh</i>
21359+ *
21360+ * The following structures define the size and relative field offsets
21361+ * for the Device Mode Registers.
21362+ *
21363+ * <i>These registers are visible only in Device mode and must not be
21364+ * accessed in Host mode, as the results are unknown.</i>
21365+ */
21366+typedef struct dwc_otg_dev_global_regs
21367+{
21368+ /** Device Configuration Register. <i>Offset 800h</i> */
21369+ volatile uint32_t dcfg;
21370+ /** Device Control Register. <i>Offset: 804h</i> */
21371+ volatile uint32_t dctl;
21372+ /** Device Status Register (Read Only). <i>Offset: 808h</i> */
21373+ volatile uint32_t dsts;
21374+ /** Reserved. <i>Offset: 80Ch</i> */
21375+ uint32_t unused;
21376+ /** Device IN Endpoint Common Interrupt Mask
21377+ * Register. <i>Offset: 810h</i> */
21378+ volatile uint32_t diepmsk;
21379+ /** Device OUT Endpoint Common Interrupt Mask
21380+ * Register. <i>Offset: 814h</i> */
21381+ volatile uint32_t doepmsk;
21382+ /** Device All Endpoints Interrupt Register. <i>Offset: 818h</i> */
21383+ volatile uint32_t daint;
21384+ /** Device All Endpoints Interrupt Mask Register. <i>Offset:
21385+ * 81Ch</i> */
21386+ volatile uint32_t daintmsk;
21387+ /** Device IN Token Queue Read Register-1 (Read Only).
21388+ * <i>Offset: 820h</i> */
21389+ volatile uint32_t dtknqr1;
21390+ /** Device IN Token Queue Read Register-2 (Read Only).
21391+ * <i>Offset: 824h</i> */
21392+ volatile uint32_t dtknqr2;
21393+ /** Device VBUS discharge Register. <i>Offset: 828h</i> */
21394+ volatile uint32_t dvbusdis;
21395+ /** Device VBUS Pulse Register. <i>Offset: 82Ch</i> */
21396+ volatile uint32_t dvbuspulse;
21397+ /** Device IN Token Queue Read Register-3 (Read Only). /
21398+ * Device Thresholding control register (Read/Write)
21399+ * <i>Offset: 830h</i> */
21400+ volatile uint32_t dtknqr3_dthrctl;
21401+ /** Device IN Token Queue Read Register-4 (Read Only). /
21402+ * Device IN EPs empty Inr. Mask Register (Read/Write)
21403+ * <i>Offset: 834h</i> */
21404+ volatile uint32_t dtknqr4_fifoemptymsk;
21405+ /** Device Each Endpoint Interrupt Register (Read Only). /
21406+ * <i>Offset: 838h</i> */
21407+ volatile uint32_t deachint;
21408+ /** Device Each Endpoint Interrupt mask Register (Read/Write). /
21409+ * <i>Offset: 83Ch</i> */
21410+ volatile uint32_t deachintmsk;
21411+ /** Device Each In Endpoint Interrupt mask Register (Read/Write). /
21412+ * <i>Offset: 840h</i> */
21413+ volatile uint32_t diepeachintmsk[MAX_EPS_CHANNELS];
21414+ /** Device Each Out Endpoint Interrupt mask Register (Read/Write). /
21415+ * <i>Offset: 880h</i> */
21416+ volatile uint32_t doepeachintmsk[MAX_EPS_CHANNELS];
21417+} dwc_otg_device_global_regs_t;
21418+
21419+/**
21420+ * This union represents the bit fields in the Device Configuration
21421+ * Register. Read the register into the <i>d32</i> member then
21422+ * set/clear the bits using the <i>b</i>it elements. Write the
21423+ * <i>d32</i> member to the dcfg register.
21424+ */
21425+typedef union dcfg_data
21426+{
21427+ /** raw register data */
21428+ uint32_t d32;
21429+ /** register bits */
21430+ struct
21431+ {
21432+ /** Device Speed */
21433+ unsigned devspd : 2;
21434+ /** Non Zero Length Status OUT Handshake */
21435+ unsigned nzstsouthshk : 1;
21436+#define DWC_DCFG_SEND_STALL 1
21437+
21438+ unsigned reserved3 : 1;
21439+ /** Device Addresses */
21440+ unsigned devaddr : 7;
21441+ /** Periodic Frame Interval */
21442+ unsigned perfrint : 2;
21443+#define DWC_DCFG_FRAME_INTERVAL_80 0
21444+#define DWC_DCFG_FRAME_INTERVAL_85 1
21445+#define DWC_DCFG_FRAME_INTERVAL_90 2
21446+#define DWC_DCFG_FRAME_INTERVAL_95 3
21447+
21448+ unsigned reserved13_17 : 5;
21449+ /** In Endpoint Mis-match count */
21450+ unsigned epmscnt : 5;
21451+ /** Enable Descriptor DMA in Device mode */
21452+ unsigned descdma : 1;
21453+ } b;
21454+} dcfg_data_t;
21455+
21456+/**
21457+ * This union represents the bit fields in the Device Control
21458+ * Register. Read the register into the <i>d32</i> member then
21459+ * set/clear the bits using the <i>b</i>it elements.
21460+ */
21461+typedef union dctl_data
21462+{
21463+ /** raw register data */
21464+ uint32_t d32;
21465+ /** register bits */
21466+ struct
21467+ {
21468+ /** Remote Wakeup */
21469+ unsigned rmtwkupsig : 1;
21470+ /** Soft Disconnect */
21471+ unsigned sftdiscon : 1;
21472+ /** Global Non-Periodic IN NAK Status */
21473+ unsigned gnpinnaksts : 1;
21474+ /** Global OUT NAK Status */
21475+ unsigned goutnaksts : 1;
21476+ /** Test Control */
21477+ unsigned tstctl : 3;
21478+ /** Set Global Non-Periodic IN NAK */
21479+ unsigned sgnpinnak : 1;
21480+ /** Clear Global Non-Periodic IN NAK */
21481+ unsigned cgnpinnak : 1;
21482+ /** Set Global OUT NAK */
21483+ unsigned sgoutnak : 1;
21484+ /** Clear Global OUT NAK */
21485+ unsigned cgoutnak : 1;
21486+
21487+ /** Power-On Programming Done */
21488+ unsigned pwronprgdone : 1;
21489+ /** Global Continue on BNA */
21490+ unsigned gcontbna : 1;
21491+ /** Global Multi Count */
21492+ unsigned gmc : 2;
21493+ /** Ignore Frame Number for ISOC EPs */
21494+ unsigned ifrmnum : 1;
21495+ /** NAK on Babble */
21496+ unsigned nakonbble : 1;
21497+
21498+ unsigned reserved16_31 : 16;
21499+ } b;
21500+} dctl_data_t;
21501+
21502+/**
21503+ * This union represents the bit fields in the Device Status
21504+ * Register. Read the register into the <i>d32</i> member then
21505+ * set/clear the bits using the <i>b</i>it elements.
21506+ */
21507+typedef union dsts_data
21508+{
21509+ /** raw register data */
21510+ uint32_t d32;
21511+ /** register bits */
21512+ struct
21513+ {
21514+ /** Suspend Status */
21515+ unsigned suspsts : 1;
21516+ /** Enumerated Speed */
21517+ unsigned enumspd : 2;
21518+#define DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ 0
21519+#define DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ 1
21520+#define DWC_DSTS_ENUMSPD_LS_PHY_6MHZ 2
21521+#define DWC_DSTS_ENUMSPD_FS_PHY_48MHZ 3
21522+ /** Erratic Error */
21523+ unsigned errticerr : 1;
21524+ unsigned reserved4_7: 4;
21525+ /** Frame or Microframe Number of the received SOF */
21526+ unsigned soffn : 14;
21527+ unsigned reserved22_31 : 10;
21528+ } b;
21529+} dsts_data_t;
21530+
21531+
21532+/**
21533+ * This union represents the bit fields in the Device IN EP Interrupt
21534+ * Register and the Device IN EP Common Mask Register.
21535+ *
21536+ * - Read the register into the <i>d32</i> member then set/clear the
21537+ * bits using the <i>b</i>it elements.
21538+ */
21539+typedef union diepint_data
21540+{
21541+ /** raw register data */
21542+ uint32_t d32;
21543+ /** register bits */
21544+ struct
21545+ {
21546+ /** Transfer complete mask */
21547+ unsigned xfercompl : 1;
21548+ /** Endpoint disable mask */
21549+ unsigned epdisabled : 1;
21550+ /** AHB Error mask */
21551+ unsigned ahberr : 1;
21552+ /** TimeOUT Handshake mask (non-ISOC EPs) */
21553+ unsigned timeout : 1;
21554+ /** IN Token received with TxF Empty mask */
21555+ unsigned intktxfemp : 1;
21556+ /** IN Token Received with EP mismatch mask */
21557+ unsigned intknepmis : 1;
21558+ /** IN Endpoint HAK Effective mask */
21559+ unsigned inepnakeff : 1;
21560+ /** IN Endpoint HAK Effective mask */
21561+ unsigned emptyintr : 1;
21562+ unsigned txfifoundrn : 1;
21563+
21564+ /** BNA Interrupt mask */
21565+ unsigned bna : 1;
21566+ unsigned reserved10_12 : 3;
21567+ /** BNA Interrupt mask */
21568+ unsigned nak : 1;
21569+ unsigned reserved14_31 : 18;
21570+ } b;
21571+} diepint_data_t;
21572+
21573+/**
21574+ * This union represents the bit fields in the Device IN EP
21575+ * Common/Dedicated Interrupt Mask Register.
21576+ */
21577+typedef union diepint_data diepmsk_data_t;
21578+
21579+/**
21580+ * This union represents the bit fields in the Device OUT EP Interrupt
21581+ * Registerand Device OUT EP Common Interrupt Mask Register.
21582+ *
21583+ * - Read the register into the <i>d32</i> member then set/clear the
21584+ * bits using the <i>b</i>it elements.
21585+ */
21586+typedef union doepint_data
21587+{
21588+ /** raw register data */
21589+ uint32_t d32;
21590+ /** register bits */
21591+ struct
21592+ {
21593+ /** Transfer complete */
21594+ unsigned xfercompl : 1;
21595+ /** Endpoint disable */
21596+ unsigned epdisabled : 1;
21597+ /** AHB Error */
21598+ unsigned ahberr : 1;
21599+ /** Setup Phase Done (contorl EPs) */
21600+ unsigned setup : 1;
21601+ /** OUT Token Received when Endpoint Disabled */
21602+ unsigned outtknepdis : 1;
21603+ unsigned stsphsercvd : 1;
21604+ /** Back-to-Back SETUP Packets Received */
21605+ unsigned back2backsetup : 1;
21606+ unsigned reserved7 : 1;
21607+ /** OUT packet Error */
21608+ unsigned outpkterr : 1;
21609+ /** BNA Interrupt */
21610+ unsigned bna : 1;
21611+ unsigned reserved10 : 1;
21612+ /** Packet Drop Status */
21613+ unsigned pktdrpsts : 1;
21614+ /** Babble Interrupt */
21615+ unsigned babble : 1;
21616+ /** NAK Interrupt */
21617+ unsigned nak : 1;
21618+ /** NYET Interrupt */
21619+ unsigned nyet : 1;
21620+
21621+ unsigned reserved15_31 : 17;
21622+ } b;
21623+} doepint_data_t;
21624+
21625+/**
21626+ * This union represents the bit fields in the Device OUT EP
21627+ * Common/Dedicated Interrupt Mask Register.
21628+ */
21629+typedef union doepint_data doepmsk_data_t;
21630+
21631+/**
21632+ * This union represents the bit fields in the Device All EP Interrupt
21633+ * and Mask Registers.
21634+ * - Read the register into the <i>d32</i> member then set/clear the
21635+ * bits using the <i>b</i>it elements.
21636+ */
21637+typedef union daint_data
21638+{
21639+ /** raw register data */
21640+ uint32_t d32;
21641+ /** register bits */
21642+ struct
21643+ {
21644+ /** IN Endpoint bits */
21645+ unsigned in : 16;
21646+ /** OUT Endpoint bits */
21647+ unsigned out : 16;
21648+ } ep;
21649+ struct
21650+ {
21651+ /** IN Endpoint bits */
21652+ unsigned inep0 : 1;
21653+ unsigned inep1 : 1;
21654+ unsigned inep2 : 1;
21655+ unsigned inep3 : 1;
21656+ unsigned inep4 : 1;
21657+ unsigned inep5 : 1;
21658+ unsigned inep6 : 1;
21659+ unsigned inep7 : 1;
21660+ unsigned inep8 : 1;
21661+ unsigned inep9 : 1;
21662+ unsigned inep10 : 1;
21663+ unsigned inep11 : 1;
21664+ unsigned inep12 : 1;
21665+ unsigned inep13 : 1;
21666+ unsigned inep14 : 1;
21667+ unsigned inep15 : 1;
21668+ /** OUT Endpoint bits */
21669+ unsigned outep0 : 1;
21670+ unsigned outep1 : 1;
21671+ unsigned outep2 : 1;
21672+ unsigned outep3 : 1;
21673+ unsigned outep4 : 1;
21674+ unsigned outep5 : 1;
21675+ unsigned outep6 : 1;
21676+ unsigned outep7 : 1;
21677+ unsigned outep8 : 1;
21678+ unsigned outep9 : 1;
21679+ unsigned outep10 : 1;
21680+ unsigned outep11 : 1;
21681+ unsigned outep12 : 1;
21682+ unsigned outep13 : 1;
21683+ unsigned outep14 : 1;
21684+ unsigned outep15 : 1;
21685+ } b;
21686+} daint_data_t;
21687+
21688+/**
21689+ * This union represents the bit fields in the Device IN Token Queue
21690+ * Read Registers.
21691+ * - Read the register into the <i>d32</i> member.
21692+ * - READ-ONLY Register
21693+ */
21694+typedef union dtknq1_data
21695+{
21696+ /** raw register data */
21697+ uint32_t d32;
21698+ /** register bits */
21699+ struct
21700+ {
21701+ /** In Token Queue Write Pointer */
21702+ unsigned intknwptr : 5;
21703+ /** Reserved */
21704+ unsigned reserved05_06 : 2;
21705+ /** write pointer has wrapped. */
21706+ unsigned wrap_bit : 1;
21707+ /** EP Numbers of IN Tokens 0 ... 4 */
21708+ unsigned epnums0_5 : 24;
21709+ }b;
21710+} dtknq1_data_t;
21711+
21712+/**
21713+ * This union represents Threshold control Register
21714+ * - Read and write the register into the <i>d32</i> member.
21715+ * - READ-WRITABLE Register
21716+ */
21717+typedef union dthrctl_data
21718+{
21719+ /** raw register data */
21720+ uint32_t d32;
21721+ /** register bits */
21722+ struct
21723+ {
21724+ /** non ISO Tx Thr. Enable */
21725+ unsigned non_iso_thr_en : 1;
21726+ /** ISO Tx Thr. Enable */
21727+ unsigned iso_thr_en : 1;
21728+ /** Tx Thr. Length */
21729+ unsigned tx_thr_len : 9;
21730+ /** Reserved */
21731+ unsigned reserved11_15 : 5;
21732+ /** Rx Thr. Enable */
21733+ unsigned rx_thr_en : 1;
21734+ /** Rx Thr. Length */
21735+ unsigned rx_thr_len : 9;
21736+ /** Reserved */
21737+ unsigned reserved26_31 : 6;
21738+ }b;
21739+} dthrctl_data_t;
21740+
21741+
21742+/**
21743+ * Device Logical IN Endpoint-Specific Registers. <i>Offsets
21744+ * 900h-AFCh</i>
21745+ *
21746+ * There will be one set of endpoint registers per logical endpoint
21747+ * implemented.
21748+ *
21749+ * <i>These registers are visible only in Device mode and must not be
21750+ * accessed in Host mode, as the results are unknown.</i>
21751+ */
21752+typedef struct dwc_otg_dev_in_ep_regs
21753+{
21754+ /** Device IN Endpoint Control Register. <i>Offset:900h +
21755+ * (ep_num * 20h) + 00h</i> */
21756+ volatile uint32_t diepctl;
21757+ /** Reserved. <i>Offset:900h + (ep_num * 20h) + 04h</i> */
21758+ uint32_t reserved04;
21759+ /** Device IN Endpoint Interrupt Register. <i>Offset:900h +
21760+ * (ep_num * 20h) + 08h</i> */
21761+ volatile uint32_t diepint;
21762+ /** Reserved. <i>Offset:900h + (ep_num * 20h) + 0Ch</i> */
21763+ uint32_t reserved0C;
21764+ /** Device IN Endpoint Transfer Size
21765+ * Register. <i>Offset:900h + (ep_num * 20h) + 10h</i> */
21766+ volatile uint32_t dieptsiz;
21767+ /** Device IN Endpoint DMA Address Register. <i>Offset:900h +
21768+ * (ep_num * 20h) + 14h</i> */
21769+ volatile uint32_t diepdma;
21770+ /** Device IN Endpoint Transmit FIFO Status Register. <i>Offset:900h +
21771+ * (ep_num * 20h) + 18h</i> */
21772+ volatile uint32_t dtxfsts;
21773+ /** Device IN Endpoint DMA Buffer Register. <i>Offset:900h +
21774+ * (ep_num * 20h) + 1Ch</i> */
21775+ volatile uint32_t diepdmab;
21776+} dwc_otg_dev_in_ep_regs_t;
21777+
21778+/**
21779+ * Device Logical OUT Endpoint-Specific Registers. <i>Offsets:
21780+ * B00h-CFCh</i>
21781+ *
21782+ * There will be one set of endpoint registers per logical endpoint
21783+ * implemented.
21784+ *
21785+ * <i>These registers are visible only in Device mode and must not be
21786+ * accessed in Host mode, as the results are unknown.</i>
21787+ */
21788+typedef struct dwc_otg_dev_out_ep_regs
21789+{
21790+ /** Device OUT Endpoint Control Register. <i>Offset:B00h +
21791+ * (ep_num * 20h) + 00h</i> */
21792+ volatile uint32_t doepctl;
21793+ /** Device OUT Endpoint Frame number Register. <i>Offset:
21794+ * B00h + (ep_num * 20h) + 04h</i> */
21795+ volatile uint32_t doepfn;
21796+ /** Device OUT Endpoint Interrupt Register. <i>Offset:B00h +
21797+ * (ep_num * 20h) + 08h</i> */
21798+ volatile uint32_t doepint;
21799+ /** Reserved. <i>Offset:B00h + (ep_num * 20h) + 0Ch</i> */
21800+ uint32_t reserved0C;
21801+ /** Device OUT Endpoint Transfer Size Register. <i>Offset:
21802+ * B00h + (ep_num * 20h) + 10h</i> */
21803+ volatile uint32_t doeptsiz;
21804+ /** Device OUT Endpoint DMA Address Register. <i>Offset:B00h
21805+ * + (ep_num * 20h) + 14h</i> */
21806+ volatile uint32_t doepdma;
21807+ /** Reserved. <i>Offset:B00h + * (ep_num * 20h) + 1Ch</i> */
21808+ uint32_t unused;
21809+ /** Device OUT Endpoint DMA Buffer Register. <i>Offset:B00h
21810+ * + (ep_num * 20h) + 1Ch</i> */
21811+ uint32_t doepdmab;
21812+} dwc_otg_dev_out_ep_regs_t;
21813+
21814+/**
21815+ * This union represents the bit fields in the Device EP Control
21816+ * Register. Read the register into the <i>d32</i> member then
21817+ * set/clear the bits using the <i>b</i>it elements.
21818+ */
21819+typedef union depctl_data
21820+{
21821+ /** raw register data */
21822+ uint32_t d32;
21823+ /** register bits */
21824+ struct
21825+ {
21826+ /** Maximum Packet Size
21827+ * IN/OUT EPn
21828+ * IN/OUT EP0 - 2 bits
21829+ * 2'b00: 64 Bytes
21830+ * 2'b01: 32
21831+ * 2'b10: 16
21832+ * 2'b11: 8 */
21833+ unsigned mps : 11;
21834+#define DWC_DEP0CTL_MPS_64 0
21835+#define DWC_DEP0CTL_MPS_32 1
21836+#define DWC_DEP0CTL_MPS_16 2
21837+#define DWC_DEP0CTL_MPS_8 3
21838+
21839+ /** Next Endpoint
21840+ * IN EPn/IN EP0
21841+ * OUT EPn/OUT EP0 - reserved */
21842+ unsigned nextep : 4;
21843+
21844+ /** USB Active Endpoint */
21845+ unsigned usbactep : 1;
21846+
21847+ /** Endpoint DPID (INTR/Bulk IN and OUT endpoints)
21848+ * This field contains the PID of the packet going to
21849+ * be received or transmitted on this endpoint. The
21850+ * application should program the PID of the first
21851+ * packet going to be received or transmitted on this
21852+ * endpoint , after the endpoint is
21853+ * activated. Application use the SetD1PID and
21854+ * SetD0PID fields of this register to program either
21855+ * D0 or D1 PID.
21856+ *
21857+ * The encoding for this field is
21858+ * - 0: D0
21859+ * - 1: D1
21860+ */
21861+ unsigned dpid : 1;
21862+
21863+ /** NAK Status */
21864+ unsigned naksts : 1;
21865+
21866+ /** Endpoint Type
21867+ * 2'b00: Control
21868+ * 2'b01: Isochronous
21869+ * 2'b10: Bulk
21870+ * 2'b11: Interrupt */
21871+ unsigned eptype : 2;
21872+
21873+ /** Snoop Mode
21874+ * OUT EPn/OUT EP0
21875+ * IN EPn/IN EP0 - reserved */
21876+ unsigned snp : 1;
21877+
21878+ /** Stall Handshake */
21879+ unsigned stall : 1;
21880+
21881+ /** Tx Fifo Number
21882+ * IN EPn/IN EP0
21883+ * OUT EPn/OUT EP0 - reserved */
21884+ unsigned txfnum : 4;
21885+
21886+ /** Clear NAK */
21887+ unsigned cnak : 1;
21888+ /** Set NAK */
21889+ unsigned snak : 1;
21890+ /** Set DATA0 PID (INTR/Bulk IN and OUT endpoints)
21891+ * Writing to this field sets the Endpoint DPID (DPID)
21892+ * field in this register to DATA0. Set Even
21893+ * (micro)frame (SetEvenFr) (ISO IN and OUT Endpoints)
21894+ * Writing to this field sets the Even/Odd
21895+ * (micro)frame (EO_FrNum) field to even (micro)
21896+ * frame.
21897+ */
21898+ unsigned setd0pid : 1;
21899+ /** Set DATA1 PID (INTR/Bulk IN and OUT endpoints)
21900+ * Writing to this field sets the Endpoint DPID (DPID)
21901+ * field in this register to DATA1 Set Odd
21902+ * (micro)frame (SetOddFr) (ISO IN and OUT Endpoints)
21903+ * Writing to this field sets the Even/Odd
21904+ * (micro)frame (EO_FrNum) field to odd (micro) frame.
21905+ */
21906+ unsigned setd1pid : 1;
21907+ /** Endpoint Disable */
21908+ unsigned epdis : 1;
21909+ /** Endpoint Enable */
21910+ unsigned epena : 1;
21911+ } b;
21912+} depctl_data_t;
21913+
21914+/**
21915+ * This union represents the bit fields in the Device EP Transfer
21916+ * Size Register. Read the register into the <i>d32</i> member then
21917+ * set/clear the bits using the <i>b</i>it elements.
21918+ */
21919+typedef union deptsiz_data
21920+{
21921+ /** raw register data */
21922+ uint32_t d32;
21923+ /** register bits */
21924+ struct {
21925+ /** Transfer size */
21926+ unsigned xfersize : 19;
21927+ /** Packet Count */
21928+ unsigned pktcnt : 10;
21929+ /** Multi Count - Periodic IN endpoints */
21930+ unsigned mc : 2;
21931+ unsigned reserved : 1;
21932+ } b;
21933+} deptsiz_data_t;
21934+
21935+/**
21936+ * This union represents the bit fields in the Device EP 0 Transfer
21937+ * Size Register. Read the register into the <i>d32</i> member then
21938+ * set/clear the bits using the <i>b</i>it elements.
21939+ */
21940+typedef union deptsiz0_data
21941+{
21942+ /** raw register data */
21943+ uint32_t d32;
21944+ /** register bits */
21945+ struct {
21946+ /** Transfer size */
21947+ unsigned xfersize : 7;
21948+ /** Reserved */
21949+ unsigned reserved7_18 : 12;
21950+ /** Packet Count */
21951+ unsigned pktcnt : 1;
21952+ /** Reserved */
21953+ unsigned reserved20_28 : 9;
21954+ /**Setup Packet Count (DOEPTSIZ0 Only) */
21955+ unsigned supcnt : 2;
21956+ unsigned reserved31;
21957+ } b;
21958+} deptsiz0_data_t;
21959+
21960+
21961+/////////////////////////////////////////////////
21962+// DMA Descriptor Specific Structures
21963+//
21964+
21965+/** Buffer status definitions */
21966+
21967+#define BS_HOST_READY 0x0
21968+#define BS_DMA_BUSY 0x1
21969+#define BS_DMA_DONE 0x2
21970+#define BS_HOST_BUSY 0x3
21971+
21972+/** Receive/Transmit status definitions */
21973+
21974+#define RTS_SUCCESS 0x0
21975+#define RTS_BUFFLUSH 0x1
21976+#define RTS_RESERVED 0x2
21977+#define RTS_BUFERR 0x3
21978+
21979+
21980+/**
21981+ * This union represents the bit fields in the DMA Descriptor
21982+ * status quadlet. Read the quadlet into the <i>d32</i> member then
21983+ * set/clear the bits using the <i>b</i>it, <i>b_iso_out</i> and
21984+ * <i>b_iso_in</i> elements.
21985+ */
21986+typedef union desc_sts_data
21987+{
21988+ /** raw register data */
21989+ uint32_t d32;
21990+ /** quadlet bits */
21991+ struct {
21992+ /** Received number of bytes */
21993+ unsigned bytes : 16;
21994+
21995+ unsigned reserved16_22 : 7;
21996+ /** Multiple Transfer - only for OUT EPs */
21997+ unsigned mtrf : 1;
21998+ /** Setup Packet received - only for OUT EPs */
21999+ unsigned sr : 1;
22000+ /** Interrupt On Complete */
22001+ unsigned ioc : 1;
22002+ /** Short Packet */
22003+ unsigned sp : 1;
22004+ /** Last */
22005+ unsigned l : 1;
22006+ /** Receive Status */
22007+ unsigned sts : 2;
22008+ /** Buffer Status */
22009+ unsigned bs : 2;
22010+ } b;
22011+
22012+#ifdef DWC_EN_ISOC
22013+ /** iso out quadlet bits */
22014+ struct {
22015+ /** Received number of bytes */
22016+ unsigned rxbytes : 11;
22017+
22018+ unsigned reserved11 : 1;
22019+ /** Frame Number */
22020+ unsigned framenum : 11;
22021+ /** Received ISO Data PID */
22022+ unsigned pid : 2;
22023+ /** Interrupt On Complete */
22024+ unsigned ioc : 1;
22025+ /** Short Packet */
22026+ unsigned sp : 1;
22027+ /** Last */
22028+ unsigned l : 1;
22029+ /** Receive Status */
22030+ unsigned rxsts : 2;
22031+ /** Buffer Status */
22032+ unsigned bs : 2;
22033+ } b_iso_out;
22034+
22035+ /** iso in quadlet bits */
22036+ struct {
22037+ /** Transmited number of bytes */
22038+ unsigned txbytes : 12;
22039+ /** Frame Number */
22040+ unsigned framenum : 11;
22041+ /** Transmited ISO Data PID */
22042+ unsigned pid : 2;
22043+ /** Interrupt On Complete */
22044+ unsigned ioc : 1;
22045+ /** Short Packet */
22046+ unsigned sp : 1;
22047+ /** Last */
22048+ unsigned l : 1;
22049+ /** Transmit Status */
22050+ unsigned txsts : 2;
22051+ /** Buffer Status */
22052+ unsigned bs : 2;
22053+ } b_iso_in;
22054+#endif //DWC_EN_ISOC
22055+} desc_sts_data_t;
22056+
22057+/**
22058+ * DMA Descriptor structure
22059+ *
22060+ * DMA Descriptor structure contains two quadlets:
22061+ * Status quadlet and Data buffer pointer.
22062+ */
22063+typedef struct dwc_otg_dma_desc
22064+{
22065+ /** DMA Descriptor status quadlet */
22066+ desc_sts_data_t status;
22067+ /** DMA Descriptor data buffer pointer */
22068+ dma_addr_t buf;
22069+} dwc_otg_dma_desc_t;
22070+
22071+/**
22072+ * The dwc_otg_dev_if structure contains information needed to manage
22073+ * the DWC_otg controller acting in device mode. It represents the
22074+ * programming view of the device-specific aspects of the controller.
22075+ */
22076+typedef struct dwc_otg_dev_if
22077+{
22078+ /** Pointer to device Global registers.
22079+ * Device Global Registers starting at offset 800h
22080+ */
22081+ dwc_otg_device_global_regs_t *dev_global_regs;
22082+#define DWC_DEV_GLOBAL_REG_OFFSET 0x800
22083+
22084+ /**
22085+ * Device Logical IN Endpoint-Specific Registers 900h-AFCh
22086+ */
22087+ dwc_otg_dev_in_ep_regs_t *in_ep_regs[MAX_EPS_CHANNELS];
22088+#define DWC_DEV_IN_EP_REG_OFFSET 0x900
22089+#define DWC_EP_REG_OFFSET 0x20
22090+
22091+ /** Device Logical OUT Endpoint-Specific Registers B00h-CFCh */
22092+ dwc_otg_dev_out_ep_regs_t *out_ep_regs[MAX_EPS_CHANNELS];
22093+#define DWC_DEV_OUT_EP_REG_OFFSET 0xB00
22094+
22095+ /* Device configuration information*/
22096+ uint8_t speed; /**< Device Speed 0: Unknown, 1: LS, 2:FS, 3: HS */
22097+ uint8_t num_in_eps; /**< Number # of Tx EP range: 0-15 exept ep0 */
22098+ uint8_t num_out_eps; /**< Number # of Rx EP range: 0-15 exept ep 0*/
22099+
22100+ /** Size of periodic FIFOs (Bytes) */
22101+ uint16_t perio_tx_fifo_size[MAX_PERIO_FIFOS];
22102+
22103+ /** Size of Tx FIFOs (Bytes) */
22104+ uint16_t tx_fifo_size[MAX_TX_FIFOS];
22105+
22106+ /** Thresholding enable flags and length varaiables **/
22107+ uint16_t rx_thr_en;
22108+ uint16_t iso_tx_thr_en;
22109+ uint16_t non_iso_tx_thr_en;
22110+
22111+ uint16_t rx_thr_length;
22112+ uint16_t tx_thr_length;
22113+
22114+ /**
22115+ * Pointers to the DMA Descriptors for EP0 Control
22116+ * transfers (virtual and physical)
22117+ */
22118+ /** 2 descriptors for SETUP packets */
22119+ uint32_t dma_setup_desc_addr[2];
22120+ dwc_otg_dma_desc_t* setup_desc_addr[2];
22121+
22122+ /** Pointer to Descriptor with latest SETUP packet */
22123+ dwc_otg_dma_desc_t* psetup;
22124+
22125+ /** Index of current SETUP handler descriptor */
22126+ uint32_t setup_desc_index;
22127+
22128+ /** Descriptor for Data In or Status In phases */
22129+ uint32_t dma_in_desc_addr;
22130+ dwc_otg_dma_desc_t* in_desc_addr;;
22131+
22132+ /** Descriptor for Data Out or Status Out phases */
22133+ uint32_t dma_out_desc_addr;
22134+ dwc_otg_dma_desc_t* out_desc_addr;
22135+} dwc_otg_dev_if_t;
22136+
22137+
22138+
22139+
22140+/////////////////////////////////////////////////
22141+// Host Mode Register Structures
22142+//
22143+/**
22144+ * The Host Global Registers structure defines the size and relative
22145+ * field offsets for the Host Mode Global Registers. Host Global
22146+ * Registers offsets 400h-7FFh.
22147+*/
22148+typedef struct dwc_otg_host_global_regs
22149+{
22150+ /** Host Configuration Register. <i>Offset: 400h</i> */
22151+ volatile uint32_t hcfg;
22152+ /** Host Frame Interval Register. <i>Offset: 404h</i> */
22153+ volatile uint32_t hfir;
22154+ /** Host Frame Number / Frame Remaining Register. <i>Offset: 408h</i> */
22155+ volatile uint32_t hfnum;
22156+ /** Reserved. <i>Offset: 40Ch</i> */
22157+ uint32_t reserved40C;
22158+ /** Host Periodic Transmit FIFO/ Queue Status Register. <i>Offset: 410h</i> */
22159+ volatile uint32_t hptxsts;
22160+ /** Host All Channels Interrupt Register. <i>Offset: 414h</i> */
22161+ volatile uint32_t haint;
22162+ /** Host All Channels Interrupt Mask Register. <i>Offset: 418h</i> */
22163+ volatile uint32_t haintmsk;
22164+} dwc_otg_host_global_regs_t;
22165+
22166+/**
22167+ * This union represents the bit fields in the Host Configuration Register.
22168+ * Read the register into the <i>d32</i> member then set/clear the bits using
22169+ * the <i>b</i>it elements. Write the <i>d32</i> member to the hcfg register.
22170+ */
22171+typedef union hcfg_data
22172+{
22173+ /** raw register data */
22174+ uint32_t d32;
22175+
22176+ /** register bits */
22177+ struct
22178+ {
22179+ /** FS/LS Phy Clock Select */
22180+ unsigned fslspclksel : 2;
22181+#define DWC_HCFG_30_60_MHZ 0
22182+#define DWC_HCFG_48_MHZ 1
22183+#define DWC_HCFG_6_MHZ 2
22184+
22185+ /** FS/LS Only Support */
22186+ unsigned fslssupp : 1;
22187+ } b;
22188+} hcfg_data_t;
22189+
22190+/**
22191+ * This union represents the bit fields in the Host Frame Remaing/Number
22192+ * Register.
22193+ */
22194+typedef union hfir_data
22195+{
22196+ /** raw register data */
22197+ uint32_t d32;
22198+
22199+ /** register bits */
22200+ struct
22201+ {
22202+ unsigned frint : 16;
22203+ unsigned reserved : 16;
22204+ } b;
22205+} hfir_data_t;
22206+
22207+/**
22208+ * This union represents the bit fields in the Host Frame Remaing/Number
22209+ * Register.
22210+ */
22211+typedef union hfnum_data
22212+{
22213+ /** raw register data */
22214+ uint32_t d32;
22215+
22216+ /** register bits */
22217+ struct
22218+ {
22219+ unsigned frnum : 16;
22220+#define DWC_HFNUM_MAX_FRNUM 0x3FFF
22221+ unsigned frrem : 16;
22222+ } b;
22223+} hfnum_data_t;
22224+
22225+typedef union hptxsts_data
22226+{
22227+ /** raw register data */
22228+ uint32_t d32;
22229+
22230+ /** register bits */
22231+ struct
22232+ {
22233+ unsigned ptxfspcavail : 16;
22234+ unsigned ptxqspcavail : 8;
22235+ /** Top of the Periodic Transmit Request Queue
22236+ * - bit 24 - Terminate (last entry for the selected channel)
22237+ * - bits 26:25 - Token Type
22238+ * - 2'b00 - Zero length
22239+ * - 2'b01 - Ping
22240+ * - 2'b10 - Disable
22241+ * - bits 30:27 - Channel Number
22242+ * - bit 31 - Odd/even microframe
22243+ */
22244+ unsigned ptxqtop_terminate : 1;
22245+ unsigned ptxqtop_token : 2;
22246+ unsigned ptxqtop_chnum : 4;
22247+ unsigned ptxqtop_odd : 1;
22248+ } b;
22249+} hptxsts_data_t;
22250+
22251+/**
22252+ * This union represents the bit fields in the Host Port Control and Status
22253+ * Register. Read the register into the <i>d32</i> member then set/clear the
22254+ * bits using the <i>b</i>it elements. Write the <i>d32</i> member to the
22255+ * hprt0 register.
22256+ */
22257+typedef union hprt0_data
22258+{
22259+ /** raw register data */
22260+ uint32_t d32;
22261+ /** register bits */
22262+ struct
22263+ {
22264+ unsigned prtconnsts : 1;
22265+ unsigned prtconndet : 1;
22266+ unsigned prtena : 1;
22267+ unsigned prtenchng : 1;
22268+ unsigned prtovrcurract : 1;
22269+ unsigned prtovrcurrchng : 1;
22270+ unsigned prtres : 1;
22271+ unsigned prtsusp : 1;
22272+ unsigned prtrst : 1;
22273+ unsigned reserved9 : 1;
22274+ unsigned prtlnsts : 2;
22275+ unsigned prtpwr : 1;
22276+ unsigned prttstctl : 4;
22277+ unsigned prtspd : 2;
22278+#define DWC_HPRT0_PRTSPD_HIGH_SPEED 0
22279+#define DWC_HPRT0_PRTSPD_FULL_SPEED 1
22280+#define DWC_HPRT0_PRTSPD_LOW_SPEED 2
22281+ unsigned reserved19_31 : 13;
22282+ } b;
22283+} hprt0_data_t;
22284+
22285+/**
22286+ * This union represents the bit fields in the Host All Interrupt
22287+ * Register.
22288+ */
22289+typedef union haint_data
22290+{
22291+ /** raw register data */
22292+ uint32_t d32;
22293+ /** register bits */
22294+ struct
22295+ {
22296+ unsigned ch0 : 1;
22297+ unsigned ch1 : 1;
22298+ unsigned ch2 : 1;
22299+ unsigned ch3 : 1;
22300+ unsigned ch4 : 1;
22301+ unsigned ch5 : 1;
22302+ unsigned ch6 : 1;
22303+ unsigned ch7 : 1;
22304+ unsigned ch8 : 1;
22305+ unsigned ch9 : 1;
22306+ unsigned ch10 : 1;
22307+ unsigned ch11 : 1;
22308+ unsigned ch12 : 1;
22309+ unsigned ch13 : 1;
22310+ unsigned ch14 : 1;
22311+ unsigned ch15 : 1;
22312+ unsigned reserved : 16;
22313+ } b;
22314+
22315+ struct
22316+ {
22317+ unsigned chint : 16;
22318+ unsigned reserved : 16;
22319+ } b2;
22320+} haint_data_t;
22321+
22322+/**
22323+ * This union represents the bit fields in the Host All Interrupt
22324+ * Register.
22325+ */
22326+typedef union haintmsk_data
22327+{
22328+ /** raw register data */
22329+ uint32_t d32;
22330+ /** register bits */
22331+ struct
22332+ {
22333+ unsigned ch0 : 1;
22334+ unsigned ch1 : 1;
22335+ unsigned ch2 : 1;
22336+ unsigned ch3 : 1;
22337+ unsigned ch4 : 1;
22338+ unsigned ch5 : 1;
22339+ unsigned ch6 : 1;
22340+ unsigned ch7 : 1;
22341+ unsigned ch8 : 1;
22342+ unsigned ch9 : 1;
22343+ unsigned ch10 : 1;
22344+ unsigned ch11 : 1;
22345+ unsigned ch12 : 1;
22346+ unsigned ch13 : 1;
22347+ unsigned ch14 : 1;
22348+ unsigned ch15 : 1;
22349+ unsigned reserved : 16;
22350+ } b;
22351+
22352+ struct
22353+ {
22354+ unsigned chint : 16;
22355+ unsigned reserved : 16;
22356+ } b2;
22357+} haintmsk_data_t;
22358+
22359+/**
22360+ * Host Channel Specific Registers. <i>500h-5FCh</i>
22361+ */
22362+typedef struct dwc_otg_hc_regs
22363+{
22364+ /** Host Channel 0 Characteristic Register. <i>Offset: 500h + (chan_num * 20h) + 00h</i> */
22365+ volatile uint32_t hcchar;
22366+ /** Host Channel 0 Split Control Register. <i>Offset: 500h + (chan_num * 20h) + 04h</i> */
22367+ volatile uint32_t hcsplt;
22368+ /** Host Channel 0 Interrupt Register. <i>Offset: 500h + (chan_num * 20h) + 08h</i> */
22369+ volatile uint32_t hcint;
22370+ /** Host Channel 0 Interrupt Mask Register. <i>Offset: 500h + (chan_num * 20h) + 0Ch</i> */
22371+ volatile uint32_t hcintmsk;
22372+ /** Host Channel 0 Transfer Size Register. <i>Offset: 500h + (chan_num * 20h) + 10h</i> */
22373+ volatile uint32_t hctsiz;
22374+ /** Host Channel 0 DMA Address Register. <i>Offset: 500h + (chan_num * 20h) + 14h</i> */
22375+ volatile uint32_t hcdma;
22376+ /** Reserved. <i>Offset: 500h + (chan_num * 20h) + 18h - 500h + (chan_num * 20h) + 1Ch</i> */
22377+ uint32_t reserved[2];
22378+} dwc_otg_hc_regs_t;
22379+
22380+/**
22381+ * This union represents the bit fields in the Host Channel Characteristics
22382+ * Register. Read the register into the <i>d32</i> member then set/clear the
22383+ * bits using the <i>b</i>it elements. Write the <i>d32</i> member to the
22384+ * hcchar register.
22385+ */
22386+typedef union hcchar_data
22387+{
22388+ /** raw register data */
22389+ uint32_t d32;
22390+
22391+ /** register bits */
22392+ struct
22393+ {
22394+ /** Maximum packet size in bytes */
22395+ unsigned mps : 11;
22396+
22397+ /** Endpoint number */
22398+ unsigned epnum : 4;
22399+
22400+ /** 0: OUT, 1: IN */
22401+ unsigned epdir : 1;
22402+
22403+ unsigned reserved : 1;
22404+
22405+ /** 0: Full/high speed device, 1: Low speed device */
22406+ unsigned lspddev : 1;
22407+
22408+ /** 0: Control, 1: Isoc, 2: Bulk, 3: Intr */
22409+ unsigned eptype : 2;
22410+
22411+ /** Packets per frame for periodic transfers. 0 is reserved. */
22412+ unsigned multicnt : 2;
22413+
22414+ /** Device address */
22415+ unsigned devaddr : 7;
22416+
22417+ /**
22418+ * Frame to transmit periodic transaction.
22419+ * 0: even, 1: odd
22420+ */
22421+ unsigned oddfrm : 1;
22422+
22423+ /** Channel disable */
22424+ unsigned chdis : 1;
22425+
22426+ /** Channel enable */
22427+ unsigned chen : 1;
22428+ } b;
22429+} hcchar_data_t;
22430+
22431+typedef union hcsplt_data
22432+{
22433+ /** raw register data */
22434+ uint32_t d32;
22435+
22436+ /** register bits */
22437+ struct
22438+ {
22439+ /** Port Address */
22440+ unsigned prtaddr : 7;
22441+
22442+ /** Hub Address */
22443+ unsigned hubaddr : 7;
22444+
22445+ /** Transaction Position */
22446+ unsigned xactpos : 2;
22447+#define DWC_HCSPLIT_XACTPOS_MID 0
22448+#define DWC_HCSPLIT_XACTPOS_END 1
22449+#define DWC_HCSPLIT_XACTPOS_BEGIN 2
22450+#define DWC_HCSPLIT_XACTPOS_ALL 3
22451+
22452+ /** Do Complete Split */
22453+ unsigned compsplt : 1;
22454+
22455+ /** Reserved */
22456+ unsigned reserved : 14;
22457+
22458+ /** Split Enble */
22459+ unsigned spltena : 1;
22460+ } b;
22461+} hcsplt_data_t;
22462+
22463+
22464+/**
22465+ * This union represents the bit fields in the Host All Interrupt
22466+ * Register.
22467+ */
22468+typedef union hcint_data
22469+{
22470+ /** raw register data */
22471+ uint32_t d32;
22472+ /** register bits */
22473+ struct
22474+ {
22475+ /** Transfer Complete */
22476+ unsigned xfercomp : 1;
22477+ /** Channel Halted */
22478+ unsigned chhltd : 1;
22479+ /** AHB Error */
22480+ unsigned ahberr : 1;
22481+ /** STALL Response Received */
22482+ unsigned stall : 1;
22483+ /** NAK Response Received */
22484+ unsigned nak : 1;
22485+ /** ACK Response Received */
22486+ unsigned ack : 1;
22487+ /** NYET Response Received */
22488+ unsigned nyet : 1;
22489+ /** Transaction Err */
22490+ unsigned xacterr : 1;
22491+ /** Babble Error */
22492+ unsigned bblerr : 1;
22493+ /** Frame Overrun */
22494+ unsigned frmovrun : 1;
22495+ /** Data Toggle Error */
22496+ unsigned datatglerr : 1;
22497+ /** Reserved */
22498+ unsigned reserved : 21;
22499+ } b;
22500+} hcint_data_t;
22501+
22502+/**
22503+ * This union represents the bit fields in the Host Channel Transfer Size
22504+ * Register. Read the register into the <i>d32</i> member then set/clear the
22505+ * bits using the <i>b</i>it elements. Write the <i>d32</i> member to the
22506+ * hcchar register.
22507+ */
22508+typedef union hctsiz_data
22509+{
22510+ /** raw register data */
22511+ uint32_t d32;
22512+
22513+ /** register bits */
22514+ struct
22515+ {
22516+ /** Total transfer size in bytes */
22517+ unsigned xfersize : 19;
22518+
22519+ /** Data packets to transfer */
22520+ unsigned pktcnt : 10;
22521+
22522+ /**
22523+ * Packet ID for next data packet
22524+ * 0: DATA0
22525+ * 1: DATA2
22526+ * 2: DATA1
22527+ * 3: MDATA (non-Control), SETUP (Control)
22528+ */
22529+ unsigned pid : 2;
22530+#define DWC_HCTSIZ_DATA0 0
22531+#define DWC_HCTSIZ_DATA1 2
22532+#define DWC_HCTSIZ_DATA2 1
22533+#define DWC_HCTSIZ_MDATA 3
22534+#define DWC_HCTSIZ_SETUP 3
22535+
22536+ /** Do PING protocol when 1 */
22537+ unsigned dopng : 1;
22538+ } b;
22539+} hctsiz_data_t;
22540+
22541+/**
22542+ * This union represents the bit fields in the Host Channel Interrupt Mask
22543+ * Register. Read the register into the <i>d32</i> member then set/clear the
22544+ * bits using the <i>b</i>it elements. Write the <i>d32</i> member to the
22545+ * hcintmsk register.
22546+ */
22547+typedef union hcintmsk_data
22548+{
22549+ /** raw register data */
22550+ uint32_t d32;
22551+
22552+ /** register bits */
22553+ struct
22554+ {
22555+ unsigned xfercompl : 1;
22556+ unsigned chhltd : 1;
22557+ unsigned ahberr : 1;
22558+ unsigned stall : 1;
22559+ unsigned nak : 1;
22560+ unsigned ack : 1;
22561+ unsigned nyet : 1;
22562+ unsigned xacterr : 1;
22563+ unsigned bblerr : 1;
22564+ unsigned frmovrun : 1;
22565+ unsigned datatglerr : 1;
22566+ unsigned reserved : 21;
22567+ } b;
22568+} hcintmsk_data_t;
22569+
22570+/** OTG Host Interface Structure.
22571+ *
22572+ * The OTG Host Interface Structure structure contains information
22573+ * needed to manage the DWC_otg controller acting in host mode. It
22574+ * represents the programming view of the host-specific aspects of the
22575+ * controller.
22576+ */
22577+typedef struct dwc_otg_host_if
22578+{
22579+ /** Host Global Registers starting at offset 400h.*/
22580+ dwc_otg_host_global_regs_t *host_global_regs;
22581+#define DWC_OTG_HOST_GLOBAL_REG_OFFSET 0x400
22582+
22583+ /** Host Port 0 Control and Status Register */
22584+ volatile uint32_t *hprt0;
22585+#define DWC_OTG_HOST_PORT_REGS_OFFSET 0x440
22586+
22587+ /** Host Channel Specific Registers at offsets 500h-5FCh. */
22588+ dwc_otg_hc_regs_t *hc_regs[MAX_EPS_CHANNELS];
22589+#define DWC_OTG_HOST_CHAN_REGS_OFFSET 0x500
22590+#define DWC_OTG_CHAN_REGS_OFFSET 0x20
22591+
22592+
22593+ /* Host configuration information */
22594+ /** Number of Host Channels (range: 1-16) */
22595+ uint8_t num_host_channels;
22596+ /** Periodic EPs supported (0: no, 1: yes) */
22597+ uint8_t perio_eps_supported;
22598+ /** Periodic Tx FIFO Size (Only 1 host periodic Tx FIFO) */
22599+ uint16_t perio_tx_fifo_size;
22600+} dwc_otg_host_if_t;
22601+
22602+
22603+/**
22604+ * This union represents the bit fields in the Power and Clock Gating Control
22605+ * Register. Read the register into the <i>d32</i> member then set/clear the
22606+ * bits using the <i>b</i>it elements.
22607+ */
22608+typedef union pcgcctl_data
22609+{
22610+ /** raw register data */
22611+ uint32_t d32;
22612+
22613+ /** register bits */
22614+ struct
22615+ {
22616+ /** Stop Pclk */
22617+ unsigned stoppclk : 1;
22618+ /** Gate Hclk */
22619+ unsigned gatehclk : 1;
22620+ /** Power Clamp */
22621+ unsigned pwrclmp : 1;
22622+ /** Reset Power Down Modules */
22623+ unsigned rstpdwnmodule : 1;
22624+ /** PHY Suspended */
22625+ unsigned physuspended : 1;
22626+ unsigned reserved : 27;
22627+ } b;
22628+} pcgcctl_data_t;
22629+
22630+
22631+#endif
22632--- a/drivers/usb/core/urb.c
22633+++ b/drivers/usb/core/urb.c
22634@@ -17,7 +17,11 @@ static void urb_destroy(struct kref *kre
22635 
22636     if (urb->transfer_flags & URB_FREE_BUFFER)
22637         kfree(urb->transfer_buffer);
22638-
22639+ if (urb->aligned_transfer_buffer) {
22640+ kfree(urb->aligned_transfer_buffer);
22641+ urb->aligned_transfer_buffer = 0;
22642+ urb->aligned_transfer_dma = 0;
22643+ }
22644     kfree(urb);
22645 }
22646 
22647--- a/include/linux/usb.h
22648+++ b/include/linux/usb.h
22649@@ -1200,6 +1200,9 @@ struct urb {
22650     unsigned int transfer_flags; /* (in) URB_SHORT_NOT_OK | ...*/
22651     void *transfer_buffer; /* (in) associated data buffer */
22652     dma_addr_t transfer_dma; /* (in) dma addr for transfer_buffer */
22653+ void *aligned_transfer_buffer; /* (in) associeated data buffer */
22654+ dma_addr_t aligned_transfer_dma;/* (in) dma addr for transfer_buffer */
22655+ u32 aligned_transfer_buffer_length; /* (in) data buffer length */
22656     struct scatterlist *sg; /* (in) scatter gather buffer list */
22657     int num_sgs; /* (in) number of entries in the sg list */
22658     u32 transfer_buffer_length; /* (in) data buffer length */
22659--- a/drivers/usb/gadget/Kconfig
22660+++ b/drivers/usb/gadget/Kconfig
22661@@ -111,7 +111,7 @@ config USB_GADGET_SELECTED
22662 #
22663 choice
22664     prompt "USB Peripheral Controller"
22665- depends on USB_GADGET
22666+ depends on USB_GADGET && !USB_DWC_OTG
22667     help
22668        A USB device uses a controller to talk to its host.
22669        Systems should have only one such upstream link.
22670

Archive Download this file



interactive