Root/target/linux/cns3xxx/patches-2.6.31/208-cns3xxx_usb_support.patch

1--- a/drivers/usb/core/Kconfig
2+++ b/drivers/usb/core/Kconfig
3@@ -106,11 +106,11 @@ config USB_SUSPEND
4 
5       If you are unsure about this, say N here.
6 
7-config USB_OTG
8- bool
9- depends on USB && EXPERIMENTAL
10- select USB_SUSPEND
11- default n
12+#config USB_OTG
13+# bool
14+# depends on USB && EXPERIMENTAL
15+# select USB_SUSPEND
16+# default n
17 
18 
19 config USB_OTG_WHITELIST
20--- a/drivers/usb/core/urb.c
21+++ b/drivers/usb/core/urb.c
22@@ -17,7 +17,11 @@ static void urb_destroy(struct kref *kre
23 
24     if (urb->transfer_flags & URB_FREE_BUFFER)
25         kfree(urb->transfer_buffer);
26-
27+ if(urb->aligned_transfer_buffer){
28+ kfree(urb->aligned_transfer_buffer);
29+ urb->aligned_transfer_buffer=0;
30+ urb->aligned_transfer_dma=0;
31+ }
32     kfree(urb);
33 }
34 
35@@ -91,6 +95,7 @@ void usb_free_urb(struct urb *urb)
36 {
37     if (urb)
38         kref_put(&urb->kref, urb_destroy);
39+
40 }
41 EXPORT_SYMBOL_GPL(usb_free_urb);
42 
43--- a/drivers/usb/gadget/file_storage.c
44+++ b/drivers/usb/gadget/file_storage.c
45@@ -225,9 +225,9 @@
46  * of the Gadget, USB Mass Storage, and SCSI protocols.
47  */
48 
49-
50-/* #define VERBOSE_DEBUG */
51-/* #define DUMP_MSGS */
52+#define DEBUG
53+#define VERBOSE_DEBUG
54+#define DUMP_MSGS
55 
56 
57 #include <linux/blkdev.h>
58@@ -3086,7 +3086,9 @@ static int received_cbw(struct fsg_dev *
59     if (req->actual != USB_BULK_CB_WRAP_LEN ||
60             cbw->Signature != cpu_to_le32(
61                 USB_BULK_CB_SIG)) {
62- DBG(fsg, "invalid CBW: len %u sig 0x%x\n",
63+ DBG(fsg, "invalid CBW: bh %.8x buf %.8x len %u sig 0x%x\n",
64+ (u32)bh,
65+ (u32)bh->buf,
66                 req->actual,
67                 le32_to_cpu(cbw->Signature));
68 
69@@ -4097,6 +4099,7 @@ static int __init fsg_bind(struct usb_ga
70          * the buffer will also work with the bulk-out (and
71          * interrupt-in) endpoint. */
72         bh->buf = kmalloc(mod_data.buflen, GFP_KERNEL);
73+ VDBG(fsg,"%s: %d, bh=%.8x, buf=%.8x\n",__func__,i,bh,bh->buf);
74         if (!bh->buf)
75             goto out;
76         bh->next = bh + 1;
77--- a/drivers/usb/gadget/Kconfig
78+++ b/drivers/usb/gadget/Kconfig
79@@ -495,6 +495,16 @@ config USB_LANGWELL
80     default USB_GADGET
81     select USB_GADGET_SELECTED
82 
83+config USB_GADGET_CNS3XXX_OTG
84+ boolean "CNS3XXX peripheral controller"
85+ depends on USB_CNS3XXX_OTG_BOTH || USB_CNS3XXX_OTG_PCD_ONLY
86+# select USB_OTG
87+ select USB_GADGET_DUALSPEED
88+ select USB_GADGET_SELECTED
89+ select USB_GADGET_SNPS_DWC_OTG
90+ help
91+ Selects the CNS3XXX Perpheral Controller driver
92+
93 
94 #
95 # LAST -- dummy/emulated controller
96--- /dev/null
97+++ b/drivers/usb/host/ehci-cns3xxx.c
98@@ -0,0 +1,171 @@
99+
100+#include <linux/platform_device.h>
101+#include <mach/board.h>
102+#include <mach/pm.h>
103+
104+#define cns3xxx_ioremap ioremap
105+#define cns3xxx_iounmap(addr) iounmap
106+
107+static int cns3xxx_ehci_init(struct usb_hcd *hcd)
108+{
109+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
110+ int retval = 0;
111+
112+ printk("%s: !!WARNING!! to verify the following ehci->caps ehci->regs \n",
113+ __FUNCTION__);
114+#ifdef CONFIG_SILICON
115+ //OTG PHY
116+ //cns3xxx_pwr_power_up(1<<PM_PLL_HM_PD_CTRL_REG_OFFSET_USB_PHY0);
117+ //USB PHY
118+ //cns3xxx_pwr_power_up(1<<PM_PLL_HM_PD_CTRL_REG_OFFSET_USB_PHY1);
119+ cns3xxx_pwr_power_up(1<<PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB);
120+ cns3xxx_pwr_clk_en(1<<PM_CLK_GATE_REG_OFFSET_USB_HOST);
121+ cns3xxx_pwr_soft_rst(1<<PM_SOFT_RST_REG_OFFST_USB_HOST);
122+ //cns3xxx_pwr_clk_en(1<<PM_CLK_GATE_REG_OFFSET_USB_OTG);
123+ //cns3xxx_pwr_soft_rst(1<<PM_SOFT_RST_REG_OFFST_USB_OTG);
124+#endif //CONFIG_SILICON
125+
126+ ehci->caps = hcd->regs;
127+ ehci->regs = hcd->regs
128+ + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
129+ ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
130+
131+ hcd->has_tt = 0;
132+ ehci_reset(ehci);
133+
134+ retval = ehci_init(hcd);
135+ if (retval)
136+ return retval;
137+
138+ /* XXX: Only for FPGA, remove it later */
139+ ehci_writel(ehci, 0x00800080, hcd->regs + 0x94);
140+
141+ ehci_port_power(ehci, 0);
142+
143+ return retval;
144+}
145+
146+static const struct hc_driver cns3xxx_ehci_hc_driver = {
147+ .description = hcd_name,
148+ .product_desc = "CNS3XXX EHCI Host Controller",
149+ .hcd_priv_size = sizeof(struct ehci_hcd),
150+ .irq = ehci_irq,
151+ .flags = HCD_MEMORY | HCD_USB2,
152+ .reset = cns3xxx_ehci_init,
153+ .start = ehci_run,
154+ .stop = ehci_stop,
155+ .shutdown = ehci_shutdown,
156+ .urb_enqueue = ehci_urb_enqueue,
157+ .urb_dequeue = ehci_urb_dequeue,
158+ .endpoint_disable = ehci_endpoint_disable,
159+ .get_frame_number = ehci_get_frame,
160+ .hub_status_data = ehci_hub_status_data,
161+ .hub_control = ehci_hub_control,
162+#if defined(CONFIG_PM)
163+ .bus_suspend = ehci_bus_suspend,
164+ .bus_resume = ehci_bus_resume,
165+#endif
166+ .relinquish_port = ehci_relinquish_port,
167+ .port_handed_over = ehci_port_handed_over,
168+};
169+
170+static int cns3xxx_ehci_probe(struct platform_device *pdev)
171+{
172+ struct usb_hcd *hcd;
173+ const struct hc_driver *driver = &cns3xxx_ehci_hc_driver;
174+ struct resource *res;
175+ int irq;
176+ int retval;
177+
178+ if (usb_disabled())
179+ return -ENODEV;
180+
181+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
182+ if (!res) {
183+ dev_err(&pdev->dev,
184+ "Found HC with no IRQ. Check %s setup!\n",
185+ dev_name(&pdev->dev));
186+ return -ENODEV;
187+ }
188+ irq = res->start;
189+
190+ hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
191+ if (!hcd) {
192+ retval = -ENOMEM;
193+ goto fail_create_hcd;
194+ }
195+
196+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
197+ if (!res) {
198+ dev_err(&pdev->dev,
199+ "Found HC with no register addr. Check %s setup!\n",
200+ dev_name(&pdev->dev));
201+ retval = -ENODEV;
202+ goto fail_request_resource;
203+ }
204+ hcd->rsrc_start = res->start;
205+ hcd->rsrc_len = res->end - res->start + 1;
206+
207+#ifdef CNS3XXX_USB_BASE_VIRT
208+ hcd->regs = (void __iomem *) CNS3XXX_USB_BASE_VIRT;
209+#else
210+ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
211+ driver->description)) {
212+ dev_dbg(&pdev->dev, "controller already in use\n");
213+ retval = -EBUSY;
214+ goto fail_request_resource;
215+ }
216+
217+ hcd->regs = cns3xxx_ioremap(hcd->rsrc_start, hcd->rsrc_len);
218+
219+ if (hcd->regs == NULL) {
220+ dev_dbg(&pdev->dev, "error mapping memory\n");
221+ retval = -EFAULT;
222+ goto fail_ioremap;
223+ }
224+#endif
225+
226+ retval = usb_add_hcd(hcd, irq, IRQF_SHARED); /* TODO: IRQF_DISABLED if any interrupt issues */
227+ if (retval)
228+ goto fail_add_hcd;
229+
230+ return retval;
231+
232+#ifndef CNS3XXX_USB_BASE_VIRT
233+fail_add_hcd:
234+ cns3xxx_iounmap(hcd->regs);
235+fail_ioremap:
236+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
237+#else
238+fail_request_resource:
239+fail_add_hcd:
240+#endif
241+ usb_put_hcd(hcd);
242+fail_create_hcd:
243+ dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), retval);
244+ return retval;
245+}
246+
247+static int cns3xxx_ehci_remove(struct platform_device *pdev)
248+{
249+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
250+
251+ usb_remove_hcd(hcd);
252+#ifndef CNS3XXX_USB_BASE_VIRT
253+ cns3xxx_iounmap(hcd->regs);
254+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
255+#endif
256+ usb_put_hcd(hcd);
257+
258+ return 0;
259+}
260+
261+MODULE_ALIAS("platform:cns3xxx-ehci");
262+
263+static struct platform_driver cns3xxx_ehci_driver = {
264+ .probe = cns3xxx_ehci_probe,
265+ .remove = cns3xxx_ehci_remove,
266+ .driver = {
267+ .name = "cns3xxx-ehci",
268+ },
269+};
270--- a/drivers/usb/host/ehci.h
271+++ b/drivers/usb/host/ehci.h
272@@ -602,6 +602,13 @@ ehci_port_speed(struct ehci_hcd *ehci, u
273 #define writel_be(val, addr) __raw_writel(val, (__force unsigned *)addr)
274 #endif
275 
276+#if defined(CONFIG_ARM) && defined(CONFIG_ARCH_CNS3XXX)
277+#undef readl
278+#undef writel
279+#define readl(addr) __raw_readl((__force unsigned *)addr)
280+#define writel(val, addr) __raw_writel(val, (__force unsigned *)addr)
281+#endif
282+
283 static inline unsigned int ehci_readl(const struct ehci_hcd *ehci,
284         __u32 __iomem * regs)
285 {
286--- a/drivers/usb/host/ehci-hcd.c
287+++ b/drivers/usb/host/ehci-hcd.c
288@@ -1120,6 +1120,11 @@ MODULE_LICENSE ("GPL");
289 #define PLATFORM_DRIVER ixp4xx_ehci_driver
290 #endif
291 
292+#ifdef CONFIG_USB_CNS3XXX_EHCI
293+#include "ehci-cns3xxx.c"
294+#define PLATFORM_DRIVER cns3xxx_ehci_driver
295+#endif
296+
297 #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
298     !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER)
299 #error "missing bus glue for ehci-hcd"
300--- a/drivers/usb/host/Kconfig
301+++ b/drivers/usb/host/Kconfig
302@@ -153,6 +153,45 @@ config USB_ISP1760_HCD
303       To compile this driver as a module, choose M here: the
304       module will be called isp1760.
305 
306+config USB_CNS3XXX_EHCI
307+ bool "Cavium CNS3XXX EHCI Module"
308+ depends on USB && USB_EHCI_HCD
309+ ---help---
310+ Cavium CNS3XXX USB EHCI Chipset support
311+
312+config USB_CNS3XXX_OTG
313+ tristate "Cavium CNS3XXX OTG Module"
314+ depends on USB
315+ ---help---
316+ Cavium CNS3XXX USB OTG Chipset support
317+
318+choice
319+ prompt "OTG function includes"
320+ depends on USB_CNS3XXX_OTG
321+ default USB_CNS3XXX_OTG_BOTH
322+
323+config USB_CNS3XXX_OTG_BOTH
324+ bool "both HCD and PCD"
325+
326+config USB_CNS3XXX_OTG_HCD_ONLY
327+ bool "HCD only"
328+
329+config USB_CNS3XXX_OTG_PCD_ONLY
330+ bool "PCD only"
331+
332+endchoice
333+config USB_CNS3XXX_OTG_ENABLE_OTG_DRVVBUS
334+ bool "Enable OTG_DRVVBUS"
335+ depends on USB_CNS3XXX_OTG
336+ default y
337+ ---help---
338+ The Power control IC (FB6862B), which is located around the OTG mini
339+ USB type A/B receptacle, in some early EVB board v1.0/v1.1(#1~#22) is
340+ incorrect(FB6862A), and need to be patched so that VBUS can be applied
341+ properly. In that case, we don't use the OTG_DRVVBUS to control the VBUS.
342+
343+ Check the board that you are using, if the IC is FB6862B, say Y. Otherwise, say N.
344+
345 config USB_OHCI_HCD
346     tristate "OHCI HCD support"
347     depends on USB && USB_ARCH_HAS_OHCI
348@@ -225,6 +264,12 @@ config USB_OHCI_HCD_SSB
349 
350       If unsure, say N.
351 
352+config USB_CNS3XXX_OHCI
353+ bool "Cavium CNS3XXX OHCI Module"
354+ depends on USB_OHCI_HCD
355+ ---help---
356+ Cavium CNS3XXX USB OHCI Chipset support
357+
358 config USB_OHCI_BIG_ENDIAN_DESC
359     bool
360     depends on USB_OHCI_HCD
361--- a/drivers/usb/host/Makefile
362+++ b/drivers/usb/host/Makefile
363@@ -31,3 +31,6 @@ obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o
364 obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o
365 obj-$(CONFIG_USB_ISP1760_HCD) += isp1760.o
366 obj-$(CONFIG_USB_HWA_HCD) += hwa-hc.o
367+obj-$(CONFIG_USB_CNS3XXX_OTG) += otg/
368+obj-$(CONFIG_USB_GADGET_CNS3XXX_OTG) += otg/
369+
370--- /dev/null
371+++ b/drivers/usb/host/ohci-cns3xxx.c
372@@ -0,0 +1,143 @@
373+
374+#include <linux/platform_device.h>
375+#include <mach/board.h>
376+
377+#define cns3xxx_ioremap ioremap
378+#define cns3xxx_iounmap(addr) iounmap
379+
380+static int __devinit
381+cns3xxx_ohci_start (struct usb_hcd *hcd)
382+{
383+ struct ohci_hcd *ohci = hcd_to_ohci (hcd);
384+ int ret;
385+
386+ if ((ret = ohci_init(ohci)) < 0)
387+ return ret;
388+
389+ ohci->num_ports = 1;
390+
391+ if ((ret = ohci_run(ohci)) < 0) {
392+ err("can't start %s", hcd->self.bus_name);
393+ ohci_stop(hcd);
394+ return ret;
395+ }
396+ return 0;
397+}
398+
399+static const struct hc_driver cns3xxx_ohci_hc_driver = {
400+ .description = hcd_name,
401+ .product_desc = "CNS3XXX OHCI Host controller",
402+ .hcd_priv_size = sizeof(struct ohci_hcd),
403+ .irq = ohci_irq,
404+ .flags = HCD_USB11 | HCD_MEMORY,
405+ .start = cns3xxx_ohci_start,
406+ .stop = ohci_stop,
407+ .shutdown = ohci_shutdown,
408+ .urb_enqueue = ohci_urb_enqueue,
409+ .urb_dequeue = ohci_urb_dequeue,
410+ .endpoint_disable = ohci_endpoint_disable,
411+ .get_frame_number = ohci_get_frame,
412+ .hub_status_data = ohci_hub_status_data,
413+ .hub_control = ohci_hub_control,
414+#ifdef CONFIG_PM
415+ .bus_suspend = ohci_bus_suspend,
416+ .bus_resume = ohci_bus_resume,
417+#endif
418+ .start_port_reset = ohci_start_port_reset,
419+};
420+
421+static int cns3xxx_ohci_probe(struct platform_device *pdev)
422+{
423+ struct usb_hcd *hcd = NULL;
424+ const struct hc_driver *driver = &cns3xxx_ohci_hc_driver;
425+ struct resource *res;
426+ int irq;
427+ int retval;
428+
429+ if (usb_disabled())
430+ return -ENODEV;
431+
432+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
433+ if (!res) {
434+ dev_err(&pdev->dev,
435+ "Found HC with no IRQ. Check %s setup!\n",
436+ dev_name(&pdev->dev));
437+ return -ENODEV;
438+ }
439+ irq = res->start;
440+
441+ hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
442+ if (!hcd)
443+ return -ENOMEM;
444+
445+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
446+ if (!res) {
447+ dev_err(&pdev->dev,
448+ "Found HC with no register addr. Check %s setup!\n",
449+ dev_name(&pdev->dev));
450+ retval = -ENODEV;
451+ goto err1;
452+ }
453+ hcd->rsrc_start = res->start;
454+ hcd->rsrc_len = res->end - res->start + 1;
455+
456+#ifdef CNS3XXX_USB_OHCI_BASE_VIRT
457+ hcd->regs = (void __iomem *) CNS3XXX_USB_OHCI_BASE_VIRT;
458+#else
459+ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
460+ driver->description)) {
461+ dev_dbg(&pdev->dev, "controller already in use\n");
462+ retval = -EBUSY;
463+ goto err1;
464+ }
465+
466+ hcd->regs = cns3xxx_ioremap(hcd->rsrc_start, hcd->rsrc_len);
467+
468+ if (hcd->regs == NULL) {
469+ dev_dbg(&pdev->dev, "error mapping memory\n");
470+ retval = -EFAULT;
471+ goto err2;
472+ }
473+#endif
474+
475+ ohci_hcd_init(hcd_to_ohci(hcd));
476+
477+ retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
478+ if (retval == 0)
479+ return retval;
480+
481+#ifndef CNS3XXX_USB_OHCI_BASE_VIRT
482+ cns3xxx_iounmap(hcd->regs);
483+
484+err2:
485+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
486+#endif
487+
488+err1:
489+ usb_put_hcd(hcd);
490+ return retval;
491+}
492+
493+static int cns3xxx_ohci_remove(struct platform_device *pdev)
494+{
495+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
496+
497+ usb_remove_hcd(hcd);
498+#ifndef CNS3XXX_USB_OHCI_BASE_VIRT
499+ cns3xxx_iounmap(hcd->regs);
500+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
501+#endif
502+ usb_put_hcd(hcd);
503+
504+ return 0;
505+}
506+
507+MODULE_ALIAS("platform:cns3xxx-ohci");
508+
509+static struct platform_driver ohci_hcd_cns3xxx_driver = {
510+ .probe = cns3xxx_ohci_probe,
511+ .remove = cns3xxx_ohci_remove,
512+ .driver = {
513+ .name = "cns3xxx-ohci",
514+ },
515+};
516--- a/drivers/usb/host/ohci.h
517+++ b/drivers/usb/host/ohci.h
518@@ -550,6 +550,14 @@ static inline struct usb_hcd *ohci_to_hc
519  * Other arches can be added if/when they're needed.
520  *
521  */
522+
523+#if defined(CONFIG_ARM) && defined(CONFIG_ARCH_CNS3XXX)
524+#undef readl
525+#undef writel
526+#define readl(addr) __raw_readl((__force unsigned *)addr)
527+#define writel(val, addr) __raw_writel(val, (__force unsigned *)addr)
528+#endif
529+
530 static inline unsigned int _ohci_readl (const struct ohci_hcd *ohci,
531                     __hc32 __iomem * regs)
532 {
533--- a/drivers/usb/host/ohci-hcd.c
534+++ b/drivers/usb/host/ohci-hcd.c
535@@ -1047,6 +1047,11 @@ MODULE_LICENSE ("GPL");
536 #define PLATFORM_DRIVER ohci_hcd_at91_driver
537 #endif
538 
539+#ifdef CONFIG_USB_CNS3XXX_OHCI
540+#include "ohci-cns3xxx.c"
541+#define PLATFORM_DRIVER ohci_hcd_cns3xxx_driver
542+#endif
543+
544 #ifdef CONFIG_ARCH_PNX4008
545 #include "ohci-pnx4008.c"
546 #define PLATFORM_DRIVER usb_hcd_pnx4008_driver
547--- /dev/null
548+++ b/drivers/usb/host/otg/dummy_audio.c
549@@ -0,0 +1,1575 @@
550+/*
551+ * zero.c -- Gadget Zero, for USB development
552+ *
553+ * Copyright (C) 2003-2004 David Brownell
554+ * All rights reserved.
555+ *
556+ * Redistribution and use in source and binary forms, with or without
557+ * modification, are permitted provided that the following conditions
558+ * are met:
559+ * 1. Redistributions of source code must retain the above copyright
560+ * notice, this list of conditions, and the following disclaimer,
561+ * without modification.
562+ * 2. Redistributions in binary form must reproduce the above copyright
563+ * notice, this list of conditions and the following disclaimer in the
564+ * documentation and/or other materials provided with the distribution.
565+ * 3. The names of the above-listed copyright holders may not be used
566+ * to endorse or promote products derived from this software without
567+ * specific prior written permission.
568+ *
569+ * ALTERNATIVELY, this software may be distributed under the terms of the
570+ * GNU General Public License ("GPL") as published by the Free Software
571+ * Foundation, either version 2 of that License or (at your option) any
572+ * later version.
573+ *
574+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
575+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
576+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
577+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
578+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
579+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
580+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
581+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
582+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
583+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
584+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
585+ */
586+
587+
588+/*
589+ * Gadget Zero only needs two bulk endpoints, and is an example of how you
590+ * can write a hardware-agnostic gadget driver running inside a USB device.
591+ *
592+ * Hardware details are visible (see CONFIG_USB_ZERO_* below) but don't
593+ * affect most of the driver.
594+ *
595+ * Use it with the Linux host/master side "usbtest" driver to get a basic
596+ * functional test of your device-side usb stack, or with "usb-skeleton".
597+ *
598+ * It supports two similar configurations. One sinks whatever the usb host
599+ * writes, and in return sources zeroes. The other loops whatever the host
600+ * writes back, so the host can read it. Module options include:
601+ *
602+ * buflen=N default N=4096, buffer size used
603+ * qlen=N default N=32, how many buffers in the loopback queue
604+ * loopdefault default false, list loopback config first
605+ *
606+ * Many drivers will only have one configuration, letting them be much
607+ * simpler if they also don't support high speed operation (like this
608+ * driver does).
609+ */
610+
611+#include <linux/config.h>
612+#include <linux/module.h>
613+#include <linux/kernel.h>
614+#include <linux/delay.h>
615+#include <linux/ioport.h>
616+#include <linux/sched.h>
617+#include <linux/slab.h>
618+#include <linux/smp_lock.h>
619+#include <linux/errno.h>
620+#include <linux/init.h>
621+#include <linux/timer.h>
622+#include <linux/list.h>
623+#include <linux/interrupt.h>
624+#include <linux/uts.h>
625+#include <linux/version.h>
626+#include <linux/device.h>
627+#include <linux/moduleparam.h>
628+#include <linux/proc_fs.h>
629+
630+#include <asm/byteorder.h>
631+#include <asm/io.h>
632+#include <asm/irq.h>
633+#include <asm/system.h>
634+#include <asm/unaligned.h>
635+
636+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
637+# include <linux/usb/ch9.h>
638+#else
639+# include <linux/usb_ch9.h>
640+#endif
641+
642+#include <linux/usb_gadget.h>
643+
644+
645+/*-------------------------------------------------------------------------*/
646+/*-------------------------------------------------------------------------*/
647+
648+
649+static int utf8_to_utf16le(const char *s, u16 *cp, unsigned len)
650+{
651+ int count = 0;
652+ u8 c;
653+ u16 uchar;
654+
655+ /* this insists on correct encodings, though not minimal ones.
656+ * BUT it currently rejects legit 4-byte UTF-8 code points,
657+ * which need surrogate pairs. (Unicode 3.1 can use them.)
658+ */
659+ while (len != 0 && (c = (u8) *s++) != 0) {
660+ if (unlikely(c & 0x80)) {
661+ // 2-byte sequence:
662+ // 00000yyyyyxxxxxx = 110yyyyy 10xxxxxx
663+ if ((c & 0xe0) == 0xc0) {
664+ uchar = (c & 0x1f) << 6;
665+
666+ c = (u8) *s++;
667+ if ((c & 0xc0) != 0xc0)
668+ goto fail;
669+ c &= 0x3f;
670+ uchar |= c;
671+
672+ // 3-byte sequence (most CJKV characters):
673+ // zzzzyyyyyyxxxxxx = 1110zzzz 10yyyyyy 10xxxxxx
674+ } else if ((c & 0xf0) == 0xe0) {
675+ uchar = (c & 0x0f) << 12;
676+
677+ c = (u8) *s++;
678+ if ((c & 0xc0) != 0xc0)
679+ goto fail;
680+ c &= 0x3f;
681+ uchar |= c << 6;
682+
683+ c = (u8) *s++;
684+ if ((c & 0xc0) != 0xc0)
685+ goto fail;
686+ c &= 0x3f;
687+ uchar |= c;
688+
689+ /* no bogus surrogates */
690+ if (0xd800 <= uchar && uchar <= 0xdfff)
691+ goto fail;
692+
693+ // 4-byte sequence (surrogate pairs, currently rare):
694+ // 11101110wwwwzzzzyy + 110111yyyyxxxxxx
695+ // = 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx
696+ // (uuuuu = wwww + 1)
697+ // FIXME accept the surrogate code points (only)
698+
699+ } else
700+ goto fail;
701+ } else
702+ uchar = c;
703+ put_unaligned (cpu_to_le16 (uchar), cp++);
704+ count++;
705+ len--;
706+ }
707+ return count;
708+fail:
709+ return -1;
710+}
711+
712+
713+/**
714+ * usb_gadget_get_string - fill out a string descriptor
715+ * @table: of c strings encoded using UTF-8
716+ * @id: string id, from low byte of wValue in get string descriptor
717+ * @buf: at least 256 bytes
718+ *
719+ * Finds the UTF-8 string matching the ID, and converts it into a
720+ * string descriptor in utf16-le.
721+ * Returns length of descriptor (always even) or negative errno
722+ *
723+ * If your driver needs stings in multiple languages, you'll probably
724+ * "switch (wIndex) { ... }" in your ep0 string descriptor logic,
725+ * using this routine after choosing which set of UTF-8 strings to use.
726+ * Note that US-ASCII is a strict subset of UTF-8; any string bytes with
727+ * the eighth bit set will be multibyte UTF-8 characters, not ISO-8859/1
728+ * characters (which are also widely used in C strings).
729+ */
730+int
731+usb_gadget_get_string (struct usb_gadget_strings *table, int id, u8 *buf)
732+{
733+ struct usb_string *s;
734+ int len;
735+
736+ /* descriptor 0 has the language id */
737+ if (id == 0) {
738+ buf [0] = 4;
739+ buf [1] = USB_DT_STRING;
740+ buf [2] = (u8) table->language;
741+ buf [3] = (u8) (table->language >> 8);
742+ return 4;
743+ }
744+ for (s = table->strings; s && s->s; s++)
745+ if (s->id == id)
746+ break;
747+
748+ /* unrecognized: stall. */
749+ if (!s || !s->s)
750+ return -EINVAL;
751+
752+ /* string descriptors have length, tag, then UTF16-LE text */
753+ len = min ((size_t) 126, strlen (s->s));
754+ memset (buf + 2, 0, 2 * len); /* zero all the bytes */
755+ len = utf8_to_utf16le(s->s, (u16 *)&buf[2], len);
756+ if (len < 0)
757+ return -EINVAL;
758+ buf [0] = (len + 1) * 2;
759+ buf [1] = USB_DT_STRING;
760+ return buf [0];
761+}
762+
763+
764+/*-------------------------------------------------------------------------*/
765+/*-------------------------------------------------------------------------*/
766+
767+
768+/**
769+ * usb_descriptor_fillbuf - fill buffer with descriptors
770+ * @buf: Buffer to be filled
771+ * @buflen: Size of buf
772+ * @src: Array of descriptor pointers, terminated by null pointer.
773+ *
774+ * Copies descriptors into the buffer, returning the length or a
775+ * negative error code if they can't all be copied. Useful when
776+ * assembling descriptors for an associated set of interfaces used
777+ * as part of configuring a composite device; or in other cases where
778+ * sets of descriptors need to be marshaled.
779+ */
780+int
781+usb_descriptor_fillbuf(void *buf, unsigned buflen,
782+ const struct usb_descriptor_header **src)
783+{
784+ u8 *dest = buf;
785+
786+ if (!src)
787+ return -EINVAL;
788+
789+ /* fill buffer from src[] until null descriptor ptr */
790+ for (; 0 != *src; src++) {
791+ unsigned len = (*src)->bLength;
792+
793+ if (len > buflen)
794+ return -EINVAL;
795+ memcpy(dest, *src, len);
796+ buflen -= len;
797+ dest += len;
798+ }
799+ return dest - (u8 *)buf;
800+}
801+
802+
803+/**
804+ * usb_gadget_config_buf - builts a complete configuration descriptor
805+ * @config: Header for the descriptor, including characteristics such
806+ * as power requirements and number of interfaces.
807+ * @desc: Null-terminated vector of pointers to the descriptors (interface,
808+ * endpoint, etc) defining all functions in this device configuration.
809+ * @buf: Buffer for the resulting configuration descriptor.
810+ * @length: Length of buffer. If this is not big enough to hold the
811+ * entire configuration descriptor, an error code will be returned.
812+ *
813+ * This copies descriptors into the response buffer, building a descriptor
814+ * for that configuration. It returns the buffer length or a negative
815+ * status code. The config.wTotalLength field is set to match the length
816+ * of the result, but other descriptor fields (including power usage and
817+ * interface count) must be set by the caller.
818+ *
819+ * Gadget drivers could use this when constructing a config descriptor
820+ * in response to USB_REQ_GET_DESCRIPTOR. They will need to patch the
821+ * resulting bDescriptorType value if USB_DT_OTHER_SPEED_CONFIG is needed.
822+ */
823+int usb_gadget_config_buf(
824+ const struct usb_config_descriptor *config,
825+ void *buf,
826+ unsigned length,
827+ const struct usb_descriptor_header **desc
828+)
829+{
830+ struct usb_config_descriptor *cp = buf;
831+ int len;
832+
833+ /* config descriptor first */
834+ if (length < USB_DT_CONFIG_SIZE || !desc)
835+ return -EINVAL;
836+ *cp = *config;
837+
838+ /* then interface/endpoint/class/vendor/... */
839+ len = usb_descriptor_fillbuf(USB_DT_CONFIG_SIZE + (u8*)buf,
840+ length - USB_DT_CONFIG_SIZE, desc);
841+ if (len < 0)
842+ return len;
843+ len += USB_DT_CONFIG_SIZE;
844+ if (len > 0xffff)
845+ return -EINVAL;
846+
847+ /* patch up the config descriptor */
848+ cp->bLength = USB_DT_CONFIG_SIZE;
849+ cp->bDescriptorType = USB_DT_CONFIG;
850+ cp->wTotalLength = cpu_to_le16(len);
851+ cp->bmAttributes |= USB_CONFIG_ATT_ONE;
852+ return len;
853+}
854+
855+/*-------------------------------------------------------------------------*/
856+/*-------------------------------------------------------------------------*/
857+
858+
859+#define RBUF_LEN (1024*1024)
860+static int rbuf_start;
861+static int rbuf_len;
862+static __u8 rbuf[RBUF_LEN];
863+
864+/*-------------------------------------------------------------------------*/
865+
866+#define DRIVER_VERSION "St Patrick's Day 2004"
867+
868+static const char shortname [] = "zero";
869+static const char longname [] = "YAMAHA YST-MS35D USB Speaker ";
870+
871+static const char source_sink [] = "source and sink data";
872+static const char loopback [] = "loop input to output";
873+
874+/*-------------------------------------------------------------------------*/
875+
876+/*
877+ * driver assumes self-powered hardware, and
878+ * has no way for users to trigger remote wakeup.
879+ *
880+ * this version autoconfigures as much as possible,
881+ * which is reasonable for most "bulk-only" drivers.
882+ */
883+static const char *EP_IN_NAME; /* source */
884+static const char *EP_OUT_NAME; /* sink */
885+
886+/*-------------------------------------------------------------------------*/
887+
888+/* big enough to hold our biggest descriptor */
889+#define USB_BUFSIZ 512
890+
891+struct zero_dev {
892+ spinlock_t lock;
893+ struct usb_gadget *gadget;
894+ struct usb_request *req; /* for control responses */
895+
896+ /* when configured, we have one of two configs:
897+ * - source data (in to host) and sink it (out from host)
898+ * - or loop it back (out from host back in to host)
899+ */
900+ u8 config;
901+ struct usb_ep *in_ep, *out_ep;
902+
903+ /* autoresume timer */
904+ struct timer_list resume;
905+};
906+
907+#define xprintk(d,level,fmt,args...) \
908+ dev_printk(level , &(d)->gadget->dev , fmt , ## args)
909+
910+#ifdef DEBUG
911+#define DBG(dev,fmt,args...) \
912+ xprintk(dev , KERN_DEBUG , fmt , ## args)
913+#else
914+#define DBG(dev,fmt,args...) \
915+ do { } while (0)
916+#endif /* DEBUG */
917+
918+#ifdef VERBOSE
919+#define VDBG DBG
920+#else
921+#define VDBG(dev,fmt,args...) \
922+ do { } while (0)
923+#endif /* VERBOSE */
924+
925+#define ERROR(dev,fmt,args...) \
926+ xprintk(dev , KERN_ERR , fmt , ## args)
927+#define WARN(dev,fmt,args...) \
928+ xprintk(dev , KERN_WARNING , fmt , ## args)
929+#define INFO(dev,fmt,args...) \
930+ xprintk(dev , KERN_INFO , fmt , ## args)
931+
932+/*-------------------------------------------------------------------------*/
933+
934+static unsigned buflen = 4096;
935+static unsigned qlen = 32;
936+static unsigned pattern = 0;
937+
938+module_param (buflen, uint, S_IRUGO|S_IWUSR);
939+module_param (qlen, uint, S_IRUGO|S_IWUSR);
940+module_param (pattern, uint, S_IRUGO|S_IWUSR);
941+
942+/*
943+ * if it's nonzero, autoresume says how many seconds to wait
944+ * before trying to wake up the host after suspend.
945+ */
946+static unsigned autoresume = 0;
947+module_param (autoresume, uint, 0);
948+
949+/*
950+ * Normally the "loopback" configuration is second (index 1) so
951+ * it's not the default. Here's where to change that order, to
952+ * work better with hosts where config changes are problematic.
953+ * Or controllers (like superh) that only support one config.
954+ */
955+static int loopdefault = 0;
956+
957+module_param (loopdefault, bool, S_IRUGO|S_IWUSR);
958+
959+/*-------------------------------------------------------------------------*/
960+
961+/* Thanks to NetChip Technologies for donating this product ID.
962+ *
963+ * DO NOT REUSE THESE IDs with a protocol-incompatible driver!! Ever!!
964+ * Instead: allocate your own, using normal USB-IF procedures.
965+ */
966+#ifndef CONFIG_USB_ZERO_HNPTEST
967+#define DRIVER_VENDOR_NUM 0x0525 /* NetChip */
968+#define DRIVER_PRODUCT_NUM 0xa4a0 /* Linux-USB "Gadget Zero" */
969+#else
970+#define DRIVER_VENDOR_NUM 0x1a0a /* OTG test device IDs */
971+#define DRIVER_PRODUCT_NUM 0xbadd
972+#endif
973+
974+/*-------------------------------------------------------------------------*/
975+
976+/*
977+ * DESCRIPTORS ... most are static, but strings and (full)
978+ * configuration descriptors are built on demand.
979+ */
980+
981+/*
982+#define STRING_MANUFACTURER 25
983+#define STRING_PRODUCT 42
984+#define STRING_SERIAL 101
985+*/
986+#define STRING_MANUFACTURER 1
987+#define STRING_PRODUCT 2
988+#define STRING_SERIAL 3
989+
990+#define STRING_SOURCE_SINK 250
991+#define STRING_LOOPBACK 251
992+
993+/*
994+ * This device advertises two configurations; these numbers work
995+ * on a pxa250 as well as more flexible hardware.
996+ */
997+#define CONFIG_SOURCE_SINK 3
998+#define CONFIG_LOOPBACK 2
999+
1000+/*
1001+static struct usb_device_descriptor
1002+device_desc = {
1003+ .bLength = sizeof device_desc,
1004+ .bDescriptorType = USB_DT_DEVICE,
1005+
1006+ .bcdUSB = __constant_cpu_to_le16 (0x0200),
1007+ .bDeviceClass = USB_CLASS_VENDOR_SPEC,
1008+
1009+ .idVendor = __constant_cpu_to_le16 (DRIVER_VENDOR_NUM),
1010+ .idProduct = __constant_cpu_to_le16 (DRIVER_PRODUCT_NUM),
1011+ .iManufacturer = STRING_MANUFACTURER,
1012+ .iProduct = STRING_PRODUCT,
1013+ .iSerialNumber = STRING_SERIAL,
1014+ .bNumConfigurations = 2,
1015+};
1016+*/
1017+static struct usb_device_descriptor
1018+device_desc = {
1019+ .bLength = sizeof device_desc,
1020+ .bDescriptorType = USB_DT_DEVICE,
1021+ .bcdUSB = __constant_cpu_to_le16 (0x0100),
1022+ .bDeviceClass = USB_CLASS_PER_INTERFACE,
1023+ .bDeviceSubClass = 0,
1024+ .bDeviceProtocol = 0,
1025+ .bMaxPacketSize0 = 64,
1026+ .bcdDevice = __constant_cpu_to_le16 (0x0100),
1027+ .idVendor = __constant_cpu_to_le16 (0x0499),
1028+ .idProduct = __constant_cpu_to_le16 (0x3002),
1029+ .iManufacturer = STRING_MANUFACTURER,
1030+ .iProduct = STRING_PRODUCT,
1031+ .iSerialNumber = STRING_SERIAL,
1032+ .bNumConfigurations = 1,
1033+};
1034+
1035+static struct usb_config_descriptor
1036+z_config = {
1037+ .bLength = sizeof z_config,
1038+ .bDescriptorType = USB_DT_CONFIG,
1039+
1040+ /* compute wTotalLength on the fly */
1041+ .bNumInterfaces = 2,
1042+ .bConfigurationValue = 1,
1043+ .iConfiguration = 0,
1044+ .bmAttributes = 0x40,
1045+ .bMaxPower = 0, /* self-powered */
1046+};
1047+
1048+
1049+static struct usb_otg_descriptor
1050+otg_descriptor = {
1051+ .bLength = sizeof otg_descriptor,
1052+ .bDescriptorType = USB_DT_OTG,
1053+
1054+ .bmAttributes = USB_OTG_SRP,
1055+};
1056+
1057+/* one interface in each configuration */
1058+#ifdef CONFIG_USB_GADGET_DUALSPEED
1059+
1060+/*
1061+ * usb 2.0 devices need to expose both high speed and full speed
1062+ * descriptors, unless they only run at full speed.
1063+ *
1064+ * that means alternate endpoint descriptors (bigger packets)
1065+ * and a "device qualifier" ... plus more construction options
1066+ * for the config descriptor.
1067+ */
1068+
1069+static struct usb_qualifier_descriptor
1070+dev_qualifier = {
1071+ .bLength = sizeof dev_qualifier,
1072+ .bDescriptorType = USB_DT_DEVICE_QUALIFIER,
1073+
1074+ .bcdUSB = __constant_cpu_to_le16 (0x0200),
1075+ .bDeviceClass = USB_CLASS_VENDOR_SPEC,
1076+
1077+ .bNumConfigurations = 2,
1078+};
1079+
1080+
1081+struct usb_cs_as_general_descriptor {
1082+ __u8 bLength;
1083+ __u8 bDescriptorType;
1084+
1085+ __u8 bDescriptorSubType;
1086+ __u8 bTerminalLink;
1087+ __u8 bDelay;
1088+ __u16 wFormatTag;
1089+} __attribute__ ((packed));
1090+
1091+struct usb_cs_as_format_descriptor {
1092+ __u8 bLength;
1093+ __u8 bDescriptorType;
1094+
1095+ __u8 bDescriptorSubType;
1096+ __u8 bFormatType;
1097+ __u8 bNrChannels;
1098+ __u8 bSubframeSize;
1099+ __u8 bBitResolution;
1100+ __u8 bSamfreqType;
1101+ __u8 tLowerSamFreq[3];
1102+ __u8 tUpperSamFreq[3];
1103+} __attribute__ ((packed));
1104+
1105+static const struct usb_interface_descriptor
1106+z_audio_control_if_desc = {
1107+ .bLength = sizeof z_audio_control_if_desc,
1108+ .bDescriptorType = USB_DT_INTERFACE,
1109+ .bInterfaceNumber = 0,
1110+ .bAlternateSetting = 0,
1111+ .bNumEndpoints = 0,
1112+ .bInterfaceClass = USB_CLASS_AUDIO,
1113+ .bInterfaceSubClass = 0x1,
1114+ .bInterfaceProtocol = 0,
1115+ .iInterface = 0,
1116+};
1117+
1118+static const struct usb_interface_descriptor
1119+z_audio_if_desc = {
1120+ .bLength = sizeof z_audio_if_desc,
1121+ .bDescriptorType = USB_DT_INTERFACE,
1122+ .bInterfaceNumber = 1,
1123+ .bAlternateSetting = 0,
1124+ .bNumEndpoints = 0,
1125+ .bInterfaceClass = USB_CLASS_AUDIO,
1126+ .bInterfaceSubClass = 0x2,
1127+ .bInterfaceProtocol = 0,
1128+ .iInterface = 0,
1129+};
1130+
1131+static const struct usb_interface_descriptor
1132+z_audio_if_desc2 = {
1133+ .bLength = sizeof z_audio_if_desc,
1134+ .bDescriptorType = USB_DT_INTERFACE,
1135+ .bInterfaceNumber = 1,
1136+ .bAlternateSetting = 1,
1137+ .bNumEndpoints = 1,
1138+ .bInterfaceClass = USB_CLASS_AUDIO,
1139+ .bInterfaceSubClass = 0x2,
1140+ .bInterfaceProtocol = 0,
1141+ .iInterface = 0,
1142+};
1143+
1144+static const struct usb_cs_as_general_descriptor
1145+z_audio_cs_as_if_desc = {
1146+ .bLength = 7,
1147+ .bDescriptorType = 0x24,
1148+
1149+ .bDescriptorSubType = 0x01,
1150+ .bTerminalLink = 0x01,
1151+ .bDelay = 0x0,
1152+ .wFormatTag = __constant_cpu_to_le16 (0x0001)
1153+};
1154+
1155+
1156+static const struct usb_cs_as_format_descriptor
1157+z_audio_cs_as_format_desc = {
1158+ .bLength = 0xe,
1159+ .bDescriptorType = 0x24,
1160+
1161+ .bDescriptorSubType = 2,
1162+ .bFormatType = 1,
1163+ .bNrChannels = 1,
1164+ .bSubframeSize = 1,
1165+ .bBitResolution = 8,
1166+ .bSamfreqType = 0,
1167+ .tLowerSamFreq = {0x7e, 0x13, 0x00},
1168+ .tUpperSamFreq = {0xe2, 0xd6, 0x00},
1169+};
1170+
1171+static const struct usb_endpoint_descriptor
1172+z_iso_ep = {
1173+ .bLength = 0x09,
1174+ .bDescriptorType = 0x05,
1175+ .bEndpointAddress = 0x04,
1176+ .bmAttributes = 0x09,
1177+ .wMaxPacketSize = 0x0038,
1178+ .bInterval = 0x01,
1179+ .bRefresh = 0x00,
1180+ .bSynchAddress = 0x00,
1181+};
1182+
1183+static char z_iso_ep2[] = {0x07, 0x25, 0x01, 0x00, 0x02, 0x00, 0x02};
1184+
1185+// 9 bytes
1186+static char z_ac_interface_header_desc[] =
1187+{ 0x09, 0x24, 0x01, 0x00, 0x01, 0x2b, 0x00, 0x01, 0x01 };
1188+
1189+// 12 bytes
1190+static char z_0[] = {0x0c, 0x24, 0x02, 0x01, 0x01, 0x01, 0x00, 0x02,
1191+ 0x03, 0x00, 0x00, 0x00};
1192+// 13 bytes
1193+static char z_1[] = {0x0d, 0x24, 0x06, 0x02, 0x01, 0x02, 0x15, 0x00,
1194+ 0x02, 0x00, 0x02, 0x00, 0x00};
1195+// 9 bytes
1196+static char z_2[] = {0x09, 0x24, 0x03, 0x03, 0x01, 0x03, 0x00, 0x02,
1197+ 0x00};
1198+
1199+static char za_0[] = {0x09, 0x04, 0x01, 0x02, 0x01, 0x01, 0x02, 0x00,
1200+ 0x00};
1201+
1202+static char za_1[] = {0x07, 0x24, 0x01, 0x01, 0x00, 0x01, 0x00};
1203+
1204+static char za_2[] = {0x0e, 0x24, 0x02, 0x01, 0x02, 0x01, 0x08, 0x00,
1205+ 0x7e, 0x13, 0x00, 0xe2, 0xd6, 0x00};
1206+
1207+static char za_3[] = {0x09, 0x05, 0x04, 0x09, 0x70, 0x00, 0x01, 0x00,
1208+ 0x00};
1209+
1210+static char za_4[] = {0x07, 0x25, 0x01, 0x00, 0x02, 0x00, 0x02};
1211+
1212+static char za_5[] = {0x09, 0x04, 0x01, 0x03, 0x01, 0x01, 0x02, 0x00,
1213+ 0x00};
1214+
1215+static char za_6[] = {0x07, 0x24, 0x01, 0x01, 0x00, 0x01, 0x00};
1216+
1217+static char za_7[] = {0x0e, 0x24, 0x02, 0x01, 0x01, 0x02, 0x10, 0x00,
1218+ 0x7e, 0x13, 0x00, 0xe2, 0xd6, 0x00};
1219+
1220+static char za_8[] = {0x09, 0x05, 0x04, 0x09, 0x70, 0x00, 0x01, 0x00,
1221+ 0x00};
1222+
1223+static char za_9[] = {0x07, 0x25, 0x01, 0x00, 0x02, 0x00, 0x02};
1224+
1225+static char za_10[] = {0x09, 0x04, 0x01, 0x04, 0x01, 0x01, 0x02, 0x00,
1226+ 0x00};
1227+
1228+static char za_11[] = {0x07, 0x24, 0x01, 0x01, 0x00, 0x01, 0x00};
1229+
1230+static char za_12[] = {0x0e, 0x24, 0x02, 0x01, 0x02, 0x02, 0x10, 0x00,
1231+ 0x73, 0x13, 0x00, 0xe2, 0xd6, 0x00};
1232+
1233+static char za_13[] = {0x09, 0x05, 0x04, 0x09, 0xe0, 0x00, 0x01, 0x00,
1234+ 0x00};
1235+
1236+static char za_14[] = {0x07, 0x25, 0x01, 0x00, 0x02, 0x00, 0x02};
1237+
1238+static char za_15[] = {0x09, 0x04, 0x01, 0x05, 0x01, 0x01, 0x02, 0x00,
1239+ 0x00};
1240+
1241+static char za_16[] = {0x07, 0x24, 0x01, 0x01, 0x00, 0x01, 0x00};
1242+
1243+static char za_17[] = {0x0e, 0x24, 0x02, 0x01, 0x01, 0x03, 0x14, 0x00,
1244+ 0x7e, 0x13, 0x00, 0xe2, 0xd6, 0x00};
1245+
1246+static char za_18[] = {0x09, 0x05, 0x04, 0x09, 0xa8, 0x00, 0x01, 0x00,
1247+ 0x00};
1248+
1249+static char za_19[] = {0x07, 0x25, 0x01, 0x00, 0x02, 0x00, 0x02};
1250+
1251+static char za_20[] = {0x09, 0x04, 0x01, 0x06, 0x01, 0x01, 0x02, 0x00,
1252+ 0x00};
1253+
1254+static char za_21[] = {0x07, 0x24, 0x01, 0x01, 0x00, 0x01, 0x00};
1255+
1256+static char za_22[] = {0x0e, 0x24, 0x02, 0x01, 0x02, 0x03, 0x14, 0x00,
1257+ 0x7e, 0x13, 0x00, 0xe2, 0xd6, 0x00};
1258+
1259+static char za_23[] = {0x09, 0x05, 0x04, 0x09, 0x50, 0x01, 0x01, 0x00,
1260+ 0x00};
1261+
1262+static char za_24[] = {0x07, 0x25, 0x01, 0x00, 0x02, 0x00, 0x02};
1263+
1264+
1265+
1266+static const struct usb_descriptor_header *z_function [] = {
1267+ (struct usb_descriptor_header *) &z_audio_control_if_desc,
1268+ (struct usb_descriptor_header *) &z_ac_interface_header_desc,
1269+ (struct usb_descriptor_header *) &z_0,
1270+ (struct usb_descriptor_header *) &z_1,
1271+ (struct usb_descriptor_header *) &z_2,
1272+ (struct usb_descriptor_header *) &z_audio_if_desc,
1273+ (struct usb_descriptor_header *) &z_audio_if_desc2,
1274+ (struct usb_descriptor_header *) &z_audio_cs_as_if_desc,
1275+ (struct usb_descriptor_header *) &z_audio_cs_as_format_desc,
1276+ (struct usb_descriptor_header *) &z_iso_ep,
1277+ (struct usb_descriptor_header *) &z_iso_ep2,
1278+ (struct usb_descriptor_header *) &za_0,
1279+ (struct usb_descriptor_header *) &za_1,
1280+ (struct usb_descriptor_header *) &za_2,
1281+ (struct usb_descriptor_header *) &za_3,
1282+ (struct usb_descriptor_header *) &za_4,
1283+ (struct usb_descriptor_header *) &za_5,
1284+ (struct usb_descriptor_header *) &za_6,
1285+ (struct usb_descriptor_header *) &za_7,
1286+ (struct usb_descriptor_header *) &za_8,
1287+ (struct usb_descriptor_header *) &za_9,
1288+ (struct usb_descriptor_header *) &za_10,
1289+ (struct usb_descriptor_header *) &za_11,
1290+ (struct usb_descriptor_header *) &za_12,
1291+ (struct usb_descriptor_header *) &za_13,
1292+ (struct usb_descriptor_header *) &za_14,
1293+ (struct usb_descriptor_header *) &za_15,
1294+ (struct usb_descriptor_header *) &za_16,
1295+ (struct usb_descriptor_header *) &za_17,
1296+ (struct usb_descriptor_header *) &za_18,
1297+ (struct usb_descriptor_header *) &za_19,
1298+ (struct usb_descriptor_header *) &za_20,
1299+ (struct usb_descriptor_header *) &za_21,
1300+ (struct usb_descriptor_header *) &za_22,
1301+ (struct usb_descriptor_header *) &za_23,
1302+ (struct usb_descriptor_header *) &za_24,
1303+ NULL,
1304+};
1305+
1306+/* maxpacket and other transfer characteristics vary by speed. */
1307+#define ep_desc(g,hs,fs) (((g)->speed==USB_SPEED_HIGH)?(hs):(fs))
1308+
1309+#else
1310+
1311+/* if there's no high speed support, maxpacket doesn't change. */
1312+#define ep_desc(g,hs,fs) fs
1313+
1314+#endif /* !CONFIG_USB_GADGET_DUALSPEED */
1315+
1316+static char manufacturer [40];
1317+//static char serial [40];
1318+static char serial [] = "Ser 00 em";
1319+
1320+/* static strings, in UTF-8 */
1321+static struct usb_string strings [] = {
1322+ { STRING_MANUFACTURER, manufacturer, },
1323+ { STRING_PRODUCT, longname, },
1324+ { STRING_SERIAL, serial, },
1325+ { STRING_LOOPBACK, loopback, },
1326+ { STRING_SOURCE_SINK, source_sink, },
1327+ { } /* end of list */
1328+};
1329+
1330+static struct usb_gadget_strings stringtab = {
1331+ .language = 0x0409, /* en-us */
1332+ .strings = strings,
1333+};
1334+
1335+/*
1336+ * config descriptors are also handcrafted. these must agree with code
1337+ * that sets configurations, and with code managing interfaces and their
1338+ * altsettings. other complexity may come from:
1339+ *
1340+ * - high speed support, including "other speed config" rules
1341+ * - multiple configurations
1342+ * - interfaces with alternate settings
1343+ * - embedded class or vendor-specific descriptors
1344+ *
1345+ * this handles high speed, and has a second config that could as easily
1346+ * have been an alternate interface setting (on most hardware).
1347+ *
1348+ * NOTE: to demonstrate (and test) more USB capabilities, this driver
1349+ * should include an altsetting to test interrupt transfers, including
1350+ * high bandwidth modes at high speed. (Maybe work like Intel's test
1351+ * device?)
1352+ */
1353+static int
1354+config_buf (struct usb_gadget *gadget, u8 *buf, u8 type, unsigned index)
1355+{
1356+ int len;
1357+ const struct usb_descriptor_header **function;
1358+
1359+ function = z_function;
1360+ len = usb_gadget_config_buf (&z_config, buf, USB_BUFSIZ, function);
1361+ if (len < 0)
1362+ return len;
1363+ ((struct usb_config_descriptor *) buf)->bDescriptorType = type;
1364+ return len;
1365+}
1366+
1367+/*-------------------------------------------------------------------------*/
1368+
1369+static struct usb_request *
1370+alloc_ep_req (struct usb_ep *ep, unsigned length)
1371+{
1372+ struct usb_request *req;
1373+
1374+ req = usb_ep_alloc_request (ep, GFP_ATOMIC);
1375+ if (req) {
1376+ req->length = length;
1377+ req->buf = usb_ep_alloc_buffer (ep, length,
1378+ &req->dma, GFP_ATOMIC);
1379+ if (!req->buf) {
1380+ usb_ep_free_request (ep, req);
1381+ req = NULL;
1382+ }
1383+ }
1384+ return req;
1385+}
1386+
1387+static void free_ep_req (struct usb_ep *ep, struct usb_request *req)
1388+{
1389+ if (req->buf)
1390+ usb_ep_free_buffer (ep, req->buf, req->dma, req->length);
1391+ usb_ep_free_request (ep, req);
1392+}
1393+
1394+/*-------------------------------------------------------------------------*/
1395+
1396+/* optionally require specific source/sink data patterns */
1397+
1398+static int
1399+check_read_data (
1400+ struct zero_dev *dev,
1401+ struct usb_ep *ep,
1402+ struct usb_request *req
1403+)
1404+{
1405+ unsigned i;
1406+ u8 *buf = req->buf;
1407+
1408+ for (i = 0; i < req->actual; i++, buf++) {
1409+ switch (pattern) {
1410+ /* all-zeroes has no synchronization issues */
1411+ case 0:
1412+ if (*buf == 0)
1413+ continue;
1414+ break;
1415+ /* mod63 stays in sync with short-terminated transfers,
1416+ * or otherwise when host and gadget agree on how large
1417+ * each usb transfer request should be. resync is done
1418+ * with set_interface or set_config.
1419+ */
1420+ case 1:
1421+ if (*buf == (u8)(i % 63))
1422+ continue;
1423+ break;
1424+ }
1425+ ERROR (dev, "bad OUT byte, buf [%d] = %d\n", i, *buf);
1426+ usb_ep_set_halt (ep);
1427+ return -EINVAL;
1428+ }
1429+ return 0;
1430+}
1431+
1432+/*-------------------------------------------------------------------------*/
1433+
1434+static void zero_reset_config (struct zero_dev *dev)
1435+{
1436+ if (dev->config == 0)
1437+ return;
1438+
1439+ DBG (dev, "reset config\n");
1440+
1441+ /* just disable endpoints, forcing completion of pending i/o.
1442+ * all our completion handlers free their requests in this case.
1443+ */
1444+ if (dev->in_ep) {
1445+ usb_ep_disable (dev->in_ep);
1446+ dev->in_ep = NULL;
1447+ }
1448+ if (dev->out_ep) {
1449+ usb_ep_disable (dev->out_ep);
1450+ dev->out_ep = NULL;
1451+ }
1452+ dev->config = 0;
1453+ del_timer (&dev->resume);
1454+}
1455+
1456+#define _write(f, buf, sz) (f->f_op->write(f, buf, sz, &f->f_pos))
1457+
1458+static void
1459+zero_isoc_complete (struct usb_ep *ep, struct usb_request *req)
1460+{
1461+ struct zero_dev *dev = ep->driver_data;
1462+ int status = req->status;
1463+ int i, j;
1464+
1465+ switch (status) {
1466+
1467+ case 0: /* normal completion? */
1468+ //printk ("\nzero ---------------> isoc normal completion %d bytes\n", req->actual);
1469+ for (i=0, j=rbuf_start; i<req->actual; i++) {
1470+ //printk ("%02x ", ((__u8*)req->buf)[i]);
1471+ rbuf[j] = ((__u8*)req->buf)[i];
1472+ j++;
1473+ if (j >= RBUF_LEN) j=0;
1474+ }
1475+ rbuf_start = j;
1476+ //printk ("\n\n");
1477+
1478+ if (rbuf_len < RBUF_LEN) {
1479+ rbuf_len += req->actual;
1480+ if (rbuf_len > RBUF_LEN) {
1481+ rbuf_len = RBUF_LEN;
1482+ }
1483+ }
1484+
1485+ break;
1486+
1487+ /* this endpoint is normally active while we're configured */
1488+ case -ECONNABORTED: /* hardware forced ep reset */
1489+ case -ECONNRESET: /* request dequeued */
1490+ case -ESHUTDOWN: /* disconnect from host */
1491+ VDBG (dev, "%s gone (%d), %d/%d\n", ep->name, status,
1492+ req->actual, req->length);
1493+ if (ep == dev->out_ep)
1494+ check_read_data (dev, ep, req);
1495+ free_ep_req (ep, req);
1496+ return;
1497+
1498+ case -EOVERFLOW: /* buffer overrun on read means that
1499+ * we didn't provide a big enough
1500+ * buffer.
1501+ */
1502+ default:
1503+#if 1
1504+ DBG (dev, "%s complete --> %d, %d/%d\n", ep->name,
1505+ status, req->actual, req->length);
1506+#endif
1507+ case -EREMOTEIO: /* short read */
1508+ break;
1509+ }
1510+
1511+ status = usb_ep_queue (ep, req, GFP_ATOMIC);
1512+ if (status) {
1513+ ERROR (dev, "kill %s: resubmit %d bytes --> %d\n",
1514+ ep->name, req->length, status);
1515+ usb_ep_set_halt (ep);
1516+ /* FIXME recover later ... somehow */
1517+ }
1518+}
1519+
1520+static struct usb_request *
1521+zero_start_isoc_ep (struct usb_ep *ep, int gfp_flags)
1522+{
1523+ struct usb_request *req;
1524+ int status;
1525+
1526+ req = alloc_ep_req (ep, 512);
1527+ if (!req)
1528+ return NULL;
1529+
1530+ req->complete = zero_isoc_complete;
1531+
1532+ status = usb_ep_queue (ep, req, gfp_flags);
1533+ if (status) {
1534+ struct zero_dev *dev = ep->driver_data;
1535+
1536+ ERROR (dev, "start %s --> %d\n", ep->name, status);
1537+ free_ep_req (ep, req);
1538+ req = NULL;
1539+ }
1540+
1541+ return req;
1542+}
1543+
1544+/* change our operational config. this code must agree with the code
1545+ * that returns config descriptors, and altsetting code.
1546+ *
1547+ * it's also responsible for power management interactions. some
1548+ * configurations might not work with our current power sources.
1549+ *
1550+ * note that some device controller hardware will constrain what this
1551+ * code can do, perhaps by disallowing more than one configuration or
1552+ * by limiting configuration choices (like the pxa2xx).
1553+ */
1554+static int
1555+zero_set_config (struct zero_dev *dev, unsigned number, int gfp_flags)
1556+{
1557+ int result = 0;
1558+ struct usb_gadget *gadget = dev->gadget;
1559+ const struct usb_endpoint_descriptor *d;
1560+ struct usb_ep *ep;
1561+
1562+ if (number == dev->config)
1563+ return 0;
1564+
1565+ zero_reset_config (dev);
1566+
1567+ gadget_for_each_ep (ep, gadget) {
1568+
1569+ if (strcmp (ep->name, "ep4") == 0) {
1570+
1571+ d = (struct usb_endpoint_descripter *)&za_23; // isoc ep desc for audio i/f alt setting 6
1572+ result = usb_ep_enable (ep, d);
1573+
1574+ if (result == 0) {
1575+ ep->driver_data = dev;
1576+ dev->in_ep = ep;
1577+
1578+ if (zero_start_isoc_ep (ep, gfp_flags) != 0) {
1579+
1580+ dev->in_ep = ep;
1581+ continue;
1582+ }
1583+
1584+ usb_ep_disable (ep);
1585+ result = -EIO;
1586+ }
1587+ }
1588+
1589+ }
1590+
1591+ dev->config = number;
1592+ return result;
1593+}
1594+
1595+/*-------------------------------------------------------------------------*/
1596+
1597+static void zero_setup_complete (struct usb_ep *ep, struct usb_request *req)
1598+{
1599+ if (req->status || req->actual != req->length)
1600+ DBG ((struct zero_dev *) ep->driver_data,
1601+ "setup complete --> %d, %d/%d\n",
1602+ req->status, req->actual, req->length);
1603+}
1604+
1605+/*
1606+ * The setup() callback implements all the ep0 functionality that's
1607+ * not handled lower down, in hardware or the hardware driver (like
1608+ * device and endpoint feature flags, and their status). It's all
1609+ * housekeeping for the gadget function we're implementing. Most of
1610+ * the work is in config-specific setup.
1611+ */
1612+static int
1613+zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
1614+{
1615+ struct zero_dev *dev = get_gadget_data (gadget);
1616+ struct usb_request *req = dev->req;
1617+ int value = -EOPNOTSUPP;
1618+
1619+ /* usually this stores reply data in the pre-allocated ep0 buffer,
1620+ * but config change events will reconfigure hardware.
1621+ */
1622+ req->zero = 0;
1623+ switch (ctrl->bRequest) {
1624+
1625+ case USB_REQ_GET_DESCRIPTOR:
1626+
1627+ switch (ctrl->wValue >> 8) {
1628+
1629+ case USB_DT_DEVICE:
1630+ value = min (ctrl->wLength, (u16) sizeof device_desc);
1631+ memcpy (req->buf, &device_desc, value);
1632+ break;
1633+#ifdef CONFIG_USB_GADGET_DUALSPEED
1634+ case USB_DT_DEVICE_QUALIFIER:
1635+ if (!gadget->is_dualspeed)
1636+ break;
1637+ value = min (ctrl->wLength, (u16) sizeof dev_qualifier);
1638+ memcpy (req->buf, &dev_qualifier, value);
1639+ break;
1640+
1641+ case USB_DT_OTHER_SPEED_CONFIG:
1642+ if (!gadget->is_dualspeed)
1643+ break;
1644+ // FALLTHROUGH
1645+#endif /* CONFIG_USB_GADGET_DUALSPEED */
1646+ case USB_DT_CONFIG:
1647+ value = config_buf (gadget, req->buf,
1648+ ctrl->wValue >> 8,
1649+ ctrl->wValue & 0xff);
1650+ if (value >= 0)
1651+ value = min (ctrl->wLength, (u16) value);
1652+ break;
1653+
1654+ case USB_DT_STRING:
1655+ /* wIndex == language code.
1656+ * this driver only handles one language, you can
1657+ * add string tables for other languages, using
1658+ * any UTF-8 characters
1659+ */
1660+ value = usb_gadget_get_string (&stringtab,
1661+ ctrl->wValue & 0xff, req->buf);
1662+ if (value >= 0) {
1663+ value = min (ctrl->wLength, (u16) value);
1664+ }
1665+ break;
1666+ }
1667+ break;
1668+
1669+ /* currently two configs, two speeds */
1670+ case USB_REQ_SET_CONFIGURATION:
1671+ if (ctrl->bRequestType != 0)
1672+ goto unknown;
1673+
1674+ spin_lock (&dev->lock);
1675+ value = zero_set_config (dev, ctrl->wValue, GFP_ATOMIC);
1676+ spin_unlock (&dev->lock);
1677+ break;
1678+ case USB_REQ_GET_CONFIGURATION:
1679+ if (ctrl->bRequestType != USB_DIR_IN)
1680+ goto unknown;
1681+ *(u8 *)req->buf = dev->config;
1682+ value = min (ctrl->wLength, (u16) 1);
1683+ break;
1684+
1685+ /* until we add altsetting support, or other interfaces,
1686+ * only 0/0 are possible. pxa2xx only supports 0/0 (poorly)
1687+ * and already killed pending endpoint I/O.
1688+ */
1689+ case USB_REQ_SET_INTERFACE:
1690+
1691+ if (ctrl->bRequestType != USB_RECIP_INTERFACE)
1692+ goto unknown;
1693+ spin_lock (&dev->lock);
1694+ if (dev->config) {
1695+ u8 config = dev->config;
1696+
1697+ /* resets interface configuration, forgets about
1698+ * previous transaction state (queued bufs, etc)
1699+ * and re-inits endpoint state (toggle etc)
1700+ * no response queued, just zero status == success.
1701+ * if we had more than one interface we couldn't
1702+ * use this "reset the config" shortcut.
1703+ */
1704+ zero_reset_config (dev);
1705+ zero_set_config (dev, config, GFP_ATOMIC);
1706+ value = 0;
1707+ }
1708+ spin_unlock (&dev->lock);
1709+ break;
1710+ case USB_REQ_GET_INTERFACE:
1711+ if ((ctrl->bRequestType == 0x21) && (ctrl->wIndex == 0x02)) {
1712+ value = ctrl->wLength;
1713+ break;
1714+ }
1715+ else {
1716+ if (ctrl->bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE))
1717+ goto unknown;
1718+ if (!dev->config)
1719+ break;
1720+ if (ctrl->wIndex != 0) {
1721+ value = -EDOM;
1722+ break;
1723+ }
1724+ *(u8 *)req->buf = 0;
1725+ value = min (ctrl->wLength, (u16) 1);
1726+ }
1727+ break;
1728+
1729+ /*
1730+ * These are the same vendor-specific requests supported by
1731+ * Intel's USB 2.0 compliance test devices. We exceed that
1732+ * device spec by allowing multiple-packet requests.
1733+ */
1734+ case 0x5b: /* control WRITE test -- fill the buffer */
1735+ if (ctrl->bRequestType != (USB_DIR_OUT|USB_TYPE_VENDOR))
1736+ goto unknown;
1737+ if (ctrl->wValue || ctrl->wIndex)
1738+ break;
1739+ /* just read that many bytes into the buffer */
1740+ if (ctrl->wLength > USB_BUFSIZ)
1741+ break;
1742+ value = ctrl->wLength;
1743+ break;
1744+ case 0x5c: /* control READ test -- return the buffer */
1745+ if (ctrl->bRequestType != (USB_DIR_IN|USB_TYPE_VENDOR))
1746+ goto unknown;
1747+ if (ctrl->wValue || ctrl->wIndex)
1748+ break;
1749+ /* expect those bytes are still in the buffer; send back */
1750+ if (ctrl->wLength > USB_BUFSIZ
1751+ || ctrl->wLength != req->length)
1752+ break;
1753+ value = ctrl->wLength;
1754+ break;
1755+
1756+ case 0x01: // SET_CUR
1757+ case 0x02:
1758+ case 0x03:
1759+ case 0x04:
1760+ case 0x05:
1761+ value = ctrl->wLength;
1762+ break;
1763+ case 0x81:
1764+ switch (ctrl->wValue) {
1765+ case 0x0201:
1766+ case 0x0202:
1767+ ((u8*)req->buf)[0] = 0x00;
1768+ ((u8*)req->buf)[1] = 0xe3;
1769+ break;
1770+ case 0x0300:
1771+ case 0x0500:
1772+ ((u8*)req->buf)[0] = 0x00;
1773+ break;
1774+ }
1775+ //((u8*)req->buf)[0] = 0x81;
1776+ //((u8*)req->buf)[1] = 0x81;
1777+ value = ctrl->wLength;
1778+ break;
1779+ case 0x82:
1780+ switch (ctrl->wValue) {
1781+ case 0x0201:
1782+ case 0x0202:
1783+ ((u8*)req->buf)[0] = 0x00;
1784+ ((u8*)req->buf)[1] = 0xc3;
1785+ break;
1786+ case 0x0300:
1787+ case 0x0500:
1788+ ((u8*)req->buf)[0] = 0x00;
1789+ break;
1790+ }
1791+ //((u8*)req->buf)[0] = 0x82;
1792+ //((u8*)req->buf)[1] = 0x82;
1793+ value = ctrl->wLength;
1794+ break;
1795+ case 0x83:
1796+ switch (ctrl->wValue) {
1797+ case 0x0201:
1798+ case 0x0202:
1799+ ((u8*)req->buf)[0] = 0x00;
1800+ ((u8*)req->buf)[1] = 0x00;
1801+ break;
1802+ case 0x0300:
1803+ ((u8*)req->buf)[0] = 0x60;
1804+ break;
1805+ case 0x0500:
1806+ ((u8*)req->buf)[0] = 0x18;
1807+ break;
1808+ }
1809+ //((u8*)req->buf)[0] = 0x83;
1810+ //((u8*)req->buf)[1] = 0x83;
1811+ value = ctrl->wLength;
1812+ break;
1813+ case 0x84:
1814+ switch (ctrl->wValue) {
1815+ case 0x0201:
1816+ case 0x0202:
1817+ ((u8*)req->buf)[0] = 0x00;
1818+ ((u8*)req->buf)[1] = 0x01;
1819+ break;
1820+ case 0x0300:
1821+ case 0x0500:
1822+ ((u8*)req->buf)[0] = 0x08;
1823+ break;
1824+ }
1825+ //((u8*)req->buf)[0] = 0x84;
1826+ //((u8*)req->buf)[1] = 0x84;
1827+ value = ctrl->wLength;
1828+ break;
1829+ case 0x85:
1830+ ((u8*)req->buf)[0] = 0x85;
1831+ ((u8*)req->buf)[1] = 0x85;
1832+ value = ctrl->wLength;
1833+ break;
1834+
1835+
1836+ default:
1837+unknown:
1838+ printk("unknown control req%02x.%02x v%04x i%04x l%d\n",
1839+ ctrl->bRequestType, ctrl->bRequest,
1840+ ctrl->wValue, ctrl->wIndex, ctrl->wLength);
1841+ }
1842+
1843+ /* respond with data transfer before status phase? */
1844+ if (value >= 0) {
1845+ req->length = value;
1846+ req->zero = value < ctrl->wLength
1847+ && (value % gadget->ep0->maxpacket) == 0;
1848+ value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC);
1849+ if (value < 0) {
1850+ DBG (dev, "ep_queue < 0 --> %d\n", value);
1851+ req->status = 0;
1852+ zero_setup_complete (gadget->ep0, req);
1853+ }
1854+ }
1855+
1856+ /* device either stalls (value < 0) or reports success */
1857+ return value;
1858+}
1859+
1860+static void
1861+zero_disconnect (struct usb_gadget *gadget)
1862+{
1863+ struct zero_dev *dev = get_gadget_data (gadget);
1864+ unsigned long flags;
1865+
1866+ spin_lock_irqsave (&dev->lock, flags);
1867+ zero_reset_config (dev);
1868+
1869+ /* a more significant application might have some non-usb
1870+ * activities to quiesce here, saving resources like power
1871+ * or pushing the notification up a network stack.
1872+ */
1873+ spin_unlock_irqrestore (&dev->lock, flags);
1874+
1875+ /* next we may get setup() calls to enumerate new connections;
1876+ * or an unbind() during shutdown (including removing module).
1877+ */
1878+}
1879+
1880+static void
1881+zero_autoresume (unsigned long _dev)
1882+{
1883+ struct zero_dev *dev = (struct zero_dev *) _dev;
1884+ int status;
1885+
1886+ /* normally the host would be woken up for something
1887+ * more significant than just a timer firing...
1888+ */
1889+ if (dev->gadget->speed != USB_SPEED_UNKNOWN) {
1890+ status = usb_gadget_wakeup (dev->gadget);
1891+ DBG (dev, "wakeup --> %d\n", status);
1892+ }
1893+}
1894+
1895+/*-------------------------------------------------------------------------*/
1896+
1897+static void
1898+zero_unbind (struct usb_gadget *gadget)
1899+{
1900+ struct zero_dev *dev = get_gadget_data (gadget);
1901+
1902+ DBG (dev, "unbind\n");
1903+
1904+ /* we've already been disconnected ... no i/o is active */
1905+ if (dev->req)
1906+ free_ep_req (gadget->ep0, dev->req);
1907+ del_timer_sync (&dev->resume);
1908+ kfree (dev);
1909+ set_gadget_data (gadget, NULL);
1910+}
1911+
1912+static int
1913+zero_bind (struct usb_gadget *gadget)
1914+{
1915+ struct zero_dev *dev;
1916+ //struct usb_ep *ep;
1917+
1918+ printk("binding\n");
1919+ /*
1920+ * DRIVER POLICY CHOICE: you may want to do this differently.
1921+ * One thing to avoid is reusing a bcdDevice revision code
1922+ * with different host-visible configurations or behavior
1923+ * restrictions -- using ep1in/ep2out vs ep1out/ep3in, etc
1924+ */
1925+ //device_desc.bcdDevice = __constant_cpu_to_le16 (0x0201);
1926+
1927+
1928+ /* ok, we made sense of the hardware ... */
1929+ dev = kmalloc (sizeof *dev, SLAB_KERNEL);
1930+ if (!dev)
1931+ return -ENOMEM;
1932+ memset (dev, 0, sizeof *dev);
1933+ spin_lock_init (&dev->lock);
1934+ dev->gadget = gadget;
1935+ set_gadget_data (gadget, dev);
1936+
1937+ /* preallocate control response and buffer */
1938+ dev->req = usb_ep_alloc_request (gadget->ep0, GFP_KERNEL);
1939+ if (!dev->req)
1940+ goto enomem;
1941+ dev->req->buf = usb_ep_alloc_buffer (gadget->ep0, USB_BUFSIZ,
1942+ &dev->req->dma, GFP_KERNEL);
1943+ if (!dev->req->buf)
1944+ goto enomem;
1945+
1946+ dev->req->complete = zero_setup_complete;
1947+
1948+ device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
1949+
1950+#ifdef CONFIG_USB_GADGET_DUALSPEED
1951+ /* assume ep0 uses the same value for both speeds ... */
1952+ dev_qualifier.bMaxPacketSize0 = device_desc.bMaxPacketSize0;
1953+
1954+ /* and that all endpoints are dual-speed */
1955+ //hs_source_desc.bEndpointAddress = fs_source_desc.bEndpointAddress;
1956+ //hs_sink_desc.bEndpointAddress = fs_sink_desc.bEndpointAddress;
1957+#endif
1958+
1959+ usb_gadget_set_selfpowered (gadget);
1960+
1961+ init_timer (&dev->resume);
1962+ dev->resume.function = zero_autoresume;
1963+ dev->resume.data = (unsigned long) dev;
1964+
1965+ gadget->ep0->driver_data = dev;
1966+
1967+ INFO (dev, "%s, version: " DRIVER_VERSION "\n", longname);
1968+ INFO (dev, "using %s, OUT %s IN %s\n", gadget->name,
1969+ EP_OUT_NAME, EP_IN_NAME);
1970+
1971+ snprintf (manufacturer, sizeof manufacturer,
1972+ UTS_SYSNAME " " UTS_RELEASE " with %s",
1973+ gadget->name);
1974+
1975+ return 0;
1976+
1977+enomem:
1978+ zero_unbind (gadget);
1979+ return -ENOMEM;
1980+}
1981+
1982+/*-------------------------------------------------------------------------*/
1983+
1984+static void
1985+zero_suspend (struct usb_gadget *gadget)
1986+{
1987+ struct zero_dev *dev = get_gadget_data (gadget);
1988+
1989+ if (gadget->speed == USB_SPEED_UNKNOWN)
1990+ return;
1991+
1992+ if (autoresume) {
1993+ mod_timer (&dev->resume, jiffies + (HZ * autoresume));
1994+ DBG (dev, "suspend, wakeup in %d seconds\n", autoresume);
1995+ } else
1996+ DBG (dev, "suspend\n");
1997+}
1998+
1999+static void
2000+zero_resume (struct usb_gadget *gadget)
2001+{
2002+ struct zero_dev *dev = get_gadget_data (gadget);
2003+
2004+ DBG (dev, "resume\n");
2005+ del_timer (&dev->resume);
2006+}
2007+
2008+
2009+/*-------------------------------------------------------------------------*/
2010+
2011+static struct usb_gadget_driver zero_driver = {
2012+#ifdef CONFIG_USB_GADGET_DUALSPEED
2013+ .speed = USB_SPEED_HIGH,
2014+#else
2015+ .speed = USB_SPEED_FULL,
2016+#endif
2017+ .function = (char *) longname,
2018+ .bind = zero_bind,
2019+ .unbind = zero_unbind,
2020+
2021+ .setup = zero_setup,
2022+ .disconnect = zero_disconnect,
2023+
2024+ .suspend = zero_suspend,
2025+ .resume = zero_resume,
2026+
2027+ .driver = {
2028+ .name = (char *) shortname,
2029+ // .shutdown = ...
2030+ // .suspend = ...
2031+ // .resume = ...
2032+ },
2033+};
2034+
2035+MODULE_AUTHOR ("David Brownell");
2036+MODULE_LICENSE ("Dual BSD/GPL");
2037+
2038+static struct proc_dir_entry *pdir, *pfile;
2039+
2040+static int isoc_read_data (char *page, char **start,
2041+ off_t off, int count,
2042+ int *eof, void *data)
2043+{
2044+ int i;
2045+ static int c = 0;
2046+ static int done = 0;
2047+ static int s = 0;
2048+
2049+/*
2050+ printk ("\ncount: %d\n", count);
2051+ printk ("rbuf_start: %d\n", rbuf_start);
2052+ printk ("rbuf_len: %d\n", rbuf_len);
2053+ printk ("off: %d\n", off);
2054+ printk ("start: %p\n\n", *start);
2055+*/
2056+ if (done) {
2057+ c = 0;
2058+ done = 0;
2059+ *eof = 1;
2060+ return 0;
2061+ }
2062+
2063+ if (c == 0) {
2064+ if (rbuf_len == RBUF_LEN)
2065+ s = rbuf_start;
2066+ else s = 0;
2067+ }
2068+
2069+ for (i=0; i<count && c<rbuf_len; i++, c++) {
2070+ page[i] = rbuf[(c+s) % RBUF_LEN];
2071+ }
2072+ *start = page;
2073+
2074+ if (c >= rbuf_len) {
2075+ *eof = 1;
2076+ done = 1;
2077+ }
2078+
2079+
2080+ return i;
2081+}
2082+
2083+static int __init init (void)
2084+{
2085+
2086+ int retval = 0;
2087+
2088+ pdir = proc_mkdir("isoc_test", NULL);
2089+ if(pdir == NULL) {
2090+ retval = -ENOMEM;
2091+ printk("Error creating dir\n");
2092+ goto done;
2093+ }
2094+ pdir->owner = THIS_MODULE;
2095+
2096+ pfile = create_proc_read_entry("isoc_data",
2097+ 0444, pdir,
2098+ isoc_read_data,
2099+ NULL);
2100+ if (pfile == NULL) {
2101+ retval = -ENOMEM;
2102+ printk("Error creating file\n");
2103+ goto no_file;
2104+ }
2105+ pfile->owner = THIS_MODULE;
2106+
2107+ return usb_gadget_register_driver (&zero_driver);
2108+
2109+ no_file:
2110+ remove_proc_entry("isoc_data", NULL);
2111+ done:
2112+ return retval;
2113+}
2114+module_init (init);
2115+
2116+static void __exit cleanup (void)
2117+{
2118+
2119+ usb_gadget_unregister_driver (&zero_driver);
2120+
2121+ remove_proc_entry("isoc_data", pdir);
2122+ remove_proc_entry("isoc_test", NULL);
2123+}
2124+module_exit (cleanup);
2125--- /dev/null
2126+++ b/drivers/usb/host/otg/dwc_otg_attr.c
2127@@ -0,0 +1,1055 @@
2128+/* ==========================================================================
2129+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_attr.c $
2130+ * $Revision: #31 $
2131+ * $Date: 2008/07/15 $
2132+ * $Change: 1064918 $
2133+ *
2134+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
2135+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
2136+ * otherwise expressly agreed to in writing between Synopsys and you.
2137+ *
2138+ * The Software IS NOT an item of Licensed Software or Licensed Product under
2139+ * any End User Software License Agreement or Agreement for Licensed Product
2140+ * with Synopsys or any supplement thereto. You are permitted to use and
2141+ * redistribute this Software in source and binary forms, with or without
2142+ * modification, provided that redistributions of source code must retain this
2143+ * notice. You may not view, use, disclose, copy or distribute this file or
2144+ * any information contained herein except pursuant to this license grant from
2145+ * Synopsys. If you do not agree with this notice, including the disclaimer
2146+ * below, then you are not authorized to use the Software.
2147+ *
2148+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
2149+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2150+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2151+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
2152+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2153+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2154+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
2155+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2156+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2157+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
2158+ * DAMAGE.
2159+ * ========================================================================== */
2160+
2161+/** @file
2162+ *
2163+ * The diagnostic interface will provide access to the controller for
2164+ * bringing up the hardware and testing. The Linux driver attributes
2165+ * feature will be used to provide the Linux Diagnostic
2166+ * Interface. These attributes are accessed through sysfs.
2167+ */
2168+
2169+/** @page "Linux Module Attributes"
2170+ *
2171+ * The Linux module attributes feature is used to provide the Linux
2172+ * Diagnostic Interface. These attributes are accessed through sysfs.
2173+ * The diagnostic interface will provide access to the controller for
2174+ * bringing up the hardware and testing.
2175+
2176+
2177+ The following table shows the attributes.
2178+ <table>
2179+ <tr>
2180+ <td><b> Name</b></td>
2181+ <td><b> Description</b></td>
2182+ <td><b> Access</b></td>
2183+ </tr>
2184+
2185+ <tr>
2186+ <td> mode </td>
2187+ <td> Returns the current mode: 0 for device mode, 1 for host mode</td>
2188+ <td> Read</td>
2189+ </tr>
2190+
2191+ <tr>
2192+ <td> hnpcapable </td>
2193+ <td> Gets or sets the "HNP-capable" bit in the Core USB Configuraton Register.
2194+ Read returns the current value.</td>
2195+ <td> Read/Write</td>
2196+ </tr>
2197+
2198+ <tr>
2199+ <td> srpcapable </td>
2200+ <td> Gets or sets the "SRP-capable" bit in the Core USB Configuraton Register.
2201+ Read returns the current value.</td>
2202+ <td> Read/Write</td>
2203+ </tr>
2204+
2205+ <tr>
2206+ <td> hnp </td>
2207+ <td> Initiates the Host Negotiation Protocol. Read returns the status.</td>
2208+ <td> Read/Write</td>
2209+ </tr>
2210+
2211+ <tr>
2212+ <td> srp </td>
2213+ <td> Initiates the Session Request Protocol. Read returns the status.</td>
2214+ <td> Read/Write</td>
2215+ </tr>
2216+
2217+ <tr>
2218+ <td> buspower </td>
2219+ <td> Gets or sets the Power State of the bus (0 - Off or 1 - On)</td>
2220+ <td> Read/Write</td>
2221+ </tr>
2222+
2223+ <tr>
2224+ <td> bussuspend </td>
2225+ <td> Suspends the USB bus.</td>
2226+ <td> Read/Write</td>
2227+ </tr>
2228+
2229+ <tr>
2230+ <td> busconnected </td>
2231+ <td> Gets the connection status of the bus</td>
2232+ <td> Read</td>
2233+ </tr>
2234+
2235+ <tr>
2236+ <td> gotgctl </td>
2237+ <td> Gets or sets the Core Control Status Register.</td>
2238+ <td> Read/Write</td>
2239+ </tr>
2240+
2241+ <tr>
2242+ <td> gusbcfg </td>
2243+ <td> Gets or sets the Core USB Configuration Register</td>
2244+ <td> Read/Write</td>
2245+ </tr>
2246+
2247+ <tr>
2248+ <td> grxfsiz </td>
2249+ <td> Gets or sets the Receive FIFO Size Register</td>
2250+ <td> Read/Write</td>
2251+ </tr>
2252+
2253+ <tr>
2254+ <td> gnptxfsiz </td>
2255+ <td> Gets or sets the non-periodic Transmit Size Register</td>
2256+ <td> Read/Write</td>
2257+ </tr>
2258+
2259+ <tr>
2260+ <td> gpvndctl </td>
2261+ <td> Gets or sets the PHY Vendor Control Register</td>
2262+ <td> Read/Write</td>
2263+ </tr>
2264+
2265+ <tr>
2266+ <td> ggpio </td>
2267+ <td> Gets the value in the lower 16-bits of the General Purpose IO Register
2268+ or sets the upper 16 bits.</td>
2269+ <td> Read/Write</td>
2270+ </tr>
2271+
2272+ <tr>
2273+ <td> guid </td>
2274+ <td> Gets or sets the value of the User ID Register</td>
2275+ <td> Read/Write</td>
2276+ </tr>
2277+
2278+ <tr>
2279+ <td> gsnpsid </td>
2280+ <td> Gets the value of the Synopsys ID Regester</td>
2281+ <td> Read</td>
2282+ </tr>
2283+
2284+ <tr>
2285+ <td> devspeed </td>
2286+ <td> Gets or sets the device speed setting in the DCFG register</td>
2287+ <td> Read/Write</td>
2288+ </tr>
2289+
2290+ <tr>
2291+ <td> enumspeed </td>
2292+ <td> Gets the device enumeration Speed.</td>
2293+ <td> Read</td>
2294+ </tr>
2295+
2296+ <tr>
2297+ <td> hptxfsiz </td>
2298+ <td> Gets the value of the Host Periodic Transmit FIFO</td>
2299+ <td> Read</td>
2300+ </tr>
2301+
2302+ <tr>
2303+ <td> hprt0 </td>
2304+ <td> Gets or sets the value in the Host Port Control and Status Register</td>
2305+ <td> Read/Write</td>
2306+ </tr>
2307+
2308+ <tr>
2309+ <td> regoffset </td>
2310+ <td> Sets the register offset for the next Register Access</td>
2311+ <td> Read/Write</td>
2312+ </tr>
2313+
2314+ <tr>
2315+ <td> regvalue </td>
2316+ <td> Gets or sets the value of the register at the offset in the regoffset attribute.</td>
2317+ <td> Read/Write</td>
2318+ </tr>
2319+
2320+ <tr>
2321+ <td> remote_wakeup </td>
2322+ <td> On read, shows the status of Remote Wakeup. On write, initiates a remote
2323+ wakeup of the host. When bit 0 is 1 and Remote Wakeup is enabled, the Remote
2324+ Wakeup signalling bit in the Device Control Register is set for 1
2325+ milli-second.</td>
2326+ <td> Read/Write</td>
2327+ </tr>
2328+
2329+ <tr>
2330+ <td> regdump </td>
2331+ <td> Dumps the contents of core registers.</td>
2332+ <td> Read</td>
2333+ </tr>
2334+
2335+ <tr>
2336+ <td> spramdump </td>
2337+ <td> Dumps the contents of core registers.</td>
2338+ <td> Read</td>
2339+ </tr>
2340+
2341+ <tr>
2342+ <td> hcddump </td>
2343+ <td> Dumps the current HCD state.</td>
2344+ <td> Read</td>
2345+ </tr>
2346+
2347+ <tr>
2348+ <td> hcd_frrem </td>
2349+ <td> Shows the average value of the Frame Remaining
2350+ field in the Host Frame Number/Frame Remaining register when an SOF interrupt
2351+ occurs. This can be used to determine the average interrupt latency. Also
2352+ shows the average Frame Remaining value for start_transfer and the "a" and
2353+ "b" sample points. The "a" and "b" sample points may be used during debugging
2354+ bto determine how long it takes to execute a section of the HCD code.</td>
2355+ <td> Read</td>
2356+ </tr>
2357+
2358+ <tr>
2359+ <td> rd_reg_test </td>
2360+ <td> Displays the time required to read the GNPTXFSIZ register many times
2361+ (the output shows the number of times the register is read).
2362+ <td> Read</td>
2363+ </tr>
2364+
2365+ <tr>
2366+ <td> wr_reg_test </td>
2367+ <td> Displays the time required to write the GNPTXFSIZ register many times
2368+ (the output shows the number of times the register is written).
2369+ <td> Read</td>
2370+ </tr>
2371+
2372+ </table>
2373+
2374+ Example usage:
2375+ To get the current mode:
2376+ cat /sys/devices/lm0/mode
2377+
2378+ To power down the USB:
2379+ echo 0 > /sys/devices/lm0/buspower
2380+ */
2381+
2382+#include <linux/kernel.h>
2383+#include <linux/module.h>
2384+#include <linux/moduleparam.h>
2385+#include <linux/init.h>
2386+#include <linux/device.h>
2387+#include <linux/errno.h>
2388+#include <linux/types.h>
2389+#include <linux/stat.h> /* permission constants */
2390+#include <linux/version.h>
2391+
2392+#include <asm/sizes.h>
2393+#include <asm/io.h>
2394+//#include <asm/arch/lm.h>
2395+#include <mach/lm.h>
2396+#include <asm/sizes.h>
2397+
2398+#include "dwc_otg_plat.h"
2399+#include "dwc_otg_attr.h"
2400+#include "dwc_otg_driver.h"
2401+#include "dwc_otg_pcd.h"
2402+#include "dwc_otg_hcd.h"
2403+
2404+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2405+/*
2406+ * MACROs for defining sysfs attribute
2407+ */
2408+#define DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
2409+static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
2410+{ \
2411+ struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev); \
2412+ dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev); \
2413+ uint32_t val; \
2414+ val = dwc_read_reg32 (_addr_); \
2415+ val = (val & (_mask_)) >> _shift_; \
2416+ return sprintf (buf, "%s = 0x%x\n", _string_, val); \
2417+}
2418+#define DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
2419+static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \
2420+ const char *buf, size_t count) \
2421+{ \
2422+ struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev); \
2423+ dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev); \
2424+ uint32_t set = simple_strtoul(buf, NULL, 16); \
2425+ uint32_t clear = set; \
2426+ clear = ((~clear) << _shift_) & _mask_; \
2427+ set = (set << _shift_) & _mask_; \
2428+ dev_dbg(_dev, "Storing Address=0x%08x Set=0x%08x Clear=0x%08x\n", (uint32_t)_addr_, set, clear); \
2429+ dwc_modify_reg32(_addr_, clear, set); \
2430+ return count; \
2431+}
2432+
2433+/*
2434+ * MACROs for defining sysfs attribute for 32-bit registers
2435+ */
2436+#define DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_addr_,_string_) \
2437+static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
2438+{ \
2439+ struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev); \
2440+ dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev); \
2441+ uint32_t val; \
2442+ val = dwc_read_reg32 (_addr_); \
2443+ return sprintf (buf, "%s = 0x%08x\n", _string_, val); \
2444+}
2445+#define DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_addr_,_string_) \
2446+static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \
2447+ const char *buf, size_t count) \
2448+{ \
2449+ struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev); \
2450+ dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev); \
2451+ uint32_t val = simple_strtoul(buf, NULL, 16); \
2452+ dev_dbg(_dev, "Storing Address=0x%08x Val=0x%08x\n", (uint32_t)_addr_, val); \
2453+ dwc_write_reg32(_addr_, val); \
2454+ return count; \
2455+}
2456+
2457+#else
2458+
2459+/*
2460+ * MACROs for defining sysfs attribute
2461+ */
2462+#define DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
2463+static ssize_t _otg_attr_name_##_show (struct device *_dev, char *buf) \
2464+{ \
2465+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);\
2466+ uint32_t val; \
2467+ val = dwc_read_reg32 (_addr_); \
2468+ val = (val & (_mask_)) >> _shift_; \
2469+ return sprintf (buf, "%s = 0x%x\n", _string_, val); \
2470+}
2471+#define DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
2472+static ssize_t _otg_attr_name_##_store (struct device *_dev, const char *buf, size_t count) \
2473+{ \
2474+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);\
2475+ uint32_t set = simple_strtoul(buf, NULL, 16); \
2476+ uint32_t clear = set; \
2477+ clear = ((~clear) << _shift_) & _mask_; \
2478+ set = (set << _shift_) & _mask_; \
2479+ dev_dbg(_dev, "Storing Address=0x%08x Set=0x%08x Clear=0x%08x\n", (uint32_t)_addr_, set, clear); \
2480+ dwc_modify_reg32(_addr_, clear, set); \
2481+ return count; \
2482+}
2483+
2484+/*
2485+ * MACROs for defining sysfs attribute for 32-bit registers
2486+ */
2487+#define DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_addr_,_string_) \
2488+static ssize_t _otg_attr_name_##_show (struct device *_dev, char *buf) \
2489+{ \
2490+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);\
2491+ uint32_t val; \
2492+ val = dwc_read_reg32 (_addr_); \
2493+ return sprintf (buf, "%s = 0x%08x\n", _string_, val); \
2494+}
2495+#define DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_addr_,_string_) \
2496+static ssize_t _otg_attr_name_##_store (struct device *_dev, const char *buf, size_t count) \
2497+{ \
2498+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);\
2499+ uint32_t val = simple_strtoul(buf, NULL, 16); \
2500+ dev_dbg(_dev, "Storing Address=0x%08x Val=0x%08x\n", (uint32_t)_addr_, val); \
2501+ dwc_write_reg32(_addr_, val); \
2502+ return count; \
2503+}
2504+
2505+#endif
2506+
2507+#define DWC_OTG_DEVICE_ATTR_BITFIELD_RW(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
2508+DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
2509+DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
2510+DEVICE_ATTR(_otg_attr_name_,0644,_otg_attr_name_##_show,_otg_attr_name_##_store);
2511+
2512+#define DWC_OTG_DEVICE_ATTR_BITFIELD_RO(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
2513+DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
2514+DEVICE_ATTR(_otg_attr_name_,0444,_otg_attr_name_##_show,NULL);
2515+
2516+#define DWC_OTG_DEVICE_ATTR_REG32_RW(_otg_attr_name_,_addr_,_string_) \
2517+DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_addr_,_string_) \
2518+DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_addr_,_string_) \
2519+DEVICE_ATTR(_otg_attr_name_,0644,_otg_attr_name_##_show,_otg_attr_name_##_store);
2520+
2521+#define DWC_OTG_DEVICE_ATTR_REG32_RO(_otg_attr_name_,_addr_,_string_) \
2522+DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_addr_,_string_) \
2523+DEVICE_ATTR(_otg_attr_name_,0444,_otg_attr_name_##_show,NULL);
2524+
2525+
2526+/** @name Functions for Show/Store of Attributes */
2527+/**@{*/
2528+
2529+/**
2530+ * Show the register offset of the Register Access.
2531+ */
2532+static ssize_t regoffset_show( struct device *_dev,
2533+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2534+ struct device_attribute *attr,
2535+#endif
2536+ char *buf)
2537+{
2538+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2539+ struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev);
2540+ dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev);
2541+#else
2542+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
2543+#endif
2544+ return snprintf(buf, sizeof("0xFFFFFFFF\n")+1,"0x%08x\n", otg_dev->reg_offset);
2545+}
2546+
2547+/**
2548+ * Set the register offset for the next Register Access Read/Write
2549+ */
2550+static ssize_t regoffset_store( struct device *_dev,
2551+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2552+ struct device_attribute *attr,
2553+#endif
2554+ const char *buf,
2555+ size_t count )
2556+{
2557+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2558+ struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev);
2559+ dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev);
2560+#else
2561+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
2562+#endif
2563+ uint32_t offset = simple_strtoul(buf, NULL, 16);
2564+ //dev_dbg(_dev, "Offset=0x%08x\n", offset);
2565+ if (offset < SZ_256K ) {
2566+ otg_dev->reg_offset = offset;
2567+ }
2568+ else {
2569+ dev_err( _dev, "invalid offset\n" );
2570+ }
2571+
2572+ return count;
2573+}
2574+DEVICE_ATTR(regoffset, S_IRUGO|S_IWUSR, (void *)regoffset_show, regoffset_store);
2575+
2576+
2577+/**
2578+ * Show the value of the register at the offset in the reg_offset
2579+ * attribute.
2580+ */
2581+static ssize_t regvalue_show( struct device *_dev,
2582+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2583+ struct device_attribute *attr,
2584+#endif
2585+ char *buf)
2586+{
2587+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2588+ struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev);
2589+ dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev);
2590+#else
2591+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
2592+#endif
2593+ uint32_t val;
2594+ volatile uint32_t *addr;
2595+
2596+ if (otg_dev->reg_offset != 0xFFFFFFFF &&
2597+ 0 != otg_dev->base) {
2598+ /* Calculate the address */
2599+ addr = (uint32_t*)(otg_dev->reg_offset +
2600+ (uint8_t*)otg_dev->base);
2601+ //dev_dbg(_dev, "@0x%08x\n", (unsigned)addr);
2602+ val = dwc_read_reg32( addr );
2603+ return snprintf(buf, sizeof("Reg@0xFFFFFFFF = 0xFFFFFFFF\n")+1,
2604+ "Reg@0x%06x = 0x%08x\n",
2605+ otg_dev->reg_offset, val);
2606+ }
2607+ else {
2608+ dev_err(_dev, "Invalid offset (0x%0x)\n",
2609+ otg_dev->reg_offset);
2610+ return sprintf(buf, "invalid offset\n" );
2611+ }
2612+}
2613+
2614+/**
2615+ * Store the value in the register at the offset in the reg_offset
2616+ * attribute.
2617+ *
2618+ */
2619+static ssize_t regvalue_store( struct device *_dev,
2620+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2621+ struct device_attribute *attr,
2622+#endif
2623+ const char *buf,
2624+ size_t count )
2625+{
2626+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2627+ struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev);
2628+ dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev);
2629+#else
2630+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
2631+#endif
2632+ volatile uint32_t * addr;
2633+ uint32_t val = simple_strtoul(buf, NULL, 16);
2634+ //dev_dbg(_dev, "Offset=0x%08x Val=0x%08x\n", otg_dev->reg_offset, val);
2635+ if (otg_dev->reg_offset != 0xFFFFFFFF && 0 != otg_dev->base) {
2636+ /* Calculate the address */
2637+ addr = (uint32_t*)(otg_dev->reg_offset +
2638+ (uint8_t*)otg_dev->base);
2639+ //dev_dbg(_dev, "@0x%08x\n", (unsigned)addr);
2640+ dwc_write_reg32( addr, val );
2641+ }
2642+ else {
2643+ dev_err(_dev, "Invalid Register Offset (0x%08x)\n",
2644+ otg_dev->reg_offset);
2645+ }
2646+ return count;
2647+}
2648+DEVICE_ATTR(regvalue, S_IRUGO|S_IWUSR, regvalue_show, regvalue_store);
2649+
2650+/*
2651+ * Attributes
2652+ */
2653+DWC_OTG_DEVICE_ATTR_BITFIELD_RO(mode,&(otg_dev->core_if->core_global_regs->gotgctl),(1<<20),20,"Mode");
2654+DWC_OTG_DEVICE_ATTR_BITFIELD_RW(hnpcapable,&(otg_dev->core_if->core_global_regs->gusbcfg),(1<<9),9,"Mode");
2655+DWC_OTG_DEVICE_ATTR_BITFIELD_RW(srpcapable,&(otg_dev->core_if->core_global_regs->gusbcfg),(1<<8),8,"Mode");
2656+
2657+//DWC_OTG_DEVICE_ATTR_BITFIELD_RW(buspower,&(otg_dev->core_if->core_global_regs->gotgctl),(1<<8),8,"Mode");
2658+//DWC_OTG_DEVICE_ATTR_BITFIELD_RW(bussuspend,&(otg_dev->core_if->core_global_regs->gotgctl),(1<<8),8,"Mode");
2659+DWC_OTG_DEVICE_ATTR_BITFIELD_RO(busconnected,otg_dev->core_if->host_if->hprt0,0x01,0,"Bus Connected");
2660+
2661+DWC_OTG_DEVICE_ATTR_REG32_RW(gotgctl,&(otg_dev->core_if->core_global_regs->gotgctl),"GOTGCTL");
2662+DWC_OTG_DEVICE_ATTR_REG32_RW(gusbcfg,&(otg_dev->core_if->core_global_regs->gusbcfg),"GUSBCFG");
2663+DWC_OTG_DEVICE_ATTR_REG32_RW(grxfsiz,&(otg_dev->core_if->core_global_regs->grxfsiz),"GRXFSIZ");
2664+DWC_OTG_DEVICE_ATTR_REG32_RW(gnptxfsiz,&(otg_dev->core_if->core_global_regs->gnptxfsiz),"GNPTXFSIZ");
2665+DWC_OTG_DEVICE_ATTR_REG32_RW(gpvndctl,&(otg_dev->core_if->core_global_regs->gpvndctl),"GPVNDCTL");
2666+DWC_OTG_DEVICE_ATTR_REG32_RW(ggpio,&(otg_dev->core_if->core_global_regs->ggpio),"GGPIO");
2667+DWC_OTG_DEVICE_ATTR_REG32_RW(guid,&(otg_dev->core_if->core_global_regs->guid),"GUID");
2668+DWC_OTG_DEVICE_ATTR_REG32_RO(gsnpsid,&(otg_dev->core_if->core_global_regs->gsnpsid),"GSNPSID");
2669+DWC_OTG_DEVICE_ATTR_BITFIELD_RW(devspeed,&(otg_dev->core_if->dev_if->dev_global_regs->dcfg),0x3,0,"Device Speed");
2670+DWC_OTG_DEVICE_ATTR_BITFIELD_RO(enumspeed,&(otg_dev->core_if->dev_if->dev_global_regs->dsts),0x6,1,"Device Enumeration Speed");
2671+
2672+DWC_OTG_DEVICE_ATTR_REG32_RO(hptxfsiz,&(otg_dev->core_if->core_global_regs->hptxfsiz),"HPTXFSIZ");
2673+DWC_OTG_DEVICE_ATTR_REG32_RW(hprt0,otg_dev->core_if->host_if->hprt0,"HPRT0");
2674+
2675+
2676+/**
2677+ * @todo Add code to initiate the HNP.
2678+ */
2679+/**
2680+ * Show the HNP status bit
2681+ */
2682+static ssize_t hnp_show( struct device *_dev,
2683+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2684+ struct device_attribute *attr,
2685+#endif
2686+ char *buf)
2687+{
2688+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2689+ struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev);
2690+ dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev);
2691+#else
2692+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
2693+#endif
2694+ gotgctl_data_t val;
2695+ val.d32 = dwc_read_reg32 (&(otg_dev->core_if->core_global_regs->gotgctl));
2696+ return sprintf (buf, "HstNegScs = 0x%x\n", val.b.hstnegscs);
2697+}
2698+
2699+/**
2700+ * Set the HNP Request bit
2701+ */
2702+static ssize_t hnp_store( struct device *_dev,
2703+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2704+ struct device_attribute *attr,
2705+#endif
2706+ const char *buf,
2707+ size_t count )
2708+{
2709+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2710+ struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev);
2711+ dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev);
2712+#else
2713+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
2714+#endif
2715+ uint32_t in = simple_strtoul(buf, NULL, 16);
2716+ uint32_t *addr = (uint32_t *)&(otg_dev->core_if->core_global_regs->gotgctl);
2717+ gotgctl_data_t mem;
2718+ mem.d32 = dwc_read_reg32(addr);
2719+ mem.b.hnpreq = in;
2720+ dev_dbg(_dev, "Storing Address=0x%08x Data=0x%08x\n", (uint32_t)addr, mem.d32);
2721+ dwc_write_reg32(addr, mem.d32);
2722+ return count;
2723+}
2724+DEVICE_ATTR(hnp, 0644, hnp_show, hnp_store);
2725+
2726+/**
2727+ * @todo Add code to initiate the SRP.
2728+ */
2729+/**
2730+ * Show the SRP status bit
2731+ */
2732+static ssize_t srp_show( struct device *_dev,
2733+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2734+ struct device_attribute *attr,
2735+#endif
2736+ char *buf)
2737+{
2738+#ifndef DWC_HOST_ONLY
2739+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2740+ struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev);
2741+ dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev);
2742+#else
2743+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
2744+#endif
2745+ gotgctl_data_t val;
2746+ val.d32 = dwc_read_reg32 (&(otg_dev->core_if->core_global_regs->gotgctl));
2747+ return sprintf (buf, "SesReqScs = 0x%x\n", val.b.sesreqscs);
2748+#else
2749+ return sprintf(buf, "Host Only Mode!\n");
2750+#endif
2751+}
2752+
2753+
2754+
2755+/**
2756+ * Set the SRP Request bit
2757+ */
2758+static ssize_t srp_store( struct device *_dev,
2759+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2760+ struct device_attribute *attr,
2761+#endif
2762+ const char *buf,
2763+ size_t count )
2764+{
2765+#ifndef DWC_HOST_ONLY
2766+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2767+ struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev);
2768+ dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev);
2769+#else
2770+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
2771+#endif
2772+ dwc_otg_pcd_initiate_srp(otg_dev->pcd);
2773+#endif
2774+ return count;
2775+}
2776+DEVICE_ATTR(srp, 0644, srp_show, srp_store);
2777+
2778+/**
2779+ * @todo Need to do more for power on/off?
2780+ */
2781+/**
2782+ * Show the Bus Power status
2783+ */
2784+static ssize_t buspower_show( struct device *_dev,
2785+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2786+ struct device_attribute *attr,
2787+#endif
2788+ char *buf)
2789+{
2790+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2791+ struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev);
2792+ dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev);
2793+#else
2794+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
2795+#endif
2796+ hprt0_data_t val;
2797+ val.d32 = dwc_read_reg32 (otg_dev->core_if->host_if->hprt0);
2798+ return sprintf (buf, "Bus Power = 0x%x\n", val.b.prtpwr);
2799+}
2800+
2801+
2802+/**
2803+ * Set the Bus Power status
2804+ */
2805+static ssize_t buspower_store( struct device *_dev,
2806+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2807+ struct device_attribute *attr,
2808+#endif
2809+ const char *buf,
2810+ size_t count )
2811+{
2812+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2813+ struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev);
2814+ dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev);
2815+#else
2816+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
2817+#endif
2818+ uint32_t on = simple_strtoul(buf, NULL, 16);
2819+ uint32_t *addr = (uint32_t *)otg_dev->core_if->host_if->hprt0;
2820+ hprt0_data_t mem;
2821+
2822+ mem.d32 = dwc_read_reg32(addr);
2823+ mem.b.prtpwr = on;
2824+
2825+ //dev_dbg(_dev, "Storing Address=0x%08x Data=0x%08x\n", (uint32_t)addr, mem.d32);
2826+ dwc_write_reg32(addr, mem.d32);
2827+
2828+ return count;
2829+}
2830+DEVICE_ATTR(buspower, 0644, buspower_show, buspower_store);
2831+
2832+/**
2833+ * @todo Need to do more for suspend?
2834+ */
2835+/**
2836+ * Show the Bus Suspend status
2837+ */
2838+static ssize_t bussuspend_show( struct device *_dev,
2839+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2840+ struct device_attribute *attr,
2841+#endif
2842+ char *buf)
2843+{
2844+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2845+ struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev);
2846+ dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev);
2847+#else
2848+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
2849+#endif
2850+ hprt0_data_t val;
2851+ val.d32 = dwc_read_reg32 (otg_dev->core_if->host_if->hprt0);
2852+ return sprintf (buf, "Bus Suspend = 0x%x\n", val.b.prtsusp);
2853+}
2854+
2855+/**
2856+ * Set the Bus Suspend status
2857+ */
2858+static ssize_t bussuspend_store( struct device *_dev,
2859+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2860+ struct device_attribute *attr,
2861+#endif
2862+ const char *buf,
2863+ size_t count )
2864+{
2865+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2866+ struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev);
2867+ dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev);
2868+#else
2869+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
2870+#endif
2871+ uint32_t in = simple_strtoul(buf, NULL, 16);
2872+ uint32_t *addr = (uint32_t *)otg_dev->core_if->host_if->hprt0;
2873+ hprt0_data_t mem;
2874+ mem.d32 = dwc_read_reg32(addr);
2875+ mem.b.prtsusp = in;
2876+ dev_dbg(_dev, "Storing Address=0x%08x Data=0x%08x\n", (uint32_t)addr, mem.d32);
2877+ dwc_write_reg32(addr, mem.d32);
2878+ return count;
2879+}
2880+DEVICE_ATTR(bussuspend, 0644, bussuspend_show, bussuspend_store);
2881+
2882+/**
2883+ * Show the status of Remote Wakeup.
2884+ */
2885+static ssize_t remote_wakeup_show( struct device *_dev,
2886+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2887+ struct device_attribute *attr,
2888+#endif
2889+ char *buf)
2890+{
2891+#ifndef DWC_HOST_ONLY
2892+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2893+ struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev);
2894+ dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev);
2895+#else
2896+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
2897+#endif
2898+ dctl_data_t val;
2899+ val.d32 =
2900+ dwc_read_reg32( &otg_dev->core_if->dev_if->dev_global_regs->dctl);
2901+ return sprintf( buf, "Remote Wakeup = %d Enabled = %d\n",
2902+ val.b.rmtwkupsig, otg_dev->pcd->remote_wakeup_enable);
2903+#else
2904+ return sprintf(buf, "Host Only Mode!\n");
2905+#endif
2906+}
2907+/**
2908+ * Initiate a remote wakeup of the host. The Device control register
2909+ * Remote Wakeup Signal bit is written if the PCD Remote wakeup enable
2910+ * flag is set.
2911+ *
2912+ */
2913+static ssize_t remote_wakeup_store( struct device *_dev,
2914+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2915+ struct device_attribute *attr,
2916+#endif
2917+ const char *buf,
2918+ size_t count )
2919+{
2920+#ifndef DWC_HOST_ONLY
2921+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2922+ struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev);
2923+ dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev);
2924+#else
2925+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
2926+#endif
2927+ uint32_t val = simple_strtoul(buf, NULL, 16);
2928+ if (val&1) {
2929+ dwc_otg_pcd_remote_wakeup(otg_dev->pcd, 1);
2930+ }
2931+ else {
2932+ dwc_otg_pcd_remote_wakeup(otg_dev->pcd, 0);
2933+ }
2934+#endif
2935+ return count;
2936+}
2937+DEVICE_ATTR(remote_wakeup, S_IRUGO|S_IWUSR, remote_wakeup_show,
2938+ remote_wakeup_store);
2939+
2940+/**
2941+ * Dump global registers and either host or device registers (depending on the
2942+ * current mode of the core).
2943+ */
2944+static ssize_t regdump_show( struct device *_dev,
2945+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2946+ struct device_attribute *attr,
2947+#endif
2948+ char *buf)
2949+{
2950+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2951+ struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev);
2952+ dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev);
2953+#else
2954+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
2955+#endif
2956+ dwc_otg_dump_global_registers( otg_dev->core_if);
2957+ if (dwc_otg_is_host_mode(otg_dev->core_if)) {
2958+ dwc_otg_dump_host_registers( otg_dev->core_if);
2959+ } else {
2960+ dwc_otg_dump_dev_registers( otg_dev->core_if);
2961+
2962+ }
2963+ return sprintf( buf, "Register Dump\n" );
2964+}
2965+
2966+DEVICE_ATTR(regdump, S_IRUGO|S_IWUSR, regdump_show, 0);
2967+
2968+/**
2969+ * Dump global registers and either host or device registers (depending on the
2970+ * current mode of the core).
2971+ */
2972+static ssize_t spramdump_show( struct device *_dev,
2973+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2974+ struct device_attribute *attr,
2975+#endif
2976+ char *buf)
2977+{
2978+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2979+ struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev);
2980+ dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev);
2981+#else
2982+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
2983+#endif
2984+ dwc_otg_dump_spram( otg_dev->core_if);
2985+
2986+ return sprintf( buf, "SPRAM Dump\n" );
2987+}
2988+
2989+DEVICE_ATTR(spramdump, S_IRUGO|S_IWUSR, spramdump_show, 0);
2990+
2991+/**
2992+ * Dump the current hcd state.
2993+ */
2994+static ssize_t hcddump_show( struct device *_dev,
2995+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2996+ struct device_attribute *attr,
2997+#endif
2998+ char *buf)
2999+{
3000+#ifndef DWC_DEVICE_ONLY
3001+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
3002+ struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev);
3003+ dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev);
3004+#else
3005+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
3006+#endif
3007+ dwc_otg_hcd_dump_state(otg_dev->hcd);
3008+#endif
3009+ return sprintf( buf, "HCD Dump\n" );
3010+}
3011+
3012+DEVICE_ATTR(hcddump, S_IRUGO|S_IWUSR, hcddump_show, 0);
3013+
3014+/**
3015+ * Dump the average frame remaining at SOF. This can be used to
3016+ * determine average interrupt latency. Frame remaining is also shown for
3017+ * start transfer and two additional sample points.
3018+ */
3019+static ssize_t hcd_frrem_show( struct device *_dev,
3020+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
3021+ struct device_attribute *attr,
3022+#endif
3023+ char *buf)
3024+{
3025+#ifndef DWC_DEVICE_ONLY
3026+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
3027+ struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev);
3028+ dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev);
3029+#else
3030+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
3031+#endif
3032+ dwc_otg_hcd_dump_frrem(otg_dev->hcd);
3033+#endif
3034+ return sprintf( buf, "HCD Dump Frame Remaining\n" );
3035+}
3036+
3037+DEVICE_ATTR(hcd_frrem, S_IRUGO|S_IWUSR, hcd_frrem_show, 0);
3038+
3039+/**
3040+ * Displays the time required to read the GNPTXFSIZ register many times (the
3041+ * output shows the number of times the register is read).
3042+ */
3043+#define RW_REG_COUNT 10000000
3044+#define MSEC_PER_JIFFIE 1000/HZ
3045+static ssize_t rd_reg_test_show( struct device *_dev,
3046+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
3047+ struct device_attribute *attr,
3048+#endif
3049+ char *buf)
3050+{
3051+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
3052+ struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev);
3053+ dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev);
3054+#else
3055+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
3056+#endif
3057+ int i;
3058+ int time;
3059+ int start_jiffies;
3060+
3061+ printk("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n",
3062+ HZ, MSEC_PER_JIFFIE, loops_per_jiffy);
3063+ start_jiffies = jiffies;
3064+ for (i = 0; i < RW_REG_COUNT; i++) {
3065+ dwc_read_reg32(&otg_dev->core_if->core_global_regs->gnptxfsiz);
3066+ }
3067+ time = jiffies - start_jiffies;
3068+ return sprintf( buf, "Time to read GNPTXFSIZ reg %d times: %d msecs (%d jiffies)\n",
3069+ RW_REG_COUNT, time * MSEC_PER_JIFFIE, time );
3070+}
3071+
3072+DEVICE_ATTR(rd_reg_test, S_IRUGO|S_IWUSR, rd_reg_test_show, 0);
3073+
3074+/**
3075+ * Displays the time required to write the GNPTXFSIZ register many times (the
3076+ * output shows the number of times the register is written).
3077+ */
3078+static ssize_t wr_reg_test_show( struct device *_dev,
3079+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
3080+ struct device_attribute *attr,
3081+#endif
3082+ char *buf)
3083+{
3084+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
3085+ struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev);
3086+ dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev);
3087+#else
3088+ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
3089+#endif
3090+ uint32_t reg_val;
3091+ int i;
3092+ int time;
3093+ int start_jiffies;
3094+
3095+ printk("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n",
3096+ HZ, MSEC_PER_JIFFIE, loops_per_jiffy);
3097+ reg_val = dwc_read_reg32(&otg_dev->core_if->core_global_regs->gnptxfsiz);
3098+ start_jiffies = jiffies;
3099+ for (i = 0; i < RW_REG_COUNT; i++) {
3100+ dwc_write_reg32(&otg_dev->core_if->core_global_regs->gnptxfsiz, reg_val);
3101+ }
3102+ time = jiffies - start_jiffies;
3103+ return sprintf( buf, "Time to write GNPTXFSIZ reg %d times: %d msecs (%d jiffies)\n",
3104+ RW_REG_COUNT, time * MSEC_PER_JIFFIE, time);
3105+}
3106+
3107+DEVICE_ATTR(wr_reg_test, S_IRUGO|S_IWUSR, wr_reg_test_show, 0);
3108+/**@}*/
3109+
3110+/**
3111+ * Create the device files
3112+ */
3113+void dwc_otg_attr_create (struct lm_device *lmdev)
3114+{
3115+ int error;
3116+
3117+ error = device_create_file(&lmdev->dev, &dev_attr_regoffset);
3118+ error = device_create_file(&lmdev->dev, &dev_attr_regvalue);
3119+ error = device_create_file(&lmdev->dev, &dev_attr_mode);
3120+ error = device_create_file(&lmdev->dev, &dev_attr_hnpcapable);
3121+ error = device_create_file(&lmdev->dev, &dev_attr_srpcapable);
3122+ error = device_create_file(&lmdev->dev, &dev_attr_hnp);
3123+ error = device_create_file(&lmdev->dev, &dev_attr_srp);
3124+ error = device_create_file(&lmdev->dev, &dev_attr_buspower);
3125+ error = device_create_file(&lmdev->dev, &dev_attr_bussuspend);
3126+ error = device_create_file(&lmdev->dev, &dev_attr_busconnected);
3127+ error = device_create_file(&lmdev->dev, &dev_attr_gotgctl);
3128+ error = device_create_file(&lmdev->dev, &dev_attr_gusbcfg);
3129+ error = device_create_file(&lmdev->dev, &dev_attr_grxfsiz);
3130+ error = device_create_file(&lmdev->dev, &dev_attr_gnptxfsiz);
3131+ error = device_create_file(&lmdev->dev, &dev_attr_gpvndctl);
3132+ error = device_create_file(&lmdev->dev, &dev_attr_ggpio);
3133+ error = device_create_file(&lmdev->dev, &dev_attr_guid);
3134+ error = device_create_file(&lmdev->dev, &dev_attr_gsnpsid);
3135+ error = device_create_file(&lmdev->dev, &dev_attr_devspeed);
3136+ error = device_create_file(&lmdev->dev, &dev_attr_enumspeed);
3137+ error = device_create_file(&lmdev->dev, &dev_attr_hptxfsiz);
3138+ error = device_create_file(&lmdev->dev, &dev_attr_hprt0);
3139+ error = device_create_file(&lmdev->dev, &dev_attr_remote_wakeup);
3140+ error = device_create_file(&lmdev->dev, &dev_attr_regdump);
3141+ error = device_create_file(&lmdev->dev, &dev_attr_spramdump);
3142+ error = device_create_file(&lmdev->dev, &dev_attr_hcddump);
3143+ error = device_create_file(&lmdev->dev, &dev_attr_hcd_frrem);
3144+ error = device_create_file(&lmdev->dev, &dev_attr_rd_reg_test);
3145+ error = device_create_file(&lmdev->dev, &dev_attr_wr_reg_test);
3146+}
3147+
3148+/**
3149+ * Remove the device files
3150+ */
3151+void dwc_otg_attr_remove (struct lm_device *lmdev)
3152+{
3153+ device_remove_file(&lmdev->dev, &dev_attr_regoffset);
3154+ device_remove_file(&lmdev->dev, &dev_attr_regvalue);
3155+ device_remove_file(&lmdev->dev, &dev_attr_mode);
3156+ device_remove_file(&lmdev->dev, &dev_attr_hnpcapable);
3157+ device_remove_file(&lmdev->dev, &dev_attr_srpcapable);
3158+ device_remove_file(&lmdev->dev, &dev_attr_hnp);
3159+ device_remove_file(&lmdev->dev, &dev_attr_srp);
3160+ device_remove_file(&lmdev->dev, &dev_attr_buspower);
3161+ device_remove_file(&lmdev->dev, &dev_attr_bussuspend);
3162+ device_remove_file(&lmdev->dev, &dev_attr_busconnected);
3163+ device_remove_file(&lmdev->dev, &dev_attr_gotgctl);
3164+ device_remove_file(&lmdev->dev, &dev_attr_gusbcfg);
3165+ device_remove_file(&lmdev->dev, &dev_attr_grxfsiz);
3166+ device_remove_file(&lmdev->dev, &dev_attr_gnptxfsiz);
3167+ device_remove_file(&lmdev->dev, &dev_attr_gpvndctl);
3168+ device_remove_file(&lmdev->dev, &dev_attr_ggpio);
3169+ device_remove_file(&lmdev->dev, &dev_attr_guid);
3170+ device_remove_file(&lmdev->dev, &dev_attr_gsnpsid);
3171+ device_remove_file(&lmdev->dev, &dev_attr_devspeed);
3172+ device_remove_file(&lmdev->dev, &dev_attr_enumspeed);
3173+ device_remove_file(&lmdev->dev, &dev_attr_hptxfsiz);
3174+ device_remove_file(&lmdev->dev, &dev_attr_hprt0);
3175+ device_remove_file(&lmdev->dev, &dev_attr_remote_wakeup);
3176+ device_remove_file(&lmdev->dev, &dev_attr_regdump);
3177+ device_remove_file(&lmdev->dev, &dev_attr_spramdump);
3178+ device_remove_file(&lmdev->dev, &dev_attr_hcddump);
3179+ device_remove_file(&lmdev->dev, &dev_attr_hcd_frrem);
3180+ device_remove_file(&lmdev->dev, &dev_attr_rd_reg_test);
3181+ device_remove_file(&lmdev->dev, &dev_attr_wr_reg_test);
3182+}
3183--- /dev/null
3184+++ b/drivers/usb/host/otg/dwc_otg_attr.h
3185@@ -0,0 +1,67 @@
3186+/* ==========================================================================
3187+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_attr.h $
3188+ * $Revision: #7 $
3189+ * $Date: 2005/03/28 $
3190+ * $Change: 477051 $
3191+ *
3192+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
3193+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
3194+ * otherwise expressly agreed to in writing between Synopsys and you.
3195+ *
3196+ * The Software IS NOT an item of Licensed Software or Licensed Product under
3197+ * any End User Software License Agreement or Agreement for Licensed Product
3198+ * with Synopsys or any supplement thereto. You are permitted to use and
3199+ * redistribute this Software in source and binary forms, with or without
3200+ * modification, provided that redistributions of source code must retain this
3201+ * notice. You may not view, use, disclose, copy or distribute this file or
3202+ * any information contained herein except pursuant to this license grant from
3203+ * Synopsys. If you do not agree with this notice, including the disclaimer
3204+ * below, then you are not authorized to use the Software.
3205+ *
3206+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
3207+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
3208+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
3209+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
3210+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
3211+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
3212+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
3213+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3214+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3215+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
3216+ * DAMAGE.
3217+ * ========================================================================== */
3218+
3219+#if !defined(__DWC_OTG_ATTR_H__)
3220+#define __DWC_OTG_ATTR_H__
3221+
3222+/** @file
3223+ * This file contains the interface to the Linux device attributes.
3224+ */
3225+extern struct device_attribute dev_attr_regoffset;
3226+extern struct device_attribute dev_attr_regvalue;
3227+
3228+extern struct device_attribute dev_attr_mode;
3229+extern struct device_attribute dev_attr_hnpcapable;
3230+extern struct device_attribute dev_attr_srpcapable;
3231+extern struct device_attribute dev_attr_hnp;
3232+extern struct device_attribute dev_attr_srp;
3233+extern struct device_attribute dev_attr_buspower;
3234+extern struct device_attribute dev_attr_bussuspend;
3235+extern struct device_attribute dev_attr_busconnected;
3236+extern struct device_attribute dev_attr_gotgctl;
3237+extern struct device_attribute dev_attr_gusbcfg;
3238+extern struct device_attribute dev_attr_grxfsiz;
3239+extern struct device_attribute dev_attr_gnptxfsiz;
3240+extern struct device_attribute dev_attr_gpvndctl;
3241+extern struct device_attribute dev_attr_ggpio;
3242+extern struct device_attribute dev_attr_guid;
3243+extern struct device_attribute dev_attr_gsnpsid;
3244+extern struct device_attribute dev_attr_devspeed;
3245+extern struct device_attribute dev_attr_enumspeed;
3246+extern struct device_attribute dev_attr_hptxfsiz;
3247+extern struct device_attribute dev_attr_hprt0;
3248+
3249+void dwc_otg_attr_create (struct lm_device *lmdev);
3250+void dwc_otg_attr_remove (struct lm_device *lmdev);
3251+
3252+#endif
3253--- /dev/null
3254+++ b/drivers/usb/host/otg/dwc_otg_cil.c
3255@@ -0,0 +1,3842 @@
3256+/* ==========================================================================
3257+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_cil.c $
3258+ * $Revision: #147 $
3259+ * $Date: 2008/10/16 $
3260+ * $Change: 1117667 $
3261+ *
3262+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
3263+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
3264+ * otherwise expressly agreed to in writing between Synopsys and you.
3265+ *
3266+ * The Software IS NOT an item of Licensed Software or Licensed Product under
3267+ * any End User Software License Agreement or Agreement for Licensed Product
3268+ * with Synopsys or any supplement thereto. You are permitted to use and
3269+ * redistribute this Software in source and binary forms, with or without
3270+ * modification, provided that redistributions of source code must retain this
3271+ * notice. You may not view, use, disclose, copy or distribute this file or
3272+ * any information contained herein except pursuant to this license grant from
3273+ * Synopsys. If you do not agree with this notice, including the disclaimer
3274+ * below, then you are not authorized to use the Software.
3275+ *
3276+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
3277+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
3278+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
3279+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
3280+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
3281+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
3282+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
3283+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3284+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3285+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
3286+ * DAMAGE.
3287+ * ========================================================================== */
3288+
3289+/** @file
3290+ *
3291+ * The Core Interface Layer provides basic services for accessing and
3292+ * managing the DWC_otg hardware. These services are used by both the
3293+ * Host Controller Driver and the Peripheral Controller Driver.
3294+ *
3295+ * The CIL manages the memory map for the core so that the HCD and PCD
3296+ * don't have to do this separately. It also handles basic tasks like
3297+ * reading/writing the registers and data FIFOs in the controller.
3298+ * Some of the data access functions provide encapsulation of several
3299+ * operations required to perform a task, such as writing multiple
3300+ * registers to start a transfer. Finally, the CIL performs basic
3301+ * services that are not specific to either the host or device modes
3302+ * of operation. These services include management of the OTG Host
3303+ * Negotiation Protocol (HNP) and Session Request Protocol (SRP). A
3304+ * Diagnostic API is also provided to allow testing of the controller
3305+ * hardware.
3306+ *
3307+ * The Core Interface Layer has the following requirements:
3308+ * - Provides basic controller operations.
3309+ * - Minimal use of OS services.
3310+ * - The OS services used will be abstracted by using inline functions
3311+ * or macros.
3312+ *
3313+ */
3314+#include <asm/unaligned.h>
3315+#include <linux/dma-mapping.h>
3316+#ifdef DEBUG
3317+#include <linux/jiffies.h>
3318+#endif
3319+
3320+#include "dwc_otg_plat.h"
3321+#include "dwc_otg_regs.h"
3322+#include "dwc_otg_cil.h"
3323+#include "dwc_otg_pcd.h"
3324+
3325+
3326+/**
3327+ * This function is called to initialize the DWC_otg CSR data
3328+ * structures. The register addresses in the device and host
3329+ * structures are initialized from the base address supplied by the
3330+ * caller. The calling function must make the OS calls to get the
3331+ * base address of the DWC_otg controller registers. The core_params
3332+ * argument holds the parameters that specify how the core should be
3333+ * configured.
3334+ *
3335+ * @param[in] reg_base_addr Base address of DWC_otg core registers
3336+ * @param[in] core_params Pointer to the core configuration parameters
3337+ *
3338+ */
3339+dwc_otg_core_if_t *dwc_otg_cil_init(const uint32_t *reg_base_addr,
3340+ dwc_otg_core_params_t *core_params)
3341+{
3342+ dwc_otg_core_if_t *core_if = 0;
3343+ dwc_otg_dev_if_t *dev_if = 0;
3344+ dwc_otg_host_if_t *host_if = 0;
3345+ uint8_t *reg_base = (uint8_t *)reg_base_addr;
3346+ int i = 0;
3347+
3348+ DWC_DEBUGPL(DBG_CILV, "%s(%p,%p)\n", __func__, reg_base_addr, core_params);
3349+
3350+ core_if = kmalloc(sizeof(dwc_otg_core_if_t), GFP_KERNEL);
3351+
3352+ if (core_if == 0) {
3353+ DWC_DEBUGPL(DBG_CIL, "Allocation of dwc_otg_core_if_t failed\n");
3354+ return 0;
3355+ }
3356+
3357+ memset(core_if, 0, sizeof(dwc_otg_core_if_t));
3358+
3359+ core_if->core_params = core_params;
3360+ core_if->core_global_regs = (dwc_otg_core_global_regs_t *)reg_base;
3361+
3362+ /*
3363+ * Allocate the Device Mode structures.
3364+ */
3365+ dev_if = kmalloc(sizeof(dwc_otg_dev_if_t), GFP_KERNEL);
3366+
3367+ if (dev_if == 0) {
3368+ DWC_DEBUGPL(DBG_CIL, "Allocation of dwc_otg_dev_if_t failed\n");
3369+ kfree(core_if);
3370+ return 0;
3371+ }
3372+
3373+ dev_if->dev_global_regs =
3374+ (dwc_otg_device_global_regs_t *)(reg_base + DWC_DEV_GLOBAL_REG_OFFSET);
3375+
3376+ for (i=0; i<MAX_EPS_CHANNELS; i++)
3377+ {
3378+ dev_if->in_ep_regs[i] = (dwc_otg_dev_in_ep_regs_t *)
3379+ (reg_base + DWC_DEV_IN_EP_REG_OFFSET +
3380+ (i * DWC_EP_REG_OFFSET));
3381+
3382+ dev_if->out_ep_regs[i] = (dwc_otg_dev_out_ep_regs_t *)
3383+ (reg_base + DWC_DEV_OUT_EP_REG_OFFSET +
3384+ (i * DWC_EP_REG_OFFSET));
3385+ DWC_DEBUGPL(DBG_CILV, "in_ep_regs[%d]->diepctl=%p\n",
3386+ i, &dev_if->in_ep_regs[i]->diepctl);
3387+ DWC_DEBUGPL(DBG_CILV, "out_ep_regs[%d]->doepctl=%p\n",
3388+ i, &dev_if->out_ep_regs[i]->doepctl);
3389+ }
3390+
3391+ dev_if->speed = 0; // unknown
3392+
3393+ core_if->dev_if = dev_if;
3394+
3395+ /*
3396+ * Allocate the Host Mode structures.
3397+ */
3398+ host_if = kmalloc(sizeof(dwc_otg_host_if_t), GFP_KERNEL);
3399+
3400+ if (host_if == 0) {
3401+ DWC_DEBUGPL(DBG_CIL, "Allocation of dwc_otg_host_if_t failed\n");
3402+ kfree(dev_if);
3403+ kfree(core_if);
3404+ return 0;
3405+ }
3406+
3407+ host_if->host_global_regs = (dwc_otg_host_global_regs_t *)
3408+ (reg_base + DWC_OTG_HOST_GLOBAL_REG_OFFSET);
3409+
3410+ host_if->hprt0 = (uint32_t*)(reg_base + DWC_OTG_HOST_PORT_REGS_OFFSET);
3411+
3412+ for (i=0; i<MAX_EPS_CHANNELS; i++)
3413+ {
3414+ host_if->hc_regs[i] = (dwc_otg_hc_regs_t *)
3415+ (reg_base + DWC_OTG_HOST_CHAN_REGS_OFFSET +
3416+ (i * DWC_OTG_CHAN_REGS_OFFSET));
3417+ DWC_DEBUGPL(DBG_CILV, "hc_reg[%d]->hcchar=%p\n",
3418+ i, &host_if->hc_regs[i]->hcchar);
3419+ }
3420+
3421+ host_if->num_host_channels = MAX_EPS_CHANNELS;
3422+ core_if->host_if = host_if;
3423+
3424+ for (i=0; i<MAX_EPS_CHANNELS; i++)
3425+ {
3426+ core_if->data_fifo[i] =
3427+ (uint32_t *)(reg_base + DWC_OTG_DATA_FIFO_OFFSET +
3428+ (i * DWC_OTG_DATA_FIFO_SIZE));
3429+ DWC_DEBUGPL(DBG_CILV, "data_fifo[%d]=0x%08x\n",
3430+ i, (unsigned)core_if->data_fifo[i]);
3431+ }
3432+
3433+ core_if->pcgcctl = (uint32_t*)(reg_base + DWC_OTG_PCGCCTL_OFFSET);
3434+
3435+ /*
3436+ * Store the contents of the hardware configuration registers here for
3437+ * easy access later.
3438+ */
3439+ core_if->hwcfg1.d32 = dwc_read_reg32(&core_if->core_global_regs->ghwcfg1);
3440+ core_if->hwcfg2.d32 = dwc_read_reg32(&core_if->core_global_regs->ghwcfg2);
3441+ core_if->hwcfg3.d32 = dwc_read_reg32(&core_if->core_global_regs->ghwcfg3);
3442+ core_if->hwcfg4.d32 = dwc_read_reg32(&core_if->core_global_regs->ghwcfg4);
3443+
3444+ DWC_DEBUGPL(DBG_CILV,"hwcfg1=%08x\n",core_if->hwcfg1.d32);
3445+ DWC_DEBUGPL(DBG_CILV,"hwcfg2=%08x\n",core_if->hwcfg2.d32);
3446+ DWC_DEBUGPL(DBG_CILV,"hwcfg3=%08x\n",core_if->hwcfg3.d32);
3447+ DWC_DEBUGPL(DBG_CILV,"hwcfg4=%08x\n",core_if->hwcfg4.d32);
3448+
3449+ core_if->hcfg.d32 = dwc_read_reg32(&core_if->host_if->host_global_regs->hcfg);
3450+ core_if->dcfg.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dcfg);
3451+
3452+ DWC_DEBUGPL(DBG_CILV,"hcfg=%08x\n",core_if->hcfg.d32);
3453+ DWC_DEBUGPL(DBG_CILV,"dcfg=%08x\n",core_if->dcfg.d32);
3454+
3455+ DWC_DEBUGPL(DBG_CILV,"op_mode=%0x\n",core_if->hwcfg2.b.op_mode);
3456+ DWC_DEBUGPL(DBG_CILV,"arch=%0x\n",core_if->hwcfg2.b.architecture);
3457+ DWC_DEBUGPL(DBG_CILV,"num_dev_ep=%d\n",core_if->hwcfg2.b.num_dev_ep);
3458+ DWC_DEBUGPL(DBG_CILV,"num_host_chan=%d\n",core_if->hwcfg2.b.num_host_chan);
3459+ DWC_DEBUGPL(DBG_CILV,"nonperio_tx_q_depth=0x%0x\n",core_if->hwcfg2.b.nonperio_tx_q_depth);
3460+ DWC_DEBUGPL(DBG_CILV,"host_perio_tx_q_depth=0x%0x\n",core_if->hwcfg2.b.host_perio_tx_q_depth);
3461+ DWC_DEBUGPL(DBG_CILV,"dev_token_q_depth=0x%0x\n",core_if->hwcfg2.b.dev_token_q_depth);
3462+
3463+ DWC_DEBUGPL(DBG_CILV,"Total FIFO SZ=%d\n", core_if->hwcfg3.b.dfifo_depth);
3464+ DWC_DEBUGPL(DBG_CILV,"xfer_size_cntr_width=%0x\n", core_if->hwcfg3.b.xfer_size_cntr_width);
3465+
3466+ /*
3467+ * Set the SRP sucess bit for FS-I2c
3468+ */
3469+ core_if->srp_success = 0;
3470+ core_if->srp_timer_started = 0;
3471+
3472+
3473+ /*
3474+ * Create new workqueue and init works
3475+ */
3476+ core_if->wq_otg = create_singlethread_workqueue("dwc_otg");
3477+ if(core_if->wq_otg == 0) {
3478+ DWC_DEBUGPL(DBG_CIL, "Creation of wq_otg failed\n");
3479+ kfree(host_if);
3480+ kfree(dev_if);
3481+ kfree(core_if);
3482+ return 0 * HZ;
3483+ }
3484+
3485+
3486+
3487+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
3488+
3489+ INIT_WORK(&core_if->w_conn_id, w_conn_id_status_change, core_if);
3490+ INIT_WORK(&core_if->w_wkp, w_wakeup_detected, core_if);
3491+
3492+#else
3493+
3494+ INIT_WORK(&core_if->w_conn_id, w_conn_id_status_change);
3495+ INIT_DELAYED_WORK(&core_if->w_wkp, w_wakeup_detected);
3496+
3497+#endif
3498+ return core_if;
3499+}
3500+
3501+/**
3502+ * This function frees the structures allocated by dwc_otg_cil_init().
3503+ *
3504+ * @param[in] core_if The core interface pointer returned from
3505+ * dwc_otg_cil_init().
3506+ *
3507+ */
3508+void dwc_otg_cil_remove(dwc_otg_core_if_t *core_if)
3509+{
3510+ /* Disable all interrupts */
3511+ dwc_modify_reg32(&core_if->core_global_regs->gahbcfg, 1, 0);
3512+ dwc_write_reg32(&core_if->core_global_regs->gintmsk, 0);
3513+
3514+ if (core_if->wq_otg) {
3515+ destroy_workqueue(core_if->wq_otg);
3516+ }
3517+ if (core_if->dev_if) {
3518+ kfree(core_if->dev_if);
3519+ }
3520+ if (core_if->host_if) {
3521+ kfree(core_if->host_if);
3522+ }
3523+ kfree(core_if);
3524+}
3525+
3526+/**
3527+ * This function enables the controller's Global Interrupt in the AHB Config
3528+ * register.
3529+ *
3530+ * @param[in] core_if Programming view of DWC_otg controller.
3531+ */
3532+void dwc_otg_enable_global_interrupts(dwc_otg_core_if_t *core_if)
3533+{
3534+ gahbcfg_data_t ahbcfg = { .d32 = 0};
3535+ ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */
3536+ dwc_modify_reg32(&core_if->core_global_regs->gahbcfg, 0, ahbcfg.d32);
3537+}
3538+
3539+/**
3540+ * This function disables the controller's Global Interrupt in the AHB Config
3541+ * register.
3542+ *
3543+ * @param[in] core_if Programming view of DWC_otg controller.
3544+ */
3545+void dwc_otg_disable_global_interrupts(dwc_otg_core_if_t *core_if)
3546+{
3547+ gahbcfg_data_t ahbcfg = { .d32 = 0};
3548+ ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */
3549+ dwc_modify_reg32(&core_if->core_global_regs->gahbcfg, ahbcfg.d32, 0);
3550+}
3551+
3552+/**
3553+ * This function initializes the commmon interrupts, used in both
3554+ * device and host modes.
3555+ *
3556+ * @param[in] core_if Programming view of the DWC_otg controller
3557+ *
3558+ */
3559+static void dwc_otg_enable_common_interrupts(dwc_otg_core_if_t *core_if)
3560+{
3561+ dwc_otg_core_global_regs_t *global_regs =
3562+ core_if->core_global_regs;
3563+ gintmsk_data_t intr_mask = { .d32 = 0};
3564+
3565+ /* Clear any pending OTG Interrupts */
3566+ dwc_write_reg32(&global_regs->gotgint, 0xFFFFFFFF);
3567+
3568+ /* Clear any pending interrupts */
3569+ dwc_write_reg32(&global_regs->gintsts, 0xFFFFFFFF);
3570+
3571+ /*
3572+ * Enable the interrupts in the GINTMSK.
3573+ */
3574+ intr_mask.b.modemismatch = 1;
3575+ intr_mask.b.otgintr = 1;
3576+
3577+ if (!core_if->dma_enable) {
3578+ intr_mask.b.rxstsqlvl = 1;
3579+ }
3580+
3581+ intr_mask.b.conidstschng = 1;
3582+ intr_mask.b.wkupintr = 1;
3583+ intr_mask.b.disconnect = 1;
3584+ intr_mask.b.usbsuspend = 1;
3585+ intr_mask.b.sessreqintr = 1;
3586+ dwc_write_reg32(&global_regs->gintmsk, intr_mask.d32);
3587+}
3588+
3589+/**
3590+ * Initializes the FSLSPClkSel field of the HCFG register depending on the PHY
3591+ * type.
3592+ */
3593+static void init_fslspclksel(dwc_otg_core_if_t *core_if)
3594+{
3595+ uint32_t val;
3596+ hcfg_data_t hcfg;
3597+
3598+ if (((core_if->hwcfg2.b.hs_phy_type == 2) &&
3599+ (core_if->hwcfg2.b.fs_phy_type == 1) &&
3600+ (core_if->core_params->ulpi_fs_ls)) ||
3601+ (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
3602+ /* Full speed PHY */
3603+ val = DWC_HCFG_48_MHZ;
3604+ }
3605+ else {
3606+ /* High speed PHY running at full speed or high speed */
3607+ val = DWC_HCFG_30_60_MHZ;
3608+ }
3609+
3610+ DWC_DEBUGPL(DBG_CIL, "Initializing HCFG.FSLSPClkSel to 0x%1x\n", val);
3611+ hcfg.d32 = dwc_read_reg32(&core_if->host_if->host_global_regs->hcfg);
3612+ hcfg.b.fslspclksel = val;
3613+ dwc_write_reg32(&core_if->host_if->host_global_regs->hcfg, hcfg.d32);
3614+}
3615+
3616+/**
3617+ * Initializes the DevSpd field of the DCFG register depending on the PHY type
3618+ * and the enumeration speed of the device.
3619+ */
3620+static void init_devspd(dwc_otg_core_if_t *core_if)
3621+{
3622+ uint32_t val;
3623+ dcfg_data_t dcfg;
3624+
3625+ if (((core_if->hwcfg2.b.hs_phy_type == 2) &&
3626+ (core_if->hwcfg2.b.fs_phy_type == 1) &&
3627+ (core_if->core_params->ulpi_fs_ls)) ||
3628+ (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
3629+ /* Full speed PHY */
3630+ val = 0x3;
3631+ }
3632+ else if (core_if->core_params->speed == DWC_SPEED_PARAM_FULL) {
3633+ /* High speed PHY running at full speed */
3634+ val = 0x1;
3635+ }
3636+ else {
3637+ /* High speed PHY running at high speed */
3638+ val = 0x0;
3639+ }
3640+
3641+ DWC_DEBUGPL(DBG_CIL, "Initializing DCFG.DevSpd to 0x%1x\n", val);
3642+
3643+ dcfg.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dcfg);
3644+ dcfg.b.devspd = val;
3645+ dwc_write_reg32(&core_if->dev_if->dev_global_regs->dcfg, dcfg.d32);
3646+}
3647+
3648+/**
3649+ * This function calculates the number of IN EPS
3650+ * using GHWCFG1 and GHWCFG2 registers values
3651+ *
3652+ * @param core_if Programming view of the DWC_otg controller
3653+ */
3654+static uint32_t calc_num_in_eps(dwc_otg_core_if_t *core_if)
3655+{
3656+ uint32_t num_in_eps = 0;
3657+ uint32_t num_eps = core_if->hwcfg2.b.num_dev_ep;
3658+ uint32_t hwcfg1 = core_if->hwcfg1.d32 >> 3;
3659+ uint32_t num_tx_fifos = core_if->hwcfg4.b.num_in_eps;
3660+ int i;
3661+
3662+
3663+ for(i = 0; i < num_eps; ++i)
3664+ {
3665+ if(!(hwcfg1 & 0x1))
3666+ num_in_eps++;
3667+
3668+ hwcfg1 >>= 2;
3669+ }
3670+
3671+ if(core_if->hwcfg4.b.ded_fifo_en) {
3672+ num_in_eps = (num_in_eps > num_tx_fifos) ? num_tx_fifos : num_in_eps;
3673+ }
3674+
3675+ return num_in_eps;
3676+}
3677+
3678+
3679+/**
3680+ * This function calculates the number of OUT EPS
3681+ * using GHWCFG1 and GHWCFG2 registers values
3682+ *
3683+ * @param core_if Programming view of the DWC_otg controller
3684+ */
3685+static uint32_t calc_num_out_eps(dwc_otg_core_if_t *core_if)
3686+{
3687+ uint32_t num_out_eps = 0;
3688+ uint32_t num_eps = core_if->hwcfg2.b.num_dev_ep;
3689+ uint32_t hwcfg1 = core_if->hwcfg1.d32 >> 2;
3690+ int i;
3691+
3692+ for(i = 0; i < num_eps; ++i)
3693+ {
3694+ if(!(hwcfg1 & 0x2))
3695+ num_out_eps++;
3696+
3697+ hwcfg1 >>= 2;
3698+ }
3699+ return num_out_eps;
3700+}
3701+/**
3702+ * This function initializes the DWC_otg controller registers and
3703+ * prepares the core for device mode or host mode operation.
3704+ *
3705+ * @param core_if Programming view of the DWC_otg controller
3706+ *
3707+ */
3708+void dwc_otg_core_init(dwc_otg_core_if_t *core_if)
3709+{
3710+ int i = 0;
3711+ dwc_otg_core_global_regs_t *global_regs =
3712+ core_if->core_global_regs;
3713+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
3714+ gahbcfg_data_t ahbcfg = { .d32 = 0 };
3715+ gusbcfg_data_t usbcfg = { .d32 = 0 };
3716+ gi2cctl_data_t i2cctl = { .d32 = 0 };
3717+
3718+ DWC_DEBUGPL(DBG_CILV, "dwc_otg_core_init(%p)\n", core_if);
3719+
3720+ /* Common Initialization */
3721+
3722+ usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
3723+
3724+// usbcfg.b.tx_end_delay = 1;
3725+ /* Program the ULPI External VBUS bit if needed */
3726+ usbcfg.b.ulpi_ext_vbus_drv =
3727+ (core_if->core_params->phy_ulpi_ext_vbus == DWC_PHY_ULPI_EXTERNAL_VBUS) ? 1 : 0;
3728+
3729+ /* Set external TS Dline pulsing */
3730+ usbcfg.b.term_sel_dl_pulse = (core_if->core_params->ts_dline == 1) ? 1 : 0;
3731+ dwc_write_reg32 (&global_regs->gusbcfg, usbcfg.d32);
3732+
3733+
3734+ /* Reset the Controller */
3735+ dwc_otg_core_reset(core_if);
3736+
3737+ /* Initialize parameters from Hardware configuration registers. */
3738+ dev_if->num_in_eps = calc_num_in_eps(core_if);
3739+ dev_if->num_out_eps = calc_num_out_eps(core_if);
3740+
3741+
3742+ DWC_DEBUGPL(DBG_CIL, "num_dev_perio_in_ep=%d\n", core_if->hwcfg4.b.num_dev_perio_in_ep);
3743+
3744+ for (i=0; i < core_if->hwcfg4.b.num_dev_perio_in_ep; i++)
3745+ {
3746+ dev_if->perio_tx_fifo_size[i] =
3747+ dwc_read_reg32(&global_regs->dptxfsiz_dieptxf[i]) >> 16;
3748+ DWC_DEBUGPL(DBG_CIL, "Periodic Tx FIFO SZ #%d=0x%0x\n",
3749+ i, dev_if->perio_tx_fifo_size[i]);
3750+ }
3751+
3752+ for (i=0; i < core_if->hwcfg4.b.num_in_eps; i++)
3753+ {
3754+ dev_if->tx_fifo_size[i] =
3755+ dwc_read_reg32(&global_regs->dptxfsiz_dieptxf[i]) >> 16;
3756+ DWC_DEBUGPL(DBG_CIL, "Tx FIFO SZ #%d=0x%0x\n",
3757+ i, dev_if->perio_tx_fifo_size[i]);
3758+ }
3759+
3760+ core_if->total_fifo_size = core_if->hwcfg3.b.dfifo_depth;
3761+ core_if->rx_fifo_size =
3762+ dwc_read_reg32(&global_regs->grxfsiz);
3763+ core_if->nperio_tx_fifo_size =
3764+ dwc_read_reg32(&global_regs->gnptxfsiz) >> 16;
3765+
3766+ DWC_DEBUGPL(DBG_CIL, "Total FIFO SZ=%d\n", core_if->total_fifo_size);
3767+ DWC_DEBUGPL(DBG_CIL, "Rx FIFO SZ=%d\n", core_if->rx_fifo_size);
3768+ DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO SZ=%d\n", core_if->nperio_tx_fifo_size);
3769+
3770+ /* This programming sequence needs to happen in FS mode before any other
3771+ * programming occurs */
3772+ if ((core_if->core_params->speed == DWC_SPEED_PARAM_FULL) &&
3773+ (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
3774+ /* If FS mode with FS PHY */
3775+
3776+ /* core_init() is now called on every switch so only call the
3777+ * following for the first time through. */
3778+ if (!core_if->phy_init_done) {
3779+ core_if->phy_init_done = 1;
3780+ DWC_DEBUGPL(DBG_CIL, "FS_PHY detected\n");
3781+ usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
3782+ usbcfg.b.physel = 1;
3783+ dwc_write_reg32 (&global_regs->gusbcfg, usbcfg.d32);
3784+
3785+ /* Reset after a PHY select */
3786+ dwc_otg_core_reset(core_if);
3787+ }
3788+
3789+ /* Program DCFG.DevSpd or HCFG.FSLSPclkSel to 48Mhz in FS. Also
3790+ * do this on HNP Dev/Host mode switches (done in dev_init and
3791+ * host_init). */
3792+ if (dwc_otg_is_host_mode(core_if)) {
3793+ init_fslspclksel(core_if);
3794+ }
3795+ else {
3796+ init_devspd(core_if);
3797+ }
3798+
3799+ if (core_if->core_params->i2c_enable) {
3800+ DWC_DEBUGPL(DBG_CIL, "FS_PHY Enabling I2c\n");
3801+ /* Program GUSBCFG.OtgUtmifsSel to I2C */
3802+ usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
3803+ usbcfg.b.otgutmifssel = 1;
3804+ dwc_write_reg32 (&global_regs->gusbcfg, usbcfg.d32);
3805+
3806+ /* Program GI2CCTL.I2CEn */
3807+ i2cctl.d32 = dwc_read_reg32(&global_regs->gi2cctl);
3808+ i2cctl.b.i2cdevaddr = 1;
3809+ i2cctl.b.i2cen = 0;
3810+ dwc_write_reg32 (&global_regs->gi2cctl, i2cctl.d32);
3811+ i2cctl.b.i2cen = 1;
3812+ dwc_write_reg32 (&global_regs->gi2cctl, i2cctl.d32);
3813+ }
3814+
3815+ } /* endif speed == DWC_SPEED_PARAM_FULL */
3816+
3817+ else {
3818+ /* High speed PHY. */
3819+ if (!core_if->phy_init_done) {
3820+ core_if->phy_init_done = 1;
3821+ /* HS PHY parameters. These parameters are preserved
3822+ * during soft reset so only program the first time. Do
3823+ * a soft reset immediately after setting phyif. */
3824+ usbcfg.b.ulpi_utmi_sel = core_if->core_params->phy_type;
3825+ if (usbcfg.b.ulpi_utmi_sel == 1) {
3826+ /* ULPI interface */
3827+ usbcfg.b.phyif = 0;
3828+ usbcfg.b.ddrsel = core_if->core_params->phy_ulpi_ddr;
3829+ }
3830+ else {
3831+ /* UTMI+ interface */
3832+ if (core_if->core_params->phy_utmi_width == 16) {
3833+ usbcfg.b.phyif = 1;
3834+ }
3835+ else {
3836+ usbcfg.b.phyif = 0;
3837+ }
3838+ }
3839+
3840+ dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
3841+
3842+ /* Reset after setting the PHY parameters */
3843+ dwc_otg_core_reset(core_if);
3844+ }
3845+ }
3846+
3847+ if ((core_if->hwcfg2.b.hs_phy_type == 2) &&
3848+ (core_if->hwcfg2.b.fs_phy_type == 1) &&
3849+ (core_if->core_params->ulpi_fs_ls)) {
3850+ DWC_DEBUGPL(DBG_CIL, "Setting ULPI FSLS\n");
3851+ usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
3852+ usbcfg.b.ulpi_fsls = 1;
3853+ usbcfg.b.ulpi_clk_sus_m = 1;
3854+ dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
3855+ }
3856+ else {
3857+ usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
3858+ usbcfg.b.ulpi_fsls = 0;
3859+ usbcfg.b.ulpi_clk_sus_m = 0;
3860+ dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
3861+ }
3862+
3863+ /* Program the GAHBCFG Register.*/
3864+ switch (core_if->hwcfg2.b.architecture) {
3865+
3866+ case DWC_SLAVE_ONLY_ARCH:
3867+ DWC_DEBUGPL(DBG_CIL, "Slave Only Mode\n");
3868+ ahbcfg.b.nptxfemplvl_txfemplvl = DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
3869+ ahbcfg.b.ptxfemplvl = DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
3870+ core_if->dma_enable = 0;
3871+ core_if->dma_desc_enable = 0;
3872+ break;
3873+
3874+ case DWC_EXT_DMA_ARCH:
3875+ DWC_DEBUGPL(DBG_CIL, "External DMA Mode\n");
3876+ ahbcfg.b.hburstlen = core_if->core_params->dma_burst_size;
3877+ core_if->dma_enable = (core_if->core_params->dma_enable != 0);
3878+ core_if->dma_desc_enable = (core_if->core_params->dma_desc_enable != 0);
3879+ break;
3880+
3881+ case DWC_INT_DMA_ARCH:
3882+ DWC_DEBUGPL(DBG_CIL, "Internal DMA Mode\n");
3883+ ahbcfg.b.hburstlen = DWC_GAHBCFG_INT_DMA_BURST_INCR;
3884+ core_if->dma_enable = (core_if->core_params->dma_enable != 0);
3885+ core_if->dma_desc_enable = (core_if->core_params->dma_desc_enable != 0);
3886+ break;
3887+
3888+ }
3889+ ahbcfg.b.dmaenable = core_if->dma_enable;
3890+ dwc_write_reg32(&global_regs->gahbcfg, ahbcfg.d32);
3891+
3892+ core_if->en_multiple_tx_fifo = core_if->hwcfg4.b.ded_fifo_en;
3893+
3894+ core_if->pti_enh_enable = core_if->core_params->pti_enable != 0;
3895+ core_if->multiproc_int_enable = core_if->core_params->mpi_enable;
3896+ DWC_PRINT("Periodic Transfer Interrupt Enhancement - %s\n", ((core_if->pti_enh_enable) ? "enabled": "disabled"));
3897+ DWC_PRINT("Multiprocessor Interrupt Enhancement - %s\n", ((core_if->multiproc_int_enable) ? "enabled": "disabled"));
3898+
3899+ /*
3900+ * Program the GUSBCFG register.
3901+ */
3902+ usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
3903+
3904+ switch (core_if->hwcfg2.b.op_mode) {
3905+ case DWC_MODE_HNP_SRP_CAPABLE:
3906+ usbcfg.b.hnpcap = (core_if->core_params->otg_cap ==
3907+ DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE);
3908+ usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
3909+ DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
3910+ break;
3911+
3912+ case DWC_MODE_SRP_ONLY_CAPABLE:
3913+ usbcfg.b.hnpcap = 0;
3914+ usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
3915+ DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
3916+ break;
3917+
3918+ case DWC_MODE_NO_HNP_SRP_CAPABLE:
3919+ usbcfg.b.hnpcap = 0;
3920+ usbcfg.b.srpcap = 0;
3921+ break;
3922+
3923+ case DWC_MODE_SRP_CAPABLE_DEVICE:
3924+ usbcfg.b.hnpcap = 0;
3925+ usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
3926+ DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
3927+ break;
3928+
3929+ case DWC_MODE_NO_SRP_CAPABLE_DEVICE:
3930+ usbcfg.b.hnpcap = 0;
3931+ usbcfg.b.srpcap = 0;
3932+ break;
3933+
3934+ case DWC_MODE_SRP_CAPABLE_HOST:
3935+ usbcfg.b.hnpcap = 0;
3936+ usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
3937+ DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
3938+ break;
3939+
3940+ case DWC_MODE_NO_SRP_CAPABLE_HOST:
3941+ usbcfg.b.hnpcap = 0;
3942+ usbcfg.b.srpcap = 0;
3943+ break;
3944+ }
3945+
3946+ dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
3947+
3948+ /* Enable common interrupts */
3949+ dwc_otg_enable_common_interrupts(core_if);
3950+
3951+ /* Do device or host intialization based on mode during PCD
3952+ * and HCD initialization */
3953+ if (dwc_otg_is_host_mode(core_if)) {
3954+ DWC_DEBUGPL(DBG_ANY, "Host Mode\n");
3955+ core_if->op_state = A_HOST;
3956+ }
3957+ else {
3958+ DWC_DEBUGPL(DBG_ANY, "Device Mode\n");
3959+ core_if->op_state = B_PERIPHERAL;
3960+#ifdef DWC_DEVICE_ONLY
3961+ dwc_otg_core_dev_init(core_if);
3962+#endif
3963+ }
3964+}
3965+
3966+
3967+/**
3968+ * This function enables the Device mode interrupts.
3969+ *
3970+ * @param core_if Programming view of DWC_otg controller
3971+ */
3972+void dwc_otg_enable_device_interrupts(dwc_otg_core_if_t *core_if)
3973+{
3974+ gintmsk_data_t intr_mask = { .d32 = 0};
3975+ dwc_otg_core_global_regs_t *global_regs =
3976+ core_if->core_global_regs;
3977+
3978+ DWC_DEBUGPL(DBG_CIL, "%s()\n", __func__);
3979+
3980+ /* Disable all interrupts. */
3981+ dwc_write_reg32(&global_regs->gintmsk, 0);
3982+
3983+ /* Clear any pending interrupts */
3984+ dwc_write_reg32(&global_regs->gintsts, 0xFFFFFFFF);
3985+
3986+ /* Enable the common interrupts */
3987+ dwc_otg_enable_common_interrupts(core_if);
3988+
3989+ /* Enable interrupts */
3990+ intr_mask.b.usbreset = 1;
3991+ intr_mask.b.enumdone = 1;
3992+
3993+ if(!core_if->multiproc_int_enable) {
3994+ intr_mask.b.inepintr = 1;
3995+ intr_mask.b.outepintr = 1;
3996+ }
3997+
3998+ intr_mask.b.erlysuspend = 1;
3999+
4000+ if(core_if->en_multiple_tx_fifo == 0) {
4001+ intr_mask.b.epmismatch = 1;
4002+ }
4003+
4004+
4005+#ifdef DWC_EN_ISOC
4006+ if(core_if->dma_enable) {
4007+ if(core_if->dma_desc_enable == 0) {
4008+ if(core_if->pti_enh_enable) {
4009+ dctl_data_t dctl = { .d32 = 0 };
4010+ dctl.b.ifrmnum = 1;
4011+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->dctl, 0, dctl.d32);
4012+ } else {
4013+ intr_mask.b.incomplisoin = 1;
4014+ intr_mask.b.incomplisoout = 1;
4015+ }
4016+ }
4017+ } else {
4018+ intr_mask.b.incomplisoin = 1;
4019+ intr_mask.b.incomplisoout = 1;
4020+ }
4021+#endif // DWC_EN_ISOC
4022+
4023+/** @todo NGS: Should this be a module parameter? */
4024+#ifdef USE_PERIODIC_EP
4025+ intr_mask.b.isooutdrop = 1;
4026+ intr_mask.b.eopframe = 1;
4027+ intr_mask.b.incomplisoin = 1;
4028+ intr_mask.b.incomplisoout = 1;
4029+#endif
4030+
4031+ dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
4032+
4033+ DWC_DEBUGPL(DBG_CIL, "%s() gintmsk=%0x\n", __func__,
4034+ dwc_read_reg32(&global_regs->gintmsk));
4035+}
4036+
4037+/**
4038+ * This function initializes the DWC_otg controller registers for
4039+ * device mode.
4040+ *
4041+ * @param core_if Programming view of DWC_otg controller
4042+ *
4043+ */
4044+void dwc_otg_core_dev_init(dwc_otg_core_if_t *core_if)
4045+{
4046+ int i,size;
4047+ u_int32_t *default_value_array;
4048+
4049+ dwc_otg_core_global_regs_t *global_regs =
4050+ core_if->core_global_regs;
4051+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
4052+ dwc_otg_core_params_t *params = core_if->core_params;
4053+ dcfg_data_t dcfg = { .d32 = 0};
4054+ grstctl_t resetctl = { .d32 = 0 };
4055+ uint32_t rx_fifo_size;
4056+ fifosize_data_t nptxfifosize;
4057+ fifosize_data_t txfifosize;
4058+ dthrctl_data_t dthrctl;
4059+
4060+ /* Restart the Phy Clock */
4061+ dwc_write_reg32(core_if->pcgcctl, 0);
4062+
4063+ /* Device configuration register */
4064+ init_devspd(core_if);
4065+ dcfg.d32 = dwc_read_reg32(&dev_if->dev_global_regs->dcfg);
4066+ dcfg.b.descdma = (core_if->dma_desc_enable) ? 1 : 0;
4067+ dcfg.b.perfrint = DWC_DCFG_FRAME_INTERVAL_80;
4068+
4069+ dwc_write_reg32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
4070+
4071+ /* Configure data FIFO sizes */
4072+ if (core_if->hwcfg2.b.dynamic_fifo && params->enable_dynamic_fifo) {
4073+ DWC_DEBUGPL(DBG_CIL, "Total FIFO Size=%d\n", core_if->total_fifo_size);
4074+ DWC_DEBUGPL(DBG_CIL, "Rx FIFO Size=%d\n", params->dev_rx_fifo_size);
4075+ DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO Size=%d\n", params->dev_nperio_tx_fifo_size);
4076+
4077+ /* Rx FIFO */
4078+ DWC_DEBUGPL(DBG_CIL, "initial grxfsiz=%08x\n",
4079+ dwc_read_reg32(&global_regs->grxfsiz));
4080+
4081+ rx_fifo_size = params->dev_rx_fifo_size;
4082+ dwc_write_reg32(&global_regs->grxfsiz, rx_fifo_size);
4083+
4084+ DWC_DEBUGPL(DBG_CIL, "new grxfsiz=%08x\n",
4085+ dwc_read_reg32(&global_regs->grxfsiz));
4086+
4087+ /** Set Periodic Tx FIFO Mask all bits 0 */
4088+ core_if->p_tx_msk = 0;
4089+
4090+ /** Set Tx FIFO Mask all bits 0 */
4091+ core_if->tx_msk = 0;
4092+
4093+ /* Non-periodic Tx FIFO */
4094+ DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n",
4095+ dwc_read_reg32(&global_regs->gnptxfsiz));
4096+
4097+ nptxfifosize.b.depth = params->dev_nperio_tx_fifo_size;
4098+ nptxfifosize.b.startaddr = params->dev_rx_fifo_size;
4099+
4100+ dwc_write_reg32(&global_regs->gnptxfsiz, nptxfifosize.d32);
4101+
4102+ DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",
4103+ dwc_read_reg32(&global_regs->gnptxfsiz));
4104+
4105+ txfifosize.b.startaddr = nptxfifosize.b.startaddr + nptxfifosize.b.depth;
4106+ if(core_if->en_multiple_tx_fifo == 0) {
4107+ //core_if->hwcfg4.b.ded_fifo_en==0
4108+
4109+ /**@todo NGS: Fix Periodic FIFO Sizing! */
4110+ /*
4111+ * Periodic Tx FIFOs These FIFOs are numbered from 1 to 15.
4112+ * Indexes of the FIFO size module parameters in the
4113+ * dev_perio_tx_fifo_size array and the FIFO size registers in
4114+ * the dptxfsiz array run from 0 to 14.
4115+ */
4116+ /** @todo Finish debug of this */
4117+ size=core_if->hwcfg4.b.num_dev_perio_in_ep;
4118+ default_value_array=params->dev_perio_tx_fifo_size;
4119+
4120+ }
4121+ else {
4122+ //core_if->hwcfg4.b.ded_fifo_en==1
4123+ /*
4124+ * Tx FIFOs These FIFOs are numbered from 1 to 15.
4125+ * Indexes of the FIFO size module parameters in the
4126+ * dev_tx_fifo_size array and the FIFO size registers in
4127+ * the dptxfsiz_dieptxf array run from 0 to 14.
4128+ */
4129+
4130+ size=core_if->hwcfg4.b.num_in_eps;
4131+ default_value_array=params->dev_tx_fifo_size;
4132+
4133+ }
4134+ for (i=0; i < size; i++)
4135+ {
4136+
4137+ txfifosize.b.depth = default_value_array[i];
4138+ DWC_DEBUGPL(DBG_CIL, "initial dptxfsiz_dieptxf[%d]=%08x\n", i,
4139+ dwc_read_reg32(&global_regs->dptxfsiz_dieptxf[i]));
4140+ dwc_write_reg32(&global_regs->dptxfsiz_dieptxf[i],
4141+ txfifosize.d32);
4142+ DWC_DEBUGPL(DBG_CIL, "new dptxfsiz_dieptxf[%d]=%08x\n", i,
4143+ dwc_read_reg32(&global_regs->dptxfsiz_dieptxf[i]));
4144+ txfifosize.b.startaddr += txfifosize.b.depth;
4145+ }
4146+ }
4147+ /* Flush the FIFOs */
4148+ dwc_otg_flush_tx_fifo(core_if, 0x10); /* all Tx FIFOs */
4149+ dwc_otg_flush_rx_fifo(core_if);
4150+
4151+ /* Flush the Learning Queue. */
4152+ resetctl.b.intknqflsh = 1;
4153+ dwc_write_reg32(&core_if->core_global_regs->grstctl, resetctl.d32);
4154+
4155+ /* Clear all pending Device Interrupts */
4156+
4157+ if(core_if->multiproc_int_enable) {
4158+ }
4159+
4160+ /** @todo - if the condition needed to be checked
4161+ * or in any case all pending interrutps should be cleared?
4162+ */
4163+ if(core_if->multiproc_int_enable) {
4164+ for(i = 0; i < core_if->dev_if->num_in_eps; ++i) {
4165+ dwc_write_reg32(&dev_if->dev_global_regs->diepeachintmsk[i], 0);
4166+ }
4167+
4168+ for(i = 0; i < core_if->dev_if->num_out_eps; ++i) {
4169+ dwc_write_reg32(&dev_if->dev_global_regs->doepeachintmsk[i], 0);
4170+ }
4171+
4172+ dwc_write_reg32(&dev_if->dev_global_regs->deachint, 0xFFFFFFFF);
4173+ dwc_write_reg32(&dev_if->dev_global_regs->deachintmsk, 0);
4174+ } else {
4175+ dwc_write_reg32(&dev_if->dev_global_regs->diepmsk, 0);
4176+ dwc_write_reg32(&dev_if->dev_global_regs->doepmsk, 0);
4177+ dwc_write_reg32(&dev_if->dev_global_regs->daint, 0xFFFFFFFF);
4178+ dwc_write_reg32(&dev_if->dev_global_regs->daintmsk, 0);
4179+ }
4180+
4181+ for (i=0; i <= dev_if->num_in_eps; i++)
4182+ {
4183+ depctl_data_t depctl;
4184+ depctl.d32 = dwc_read_reg32(&dev_if->in_ep_regs[i]->diepctl);
4185+ if (depctl.b.epena) {
4186+ depctl.d32 = 0;
4187+ depctl.b.epdis = 1;
4188+ depctl.b.snak = 1;
4189+ }
4190+ else {
4191+ depctl.d32 = 0;
4192+ }
4193+
4194+ dwc_write_reg32(&dev_if->in_ep_regs[i]->diepctl, depctl.d32);
4195+
4196+
4197+ dwc_write_reg32(&dev_if->in_ep_regs[i]->dieptsiz, 0);
4198+ dwc_write_reg32(&dev_if->in_ep_regs[i]->diepdma, 0);
4199+ dwc_write_reg32(&dev_if->in_ep_regs[i]->diepint, 0xFF);
4200+ }
4201+
4202+ for (i=0; i <= dev_if->num_out_eps; i++)
4203+ {
4204+ depctl_data_t depctl;
4205+ depctl.d32 = dwc_read_reg32(&dev_if->out_ep_regs[i]->doepctl);
4206+ if (depctl.b.epena) {
4207+ depctl.d32 = 0;
4208+ depctl.b.epdis = 1;
4209+ depctl.b.snak = 1;
4210+ }
4211+ else {
4212+ depctl.d32 = 0;
4213+ }
4214+
4215+ dwc_write_reg32(&dev_if->out_ep_regs[i]->doepctl, depctl.d32);
4216+
4217+ dwc_write_reg32(&dev_if->out_ep_regs[i]->doeptsiz, 0);
4218+ dwc_write_reg32(&dev_if->out_ep_regs[i]->doepdma, 0);
4219+ dwc_write_reg32(&dev_if->out_ep_regs[i]->doepint, 0xFF);
4220+ }
4221+
4222+ if(core_if->en_multiple_tx_fifo && core_if->dma_enable) {
4223+ dev_if->non_iso_tx_thr_en = params->thr_ctl & 0x1;
4224+ dev_if->iso_tx_thr_en = (params->thr_ctl >> 1) & 0x1;
4225+ dev_if->rx_thr_en = (params->thr_ctl >> 2) & 0x1;
4226+
4227+ dev_if->rx_thr_length = params->rx_thr_length;
4228+ dev_if->tx_thr_length = params->tx_thr_length;
4229+
4230+ dev_if->setup_desc_index = 0;
4231+
4232+ dthrctl.d32 = 0;
4233+ dthrctl.b.non_iso_thr_en = dev_if->non_iso_tx_thr_en;
4234+ dthrctl.b.iso_thr_en = dev_if->iso_tx_thr_en;
4235+ dthrctl.b.tx_thr_len = dev_if->tx_thr_length;
4236+ dthrctl.b.rx_thr_en = dev_if->rx_thr_en;
4237+ dthrctl.b.rx_thr_len = dev_if->rx_thr_length;
4238+
4239+ dwc_write_reg32(&dev_if->dev_global_regs->dtknqr3_dthrctl, dthrctl.d32);
4240+
4241+ 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",
4242+ 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);
4243+
4244+ }
4245+
4246+ dwc_otg_enable_device_interrupts(core_if);
4247+
4248+ {
4249+ diepmsk_data_t msk = { .d32 = 0 };
4250+ msk.b.txfifoundrn = 1;
4251+ if(core_if->multiproc_int_enable) {
4252+ dwc_modify_reg32(&dev_if->dev_global_regs->diepeachintmsk[0], msk.d32, msk.d32);
4253+ } else {
4254+ dwc_modify_reg32(&dev_if->dev_global_regs->diepmsk, msk.d32, msk.d32);
4255+ }
4256+ }
4257+
4258+
4259+ if(core_if->multiproc_int_enable) {
4260+ /* Set NAK on Babble */
4261+ dctl_data_t dctl = { .d32 = 0};
4262+ dctl.b.nakonbble = 1;
4263+ dwc_modify_reg32(&dev_if->dev_global_regs->dctl, 0, dctl.d32);
4264+ }
4265+}
4266+
4267+/**
4268+ * This function enables the Host mode interrupts.
4269+ *
4270+ * @param core_if Programming view of DWC_otg controller
4271+ */
4272+void dwc_otg_enable_host_interrupts(dwc_otg_core_if_t *core_if)
4273+{
4274+ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
4275+ gintmsk_data_t intr_mask = { .d32 = 0 };
4276+
4277+ DWC_DEBUGPL(DBG_CIL, "%s()\n", __func__);
4278+
4279+ /* Disable all interrupts. */
4280+ dwc_write_reg32(&global_regs->gintmsk, 0);
4281+
4282+ /* Clear any pending interrupts. */
4283+ dwc_write_reg32(&global_regs->gintsts, 0xFFFFFFFF);
4284+
4285+ /* Enable the common interrupts */
4286+ dwc_otg_enable_common_interrupts(core_if);
4287+
4288+ /*
4289+ * Enable host mode interrupts without disturbing common
4290+ * interrupts.
4291+ */
4292+ intr_mask.b.sofintr = 1;
4293+ intr_mask.b.portintr = 1;
4294+ intr_mask.b.hcintr = 1;
4295+
4296+ dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
4297+}
4298+
4299+/**
4300+ * This function disables the Host Mode interrupts.
4301+ *
4302+ * @param core_if Programming view of DWC_otg controller
4303+ */
4304+void dwc_otg_disable_host_interrupts(dwc_otg_core_if_t *core_if)
4305+{
4306+ dwc_otg_core_global_regs_t *global_regs =
4307+ core_if->core_global_regs;
4308+ gintmsk_data_t intr_mask = { .d32 = 0 };
4309+
4310+ DWC_DEBUGPL(DBG_CILV, "%s()\n", __func__);
4311+
4312+ /*
4313+ * Disable host mode interrupts without disturbing common
4314+ * interrupts.
4315+ */
4316+ intr_mask.b.sofintr = 1;
4317+ intr_mask.b.portintr = 1;
4318+ intr_mask.b.hcintr = 1;
4319+ intr_mask.b.ptxfempty = 1;
4320+ intr_mask.b.nptxfempty = 1;
4321+
4322+ dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, 0);
4323+}
4324+
4325+/**
4326+ * This function initializes the DWC_otg controller registers for
4327+ * host mode.
4328+ *
4329+ * This function flushes the Tx and Rx FIFOs and it flushes any entries in the
4330+ * request queues. Host channels are reset to ensure that they are ready for
4331+ * performing transfers.
4332+ *
4333+ * @param core_if Programming view of DWC_otg controller
4334+ *
4335+ */
4336+void dwc_otg_core_host_init(dwc_otg_core_if_t *core_if)
4337+{
4338+ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
4339+ dwc_otg_host_if_t *host_if = core_if->host_if;
4340+ dwc_otg_core_params_t *params = core_if->core_params;
4341+ hprt0_data_t hprt0 = { .d32 = 0 };
4342+ fifosize_data_t nptxfifosize;
4343+ fifosize_data_t ptxfifosize;
4344+ int i;
4345+ hcchar_data_t hcchar;
4346+ hcfg_data_t hcfg;
4347+ dwc_otg_hc_regs_t *hc_regs;
4348+ int num_channels;
4349+ gotgctl_data_t gotgctl = { .d32 = 0 };
4350+
4351+ DWC_DEBUGPL(DBG_CILV,"%s(%p)\n", __func__, core_if);
4352+
4353+ /* Restart the Phy Clock */
4354+ dwc_write_reg32(core_if->pcgcctl, 0);
4355+
4356+ /* Initialize Host Configuration Register */
4357+ init_fslspclksel(core_if);
4358+ if (core_if->core_params->speed == DWC_SPEED_PARAM_FULL)
4359+ {
4360+ hcfg.d32 = dwc_read_reg32(&host_if->host_global_regs->hcfg);
4361+ hcfg.b.fslssupp = 1;
4362+ dwc_write_reg32(&host_if->host_global_regs->hcfg, hcfg.d32);
4363+ }
4364+
4365+ /* Configure data FIFO sizes */
4366+ if (core_if->hwcfg2.b.dynamic_fifo && params->enable_dynamic_fifo) {
4367+ DWC_DEBUGPL(DBG_CIL,"Total FIFO Size=%d\n", core_if->total_fifo_size);
4368+ DWC_DEBUGPL(DBG_CIL,"Rx FIFO Size=%d\n", params->host_rx_fifo_size);
4369+ DWC_DEBUGPL(DBG_CIL,"NP Tx FIFO Size=%d\n", params->host_nperio_tx_fifo_size);
4370+ DWC_DEBUGPL(DBG_CIL,"P Tx FIFO Size=%d\n", params->host_perio_tx_fifo_size);
4371+
4372+ /* Rx FIFO */
4373+ DWC_DEBUGPL(DBG_CIL,"initial grxfsiz=%08x\n", dwc_read_reg32(&global_regs->grxfsiz));
4374+ dwc_write_reg32(&global_regs->grxfsiz, params->host_rx_fifo_size);
4375+ DWC_DEBUGPL(DBG_CIL,"new grxfsiz=%08x\n", dwc_read_reg32(&global_regs->grxfsiz));
4376+
4377+ /* Non-periodic Tx FIFO */
4378+ DWC_DEBUGPL(DBG_CIL,"initial gnptxfsiz=%08x\n", dwc_read_reg32(&global_regs->gnptxfsiz));
4379+ nptxfifosize.b.depth = params->host_nperio_tx_fifo_size;
4380+ nptxfifosize.b.startaddr = params->host_rx_fifo_size;
4381+ dwc_write_reg32(&global_regs->gnptxfsiz, nptxfifosize.d32);
4382+ DWC_DEBUGPL(DBG_CIL,"new gnptxfsiz=%08x\n", dwc_read_reg32(&global_regs->gnptxfsiz));
4383+
4384+ /* Periodic Tx FIFO */
4385+ DWC_DEBUGPL(DBG_CIL,"initial hptxfsiz=%08x\n", dwc_read_reg32(&global_regs->hptxfsiz));
4386+ ptxfifosize.b.depth = params->host_perio_tx_fifo_size;
4387+ ptxfifosize.b.startaddr = nptxfifosize.b.startaddr + nptxfifosize.b.depth;
4388+ dwc_write_reg32(&global_regs->hptxfsiz, ptxfifosize.d32);
4389+ DWC_DEBUGPL(DBG_CIL,"new hptxfsiz=%08x\n", dwc_read_reg32(&global_regs->hptxfsiz));
4390+ }
4391+
4392+ /* Clear Host Set HNP Enable in the OTG Control Register */
4393+ gotgctl.b.hstsethnpen = 1;
4394+ dwc_modify_reg32(&global_regs->gotgctl, gotgctl.d32, 0);
4395+
4396+ /* Make sure the FIFOs are flushed. */
4397+ dwc_otg_flush_tx_fifo(core_if, 0x10 /* all Tx FIFOs */);
4398+ dwc_otg_flush_rx_fifo(core_if);
4399+
4400+ /* Flush out any leftover queued requests. */
4401+ num_channels = core_if->core_params->host_channels;
4402+ for (i = 0; i < num_channels; i++)
4403+ {
4404+ hc_regs = core_if->host_if->hc_regs[i];
4405+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
4406+ hcchar.b.chen = 0;
4407+ hcchar.b.chdis = 1;
4408+ hcchar.b.epdir = 0;
4409+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
4410+ }
4411+
4412+ /* Halt all channels to put them into a known state. */
4413+ for (i = 0; i < num_channels; i++)
4414+ {
4415+ int count = 0;
4416+ hc_regs = core_if->host_if->hc_regs[i];
4417+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
4418+ hcchar.b.chen = 1;
4419+ hcchar.b.chdis = 1;
4420+ hcchar.b.epdir = 0;
4421+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
4422+ DWC_DEBUGPL(DBG_HCDV, "%s: Halt channel %d\n", __func__, i);
4423+ do {
4424+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
4425+ if (++count > 1000)
4426+ {
4427+ DWC_ERROR("%s: Unable to clear halt on channel %d\n",
4428+ __func__, i);
4429+ break;
4430+ }
4431+ }
4432+ while (hcchar.b.chen);
4433+ }
4434+
4435+ /* Turn on the vbus power. */
4436+ DWC_PRINT("Init: Port Power? op_state=%d\n", core_if->op_state);
4437+ if (core_if->op_state == A_HOST) {
4438+ hprt0.d32 = dwc_otg_read_hprt0(core_if);
4439+ DWC_PRINT("Init: Power Port (%d)\n", hprt0.b.prtpwr);
4440+ if (hprt0.b.prtpwr == 0) {
4441+ hprt0.b.prtpwr = 1;
4442+ dwc_write_reg32(host_if->hprt0, hprt0.d32);
4443+ }
4444+ }
4445+
4446+ dwc_otg_enable_host_interrupts(core_if);
4447+}
4448+
4449+/**
4450+ * Prepares a host channel for transferring packets to/from a specific
4451+ * endpoint. The HCCHARn register is set up with the characteristics specified
4452+ * in _hc. Host channel interrupts that may need to be serviced while this
4453+ * transfer is in progress are enabled.
4454+ *
4455+ * @param core_if Programming view of DWC_otg controller
4456+ * @param hc Information needed to initialize the host channel
4457+ */
4458+void dwc_otg_hc_init(dwc_otg_core_if_t *core_if, dwc_hc_t *hc)
4459+{
4460+ uint32_t intr_enable;
4461+ hcintmsk_data_t hc_intr_mask;
4462+ gintmsk_data_t gintmsk = { .d32 = 0 };
4463+ hcchar_data_t hcchar;
4464+ hcsplt_data_t hcsplt;
4465+
4466+ uint8_t hc_num = hc->hc_num;
4467+ dwc_otg_host_if_t *host_if = core_if->host_if;
4468+ dwc_otg_hc_regs_t *hc_regs = host_if->hc_regs[hc_num];
4469+
4470+ /* Clear old interrupt conditions for this host channel. */
4471+ hc_intr_mask.d32 = 0xFFFFFFFF;
4472+ hc_intr_mask.b.reserved = 0;
4473+ dwc_write_reg32(&hc_regs->hcint, hc_intr_mask.d32);
4474+
4475+ /* Enable channel interrupts required for this transfer. */
4476+ hc_intr_mask.d32 = 0;
4477+ hc_intr_mask.b.chhltd = 1;
4478+ if (core_if->dma_enable) {
4479+ hc_intr_mask.b.ahberr = 1;
4480+ if (hc->error_state && !hc->do_split &&
4481+ hc->ep_type != DWC_OTG_EP_TYPE_ISOC) {
4482+ hc_intr_mask.b.ack = 1;
4483+ if (hc->ep_is_in) {
4484+ hc_intr_mask.b.datatglerr = 1;
4485+ if (hc->ep_type != DWC_OTG_EP_TYPE_INTR) {
4486+ hc_intr_mask.b.nak = 1;
4487+ }
4488+ }
4489+ }
4490+ }
4491+ else {
4492+ switch (hc->ep_type) {
4493+ case DWC_OTG_EP_TYPE_CONTROL:
4494+ case DWC_OTG_EP_TYPE_BULK:
4495+ hc_intr_mask.b.xfercompl = 1;
4496+ hc_intr_mask.b.stall = 1;
4497+ hc_intr_mask.b.xacterr = 1;
4498+ hc_intr_mask.b.datatglerr = 1;
4499+ if (hc->ep_is_in) {
4500+ hc_intr_mask.b.bblerr = 1;
4501+ }
4502+ else {
4503+ hc_intr_mask.b.nak = 1;
4504+ hc_intr_mask.b.nyet = 1;
4505+ if (hc->do_ping) {
4506+ hc_intr_mask.b.ack = 1;
4507+ }
4508+ }
4509+
4510+ if (hc->do_split) {
4511+ hc_intr_mask.b.nak = 1;
4512+ if (hc->complete_split) {
4513+ hc_intr_mask.b.nyet = 1;
4514+ }
4515+ else {
4516+ hc_intr_mask.b.ack = 1;
4517+ }
4518+ }
4519+
4520+ if (hc->error_state) {
4521+ hc_intr_mask.b.ack = 1;
4522+ }
4523+ break;
4524+ case DWC_OTG_EP_TYPE_INTR:
4525+ hc_intr_mask.b.xfercompl = 1;
4526+ hc_intr_mask.b.nak = 1;
4527+ hc_intr_mask.b.stall = 1;
4528+ hc_intr_mask.b.xacterr = 1;
4529+ hc_intr_mask.b.datatglerr = 1;
4530+ hc_intr_mask.b.frmovrun = 1;
4531+
4532+ if (hc->ep_is_in) {
4533+ hc_intr_mask.b.bblerr = 1;
4534+ }
4535+ if (hc->error_state) {
4536+ hc_intr_mask.b.ack = 1;
4537+ }
4538+ if (hc->do_split) {
4539+ if (hc->complete_split) {
4540+ hc_intr_mask.b.nyet = 1;
4541+ }
4542+ else {
4543+ hc_intr_mask.b.ack = 1;
4544+ }
4545+ }
4546+ break;
4547+ case DWC_OTG_EP_TYPE_ISOC:
4548+ hc_intr_mask.b.xfercompl = 1;
4549+ hc_intr_mask.b.frmovrun = 1;
4550+ hc_intr_mask.b.ack = 1;
4551+
4552+ if (hc->ep_is_in) {
4553+ hc_intr_mask.b.xacterr = 1;
4554+ hc_intr_mask.b.bblerr = 1;
4555+ }
4556+ break;
4557+ }
4558+ }
4559+ dwc_write_reg32(&hc_regs->hcintmsk, hc_intr_mask.d32);
4560+
4561+// if(hc->ep_type == DWC_OTG_EP_TYPE_BULK && !hc->ep_is_in)
4562+// hc->max_packet = 512;
4563+ /* Enable the top level host channel interrupt. */
4564+ intr_enable = (1 << hc_num);
4565+ dwc_modify_reg32(&host_if->host_global_regs->haintmsk, 0, intr_enable);
4566+
4567+ /* Make sure host channel interrupts are enabled. */
4568+ gintmsk.b.hcintr = 1;
4569+ dwc_modify_reg32(&core_if->core_global_regs->gintmsk, 0, gintmsk.d32);
4570+
4571+ /*
4572+ * Program the HCCHARn register with the endpoint characteristics for
4573+ * the current transfer.
4574+ */
4575+ hcchar.d32 = 0;
4576+ hcchar.b.devaddr = hc->dev_addr;
4577+ hcchar.b.epnum = hc->ep_num;
4578+ hcchar.b.epdir = hc->ep_is_in;
4579+ hcchar.b.lspddev = (hc->speed == DWC_OTG_EP_SPEED_LOW);
4580+ hcchar.b.eptype = hc->ep_type;
4581+ hcchar.b.mps = hc->max_packet;
4582+
4583+ dwc_write_reg32(&host_if->hc_regs[hc_num]->hcchar, hcchar.d32);
4584+
4585+ DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
4586+ DWC_DEBUGPL(DBG_HCDV, " Dev Addr: %d\n", hcchar.b.devaddr);
4587+ DWC_DEBUGPL(DBG_HCDV, " Ep Num: %d\n", hcchar.b.epnum);
4588+ DWC_DEBUGPL(DBG_HCDV, " Is In: %d\n", hcchar.b.epdir);
4589+ DWC_DEBUGPL(DBG_HCDV, " Is Low Speed: %d\n", hcchar.b.lspddev);
4590+ DWC_DEBUGPL(DBG_HCDV, " Ep Type: %d\n", hcchar.b.eptype);
4591+ DWC_DEBUGPL(DBG_HCDV, " Max Pkt: %d\n", hcchar.b.mps);
4592+ DWC_DEBUGPL(DBG_HCDV, " Multi Cnt: %d\n", hcchar.b.multicnt);
4593+
4594+ /*
4595+ * Program the HCSPLIT register for SPLITs
4596+ */
4597+ hcsplt.d32 = 0;
4598+ if (hc->do_split) {
4599+ DWC_DEBUGPL(DBG_HCDV, "Programming HC %d with split --> %s\n", hc->hc_num,
4600+ hc->complete_split ? "CSPLIT" : "SSPLIT");
4601+ hcsplt.b.compsplt = hc->complete_split;
4602+ hcsplt.b.xactpos = hc->xact_pos;
4603+ hcsplt.b.hubaddr = hc->hub_addr;
4604+ hcsplt.b.prtaddr = hc->port_addr;
4605+ DWC_DEBUGPL(DBG_HCDV, " comp split %d\n", hc->complete_split);
4606+ DWC_DEBUGPL(DBG_HCDV, " xact pos %d\n", hc->xact_pos);
4607+ DWC_DEBUGPL(DBG_HCDV, " hub addr %d\n", hc->hub_addr);
4608+ DWC_DEBUGPL(DBG_HCDV, " port addr %d\n", hc->port_addr);
4609+ DWC_DEBUGPL(DBG_HCDV, " is_in %d\n", hc->ep_is_in);
4610+ DWC_DEBUGPL(DBG_HCDV, " Max Pkt: %d\n", hcchar.b.mps);
4611+ DWC_DEBUGPL(DBG_HCDV, " xferlen: %d\n", hc->xfer_len);
4612+ }
4613+ dwc_write_reg32(&host_if->hc_regs[hc_num]->hcsplt, hcsplt.d32);
4614+
4615+}
4616+
4617+/**
4618+ * Attempts to halt a host channel. This function should only be called in
4619+ * Slave mode or to abort a transfer in either Slave mode or DMA mode. Under
4620+ * normal circumstances in DMA mode, the controller halts the channel when the
4621+ * transfer is complete or a condition occurs that requires application
4622+ * intervention.
4623+ *
4624+ * In slave mode, checks for a free request queue entry, then sets the Channel
4625+ * Enable and Channel Disable bits of the Host Channel Characteristics
4626+ * register of the specified channel to intiate the halt. If there is no free
4627+ * request queue entry, sets only the Channel Disable bit of the HCCHARn
4628+ * register to flush requests for this channel. In the latter case, sets a
4629+ * flag to indicate that the host channel needs to be halted when a request
4630+ * queue slot is open.
4631+ *
4632+ * In DMA mode, always sets the Channel Enable and Channel Disable bits of the
4633+ * HCCHARn register. The controller ensures there is space in the request
4634+ * queue before submitting the halt request.
4635+ *
4636+ * Some time may elapse before the core flushes any posted requests for this
4637+ * host channel and halts. The Channel Halted interrupt handler completes the
4638+ * deactivation of the host channel.
4639+ *
4640+ * @param core_if Controller register interface.
4641+ * @param hc Host channel to halt.
4642+ * @param halt_status Reason for halting the channel.
4643+ */
4644+void dwc_otg_hc_halt(dwc_otg_core_if_t *core_if,
4645+ dwc_hc_t *hc,
4646+ dwc_otg_halt_status_e halt_status)
4647+{
4648+ gnptxsts_data_t nptxsts;
4649+ hptxsts_data_t hptxsts;
4650+ hcchar_data_t hcchar;
4651+ dwc_otg_hc_regs_t *hc_regs;
4652+ dwc_otg_core_global_regs_t *global_regs;
4653+ dwc_otg_host_global_regs_t *host_global_regs;
4654+
4655+ hc_regs = core_if->host_if->hc_regs[hc->hc_num];
4656+ global_regs = core_if->core_global_regs;
4657+ host_global_regs = core_if->host_if->host_global_regs;
4658+
4659+ WARN_ON(halt_status == DWC_OTG_HC_XFER_NO_HALT_STATUS);
4660+
4661+ if (halt_status == DWC_OTG_HC_XFER_URB_DEQUEUE ||
4662+ halt_status == DWC_OTG_HC_XFER_AHB_ERR) {
4663+ /*
4664+ * Disable all channel interrupts except Ch Halted. The QTD
4665+ * and QH state associated with this transfer has been cleared
4666+ * (in the case of URB_DEQUEUE), so the channel needs to be
4667+ * shut down carefully to prevent crashes.
4668+ */
4669+ hcintmsk_data_t hcintmsk;
4670+ hcintmsk.d32 = 0;
4671+ hcintmsk.b.chhltd = 1;
4672+ dwc_write_reg32(&hc_regs->hcintmsk, hcintmsk.d32);
4673+
4674+ /*
4675+ * Make sure no other interrupts besides halt are currently
4676+ * pending. Handling another interrupt could cause a crash due
4677+ * to the QTD and QH state.
4678+ */
4679+ dwc_write_reg32(&hc_regs->hcint, ~hcintmsk.d32);
4680+
4681+ /*
4682+ * Make sure the halt status is set to URB_DEQUEUE or AHB_ERR
4683+ * even if the channel was already halted for some other
4684+ * reason.
4685+ */
4686+ hc->halt_status = halt_status;
4687+
4688+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
4689+ if (hcchar.b.chen == 0) {
4690+ /*
4691+ * The channel is either already halted or it hasn't
4692+ * started yet. In DMA mode, the transfer may halt if
4693+ * it finishes normally or a condition occurs that
4694+ * requires driver intervention. Don't want to halt
4695+ * the channel again. In either Slave or DMA mode,
4696+ * it's possible that the transfer has been assigned
4697+ * to a channel, but not started yet when an URB is
4698+ * dequeued. Don't want to halt a channel that hasn't
4699+ * started yet.
4700+ */
4701+ return;
4702+ }
4703+ }
4704+
4705+ if (hc->halt_pending) {
4706+ /*
4707+ * A halt has already been issued for this channel. This might
4708+ * happen when a transfer is aborted by a higher level in
4709+ * the stack.
4710+ */
4711+#ifdef DEBUG
4712+ DWC_PRINT("*** %s: Channel %d, _hc->halt_pending already set ***\n",
4713+ __func__, hc->hc_num);
4714+
4715+/* dwc_otg_dump_global_registers(core_if); */
4716+/* dwc_otg_dump_host_registers(core_if); */
4717+#endif
4718+ return;
4719+ }
4720+
4721+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
4722+ hcchar.b.chen = 1;
4723+ hcchar.b.chdis = 1;
4724+
4725+ if (!core_if->dma_enable) {
4726+ /* Check for space in the request queue to issue the halt. */
4727+ if (hc->ep_type == DWC_OTG_EP_TYPE_CONTROL ||
4728+ hc->ep_type == DWC_OTG_EP_TYPE_BULK) {
4729+ nptxsts.d32 = dwc_read_reg32(&global_regs->gnptxsts);
4730+ if (nptxsts.b.nptxqspcavail == 0) {
4731+ hcchar.b.chen = 0;
4732+ }
4733+ }
4734+ else {
4735+ hptxsts.d32 = dwc_read_reg32(&host_global_regs->hptxsts);
4736+ if ((hptxsts.b.ptxqspcavail == 0) || (core_if->queuing_high_bandwidth)) {
4737+ hcchar.b.chen = 0;
4738+ }
4739+ }
4740+ }
4741+
4742+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
4743+
4744+ hc->halt_status = halt_status;
4745+
4746+ if (hcchar.b.chen) {
4747+ hc->halt_pending = 1;
4748+ hc->halt_on_queue = 0;
4749+ }
4750+ else {
4751+ hc->halt_on_queue = 1;
4752+ }
4753+
4754+ DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
4755+ DWC_DEBUGPL(DBG_HCDV, " hcchar: 0x%08x\n", hcchar.d32);
4756+ DWC_DEBUGPL(DBG_HCDV, " halt_pending: %d\n", hc->halt_pending);
4757+ DWC_DEBUGPL(DBG_HCDV, " halt_on_queue: %d\n", hc->halt_on_queue);
4758+ DWC_DEBUGPL(DBG_HCDV, " halt_status: %d\n", hc->halt_status);
4759+
4760+ return;
4761+}
4762+
4763+/**
4764+ * Clears the transfer state for a host channel. This function is normally
4765+ * called after a transfer is done and the host channel is being released.
4766+ *
4767+ * @param core_if Programming view of DWC_otg controller.
4768+ * @param hc Identifies the host channel to clean up.
4769+ */
4770+void dwc_otg_hc_cleanup(dwc_otg_core_if_t *core_if, dwc_hc_t *hc)
4771+{
4772+ dwc_otg_hc_regs_t *hc_regs;
4773+
4774+ hc->xfer_started = 0;
4775+
4776+ /*
4777+ * Clear channel interrupt enables and any unhandled channel interrupt
4778+ * conditions.
4779+ */
4780+ hc_regs = core_if->host_if->hc_regs[hc->hc_num];
4781+ dwc_write_reg32(&hc_regs->hcintmsk, 0);
4782+ dwc_write_reg32(&hc_regs->hcint, 0xFFFFFFFF);
4783+
4784+#ifdef DEBUG
4785+ del_timer(&core_if->hc_xfer_timer[hc->hc_num]);
4786+ {
4787+ hcchar_data_t hcchar;
4788+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
4789+ if (hcchar.b.chdis) {
4790+ DWC_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n",
4791+ __func__, hc->hc_num, hcchar.d32);
4792+ }
4793+ }
4794+#endif
4795+}
4796+
4797+/**
4798+ * Sets the channel property that indicates in which frame a periodic transfer
4799+ * should occur. This is always set to the _next_ frame. This function has no
4800+ * effect on non-periodic transfers.
4801+ *
4802+ * @param core_if Programming view of DWC_otg controller.
4803+ * @param hc Identifies the host channel to set up and its properties.
4804+ * @param hcchar Current value of the HCCHAR register for the specified host
4805+ * channel.
4806+ */
4807+static inline void hc_set_even_odd_frame(dwc_otg_core_if_t *core_if,
4808+ dwc_hc_t *hc,
4809+ hcchar_data_t *hcchar)
4810+{
4811+ if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
4812+ hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
4813+ hfnum_data_t hfnum;
4814+ hfnum.d32 = dwc_read_reg32(&core_if->host_if->host_global_regs->hfnum);
4815+
4816+ /* 1 if _next_ frame is odd, 0 if it's even */
4817+ hcchar->b.oddfrm = (hfnum.b.frnum & 0x1) ? 0 : 1;
4818+#ifdef DEBUG
4819+ if (hc->ep_type == DWC_OTG_EP_TYPE_INTR && hc->do_split && !hc->complete_split) {
4820+ switch (hfnum.b.frnum & 0x7) {
4821+ case 7:
4822+ core_if->hfnum_7_samples++;
4823+ core_if->hfnum_7_frrem_accum += hfnum.b.frrem;
4824+ break;
4825+ case 0:
4826+ core_if->hfnum_0_samples++;
4827+ core_if->hfnum_0_frrem_accum += hfnum.b.frrem;
4828+ break;
4829+ default:
4830+ core_if->hfnum_other_samples++;
4831+ core_if->hfnum_other_frrem_accum += hfnum.b.frrem;
4832+ break;
4833+ }
4834+ }
4835+#endif
4836+ }
4837+}
4838+
4839+#ifdef DEBUG
4840+static void hc_xfer_timeout(unsigned long ptr)
4841+{
4842+ hc_xfer_info_t *xfer_info = (hc_xfer_info_t *)ptr;
4843+ int hc_num = xfer_info->hc->hc_num;
4844+ DWC_WARN("%s: timeout on channel %d\n", __func__, hc_num);
4845+ DWC_WARN(" start_hcchar_val 0x%08x\n", xfer_info->core_if->start_hcchar_val[hc_num]);
4846+}
4847+#endif
4848+
4849+/*
4850+ * This function does the setup for a data transfer for a host channel and
4851+ * starts the transfer. May be called in either Slave mode or DMA mode. In
4852+ * Slave mode, the caller must ensure that there is sufficient space in the
4853+ * request queue and Tx Data FIFO.
4854+ *
4855+ * For an OUT transfer in Slave mode, it loads a data packet into the
4856+ * appropriate FIFO. If necessary, additional data packets will be loaded in
4857+ * the Host ISR.
4858+ *
4859+ * For an IN transfer in Slave mode, a data packet is requested. The data
4860+ * packets are unloaded from the Rx FIFO in the Host ISR. If necessary,
4861+ * additional data packets are requested in the Host ISR.
4862+ *
4863+ * For a PING transfer in Slave mode, the Do Ping bit is set in the HCTSIZ
4864+ * register along with a packet count of 1 and the channel is enabled. This
4865+ * causes a single PING transaction to occur. Other fields in HCTSIZ are
4866+ * simply set to 0 since no data transfer occurs in this case.
4867+ *
4868+ * For a PING transfer in DMA mode, the HCTSIZ register is initialized with
4869+ * all the information required to perform the subsequent data transfer. In
4870+ * addition, the Do Ping bit is set in the HCTSIZ register. In this case, the
4871+ * controller performs the entire PING protocol, then starts the data
4872+ * transfer.
4873+ *
4874+ * @param core_if Programming view of DWC_otg controller.
4875+ * @param hc Information needed to initialize the host channel. The xfer_len
4876+ * value may be reduced to accommodate the max widths of the XferSize and
4877+ * PktCnt fields in the HCTSIZn register. The multi_count value may be changed
4878+ * to reflect the final xfer_len value.
4879+ */
4880+void dwc_otg_hc_start_transfer(dwc_otg_core_if_t *core_if, dwc_hc_t *hc)
4881+{
4882+ hcchar_data_t hcchar;
4883+ hctsiz_data_t hctsiz;
4884+ uint16_t num_packets;
4885+ uint32_t max_hc_xfer_size = core_if->core_params->max_transfer_size;
4886+ uint16_t max_hc_pkt_count = core_if->core_params->max_packet_count;
4887+ dwc_otg_hc_regs_t *hc_regs = core_if->host_if->hc_regs[hc->hc_num];
4888+
4889+ hctsiz.d32 = 0;
4890+
4891+ if (hc->do_ping) {
4892+ if (!core_if->dma_enable) {
4893+ dwc_otg_hc_do_ping(core_if, hc);
4894+ hc->xfer_started = 1;
4895+ return;
4896+ }
4897+ else {
4898+ hctsiz.b.dopng = 1;
4899+ }
4900+ }
4901+
4902+ if (hc->do_split) {
4903+ num_packets = 1;
4904+
4905+ if (hc->complete_split && !hc->ep_is_in) {
4906+ /* For CSPLIT OUT Transfer, set the size to 0 so the
4907+ * core doesn't expect any data written to the FIFO */
4908+ hc->xfer_len = 0;
4909+ }
4910+ else if (hc->ep_is_in || (hc->xfer_len > hc->max_packet)) {
4911+ hc->xfer_len = hc->max_packet;
4912+ }
4913+ else if (!hc->ep_is_in && (hc->xfer_len > 188)) {
4914+ hc->xfer_len = 188;
4915+ }
4916+
4917+ hctsiz.b.xfersize = hc->xfer_len;
4918+ }
4919+ else {
4920+ /*
4921+ * Ensure that the transfer length and packet count will fit
4922+ * in the widths allocated for them in the HCTSIZn register.
4923+ */
4924+ if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
4925+ hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
4926+ /*
4927+ * Make sure the transfer size is no larger than one
4928+ * (micro)frame's worth of data. (A check was done
4929+ * when the periodic transfer was accepted to ensure
4930+ * that a (micro)frame's worth of data can be
4931+ * programmed into a channel.)
4932+ */
4933+ uint32_t max_periodic_len = hc->multi_count * hc->max_packet;
4934+ if (hc->xfer_len > max_periodic_len) {
4935+ hc->xfer_len = max_periodic_len;
4936+ }
4937+ else {
4938+ }
4939+ }
4940+ else if (hc->xfer_len > max_hc_xfer_size) {
4941+ /* Make sure that xfer_len is a multiple of max packet size. */
4942+ hc->xfer_len = max_hc_xfer_size - hc->max_packet + 1;
4943+ }
4944+
4945+ if (hc->xfer_len > 0) {
4946+ num_packets = (hc->xfer_len + hc->max_packet - 1) / hc->max_packet;
4947+ if (num_packets > max_hc_pkt_count) {
4948+ num_packets = max_hc_pkt_count;
4949+ hc->xfer_len = num_packets * hc->max_packet;
4950+ }
4951+ }
4952+ else {
4953+ /* Need 1 packet for transfer length of 0. */
4954+ num_packets = 1;
4955+ }
4956+
4957+#if 0
4958+//host testusb item 10, would do series of Control transfer
4959+//with URB_SHORT_NOT_OK set in transfer_flags ,
4960+//changing the xfer_len would cause the test fail
4961+ if (hc->ep_is_in) {
4962+ /* Always program an integral # of max packets for IN transfers. */
4963+ hc->xfer_len = num_packets * hc->max_packet;
4964+ }
4965+#endif
4966+
4967+ if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
4968+ hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
4969+ /*
4970+ * Make sure that the multi_count field matches the
4971+ * actual transfer length.
4972+ */
4973+ hc->multi_count = num_packets;
4974+ }
4975+
4976+ if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
4977+ /* Set up the initial PID for the transfer. */
4978+ if (hc->speed == DWC_OTG_EP_SPEED_HIGH) {
4979+ if (hc->ep_is_in) {
4980+ if (hc->multi_count == 1) {
4981+ hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
4982+ }
4983+ else if (hc->multi_count == 2) {
4984+ hc->data_pid_start = DWC_OTG_HC_PID_DATA1;
4985+ }
4986+ else {
4987+ hc->data_pid_start = DWC_OTG_HC_PID_DATA2;
4988+ }
4989+ }
4990+ else {
4991+ if (hc->multi_count == 1) {
4992+ hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
4993+ }
4994+ else {
4995+ hc->data_pid_start = DWC_OTG_HC_PID_MDATA;
4996+ }
4997+ }
4998+ }
4999+ else {
5000+ hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
5001+ }
5002+ }
5003+
5004+ hctsiz.b.xfersize = hc->xfer_len;
5005+ }
5006+
5007+ hc->start_pkt_count = num_packets;
5008+ hctsiz.b.pktcnt = num_packets;
5009+ hctsiz.b.pid = hc->data_pid_start;
5010+ dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
5011+
5012+ DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
5013+ DWC_DEBUGPL(DBG_HCDV, " Xfer Size: %d\n", hctsiz.b.xfersize);
5014+ DWC_DEBUGPL(DBG_HCDV, " Num Pkts: %d\n", hctsiz.b.pktcnt);
5015+ DWC_DEBUGPL(DBG_HCDV, " Start PID: %d\n", hctsiz.b.pid);
5016+
5017+ if (core_if->dma_enable) {
5018+ dwc_write_reg32(&hc_regs->hcdma, (uint32_t)hc->xfer_buff);
5019+ }
5020+
5021+ /* Start the split */
5022+ if (hc->do_split) {
5023+ hcsplt_data_t hcsplt;
5024+ hcsplt.d32 = dwc_read_reg32 (&hc_regs->hcsplt);
5025+ hcsplt.b.spltena = 1;
5026+ dwc_write_reg32(&hc_regs->hcsplt, hcsplt.d32);
5027+ }
5028+
5029+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
5030+ hcchar.b.multicnt = hc->multi_count;
5031+ hc_set_even_odd_frame(core_if, hc, &hcchar);
5032+#ifdef DEBUG
5033+ core_if->start_hcchar_val[hc->hc_num] = hcchar.d32;
5034+ if (hcchar.b.chdis) {
5035+ DWC_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n",
5036+ __func__, hc->hc_num, hcchar.d32);
5037+ }
5038+#endif
5039+
5040+ /* Set host channel enable after all other setup is complete. */
5041+ hcchar.b.chen = 1;
5042+ hcchar.b.chdis = 0;
5043+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
5044+
5045+ hc->xfer_started = 1;
5046+ hc->requests++;
5047+
5048+ if (!core_if->dma_enable &&
5049+ !hc->ep_is_in && hc->xfer_len > 0) {
5050+ /* Load OUT packet into the appropriate Tx FIFO. */
5051+ dwc_otg_hc_write_packet(core_if, hc);
5052+ }
5053+
5054+#ifdef DEBUG
5055+ /* Start a timer for this transfer. */
5056+ core_if->hc_xfer_timer[hc->hc_num].function = hc_xfer_timeout;
5057+ core_if->hc_xfer_info[hc->hc_num].core_if = core_if;
5058+ core_if->hc_xfer_info[hc->hc_num].hc = hc;
5059+ core_if->hc_xfer_timer[hc->hc_num].data = (unsigned long)(&core_if->hc_xfer_info[hc->hc_num]);
5060+ core_if->hc_xfer_timer[hc->hc_num].expires = jiffies + (HZ*10);
5061+ add_timer(&core_if->hc_xfer_timer[hc->hc_num]);
5062+#endif
5063+}
5064+
5065+/**
5066+ * This function continues a data transfer that was started by previous call
5067+ * to <code>dwc_otg_hc_start_transfer</code>. The caller must ensure there is
5068+ * sufficient space in the request queue and Tx Data FIFO. This function
5069+ * should only be called in Slave mode. In DMA mode, the controller acts
5070+ * autonomously to complete transfers programmed to a host channel.
5071+ *
5072+ * For an OUT transfer, a new data packet is loaded into the appropriate FIFO
5073+ * if there is any data remaining to be queued. For an IN transfer, another
5074+ * data packet is always requested. For the SETUP phase of a control transfer,
5075+ * this function does nothing.
5076+ *
5077+ * @return 1 if a new request is queued, 0 if no more requests are required
5078+ * for this transfer.
5079+ */
5080+int dwc_otg_hc_continue_transfer(dwc_otg_core_if_t *core_if, dwc_hc_t *hc)
5081+{
5082+ DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
5083+
5084+ if (hc->do_split) {
5085+ /* SPLITs always queue just once per channel */
5086+ return 0;
5087+ }
5088+ else if (hc->data_pid_start == DWC_OTG_HC_PID_SETUP) {
5089+ /* SETUPs are queued only once since they can't be NAKed. */
5090+ return 0;
5091+ }
5092+ else if (hc->ep_is_in) {
5093+ /*
5094+ * Always queue another request for other IN transfers. If
5095+ * back-to-back INs are issued and NAKs are received for both,
5096+ * the driver may still be processing the first NAK when the
5097+ * second NAK is received. When the interrupt handler clears
5098+ * the NAK interrupt for the first NAK, the second NAK will
5099+ * not be seen. So we can't depend on the NAK interrupt
5100+ * handler to requeue a NAKed request. Instead, IN requests
5101+ * are issued each time this function is called. When the
5102+ * transfer completes, the extra requests for the channel will
5103+ * be flushed.
5104+ */
5105+ hcchar_data_t hcchar;
5106+ dwc_otg_hc_regs_t *hc_regs = core_if->host_if->hc_regs[hc->hc_num];
5107+
5108+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
5109+ hc_set_even_odd_frame(core_if, hc, &hcchar);
5110+ hcchar.b.chen = 1;
5111+ hcchar.b.chdis = 0;
5112+ DWC_DEBUGPL(DBG_HCDV, " IN xfer: hcchar = 0x%08x\n", hcchar.d32);
5113+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
5114+ hc->requests++;
5115+ return 1;
5116+ }
5117+ else {
5118+ /* OUT transfers. */
5119+ if (hc->xfer_count < hc->xfer_len) {
5120+ if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
5121+ hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
5122+ hcchar_data_t hcchar;
5123+ dwc_otg_hc_regs_t *hc_regs;
5124+ hc_regs = core_if->host_if->hc_regs[hc->hc_num];
5125+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
5126+ hc_set_even_odd_frame(core_if, hc, &hcchar);
5127+ }
5128+
5129+ /* Load OUT packet into the appropriate Tx FIFO. */
5130+ dwc_otg_hc_write_packet(core_if, hc);
5131+ hc->requests++;
5132+ return 1;
5133+ }
5134+ else {
5135+ return 0;
5136+ }
5137+ }
5138+}
5139+
5140+/**
5141+ * Starts a PING transfer. This function should only be called in Slave mode.
5142+ * The Do Ping bit is set in the HCTSIZ register, then the channel is enabled.
5143+ */
5144+void dwc_otg_hc_do_ping(dwc_otg_core_if_t *core_if, dwc_hc_t *hc)
5145+{
5146+ hcchar_data_t hcchar;
5147+ hctsiz_data_t hctsiz;
5148+ dwc_otg_hc_regs_t *hc_regs = core_if->host_if->hc_regs[hc->hc_num];
5149+
5150+ DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
5151+
5152+ hctsiz.d32 = 0;
5153+ hctsiz.b.dopng = 1;
5154+ hctsiz.b.pktcnt = 1;
5155+ dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
5156+
5157+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
5158+ hcchar.b.chen = 1;
5159+ hcchar.b.chdis = 0;
5160+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
5161+}
5162+
5163+/*
5164+ * This function writes a packet into the Tx FIFO associated with the Host
5165+ * Channel. For a channel associated with a non-periodic EP, the non-periodic
5166+ * Tx FIFO is written. For a channel associated with a periodic EP, the
5167+ * periodic Tx FIFO is written. This function should only be called in Slave
5168+ * mode.
5169+ *
5170+ * Upon return the xfer_buff and xfer_count fields in _hc are incremented by
5171+ * then number of bytes written to the Tx FIFO.
5172+ */
5173+void dwc_otg_hc_write_packet(dwc_otg_core_if_t *core_if, dwc_hc_t *hc)
5174+{
5175+ uint32_t i;
5176+ uint32_t remaining_count;
5177+ uint32_t byte_count;
5178+ uint32_t dword_count;
5179+
5180+ uint32_t *data_buff = (uint32_t *)(hc->xfer_buff);
5181+ uint32_t *data_fifo = core_if->data_fifo[hc->hc_num];
5182+
5183+ remaining_count = hc->xfer_len - hc->xfer_count;
5184+ if (remaining_count > hc->max_packet) {
5185+ byte_count = hc->max_packet;
5186+ }
5187+ else {
5188+ byte_count = remaining_count;
5189+ }
5190+
5191+ dword_count = (byte_count + 3) / 4;
5192+
5193+ if ((((unsigned long)data_buff) & 0x3) == 0) {
5194+ /* xfer_buff is DWORD aligned. */
5195+ for (i = 0; i < dword_count; i++, data_buff++)
5196+ {
5197+ dwc_write_reg32(data_fifo, *data_buff);
5198+ }
5199+ }
5200+ else {
5201+ /* xfer_buff is not DWORD aligned. */
5202+ for (i = 0; i < dword_count; i++, data_buff++)
5203+ {
5204+ dwc_write_reg32(data_fifo, get_unaligned(data_buff));
5205+ }
5206+ }
5207+
5208+ hc->xfer_count += byte_count;
5209+ hc->xfer_buff += byte_count;
5210+}
5211+
5212+/**
5213+ * Gets the current USB frame number. This is the frame number from the last
5214+ * SOF packet.
5215+ */
5216+uint32_t dwc_otg_get_frame_number(dwc_otg_core_if_t *core_if)
5217+{
5218+ dsts_data_t dsts;
5219+ dsts.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts);
5220+
5221+ /* read current frame/microframe number from DSTS register */
5222+ return dsts.b.soffn;
5223+}
5224+
5225+/**
5226+ * This function reads a setup packet from the Rx FIFO into the destination
5227+ * buffer. This function is called from the Rx Status Queue Level (RxStsQLvl)
5228+ * Interrupt routine when a SETUP packet has been received in Slave mode.
5229+ *
5230+ * @param core_if Programming view of DWC_otg controller.
5231+ * @param dest Destination buffer for packet data.
5232+ */
5233+void dwc_otg_read_setup_packet(dwc_otg_core_if_t *core_if, uint32_t *dest)
5234+{
5235+ /* Get the 8 bytes of a setup transaction data */
5236+
5237+ /* Pop 2 DWORDS off the receive data FIFO into memory */
5238+ dest[0] = dwc_read_reg32(core_if->data_fifo[0]);
5239+ dest[1] = dwc_read_reg32(core_if->data_fifo[0]);
5240+}
5241+
5242+
5243+/**
5244+ * This function enables EP0 OUT to receive SETUP packets and configures EP0
5245+ * IN for transmitting packets. It is normally called when the
5246+ * "Enumeration Done" interrupt occurs.
5247+ *
5248+ * @param core_if Programming view of DWC_otg controller.
5249+ * @param ep The EP0 data.
5250+ */
5251+void dwc_otg_ep0_activate(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
5252+{
5253+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
5254+ dsts_data_t dsts;
5255+ depctl_data_t diepctl;
5256+ depctl_data_t doepctl;
5257+ dctl_data_t dctl = { .d32 = 0 };
5258+
5259+ /* Read the Device Status and Endpoint 0 Control registers */
5260+ dsts.d32 = dwc_read_reg32(&dev_if->dev_global_regs->dsts);
5261+ diepctl.d32 = dwc_read_reg32(&dev_if->in_ep_regs[0]->diepctl);
5262+ doepctl.d32 = dwc_read_reg32(&dev_if->out_ep_regs[0]->doepctl);
5263+
5264+ /* Set the MPS of the IN EP based on the enumeration speed */
5265+ switch (dsts.b.enumspd) {
5266+ case DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
5267+ case DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
5268+ case DWC_DSTS_ENUMSPD_FS_PHY_48MHZ:
5269+ diepctl.b.mps = DWC_DEP0CTL_MPS_64;
5270+ break;
5271+ case DWC_DSTS_ENUMSPD_LS_PHY_6MHZ:
5272+ diepctl.b.mps = DWC_DEP0CTL_MPS_8;
5273+ break;
5274+ }
5275+
5276+ dwc_write_reg32(&dev_if->in_ep_regs[0]->diepctl, diepctl.d32);
5277+
5278+ /* Enable OUT EP for receive */
5279+ doepctl.b.epena = 1;
5280+ dwc_write_reg32(&dev_if->out_ep_regs[0]->doepctl, doepctl.d32);
5281+
5282+#ifdef VERBOSE
5283+ DWC_DEBUGPL(DBG_PCDV,"doepctl0=%0x\n",
5284+ dwc_read_reg32(&dev_if->out_ep_regs[0]->doepctl));
5285+ DWC_DEBUGPL(DBG_PCDV,"diepctl0=%0x\n",
5286+ dwc_read_reg32(&dev_if->in_ep_regs[0]->diepctl));
5287+#endif
5288+ dctl.b.cgnpinnak = 1;
5289+
5290+ dwc_modify_reg32(&dev_if->dev_global_regs->dctl, dctl.d32, dctl.d32);
5291+ DWC_DEBUGPL(DBG_PCDV,"dctl=%0x\n",
5292+ dwc_read_reg32(&dev_if->dev_global_regs->dctl));
5293+}
5294+
5295+/**
5296+ * This function activates an EP. The Device EP control register for
5297+ * the EP is configured as defined in the ep structure. Note: This
5298+ * function is not used for EP0.
5299+ *
5300+ * @param core_if Programming view of DWC_otg controller.
5301+ * @param ep The EP to activate.
5302+ */
5303+void dwc_otg_ep_activate(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
5304+{
5305+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
5306+ depctl_data_t depctl;
5307+ volatile uint32_t *addr;
5308+ daint_data_t daintmsk = { .d32 = 0 };
5309+
5310+ DWC_DEBUGPL(DBG_PCDV, "%s() EP%d-%s\n", __func__, ep->num,
5311+ (ep->is_in?"IN":"OUT"));
5312+
5313+ /* Read DEPCTLn register */
5314+ if (ep->is_in == 1) {
5315+ addr = &dev_if->in_ep_regs[ep->num]->diepctl;
5316+ daintmsk.ep.in = 1<<ep->num;
5317+ }
5318+ else {
5319+ addr = &dev_if->out_ep_regs[ep->num]->doepctl;
5320+ daintmsk.ep.out = 1<<ep->num;
5321+ }
5322+
5323+ /* If the EP is already active don't change the EP Control
5324+ * register. */
5325+ depctl.d32 = dwc_read_reg32(addr);
5326+ if (!depctl.b.usbactep) {
5327+ depctl.b.mps = ep->maxpacket;
5328+ depctl.b.eptype = ep->type;
5329+ depctl.b.txfnum = ep->tx_fifo_num;
5330+
5331+ if (ep->type == DWC_OTG_EP_TYPE_ISOC) {
5332+ depctl.b.setd0pid = 1; // ???
5333+ }
5334+ else {
5335+ depctl.b.setd0pid = 1;
5336+ }
5337+ depctl.b.usbactep = 1;
5338+
5339+ dwc_write_reg32(addr, depctl.d32);
5340+ DWC_DEBUGPL(DBG_PCDV,"DEPCTL(%.8x)=%08x\n",(u32)addr, dwc_read_reg32(addr));
5341+ }
5342+
5343+ /* Enable the Interrupt for this EP */
5344+ if(core_if->multiproc_int_enable) {
5345+ if (ep->is_in == 1) {
5346+ diepmsk_data_t diepmsk = { .d32 = 0};
5347+ diepmsk.b.xfercompl = 1;
5348+ diepmsk.b.timeout = 1;
5349+ diepmsk.b.epdisabled = 1;
5350+ diepmsk.b.ahberr = 1;
5351+ diepmsk.b.intknepmis = 1;
5352+ diepmsk.b.txfifoundrn = 1; //?????
5353+
5354+
5355+ if(core_if->dma_desc_enable) {
5356+ diepmsk.b.bna = 1;
5357+ }
5358+/*
5359+ if(core_if->dma_enable) {
5360+ doepmsk.b.nak = 1;
5361+ }
5362+*/
5363+ dwc_write_reg32(&dev_if->dev_global_regs->diepeachintmsk[ep->num], diepmsk.d32);
5364+
5365+ } else {
5366+ doepmsk_data_t doepmsk = { .d32 = 0};
5367+ doepmsk.b.xfercompl = 1;
5368+ doepmsk.b.ahberr = 1;
5369+ doepmsk.b.epdisabled = 1;
5370+
5371+
5372+ if(core_if->dma_desc_enable) {
5373+ doepmsk.b.bna = 1;
5374+ }
5375+/*
5376+ doepmsk.b.babble = 1;
5377+ doepmsk.b.nyet = 1;
5378+ doepmsk.b.nak = 1;
5379+*/
5380+ dwc_write_reg32(&dev_if->dev_global_regs->doepeachintmsk[ep->num], doepmsk.d32);
5381+ }
5382+ dwc_modify_reg32(&dev_if->dev_global_regs->deachintmsk,
5383+ 0, daintmsk.d32);
5384+ } else {
5385+ dwc_modify_reg32(&dev_if->dev_global_regs->daintmsk,
5386+ 0, daintmsk.d32);
5387+ }
5388+
5389+ DWC_DEBUGPL(DBG_PCDV,"DAINTMSK=%0x\n",
5390+ dwc_read_reg32(&dev_if->dev_global_regs->daintmsk));
5391+
5392+ ep->stall_clear_flag = 0;
5393+ return;
5394+}
5395+
5396+/**
5397+ * This function deactivates an EP. This is done by clearing the USB Active
5398+ * EP bit in the Device EP control register. Note: This function is not used
5399+ * for EP0. EP0 cannot be deactivated.
5400+ *
5401+ * @param core_if Programming view of DWC_otg controller.
5402+ * @param ep The EP to deactivate.
5403+ */
5404+void dwc_otg_ep_deactivate(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
5405+{
5406+ depctl_data_t depctl = { .d32 = 0 };
5407+ volatile uint32_t *addr;
5408+ daint_data_t daintmsk = { .d32 = 0};
5409+
5410+ /* Read DEPCTLn register */
5411+ if (ep->is_in == 1) {
5412+ addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl;
5413+ daintmsk.ep.in = 1<<ep->num;
5414+ }
5415+ else {
5416+ addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl;
5417+ daintmsk.ep.out = 1<<ep->num;
5418+ }
5419+
5420+ //disabled ep only when ep is enabled
5421+ //or got halt in the loop in test in cv9
5422+ depctl.d32=dwc_read_reg32(addr);
5423+ if(depctl.b.epena){
5424+ if (ep->is_in == 1) {
5425+ diepint_data_t diepint;
5426+ dwc_otg_dev_in_ep_regs_t *in_reg=core_if->dev_if->in_ep_regs[ep->num];
5427+
5428+ //Set ep nak
5429+ depctl.d32=dwc_read_reg32(&in_reg->diepctl);
5430+ depctl.b.snak=1;
5431+ dwc_write_reg32(&in_reg->diepctl,depctl.d32);
5432+
5433+ //wait for diepint.b.inepnakeff
5434+ diepint.d32=dwc_read_reg32(&in_reg->diepint);
5435+ while(!diepint.b.inepnakeff){
5436+ udelay(1);
5437+ diepint.d32=dwc_read_reg32(&in_reg->diepint);
5438+ }
5439+ diepint.d32=0;
5440+ diepint.b.inepnakeff=1;
5441+ dwc_write_reg32(&in_reg->diepint,diepint.d32);
5442+
5443+ //set ep disable and snak
5444+ depctl.d32=dwc_read_reg32(&in_reg->diepctl);
5445+ depctl.b.snak=1;
5446+ depctl.b.epdis=1;
5447+ dwc_write_reg32(&in_reg->diepctl,depctl.d32);
5448+
5449+ //wait for diepint.b.epdisabled
5450+ diepint.d32=dwc_read_reg32(&in_reg->diepint);
5451+ while(!diepint.b.epdisabled){
5452+ udelay(1);
5453+ diepint.d32=dwc_read_reg32(&in_reg->diepint);
5454+ }
5455+ diepint.d32=0;
5456+ diepint.b.epdisabled=1;
5457+ dwc_write_reg32(&in_reg->diepint,diepint.d32);
5458+
5459+ //clear ep enable and disable bit
5460+ depctl.d32=dwc_read_reg32(&in_reg->diepctl);
5461+ depctl.b.epena=0;
5462+ depctl.b.epdis=0;
5463+ dwc_write_reg32(&in_reg->diepctl,depctl.d32);
5464+
5465+ }
5466+#if 0
5467+//following DWC OTG DataBook v2.72a, 6.4.2.1.3 Disabling an OUT Endpoint,
5468+//but this doesn't work, the old code do.
5469+ else {
5470+ doepint_data_t doepint;
5471+ dwc_otg_dev_out_ep_regs_t *out_reg=core_if->dev_if->out_ep_regs[ep->num];
5472+ dctl_data_t dctl;
5473+ gintsts_data_t gintsts;
5474+
5475+ //set dctl global out nak
5476+ dctl.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dctl);
5477+ dctl.b.sgoutnak=1;
5478+ dwc_write_reg32(&core_if->dev_if->dev_global_regs->dctl,dctl.d32);
5479+
5480+ //wait for gintsts.goutnakeff
5481+ gintsts.d32=dwc_read_reg32(&core_if->core_global_regs->gintsts);
5482+ while(!gintsts.b.goutnakeff){
5483+ udelay(1);
5484+ gintsts.d32=dwc_read_reg32(&core_if->core_global_regs->gintsts);
5485+ }
5486+ gintsts.d32=0;
5487+ gintsts.b.goutnakeff=1;
5488+ dwc_write_reg32 (&core_if->core_global_regs->gintsts, gintsts.d32);
5489+
5490+ //set ep disable and snak
5491+ depctl.d32=dwc_read_reg32(&out_reg->doepctl);
5492+ depctl.b.snak=1;
5493+ depctl.b.epdis=1;
5494+ dwc_write_reg32(&out_reg->doepctl,depctl.d32);
5495+
5496+ //wait for diepint.b.epdisabled
5497+ doepint.d32=dwc_read_reg32(&out_reg->doepint);
5498+ while(!doepint.b.epdisabled){
5499+ udelay(1);
5500+ doepint.d32=dwc_read_reg32(&out_reg->doepint);
5501+ }
5502+ doepint.d32=0;
5503+ doepint.b.epdisabled=1;
5504+ dwc_write_reg32(&out_reg->doepint,doepint.d32);
5505+
5506+ //clear ep enable and disable bit
5507+ depctl.d32=dwc_read_reg32(&out_reg->doepctl);
5508+ depctl.b.epena=0;
5509+ depctl.b.epdis=0;
5510+ dwc_write_reg32(&out_reg->doepctl,depctl.d32);
5511+ }
5512+#endif
5513+
5514+ depctl.d32=0;
5515+ depctl.b.usbactep = 0;
5516+
5517+ if (ep->is_in == 0) {
5518+ if(core_if->dma_enable||core_if->dma_desc_enable)
5519+ depctl.b.epdis = 1;
5520+ }
5521+
5522+ dwc_write_reg32(addr, depctl.d32);
5523+ }
5524+
5525+ /* Disable the Interrupt for this EP */
5526+ if(core_if->multiproc_int_enable) {
5527+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->deachintmsk,
5528+ daintmsk.d32, 0);
5529+
5530+ if (ep->is_in == 1) {
5531+ dwc_write_reg32(&core_if->dev_if->dev_global_regs->diepeachintmsk[ep->num], 0);
5532+ } else {
5533+ dwc_write_reg32(&core_if->dev_if->dev_global_regs->doepeachintmsk[ep->num], 0);
5534+ }
5535+ } else {
5536+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->daintmsk,
5537+ daintmsk.d32, 0);
5538+ }
5539+
5540+ if (ep->is_in == 1) {
5541+ DWC_DEBUGPL(DBG_PCD, "DIEPCTL(%.8x)=%08x DIEPTSIZ=%08x, DIEPINT=%.8x, DIEPDMA=%.8x, DTXFSTS=%.8x\n",
5542+ (u32)&core_if->dev_if->in_ep_regs[ep->num]->diepctl,
5543+ dwc_read_reg32(&core_if->dev_if->in_ep_regs[ep->num]->diepctl),
5544+ dwc_read_reg32(&core_if->dev_if->in_ep_regs[ep->num]->dieptsiz),
5545+ dwc_read_reg32(&core_if->dev_if->in_ep_regs[ep->num]->diepint),
5546+ dwc_read_reg32(&core_if->dev_if->in_ep_regs[ep->num]->diepdma),
5547+ dwc_read_reg32(&core_if->dev_if->in_ep_regs[ep->num]->dtxfsts));
5548+ DWC_DEBUGPL(DBG_PCD, "DAINTMSK=%08x GINTMSK=%08x\n",
5549+ dwc_read_reg32(&core_if->dev_if->dev_global_regs->daintmsk),
5550+ dwc_read_reg32(&core_if->core_global_regs->gintmsk));
5551+ }
5552+ else {
5553+ DWC_DEBUGPL(DBG_PCD, "DOEPCTL(%.8x)=%08x DOEPTSIZ=%08x, DOEPINT=%.8x, DOEPDMA=%.8x\n",
5554+ (u32)&core_if->dev_if->out_ep_regs[ep->num]->doepctl,
5555+ dwc_read_reg32(&core_if->dev_if->out_ep_regs[ep->num]->doepctl),
5556+ dwc_read_reg32(&core_if->dev_if->out_ep_regs[ep->num]->doeptsiz),
5557+ dwc_read_reg32(&core_if->dev_if->out_ep_regs[ep->num]->doepint),
5558+ dwc_read_reg32(&core_if->dev_if->out_ep_regs[ep->num]->doepdma));
5559+
5560+ DWC_DEBUGPL(DBG_PCD, "DAINTMSK=%08x GINTMSK=%08x\n",
5561+ dwc_read_reg32(&core_if->dev_if->dev_global_regs->daintmsk),
5562+ dwc_read_reg32(&core_if->core_global_regs->gintmsk));
5563+ }
5564+
5565+}
5566+
5567+/**
5568+ * This function does the setup for a data transfer for an EP and
5569+ * starts the transfer. For an IN transfer, the packets will be
5570+ * loaded into the appropriate Tx FIFO in the ISR. For OUT transfers,
5571+ * the packets are unloaded from the Rx FIFO in the ISR. the ISR.
5572+ *
5573+ * @param core_if Programming view of DWC_otg controller.
5574+ * @param ep The EP to start the transfer on.
5575+ */
5576+static void init_dma_desc_chain(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
5577+{
5578+ dwc_otg_dma_desc_t* dma_desc;
5579+ uint32_t offset;
5580+ uint32_t xfer_est;
5581+ int i;
5582+
5583+ ep->desc_cnt = ( ep->total_len / ep->maxxfer) +
5584+ ((ep->total_len % ep->maxxfer) ? 1 : 0);
5585+ if(!ep->desc_cnt)
5586+ ep->desc_cnt = 1;
5587+
5588+ dma_desc = ep->desc_addr;
5589+ xfer_est = ep->total_len;
5590+ offset = 0;
5591+ for( i = 0; i < ep->desc_cnt; ++i) {
5592+ /** DMA Descriptor Setup */
5593+ if(xfer_est > ep->maxxfer) {
5594+ dma_desc->status.b.bs = BS_HOST_BUSY;
5595+ dma_desc->status.b.l = 0;
5596+ dma_desc->status.b.ioc = 0;
5597+ dma_desc->status.b.sp = 0;
5598+ dma_desc->status.b.bytes = ep->maxxfer;
5599+ dma_desc->buf = ep->dma_addr + offset;
5600+ dma_desc->status.b.bs = BS_HOST_READY;
5601+
5602+ xfer_est -= ep->maxxfer;
5603+ offset += ep->maxxfer;
5604+ } else {
5605+ dma_desc->status.b.bs = BS_HOST_BUSY;
5606+ dma_desc->status.b.l = 1;
5607+ dma_desc->status.b.ioc = 1;
5608+ if(ep->is_in) {
5609+ dma_desc->status.b.sp = (xfer_est % ep->maxpacket) ?
5610+ 1 : ((ep->sent_zlp) ? 1 : 0);
5611+ dma_desc->status.b.bytes = xfer_est;
5612+ } else {
5613+ dma_desc->status.b.bytes = xfer_est + ((4 - (xfer_est & 0x3)) & 0x3) ;
5614+ }
5615+
5616+ dma_desc->buf = ep->dma_addr + offset;
5617+ dma_desc->status.b.bs = BS_HOST_READY;
5618+ }
5619+ dma_desc ++;
5620+ }
5621+}
5622+
5623+/**
5624+ * This function does the setup for a data transfer for an EP and
5625+ * starts the transfer. For an IN transfer, the packets will be
5626+ * loaded into the appropriate Tx FIFO in the ISR. For OUT transfers,
5627+ * the packets are unloaded from the Rx FIFO in the ISR. the ISR.
5628+ *
5629+ * @param core_if Programming view of DWC_otg controller.
5630+ * @param ep The EP to start the transfer on.
5631+ */
5632+
5633+void dwc_otg_ep_start_transfer(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
5634+{
5635+ depctl_data_t depctl;
5636+ deptsiz_data_t deptsiz;
5637+ gintmsk_data_t intr_mask = { .d32 = 0};
5638+
5639+ DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s()\n", __func__);
5640+
5641+ DWC_DEBUGPL(DBG_PCD, "ep%d-%s xfer_len=%d xfer_cnt=%d "
5642+ "xfer_buff=%p start_xfer_buff=%p\n",
5643+ ep->num, (ep->is_in?"IN":"OUT"), ep->xfer_len,
5644+ ep->xfer_count, ep->xfer_buff, ep->start_xfer_buff);
5645+
5646+ /* IN endpoint */
5647+ if (ep->is_in == 1) {
5648+ dwc_otg_dev_in_ep_regs_t *in_regs =
5649+ core_if->dev_if->in_ep_regs[ep->num];
5650+
5651+ gnptxsts_data_t gtxstatus;
5652+
5653+ gtxstatus.d32 =
5654+ dwc_read_reg32(&core_if->core_global_regs->gnptxsts);
5655+
5656+ if(core_if->en_multiple_tx_fifo == 0 && gtxstatus.b.nptxqspcavail == 0) {
5657+#ifdef DEBUG
5658+ DWC_PRINT("TX Queue Full (0x%0x)\n", gtxstatus.d32);
5659+#endif
5660+ return;
5661+ }
5662+
5663+ depctl.d32 = dwc_read_reg32(&(in_regs->diepctl));
5664+ deptsiz.d32 = dwc_read_reg32(&(in_regs->dieptsiz));
5665+
5666+ ep->xfer_len += (ep->maxxfer < (ep->total_len - ep->xfer_len)) ?
5667+ ep->maxxfer : (ep->total_len - ep->xfer_len);
5668+
5669+ /* Zero Length Packet? */
5670+ if ((ep->xfer_len - ep->xfer_count) == 0) {
5671+ deptsiz.b.xfersize = 0;
5672+ deptsiz.b.pktcnt = 1;
5673+ }
5674+ else {
5675+ /* Program the transfer size and packet count
5676+ * as follows: xfersize = N * maxpacket +
5677+ * short_packet pktcnt = N + (short_packet
5678+ * exist ? 1 : 0)
5679+ */
5680+ deptsiz.b.xfersize = ep->xfer_len - ep->xfer_count;
5681+ deptsiz.b.pktcnt =
5682+ (ep->xfer_len - ep->xfer_count - 1 + ep->maxpacket) /
5683+ ep->maxpacket;
5684+ }
5685+
5686+
5687+ /* Write the DMA register */
5688+ if (core_if->dma_enable) {
5689+ if (/*(core_if->dma_enable)&&*/(ep->dma_addr==DMA_ADDR_INVALID)) {
5690+ ep->dma_addr=dma_map_single(NULL,(void *)(ep->xfer_buff),(ep->xfer_len),DMA_TO_DEVICE);
5691+ }
5692+ DWC_DEBUGPL(DBG_PCDV, "ep%d dma_addr=%.8x\n", ep->num, ep->dma_addr);
5693+
5694+ if (core_if->dma_desc_enable == 0) {
5695+ dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
5696+
5697+ VERIFY_PCD_DMA_ADDR(ep->dma_addr);
5698+ dwc_write_reg32 (&(in_regs->diepdma),
5699+ (uint32_t)ep->dma_addr);
5700+ }
5701+ else {
5702+ init_dma_desc_chain(core_if, ep);
5703+ /** DIEPDMAn Register write */
5704+
5705+ VERIFY_PCD_DMA_ADDR(ep->dma_desc_addr);
5706+ dwc_write_reg32(&in_regs->diepdma, ep->dma_desc_addr);
5707+ }
5708+ }
5709+ else
5710+ {
5711+ dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
5712+ if(ep->type != DWC_OTG_EP_TYPE_ISOC) {
5713+ /**
5714+ * Enable the Non-Periodic Tx FIFO empty interrupt,
5715+ * or the Tx FIFO epmty interrupt in dedicated Tx FIFO mode,
5716+ * the data will be written into the fifo by the ISR.
5717+ */
5718+ if(core_if->en_multiple_tx_fifo == 0) {
5719+ intr_mask.b.nptxfempty = 1;
5720+ dwc_modify_reg32(&core_if->core_global_regs->gintmsk,
5721+ intr_mask.d32, intr_mask.d32);
5722+ }
5723+ else {
5724+ /* Enable the Tx FIFO Empty Interrupt for this EP */
5725+ if(ep->xfer_len > 0) {
5726+ uint32_t fifoemptymsk = 0;
5727+ fifoemptymsk = 1 << ep->num;
5728+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
5729+ 0, fifoemptymsk);
5730+
5731+ }
5732+ }
5733+ }
5734+ }
5735+
5736+ /* EP enable, IN data in FIFO */
5737+ depctl.b.cnak = 1;
5738+ depctl.b.epena = 1;
5739+ dwc_write_reg32(&in_regs->diepctl, depctl.d32);
5740+
5741+ depctl.d32 = dwc_read_reg32 (&core_if->dev_if->in_ep_regs[0]->diepctl);
5742+ depctl.b.nextep = ep->num;
5743+ dwc_write_reg32 (&core_if->dev_if->in_ep_regs[0]->diepctl, depctl.d32);
5744+
5745+ DWC_DEBUGPL(DBG_PCD, "DIEPCTL(%.8x)=%08x DIEPTSIZ=%08x, DIEPINT=%.8x, DIEPDMA=%.8x, DTXFSTS=%.8x\n",
5746+ (u32)&in_regs->diepctl,
5747+ dwc_read_reg32(&in_regs->diepctl),
5748+ dwc_read_reg32(&in_regs->dieptsiz),
5749+ dwc_read_reg32(&in_regs->diepint),
5750+ dwc_read_reg32(&in_regs->diepdma),
5751+ dwc_read_reg32(&in_regs->dtxfsts));
5752+ DWC_DEBUGPL(DBG_PCD, "DAINTMSK=%08x GINTMSK=%08x\n",
5753+ dwc_read_reg32(&core_if->dev_if->dev_global_regs->daintmsk),
5754+ dwc_read_reg32(&core_if->core_global_regs->gintmsk));
5755+
5756+ }
5757+ else {
5758+ /* OUT endpoint */
5759+ dwc_otg_dev_out_ep_regs_t *out_regs =
5760+ core_if->dev_if->out_ep_regs[ep->num];
5761+
5762+ depctl.d32 = dwc_read_reg32(&(out_regs->doepctl));
5763+ deptsiz.d32 = dwc_read_reg32(&(out_regs->doeptsiz));
5764+
5765+ ep->xfer_len += (ep->maxxfer < (ep->total_len - ep->xfer_len)) ?
5766+ ep->maxxfer : (ep->total_len - ep->xfer_len);
5767+
5768+ /* Program the transfer size and packet count as follows:
5769+ *
5770+ * pktcnt = N
5771+ * xfersize = N * maxpacket
5772+ */
5773+ if ((ep->xfer_len - ep->xfer_count) == 0) {
5774+ /* Zero Length Packet */
5775+ deptsiz.b.xfersize = ep->maxpacket;
5776+ deptsiz.b.pktcnt = 1;
5777+ }
5778+ else {
5779+ deptsiz.b.pktcnt =
5780+ (ep->xfer_len - ep->xfer_count + (ep->maxpacket - 1)) /
5781+ ep->maxpacket;
5782+ ep->xfer_len = deptsiz.b.pktcnt * ep->maxpacket + ep->xfer_count;
5783+ deptsiz.b.xfersize = ep->xfer_len - ep->xfer_count;
5784+ }
5785+
5786+ DWC_DEBUGPL(DBG_PCDV, "ep%d xfersize=%d pktcnt=%d\n",
5787+ ep->num,
5788+ deptsiz.b.xfersize, deptsiz.b.pktcnt);
5789+
5790+ if (core_if->dma_enable) {
5791+ if (/*(core_if->dma_enable)&&*/(ep->dma_addr==DMA_ADDR_INVALID)) {
5792+ ep->dma_addr=dma_map_single(NULL,(void *)(ep->xfer_buff),(ep->xfer_len),DMA_TO_DEVICE);
5793+ }
5794+ DWC_DEBUGPL(DBG_PCDV, "ep%d dma_addr=%.8x\n",
5795+ ep->num,
5796+ ep->dma_addr);
5797+ if (!core_if->dma_desc_enable) {
5798+ dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32);
5799+
5800+ VERIFY_PCD_DMA_ADDR(ep->dma_addr);
5801+ dwc_write_reg32 (&(out_regs->doepdma),
5802+ (uint32_t)ep->dma_addr);
5803+ }
5804+ else {
5805+ init_dma_desc_chain(core_if, ep);
5806+
5807+ /** DOEPDMAn Register write */
5808+
5809+ VERIFY_PCD_DMA_ADDR(ep->dma_desc_addr);
5810+ dwc_write_reg32(&out_regs->doepdma, ep->dma_desc_addr);
5811+ }
5812+ }
5813+ else {
5814+ dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32);
5815+ }
5816+
5817+ /* EP enable */
5818+ depctl.b.cnak = 1;
5819+ depctl.b.epena = 1;
5820+
5821+ dwc_write_reg32(&out_regs->doepctl, depctl.d32);
5822+
5823+ DWC_DEBUGPL(DBG_PCD, "DOEPCTL(%.8x)=%08x DOEPTSIZ=%08x, DOEPINT=%.8x, DOEPDMA=%.8x\n",
5824+ (u32)&out_regs->doepctl,
5825+ dwc_read_reg32(&out_regs->doepctl),
5826+ dwc_read_reg32(&out_regs->doeptsiz),
5827+ dwc_read_reg32(&out_regs->doepint),
5828+ dwc_read_reg32(&out_regs->doepdma));
5829+
5830+ DWC_DEBUGPL(DBG_PCD, "DAINTMSK=%08x GINTMSK=%08x\n",
5831+ dwc_read_reg32(&core_if->dev_if->dev_global_regs->daintmsk),
5832+ dwc_read_reg32(&core_if->core_global_regs->gintmsk));
5833+ }
5834+}
5835+
5836+/**
5837+ * This function setup a zero length transfer in Buffer DMA and
5838+ * Slave modes for usb requests with zero field set
5839+ *
5840+ * @param core_if Programming view of DWC_otg controller.
5841+ * @param ep The EP to start the transfer on.
5842+ *
5843+ */
5844+void dwc_otg_ep_start_zl_transfer(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
5845+{
5846+
5847+ depctl_data_t depctl;
5848+ deptsiz_data_t deptsiz;
5849+ gintmsk_data_t intr_mask = { .d32 = 0};
5850+
5851+ DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s()\n", __func__);
5852+
5853+ /* IN endpoint */
5854+ if (ep->is_in == 1) {
5855+ dwc_otg_dev_in_ep_regs_t *in_regs =
5856+ core_if->dev_if->in_ep_regs[ep->num];
5857+
5858+ depctl.d32 = dwc_read_reg32(&(in_regs->diepctl));
5859+ deptsiz.d32 = dwc_read_reg32(&(in_regs->dieptsiz));
5860+
5861+ deptsiz.b.xfersize = 0;
5862+ deptsiz.b.pktcnt = 1;
5863+
5864+
5865+ /* Write the DMA register */
5866+ if (core_if->dma_enable) {
5867+ if (/*(core_if->dma_enable)&&*/(ep->dma_addr==DMA_ADDR_INVALID)) {
5868+ ep->dma_addr=dma_map_single(NULL,(void *)(ep->xfer_buff),(ep->xfer_len),DMA_TO_DEVICE);
5869+ }
5870+ if (core_if->dma_desc_enable == 0) {
5871+ dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
5872+
5873+ VERIFY_PCD_DMA_ADDR(ep->dma_addr);
5874+ dwc_write_reg32 (&(in_regs->diepdma),
5875+ (uint32_t)ep->dma_addr);
5876+ }
5877+ }
5878+ else {
5879+ dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
5880+ /**
5881+ * Enable the Non-Periodic Tx FIFO empty interrupt,
5882+ * or the Tx FIFO epmty interrupt in dedicated Tx FIFO mode,
5883+ * the data will be written into the fifo by the ISR.
5884+ */
5885+ if(core_if->en_multiple_tx_fifo == 0) {
5886+ intr_mask.b.nptxfempty = 1;
5887+ dwc_modify_reg32(&core_if->core_global_regs->gintmsk,
5888+ intr_mask.d32, intr_mask.d32);
5889+ }
5890+ else {
5891+ /* Enable the Tx FIFO Empty Interrupt for this EP */
5892+ if(ep->xfer_len > 0) {
5893+ uint32_t fifoemptymsk = 0;
5894+ fifoemptymsk = 1 << ep->num;
5895+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
5896+ 0, fifoemptymsk);
5897+ }
5898+ }
5899+ }
5900+
5901+ /* EP enable, IN data in FIFO */
5902+ depctl.b.cnak = 1;
5903+ depctl.b.epena = 1;
5904+ dwc_write_reg32(&in_regs->diepctl, depctl.d32);
5905+
5906+ depctl.d32 = dwc_read_reg32 (&core_if->dev_if->in_ep_regs[0]->diepctl);
5907+ depctl.b.nextep = ep->num;
5908+ dwc_write_reg32 (&core_if->dev_if->in_ep_regs[0]->diepctl, depctl.d32);
5909+
5910+ }
5911+ else {
5912+ /* OUT endpoint */
5913+ dwc_otg_dev_out_ep_regs_t *out_regs =
5914+ core_if->dev_if->out_ep_regs[ep->num];
5915+
5916+ depctl.d32 = dwc_read_reg32(&(out_regs->doepctl));
5917+ deptsiz.d32 = dwc_read_reg32(&(out_regs->doeptsiz));
5918+
5919+ /* Zero Length Packet */
5920+ deptsiz.b.xfersize = ep->maxpacket;
5921+ deptsiz.b.pktcnt = 1;
5922+
5923+ if (core_if->dma_enable) {
5924+ if (/*(core_if->dma_enable)&&*/(ep->dma_addr==DMA_ADDR_INVALID)) {
5925+ ep->dma_addr=dma_map_single(NULL,(void *)(ep->xfer_buff),(ep->xfer_len),DMA_TO_DEVICE);
5926+ }
5927+ if (!core_if->dma_desc_enable) {
5928+ dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32);
5929+
5930+
5931+ VERIFY_PCD_DMA_ADDR(ep->dma_addr);
5932+ dwc_write_reg32 (&(out_regs->doepdma),
5933+ (uint32_t)ep->dma_addr);
5934+ }
5935+ }
5936+ else {
5937+ dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32);
5938+ }
5939+
5940+ /* EP enable */
5941+ depctl.b.cnak = 1;
5942+ depctl.b.epena = 1;
5943+
5944+ dwc_write_reg32(&out_regs->doepctl, depctl.d32);
5945+
5946+ }
5947+}
5948+
5949+/**
5950+ * This function does the setup for a data transfer for EP0 and starts
5951+ * the transfer. For an IN transfer, the packets will be loaded into
5952+ * the appropriate Tx FIFO in the ISR. For OUT transfers, the packets are
5953+ * unloaded from the Rx FIFO in the ISR.
5954+ *
5955+ * @param core_if Programming view of DWC_otg controller.
5956+ * @param ep The EP0 data.
5957+ */
5958+void dwc_otg_ep0_start_transfer(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
5959+{
5960+ depctl_data_t depctl;
5961+ deptsiz0_data_t deptsiz;
5962+ gintmsk_data_t intr_mask = { .d32 = 0};
5963+ dwc_otg_dma_desc_t* dma_desc;
5964+
5965+ DWC_DEBUGPL(DBG_PCD, "ep%d-%s xfer_len=%d xfer_cnt=%d "
5966+ "xfer_buff=%p start_xfer_buff=%p, dma_addr=%.8x\n",
5967+ ep->num, (ep->is_in?"IN":"OUT"), ep->xfer_len,
5968+ ep->xfer_count, ep->xfer_buff, ep->start_xfer_buff,ep->dma_addr);
5969+
5970+ ep->total_len = ep->xfer_len;
5971+
5972+ /* IN endpoint */
5973+ if (ep->is_in == 1) {
5974+ dwc_otg_dev_in_ep_regs_t *in_regs =
5975+ core_if->dev_if->in_ep_regs[0];
5976+
5977+ gnptxsts_data_t gtxstatus;
5978+
5979+ gtxstatus.d32 =
5980+ dwc_read_reg32(&core_if->core_global_regs->gnptxsts);
5981+
5982+ if(core_if->en_multiple_tx_fifo == 0 && gtxstatus.b.nptxqspcavail == 0) {
5983+#ifdef DEBUG
5984+ deptsiz.d32 = dwc_read_reg32(&in_regs->dieptsiz);
5985+ DWC_DEBUGPL(DBG_PCD,"DIEPCTL0=%0x\n",
5986+ dwc_read_reg32(&in_regs->diepctl));
5987+ DWC_DEBUGPL(DBG_PCD, "DIEPTSIZ0=%0x (sz=%d, pcnt=%d)\n",
5988+ deptsiz.d32,
5989+ deptsiz.b.xfersize, deptsiz.b.pktcnt);
5990+ DWC_PRINT("TX Queue or FIFO Full (0x%0x)\n",
5991+ gtxstatus.d32);
5992+#endif
5993+ return;
5994+ }
5995+
5996+
5997+ depctl.d32 = dwc_read_reg32(&in_regs->diepctl);
5998+ deptsiz.d32 = dwc_read_reg32(&in_regs->dieptsiz);
5999+
6000+ /* Zero Length Packet? */
6001+ if (ep->xfer_len == 0) {
6002+ deptsiz.b.xfersize = 0;
6003+ deptsiz.b.pktcnt = 1;
6004+ }
6005+ else {
6006+ /* Program the transfer size and packet count
6007+ * as follows: xfersize = N * maxpacket +
6008+ * short_packet pktcnt = N + (short_packet
6009+ * exist ? 1 : 0)
6010+ */
6011+ if (ep->xfer_len > ep->maxpacket) {
6012+ ep->xfer_len = ep->maxpacket;
6013+ deptsiz.b.xfersize = ep->maxpacket;
6014+ }
6015+ else {
6016+ deptsiz.b.xfersize = ep->xfer_len;
6017+ }
6018+ deptsiz.b.pktcnt = 1;
6019+
6020+ }
6021+ DWC_DEBUGPL(DBG_PCDV, "IN len=%d xfersize=%d pktcnt=%d [%08x]\n",
6022+ ep->xfer_len,
6023+ deptsiz.b.xfersize, deptsiz.b.pktcnt, deptsiz.d32);
6024+ /* Write the DMA register */
6025+ if (core_if->dma_enable) {
6026+ if (/*(core_if->dma_enable)&&*/(ep->dma_addr==DMA_ADDR_INVALID)) {
6027+ ep->dma_addr=dma_map_single(NULL,(void *)(ep->xfer_buff),(ep->xfer_len),DMA_TO_DEVICE);
6028+ }
6029+ if(core_if->dma_desc_enable == 0) {
6030+ dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
6031+
6032+ VERIFY_PCD_DMA_ADDR(ep->dma_addr);
6033+ dwc_write_reg32 (&(in_regs->diepdma),
6034+ (uint32_t)ep->dma_addr);
6035+ }
6036+ else {
6037+ dma_desc = core_if->dev_if->in_desc_addr;
6038+
6039+ /** DMA Descriptor Setup */
6040+ dma_desc->status.b.bs = BS_HOST_BUSY;
6041+ dma_desc->status.b.l = 1;
6042+ dma_desc->status.b.ioc = 1;
6043+ dma_desc->status.b.sp = (ep->xfer_len == ep->maxpacket) ? 0 : 1;
6044+ dma_desc->status.b.bytes = ep->xfer_len;
6045+ dma_desc->buf = ep->dma_addr;
6046+ dma_desc->status.b.bs = BS_HOST_READY;
6047+
6048+ /** DIEPDMA0 Register write */
6049+
6050+ VERIFY_PCD_DMA_ADDR(core_if->dev_if->dma_in_desc_addr);
6051+ dwc_write_reg32(&in_regs->diepdma, core_if->dev_if->dma_in_desc_addr);
6052+ }
6053+ }
6054+ else {
6055+ dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
6056+ }
6057+
6058+ /* EP enable, IN data in FIFO */
6059+ depctl.b.cnak = 1;
6060+ depctl.b.epena = 1;
6061+ dwc_write_reg32(&in_regs->diepctl, depctl.d32);
6062+
6063+ /**
6064+ * Enable the Non-Periodic Tx FIFO empty interrupt, the
6065+ * data will be written into the fifo by the ISR.
6066+ */
6067+ if (!core_if->dma_enable) {
6068+ if(core_if->en_multiple_tx_fifo == 0) {
6069+ intr_mask.b.nptxfempty = 1;
6070+ dwc_modify_reg32(&core_if->core_global_regs->gintmsk,
6071+ intr_mask.d32, intr_mask.d32);
6072+ }
6073+ else {
6074+ /* Enable the Tx FIFO Empty Interrupt for this EP */
6075+ if(ep->xfer_len > 0) {
6076+ uint32_t fifoemptymsk = 0;
6077+ fifoemptymsk |= 1 << ep->num;
6078+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
6079+ 0, fifoemptymsk);
6080+ }
6081+ }
6082+ }
6083+ }
6084+ else {
6085+ /* OUT endpoint */
6086+ dwc_otg_dev_out_ep_regs_t *out_regs =
6087+ core_if->dev_if->out_ep_regs[0];
6088+
6089+ depctl.d32 = dwc_read_reg32(&out_regs->doepctl);
6090+ deptsiz.d32 = dwc_read_reg32(&out_regs->doeptsiz);
6091+
6092+ /* Program the transfer size and packet count as follows:
6093+ * xfersize = N * (maxpacket + 4 - (maxpacket % 4))
6094+ * pktcnt = N */
6095+ /* Zero Length Packet */
6096+ deptsiz.b.xfersize = ep->maxpacket;
6097+ deptsiz.b.pktcnt = 1;
6098+
6099+ DWC_DEBUGPL(DBG_PCDV, "len=%d xfersize=%d pktcnt=%d\n",
6100+ ep->xfer_len,
6101+ deptsiz.b.xfersize, deptsiz.b.pktcnt);
6102+
6103+ if (core_if->dma_enable) {
6104+ if (/*(core_if->dma_enable)&&*/(ep->dma_addr==DMA_ADDR_INVALID)) {
6105+ ep->dma_addr=dma_map_single(NULL,(void *)(ep->xfer_buff),(ep->xfer_len),DMA_TO_DEVICE);
6106+ }
6107+ if(!core_if->dma_desc_enable) {
6108+ dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32);
6109+
6110+
6111+ VERIFY_PCD_DMA_ADDR(ep->dma_addr);
6112+ dwc_write_reg32 (&(out_regs->doepdma),
6113+ (uint32_t)ep->dma_addr);
6114+ }
6115+ else {
6116+ dma_desc = core_if->dev_if->out_desc_addr;
6117+
6118+ /** DMA Descriptor Setup */
6119+ dma_desc->status.b.bs = BS_HOST_BUSY;
6120+ dma_desc->status.b.l = 1;
6121+ dma_desc->status.b.ioc = 1;
6122+ dma_desc->status.b.bytes = ep->maxpacket;
6123+ dma_desc->buf = ep->dma_addr;
6124+ dma_desc->status.b.bs = BS_HOST_READY;
6125+
6126+ /** DOEPDMA0 Register write */
6127+ VERIFY_PCD_DMA_ADDR(core_if->dev_if->dma_out_desc_addr);
6128+ dwc_write_reg32(&out_regs->doepdma, core_if->dev_if->dma_out_desc_addr);
6129+ }
6130+ }
6131+ else {
6132+ dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32);
6133+ }
6134+
6135+ /* EP enable */
6136+ depctl.b.cnak = 1;
6137+ depctl.b.epena = 1;
6138+ dwc_write_reg32 (&(out_regs->doepctl), depctl.d32);
6139+ }
6140+}
6141+
6142+/**
6143+ * This function continues control IN transfers started by
6144+ * dwc_otg_ep0_start_transfer, when the transfer does not fit in a
6145+ * single packet. NOTE: The DIEPCTL0/DOEPCTL0 registers only have one
6146+ * bit for the packet count.
6147+ *
6148+ * @param core_if Programming view of DWC_otg controller.
6149+ * @param ep The EP0 data.
6150+ */
6151+void dwc_otg_ep0_continue_transfer(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
6152+{
6153+ depctl_data_t depctl;
6154+ deptsiz0_data_t deptsiz;
6155+ gintmsk_data_t intr_mask = { .d32 = 0};
6156+ dwc_otg_dma_desc_t* dma_desc;
6157+
6158+ if (ep->is_in == 1) {
6159+ dwc_otg_dev_in_ep_regs_t *in_regs =
6160+ core_if->dev_if->in_ep_regs[0];
6161+ gnptxsts_data_t tx_status = { .d32 = 0 };
6162+
6163+ tx_status.d32 = dwc_read_reg32(&core_if->core_global_regs->gnptxsts);
6164+ /** @todo Should there be check for room in the Tx
6165+ * Status Queue. If not remove the code above this comment. */
6166+
6167+ depctl.d32 = dwc_read_reg32(&in_regs->diepctl);
6168+ deptsiz.d32 = dwc_read_reg32(&in_regs->dieptsiz);
6169+
6170+ /* Program the transfer size and packet count
6171+ * as follows: xfersize = N * maxpacket +
6172+ * short_packet pktcnt = N + (short_packet
6173+ * exist ? 1 : 0)
6174+ */
6175+
6176+
6177+ if(core_if->dma_desc_enable == 0) {
6178+ deptsiz.b.xfersize = (ep->total_len - ep->xfer_count) > ep->maxpacket ? ep->maxpacket :
6179+ (ep->total_len - ep->xfer_count);
6180+ deptsiz.b.pktcnt = 1;
6181+ if(core_if->dma_enable == 0) {
6182+ ep->xfer_len += deptsiz.b.xfersize;
6183+ } else {
6184+ ep->xfer_len = deptsiz.b.xfersize;
6185+ }
6186+ dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
6187+ }
6188+ else {
6189+ ep->xfer_len = (ep->total_len - ep->xfer_count) > ep->maxpacket ? ep->maxpacket :
6190+ (ep->total_len - ep->xfer_count);
6191+
6192+ dma_desc = core_if->dev_if->in_desc_addr;
6193+
6194+ /** DMA Descriptor Setup */
6195+ dma_desc->status.b.bs = BS_HOST_BUSY;
6196+ dma_desc->status.b.l = 1;
6197+ dma_desc->status.b.ioc = 1;
6198+ dma_desc->status.b.sp = (ep->xfer_len == ep->maxpacket) ? 0 : 1;
6199+ dma_desc->status.b.bytes = ep->xfer_len;
6200+ dma_desc->buf = ep->dma_addr;
6201+ dma_desc->status.b.bs = BS_HOST_READY;
6202+
6203+
6204+ /** DIEPDMA0 Register write */
6205+ VERIFY_PCD_DMA_ADDR(core_if->dev_if->dma_in_desc_addr);
6206+ dwc_write_reg32(&in_regs->diepdma, core_if->dev_if->dma_in_desc_addr);
6207+ }
6208+
6209+
6210+ DWC_DEBUGPL(DBG_PCDV, "IN len=%d xfersize=%d pktcnt=%d [%08x]\n",
6211+ ep->xfer_len,
6212+ deptsiz.b.xfersize, deptsiz.b.pktcnt, deptsiz.d32);
6213+
6214+ /* Write the DMA register */
6215+ if (core_if->hwcfg2.b.architecture == DWC_INT_DMA_ARCH) {
6216+ if(core_if->dma_desc_enable == 0){
6217+
6218+ VERIFY_PCD_DMA_ADDR(ep->dma_addr);
6219+ dwc_write_reg32 (&(in_regs->diepdma), (uint32_t)ep->dma_addr);
6220+ }
6221+ }
6222+
6223+ /* EP enable, IN data in FIFO */
6224+ depctl.b.cnak = 1;
6225+ depctl.b.epena = 1;
6226+ dwc_write_reg32(&in_regs->diepctl, depctl.d32);
6227+
6228+ /**
6229+ * Enable the Non-Periodic Tx FIFO empty interrupt, the
6230+ * data will be written into the fifo by the ISR.
6231+ */
6232+ if (!core_if->dma_enable) {
6233+ if(core_if->en_multiple_tx_fifo == 0) {
6234+ /* First clear it from GINTSTS */
6235+ intr_mask.b.nptxfempty = 1;
6236+ dwc_modify_reg32(&core_if->core_global_regs->gintmsk,
6237+ intr_mask.d32, intr_mask.d32);
6238+
6239+ }
6240+ else {
6241+ /* Enable the Tx FIFO Empty Interrupt for this EP */
6242+ if(ep->xfer_len > 0) {
6243+ uint32_t fifoemptymsk = 0;
6244+ fifoemptymsk |= 1 << ep->num;
6245+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
6246+ 0, fifoemptymsk);
6247+ }
6248+ }
6249+ }
6250+ }
6251+ else {
6252+ dwc_otg_dev_out_ep_regs_t *out_regs =
6253+ core_if->dev_if->out_ep_regs[0];
6254+
6255+
6256+ depctl.d32 = dwc_read_reg32(&out_regs->doepctl);
6257+ deptsiz.d32 = dwc_read_reg32(&out_regs->doeptsiz);
6258+
6259+ /* Program the transfer size and packet count
6260+ * as follows: xfersize = N * maxpacket +
6261+ * short_packet pktcnt = N + (short_packet
6262+ * exist ? 1 : 0)
6263+ */
6264+ deptsiz.b.xfersize = ep->maxpacket;
6265+ deptsiz.b.pktcnt = 1;
6266+
6267+
6268+ if(core_if->dma_desc_enable == 0) {
6269+ dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32);
6270+ }
6271+ else {
6272+ dma_desc = core_if->dev_if->out_desc_addr;
6273+
6274+ /** DMA Descriptor Setup */
6275+ dma_desc->status.b.bs = BS_HOST_BUSY;
6276+ dma_desc->status.b.l = 1;
6277+ dma_desc->status.b.ioc = 1;
6278+ dma_desc->status.b.bytes = ep->maxpacket;
6279+ dma_desc->buf = ep->dma_addr;
6280+ dma_desc->status.b.bs = BS_HOST_READY;
6281+
6282+ /** DOEPDMA0 Register write */
6283+ VERIFY_PCD_DMA_ADDR(core_if->dev_if->dma_out_desc_addr);
6284+ dwc_write_reg32(&out_regs->doepdma, core_if->dev_if->dma_out_desc_addr);
6285+ }
6286+
6287+
6288+ DWC_DEBUGPL(DBG_PCDV, "IN len=%d xfersize=%d pktcnt=%d [%08x]\n",
6289+ ep->xfer_len,
6290+ deptsiz.b.xfersize, deptsiz.b.pktcnt, deptsiz.d32);
6291+
6292+ /* Write the DMA register */
6293+ if (core_if->hwcfg2.b.architecture == DWC_INT_DMA_ARCH) {
6294+ if(core_if->dma_desc_enable == 0){
6295+
6296+ VERIFY_PCD_DMA_ADDR(ep->dma_addr);
6297+ dwc_write_reg32 (&(out_regs->doepdma), (uint32_t)ep->dma_addr);
6298+ }
6299+ }
6300+
6301+ /* EP enable, IN data in FIFO */
6302+ depctl.b.cnak = 1;
6303+ depctl.b.epena = 1;
6304+ dwc_write_reg32(&out_regs->doepctl, depctl.d32);
6305+
6306+ }
6307+}
6308+
6309+#ifdef DEBUG
6310+void dump_msg(const u8 *buf, unsigned int length)
6311+{
6312+ unsigned int start, num, i;
6313+ char line[52], *p;
6314+
6315+ if (length >= 512)
6316+ return;
6317+ start = 0;
6318+ while (length > 0) {
6319+ num = min(length, 16u);
6320+ p = line;
6321+ for (i = 0; i < num; ++i)
6322+ {
6323+ if (i == 8)
6324+ *p++ = ' ';
6325+ sprintf(p, " %02x", buf[i]);
6326+ p += 3;
6327+ }
6328+ *p = 0;
6329+ DWC_PRINT("%6x: %s\n", start, line);
6330+ buf += num;
6331+ start += num;
6332+ length -= num;
6333+ }
6334+}
6335+#else
6336+static inline void dump_msg(const u8 *buf, unsigned int length)
6337+{
6338+}
6339+#endif
6340+
6341+/**
6342+ * This function writes a packet into the Tx FIFO associated with the
6343+ * EP. For non-periodic EPs the non-periodic Tx FIFO is written. For
6344+ * periodic EPs the periodic Tx FIFO associated with the EP is written
6345+ * with all packets for the next micro-frame.
6346+ *
6347+ * @param core_if Programming view of DWC_otg controller.
6348+ * @param ep The EP to write packet for.
6349+ * @param dma Indicates if DMA is being used.
6350+ */
6351+void dwc_otg_ep_write_packet(dwc_otg_core_if_t *core_if, dwc_ep_t *ep, int dma)
6352+{
6353+ /**
6354+ * The buffer is padded to DWORD on a per packet basis in
6355+ * slave/dma mode if the MPS is not DWORD aligned. The last
6356+ * packet, if short, is also padded to a multiple of DWORD.
6357+ *
6358+ * ep->xfer_buff always starts DWORD aligned in memory and is a
6359+ * multiple of DWORD in length
6360+ *
6361+ * ep->xfer_len can be any number of bytes
6362+ *
6363+ * ep->xfer_count is a multiple of ep->maxpacket until the last
6364+ * packet
6365+ *
6366+ * FIFO access is DWORD */
6367+
6368+ uint32_t i;
6369+ uint32_t byte_count;
6370+ uint32_t dword_count;
6371+ uint32_t *fifo;
6372+ uint32_t *data_buff = (uint32_t *)ep->xfer_buff;
6373+
6374+ DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s(%p,%p)\n", __func__, core_if, ep);
6375+ if (ep->xfer_count >= ep->xfer_len) {
6376+ DWC_WARN("%s() No data for EP%d!!!\n", __func__, ep->num);
6377+ return;
6378+ }
6379+
6380+ /* Find the byte length of the packet either short packet or MPS */
6381+ if ((ep->xfer_len - ep->xfer_count) < ep->maxpacket) {
6382+ byte_count = ep->xfer_len - ep->xfer_count;
6383+ }
6384+ else {
6385+ byte_count = ep->maxpacket;
6386+ }
6387+
6388+ /* Find the DWORD length, padded by extra bytes as neccessary if MPS
6389+ * is not a multiple of DWORD */
6390+ dword_count = (byte_count + 3) / 4;
6391+
6392+#ifdef VERBOSE
6393+ dump_msg(ep->xfer_buff, byte_count);
6394+#endif
6395+
6396+ /**@todo NGS Where are the Periodic Tx FIFO addresses
6397+ * intialized? What should this be? */
6398+
6399+ fifo = core_if->data_fifo[ep->num];
6400+
6401+
6402+ DWC_DEBUGPL((DBG_PCDV|DBG_CILV), "fifo=%p buff=%p *p=%08x bc=%d\n", fifo, data_buff, *data_buff, byte_count);
6403+
6404+ if (!dma) {
6405+ for (i=0; i<dword_count; i++, data_buff++) {
6406+ dwc_write_reg32(fifo, *data_buff);
6407+ }
6408+ }
6409+
6410+ ep->xfer_count += byte_count;
6411+ ep->xfer_buff += byte_count;
6412+ ep->dma_addr += byte_count;
6413+}
6414+
6415+/**
6416+ * Set the EP STALL.
6417+ *
6418+ * @param core_if Programming view of DWC_otg controller.
6419+ * @param ep The EP to set the stall on.
6420+ */
6421+void dwc_otg_ep_set_stall(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
6422+{
6423+ depctl_data_t depctl;
6424+ volatile uint32_t *depctl_addr;
6425+
6426+ DWC_DEBUGPL(DBG_PCDV, "%s ep%d-%s1\n", __func__, ep->num,
6427+ (ep->is_in?"IN":"OUT"));
6428+
6429+ DWC_PRINT("%s ep%d-%s\n", __func__, ep->num,
6430+ (ep->is_in?"in":"out"));
6431+
6432+ if (ep->is_in == 1) {
6433+ depctl_addr = &(core_if->dev_if->in_ep_regs[ep->num]->diepctl);
6434+ depctl.d32 = dwc_read_reg32(depctl_addr);
6435+
6436+ /* set the disable and stall bits */
6437+#if 0
6438+//epdis is set here but not cleared at latter dwc_otg_ep_clear_stall,
6439+//which cause the testusb item 13 failed(Host:pc, device: otg device)
6440+ if (depctl.b.epena) {
6441+ depctl.b.epdis = 1;
6442+ }
6443+#endif
6444+ depctl.b.stall = 1;
6445+ dwc_write_reg32(depctl_addr, depctl.d32);
6446+ }
6447+ else {
6448+ depctl_addr = &(core_if->dev_if->out_ep_regs[ep->num]->doepctl);
6449+ depctl.d32 = dwc_read_reg32(depctl_addr);
6450+
6451+ /* set the stall bit */
6452+ depctl.b.stall = 1;
6453+ dwc_write_reg32(depctl_addr, depctl.d32);
6454+ }
6455+
6456+ DWC_DEBUGPL(DBG_PCDV,"%s: DEPCTL(%.8x)=%0x\n",__func__,(u32)depctl_addr,dwc_read_reg32(depctl_addr));
6457+
6458+ return;
6459+}
6460+
6461+/**
6462+ * Clear the EP STALL.
6463+ *
6464+ * @param core_if Programming view of DWC_otg controller.
6465+ * @param ep The EP to clear stall from.
6466+ */
6467+void dwc_otg_ep_clear_stall(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
6468+{
6469+ depctl_data_t depctl;
6470+ volatile uint32_t *depctl_addr;
6471+
6472+ DWC_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, ep->num,
6473+ (ep->is_in?"IN":"OUT"));
6474+
6475+ if (ep->is_in == 1) {
6476+ depctl_addr = &(core_if->dev_if->in_ep_regs[ep->num]->diepctl);
6477+ }
6478+ else {
6479+ depctl_addr = &(core_if->dev_if->out_ep_regs[ep->num]->doepctl);
6480+ }
6481+
6482+ depctl.d32 = dwc_read_reg32(depctl_addr);
6483+
6484+ /* clear the stall bits */
6485+ depctl.b.stall = 0;
6486+
6487+ /*
6488+ * USB Spec 9.4.5: For endpoints using data toggle, regardless
6489+ * of whether an endpoint has the Halt feature set, a
6490+ * ClearFeature(ENDPOINT_HALT) request always results in the
6491+ * data toggle being reinitialized to DATA0.
6492+ */
6493+ if (ep->type == DWC_OTG_EP_TYPE_INTR ||
6494+ ep->type == DWC_OTG_EP_TYPE_BULK) {
6495+ depctl.b.setd0pid = 1; /* DATA0 */
6496+ }
6497+
6498+ dwc_write_reg32(depctl_addr, depctl.d32);
6499+ DWC_DEBUGPL(DBG_PCD,"DEPCTL=%0x\n",dwc_read_reg32(depctl_addr));
6500+ return;
6501+}
6502+
6503+/**
6504+ * This function reads a packet from the Rx FIFO into the destination
6505+ * buffer. To read SETUP data use dwc_otg_read_setup_packet.
6506+ *
6507+ * @param core_if Programming view of DWC_otg controller.
6508+ * @param dest Destination buffer for the packet.
6509+ * @param bytes Number of bytes to copy to the destination.
6510+ */
6511+void dwc_otg_read_packet(dwc_otg_core_if_t *core_if,
6512+ uint8_t *dest,
6513+ uint16_t bytes)
6514+{
6515+ int i;
6516+ int word_count = (bytes + 3) / 4;
6517+
6518+ volatile uint32_t *fifo = core_if->data_fifo[0];
6519+ uint32_t *data_buff = (uint32_t *)dest;
6520+
6521+ /**
6522+ * @todo Account for the case where _dest is not dword aligned. This
6523+ * requires reading data from the FIFO into a uint32_t temp buffer,
6524+ * then moving it into the data buffer.
6525+ */
6526+
6527+ DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s(%p,%p,%d)\n", __func__,
6528+ core_if, dest, bytes);
6529+
6530+ for (i=0; i<word_count; i++, data_buff++)
6531+ {
6532+ *data_buff = dwc_read_reg32(fifo);
6533+ }
6534+
6535+ return;
6536+}
6537+
6538+
6539+
6540+/**
6541+ * This functions reads the device registers and prints them
6542+ *
6543+ * @param core_if Programming view of DWC_otg controller.
6544+ */
6545+void dwc_otg_dump_dev_registers(dwc_otg_core_if_t *core_if)
6546+{
6547+ int i;
6548+ volatile uint32_t *addr;
6549+
6550+ DWC_PRINT("Device Global Registers\n");
6551+ addr=&core_if->dev_if->dev_global_regs->dcfg;
6552+ DWC_PRINT("DCFG @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6553+ addr=&core_if->dev_if->dev_global_regs->dctl;
6554+ DWC_PRINT("DCTL @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6555+ addr=&core_if->dev_if->dev_global_regs->dsts;
6556+ DWC_PRINT("DSTS @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6557+ addr=&core_if->dev_if->dev_global_regs->diepmsk;
6558+ DWC_PRINT("DIEPMSK @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6559+ addr=&core_if->dev_if->dev_global_regs->doepmsk;
6560+ DWC_PRINT("DOEPMSK @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6561+ addr=&core_if->dev_if->dev_global_regs->daint;
6562+ DWC_PRINT("DAINT @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6563+ addr=&core_if->dev_if->dev_global_regs->daintmsk;
6564+ DWC_PRINT("DAINTMSK @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6565+ addr=&core_if->dev_if->dev_global_regs->dtknqr1;
6566+ DWC_PRINT("DTKNQR1 @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6567+ if (core_if->hwcfg2.b.dev_token_q_depth > 6) {
6568+ addr=&core_if->dev_if->dev_global_regs->dtknqr2;
6569+ DWC_PRINT("DTKNQR2 @0x%08X : 0x%08X\n",
6570+ (uint32_t)addr,dwc_read_reg32(addr));
6571+ }
6572+
6573+ addr=&core_if->dev_if->dev_global_regs->dvbusdis;
6574+ DWC_PRINT("DVBUSID @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6575+
6576+ addr=&core_if->dev_if->dev_global_regs->dvbuspulse;
6577+ DWC_PRINT("DVBUSPULSE @0x%08X : 0x%08X\n",
6578+ (uint32_t)addr,dwc_read_reg32(addr));
6579+
6580+ if (core_if->hwcfg2.b.dev_token_q_depth > 14) {
6581+ addr=&core_if->dev_if->dev_global_regs->dtknqr3_dthrctl;
6582+ DWC_PRINT("DTKNQR3_DTHRCTL @0x%08X : 0x%08X\n",
6583+ (uint32_t)addr, dwc_read_reg32(addr));
6584+ }
6585+/*
6586+ if (core_if->hwcfg2.b.dev_token_q_depth > 22) {
6587+ addr=&core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk;
6588+ DWC_PRINT("DTKNQR4 @0x%08X : 0x%08X\n",
6589+ (uint32_t)addr, dwc_read_reg32(addr));
6590+ }
6591+*/
6592+ addr=&core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk;
6593+ DWC_PRINT("FIFOEMPMSK @0x%08X : 0x%08X\n", (uint32_t)addr, dwc_read_reg32(addr));
6594+
6595+ addr=&core_if->dev_if->dev_global_regs->deachint;
6596+ DWC_PRINT("DEACHINT @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6597+ addr=&core_if->dev_if->dev_global_regs->deachintmsk;
6598+ DWC_PRINT("DEACHINTMSK @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6599+
6600+ for (i=0; i<= core_if->dev_if->num_in_eps; i++) {
6601+ addr=&core_if->dev_if->dev_global_regs->diepeachintmsk[i];
6602+ DWC_PRINT("DIEPEACHINTMSK[%d] @0x%08X : 0x%08X\n", i, (uint32_t)addr, dwc_read_reg32(addr));
6603+ }
6604+
6605+
6606+ for (i=0; i<= core_if->dev_if->num_out_eps; i++) {
6607+ addr=&core_if->dev_if->dev_global_regs->doepeachintmsk[i];
6608+ DWC_PRINT("DOEPEACHINTMSK[%d] @0x%08X : 0x%08X\n", i, (uint32_t)addr, dwc_read_reg32(addr));
6609+ }
6610+
6611+ for (i=0; i<= core_if->dev_if->num_in_eps; i++) {
6612+ DWC_PRINT("Device IN EP %d Registers\n", i);
6613+ addr=&core_if->dev_if->in_ep_regs[i]->diepctl;
6614+ DWC_PRINT("DIEPCTL @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6615+ addr=&core_if->dev_if->in_ep_regs[i]->diepint;
6616+ DWC_PRINT("DIEPINT @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6617+ addr=&core_if->dev_if->in_ep_regs[i]->dieptsiz;
6618+ DWC_PRINT("DIETSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6619+ addr=&core_if->dev_if->in_ep_regs[i]->diepdma;
6620+ DWC_PRINT("DIEPDMA @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6621+ addr=&core_if->dev_if->in_ep_regs[i]->dtxfsts;
6622+ DWC_PRINT("DTXFSTS @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6623+ //reading depdmab in non desc dma mode would halt the ahb bus...
6624+ if(core_if->dma_desc_enable){
6625+ addr=&core_if->dev_if->in_ep_regs[i]->diepdmab;
6626+ DWC_PRINT("DIEPDMAB @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6627+ }
6628+ }
6629+
6630+
6631+ for (i=0; i<= core_if->dev_if->num_out_eps; i++) {
6632+ DWC_PRINT("Device OUT EP %d Registers\n", i);
6633+ addr=&core_if->dev_if->out_ep_regs[i]->doepctl;
6634+ DWC_PRINT("DOEPCTL @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6635+ addr=&core_if->dev_if->out_ep_regs[i]->doepfn;
6636+ DWC_PRINT("DOEPFN @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6637+ addr=&core_if->dev_if->out_ep_regs[i]->doepint;
6638+ DWC_PRINT("DOEPINT @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6639+ addr=&core_if->dev_if->out_ep_regs[i]->doeptsiz;
6640+ DWC_PRINT("DOETSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6641+ addr=&core_if->dev_if->out_ep_regs[i]->doepdma;
6642+ DWC_PRINT("DOEPDMA @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6643+
6644+ //reading depdmab in non desc dma mode would halt the ahb bus...
6645+ if(core_if->dma_desc_enable){
6646+ addr=&core_if->dev_if->out_ep_regs[i]->doepdmab;
6647+ DWC_PRINT("DOEPDMAB @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6648+ }
6649+
6650+ }
6651+
6652+
6653+
6654+ return;
6655+}
6656+
6657+/**
6658+ * This functions reads the SPRAM and prints its content
6659+ *
6660+ * @param core_if Programming view of DWC_otg controller.
6661+ */
6662+void dwc_otg_dump_spram(dwc_otg_core_if_t *core_if)
6663+{
6664+ volatile uint8_t *addr, *start_addr, *end_addr;
6665+
6666+ DWC_PRINT("SPRAM Data:\n");
6667+ start_addr = (void*)core_if->core_global_regs;
6668+ DWC_PRINT("Base Address: 0x%8X\n", (uint32_t)start_addr);
6669+ start_addr += 0x00028000;
6670+ end_addr=(void*)core_if->core_global_regs;
6671+ end_addr += 0x000280e0;
6672+
6673+ for(addr = start_addr; addr < end_addr; addr+=16)
6674+ {
6675+ 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,
6676+ addr[0],
6677+ addr[1],
6678+ addr[2],
6679+ addr[3],
6680+ addr[4],
6681+ addr[5],
6682+ addr[6],
6683+ addr[7],
6684+ addr[8],
6685+ addr[9],
6686+ addr[10],
6687+ addr[11],
6688+ addr[12],
6689+ addr[13],
6690+ addr[14],
6691+ addr[15]
6692+ );
6693+ }
6694+
6695+ return;
6696+}
6697+/**
6698+ * This function reads the host registers and prints them
6699+ *
6700+ * @param core_if Programming view of DWC_otg controller.
6701+ */
6702+void dwc_otg_dump_host_registers(dwc_otg_core_if_t *core_if)
6703+{
6704+ int i;
6705+ volatile uint32_t *addr;
6706+
6707+ DWC_PRINT("Host Global Registers\n");
6708+ addr=&core_if->host_if->host_global_regs->hcfg;
6709+ DWC_PRINT("HCFG @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6710+ addr=&core_if->host_if->host_global_regs->hfir;
6711+ DWC_PRINT("HFIR @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6712+ addr=&core_if->host_if->host_global_regs->hfnum;
6713+ DWC_PRINT("HFNUM @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6714+ addr=&core_if->host_if->host_global_regs->hptxsts;
6715+ DWC_PRINT("HPTXSTS @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6716+ addr=&core_if->host_if->host_global_regs->haint;
6717+ DWC_PRINT("HAINT @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6718+ addr=&core_if->host_if->host_global_regs->haintmsk;
6719+ DWC_PRINT("HAINTMSK @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6720+ addr=core_if->host_if->hprt0;
6721+ DWC_PRINT("HPRT0 @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6722+
6723+ for (i=0; i<core_if->core_params->host_channels; i++)
6724+ {
6725+ DWC_PRINT("Host Channel %d Specific Registers\n", i);
6726+ addr=&core_if->host_if->hc_regs[i]->hcchar;
6727+ DWC_PRINT("HCCHAR @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6728+ addr=&core_if->host_if->hc_regs[i]->hcsplt;
6729+ DWC_PRINT("HCSPLT @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6730+ addr=&core_if->host_if->hc_regs[i]->hcint;
6731+ DWC_PRINT("HCINT @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6732+ addr=&core_if->host_if->hc_regs[i]->hcintmsk;
6733+ DWC_PRINT("HCINTMSK @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6734+ addr=&core_if->host_if->hc_regs[i]->hctsiz;
6735+ DWC_PRINT("HCTSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6736+ addr=&core_if->host_if->hc_regs[i]->hcdma;
6737+ DWC_PRINT("HCDMA @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6738+ }
6739+ return;
6740+}
6741+
6742+/**
6743+ * This function reads the core global registers and prints them
6744+ *
6745+ * @param core_if Programming view of DWC_otg controller.
6746+ */
6747+void dwc_otg_dump_global_registers(dwc_otg_core_if_t *core_if)
6748+{
6749+ int i,size;
6750+ char* str;
6751+ volatile uint32_t *addr;
6752+
6753+ DWC_PRINT("Core Global Registers\n");
6754+ addr=&core_if->core_global_regs->gotgctl;
6755+ DWC_PRINT("GOTGCTL @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6756+ addr=&core_if->core_global_regs->gotgint;
6757+ DWC_PRINT("GOTGINT @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6758+ addr=&core_if->core_global_regs->gahbcfg;
6759+ DWC_PRINT("GAHBCFG @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6760+ addr=&core_if->core_global_regs->gusbcfg;
6761+ DWC_PRINT("GUSBCFG @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6762+ addr=&core_if->core_global_regs->grstctl;
6763+ DWC_PRINT("GRSTCTL @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6764+ addr=&core_if->core_global_regs->gintsts;
6765+ DWC_PRINT("GINTSTS @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6766+ addr=&core_if->core_global_regs->gintmsk;
6767+ DWC_PRINT("GINTMSK @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6768+ addr=&core_if->core_global_regs->grxstsr;
6769+ DWC_PRINT("GRXSTSR @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6770+ //addr=&core_if->core_global_regs->grxstsp;
6771+ //DWC_PRINT("GRXSTSP @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6772+ addr=&core_if->core_global_regs->grxfsiz;
6773+ DWC_PRINT("GRXFSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6774+ addr=&core_if->core_global_regs->gnptxfsiz;
6775+ DWC_PRINT("GNPTXFSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6776+ addr=&core_if->core_global_regs->gnptxsts;
6777+ DWC_PRINT("GNPTXSTS @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6778+ addr=&core_if->core_global_regs->gi2cctl;
6779+ DWC_PRINT("GI2CCTL @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6780+ addr=&core_if->core_global_regs->gpvndctl;
6781+ DWC_PRINT("GPVNDCTL @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6782+ addr=&core_if->core_global_regs->ggpio;
6783+ DWC_PRINT("GGPIO @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6784+ addr=&core_if->core_global_regs->guid;
6785+ DWC_PRINT("GUID @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6786+ addr=&core_if->core_global_regs->gsnpsid;
6787+ DWC_PRINT("GSNPSID @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6788+ addr=&core_if->core_global_regs->ghwcfg1;
6789+ DWC_PRINT("GHWCFG1 @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6790+ addr=&core_if->core_global_regs->ghwcfg2;
6791+ DWC_PRINT("GHWCFG2 @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6792+ addr=&core_if->core_global_regs->ghwcfg3;
6793+ DWC_PRINT("GHWCFG3 @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6794+ addr=&core_if->core_global_regs->ghwcfg4;
6795+ DWC_PRINT("GHWCFG4 @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6796+ addr=&core_if->core_global_regs->hptxfsiz;
6797+ DWC_PRINT("HPTXFSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
6798+
6799+ size=(core_if->hwcfg4.b.ded_fifo_en)?
6800+ core_if->hwcfg4.b.num_in_eps:core_if->hwcfg4.b.num_dev_perio_in_ep;
6801+ str=(core_if->hwcfg4.b.ded_fifo_en)?"DIEPTXF":"DPTXFSIZ";
6802+ for (i=0; i<size; i++)
6803+ {
6804+ addr=&core_if->core_global_regs->dptxfsiz_dieptxf[i];
6805+ DWC_PRINT("%s[%d] @0x%08X : 0x%08X\n",str,i,(uint32_t)addr,dwc_read_reg32(addr));
6806+ }
6807+}
6808+
6809+/**
6810+ * Flush a Tx FIFO.
6811+ *
6812+ * @param core_if Programming view of DWC_otg controller.
6813+ * @param num Tx FIFO to flush.
6814+ */
6815+void dwc_otg_flush_tx_fifo(dwc_otg_core_if_t *core_if,
6816+ const int num)
6817+{
6818+ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
6819+ volatile grstctl_t greset = { .d32 = 0};
6820+ int count = 0;
6821+
6822+ DWC_DEBUGPL((DBG_CIL|DBG_PCDV), "Flush Tx FIFO %d\n", num);
6823+
6824+ greset.b.txfflsh = 1;
6825+ greset.b.txfnum = num;
6826+ dwc_write_reg32(&global_regs->grstctl, greset.d32);
6827+
6828+ do {
6829+ greset.d32 = dwc_read_reg32(&global_regs->grstctl);
6830+ if (++count > 10000) {
6831+ DWC_WARN("%s() HANG! GRSTCTL=%0x GNPTXSTS=0x%08x\n",
6832+ __func__, greset.d32,
6833+ dwc_read_reg32(&global_regs->gnptxsts));
6834+ break;
6835+ }
6836+ }
6837+ while (greset.b.txfflsh == 1);
6838+
6839+ /* Wait for 3 PHY Clocks*/
6840+ UDELAY(1);
6841+}
6842+
6843+/**
6844+ * Flush Rx FIFO.
6845+ *
6846+ * @param core_if Programming view of DWC_otg controller.
6847+ */
6848+void dwc_otg_flush_rx_fifo(dwc_otg_core_if_t *core_if)
6849+{
6850+ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
6851+ volatile grstctl_t greset = { .d32 = 0};
6852+ int count = 0;
6853+
6854+ DWC_DEBUGPL((DBG_CIL|DBG_PCDV), "%s\n", __func__);
6855+ /*
6856+ *
6857+ */
6858+ greset.b.rxfflsh = 1;
6859+ dwc_write_reg32(&global_regs->grstctl, greset.d32);
6860+
6861+ do {
6862+ greset.d32 = dwc_read_reg32(&global_regs->grstctl);
6863+ if (++count > 10000) {
6864+ DWC_WARN("%s() HANG! GRSTCTL=%0x\n", __func__,
6865+ greset.d32);
6866+ break;
6867+ }
6868+ }
6869+ while (greset.b.rxfflsh == 1);
6870+
6871+ /* Wait for 3 PHY Clocks*/
6872+ UDELAY(1);
6873+}
6874+
6875+/**
6876+ * Do core a soft reset of the core. Be careful with this because it
6877+ * resets all the internal state machines of the core.
6878+ */
6879+void dwc_otg_core_reset(dwc_otg_core_if_t *core_if)
6880+{
6881+ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
6882+ volatile grstctl_t greset = { .d32 = 0};
6883+ int count = 0;
6884+
6885+ DWC_DEBUGPL(DBG_CILV, "%s\n", __func__);
6886+ /* Wait for AHB master IDLE state. */
6887+ do {
6888+ UDELAY(10);
6889+ greset.d32 = dwc_read_reg32(&global_regs->grstctl);
6890+ if (++count > 100000) {
6891+ DWC_WARN("%s() HANG! AHB Idle GRSTCTL=%0x\n", __func__,
6892+ greset.d32);
6893+ return;
6894+ }
6895+ }
6896+ while (greset.b.ahbidle == 0);
6897+
6898+ /* Core Soft Reset */
6899+ count = 0;
6900+ greset.b.csftrst = 1;
6901+ dwc_write_reg32(&global_regs->grstctl, greset.d32);
6902+ do {
6903+ greset.d32 = dwc_read_reg32(&global_regs->grstctl);
6904+ if (++count > 10000) {
6905+ DWC_WARN("%s() HANG! Soft Reset GRSTCTL=%0x\n", __func__,
6906+ greset.d32);
6907+ break;
6908+ }
6909+ }
6910+ while (greset.b.csftrst == 1);
6911+
6912+ /* Wait for 3 PHY Clocks*/
6913+ MDELAY(100);
6914+
6915+ DWC_DEBUGPL(DBG_CILV, "GINTSTS=%.8x\n", dwc_read_reg32(&global_regs->gintsts));
6916+ DWC_DEBUGPL(DBG_CILV, "GINTSTS=%.8x\n", dwc_read_reg32(&global_regs->gintsts));
6917+ DWC_DEBUGPL(DBG_CILV, "GINTSTS=%.8x\n", dwc_read_reg32(&global_regs->gintsts));
6918+
6919+}
6920+
6921+
6922+
6923+/**
6924+ * Register HCD callbacks. The callbacks are used to start and stop
6925+ * the HCD for interrupt processing.
6926+ *
6927+ * @param core_if Programming view of DWC_otg controller.
6928+ * @param cb the HCD callback structure.
6929+ * @param p pointer to be passed to callback function (usb_hcd*).
6930+ */
6931+void dwc_otg_cil_register_hcd_callbacks(dwc_otg_core_if_t *core_if,
6932+ dwc_otg_cil_callbacks_t *cb,
6933+ void *p)
6934+{
6935+ core_if->hcd_cb = cb;
6936+ cb->p = p;
6937+}
6938+
6939+/**
6940+ * Register PCD callbacks. The callbacks are used to start and stop
6941+ * the PCD for interrupt processing.
6942+ *
6943+ * @param core_if Programming view of DWC_otg controller.
6944+ * @param cb the PCD callback structure.
6945+ * @param p pointer to be passed to callback function (pcd*).
6946+ */
6947+void dwc_otg_cil_register_pcd_callbacks(dwc_otg_core_if_t *core_if,
6948+ dwc_otg_cil_callbacks_t *cb,
6949+ void *p)
6950+{
6951+ core_if->pcd_cb = cb;
6952+ cb->p = p;
6953+}
6954+
6955+#ifdef DWC_EN_ISOC
6956+
6957+/**
6958+ * This function writes isoc data per 1 (micro)frame into tx fifo
6959+ *
6960+ * @param core_if Programming view of DWC_otg controller.
6961+ * @param ep The EP to start the transfer on.
6962+ *
6963+ */
6964+void write_isoc_frame_data(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
6965+{
6966+ dwc_otg_dev_in_ep_regs_t *ep_regs;
6967+ dtxfsts_data_t txstatus = {.d32 = 0};
6968+ uint32_t len = 0;
6969+ uint32_t dwords;
6970+
6971+ ep->xfer_len = ep->data_per_frame;
6972+ ep->xfer_count = 0;
6973+
6974+ ep_regs = core_if->dev_if->in_ep_regs[ep->num];
6975+
6976+ len = ep->xfer_len - ep->xfer_count;
6977+
6978+ if (len > ep->maxpacket) {
6979+ len = ep->maxpacket;
6980+ }
6981+
6982+ dwords = (len + 3)/4;
6983+
6984+ /* While there is space in the queue and space in the FIFO and
6985+ * More data to tranfer, Write packets to the Tx FIFO */
6986+ txstatus.d32 = dwc_read_reg32(&core_if->dev_if->in_ep_regs[ep->num]->dtxfsts);
6987+ DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n",ep->num,txstatus.d32);
6988+
6989+ while (txstatus.b.txfspcavail > dwords &&
6990+ ep->xfer_count < ep->xfer_len &&
6991+ ep->xfer_len != 0) {
6992+ /* Write the FIFO */
6993+ dwc_otg_ep_write_packet(core_if, ep, 0);
6994+
6995+ len = ep->xfer_len - ep->xfer_count;
6996+ if (len > ep->maxpacket) {
6997+ len = ep->maxpacket;
6998+ }
6999+
7000+ dwords = (len + 3)/4;
7001+ txstatus.d32 = dwc_read_reg32(&core_if->dev_if->in_ep_regs[ep->num]->dtxfsts);
7002+ DWC_DEBUGPL(DBG_PCDV,"dtxfsts[%d]=0x%08x\n", ep->num, txstatus.d32);
7003+ }
7004+}
7005+
7006+
7007+/**
7008+ * This function initializes a descriptor chain for Isochronous transfer
7009+ *
7010+ * @param core_if Programming view of DWC_otg controller.
7011+ * @param ep The EP to start the transfer on.
7012+ *
7013+ */
7014+void dwc_otg_iso_ep_start_frm_transfer(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
7015+{
7016+ deptsiz_data_t deptsiz = { .d32 = 0 };
7017+ depctl_data_t depctl = { .d32 = 0 };
7018+ dsts_data_t dsts = { .d32 = 0 };
7019+ volatile uint32_t *addr;
7020+
7021+ if(ep->is_in) {
7022+ addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl;
7023+ } else {
7024+ addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl;
7025+ }
7026+
7027+ ep->xfer_len = ep->data_per_frame;
7028+ ep->xfer_count = 0;
7029+ ep->xfer_buff = ep->cur_pkt_addr;
7030+ ep->dma_addr = ep->cur_pkt_dma_addr;
7031+
7032+ if(ep->is_in) {
7033+ /* Program the transfer size and packet count
7034+ * as follows: xfersize = N * maxpacket +
7035+ * short_packet pktcnt = N + (short_packet
7036+ * exist ? 1 : 0)
7037+ */
7038+ deptsiz.b.xfersize = ep->xfer_len;
7039+ deptsiz.b.pktcnt =
7040+ (ep->xfer_len - 1 + ep->maxpacket) /
7041+ ep->maxpacket;
7042+ deptsiz.b.mc = deptsiz.b.pktcnt;
7043+ dwc_write_reg32(&core_if->dev_if->in_ep_regs[ep->num]->dieptsiz, deptsiz.d32);
7044+
7045+ /* Write the DMA register */
7046+ if (core_if->dma_enable) {
7047+ dwc_write_reg32 (&(core_if->dev_if->in_ep_regs[ep->num]->diepdma), (uint32_t)ep->dma_addr);
7048+ }
7049+ } else {
7050+ deptsiz.b.pktcnt =
7051+ (ep->xfer_len + (ep->maxpacket - 1)) /
7052+ ep->maxpacket;
7053+ deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket;
7054+
7055+ dwc_write_reg32(&core_if->dev_if->out_ep_regs[ep->num]->doeptsiz, deptsiz.d32);
7056+
7057+ if (core_if->dma_enable) {
7058+ dwc_write_reg32 (&(core_if->dev_if->out_ep_regs[ep->num]->doepdma),
7059+ (uint32_t)ep->dma_addr);
7060+ }
7061+ }
7062+
7063+
7064+ /** Enable endpoint, clear nak */
7065+
7066+ depctl.d32 = 0;
7067+ if(ep->bInterval == 1) {
7068+ dsts.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts);
7069+ ep->next_frame = dsts.b.soffn + ep->bInterval;
7070+
7071+ if(ep->next_frame & 0x1) {
7072+ depctl.b.setd1pid = 1;
7073+ } else {
7074+ depctl.b.setd0pid = 1;
7075+ }
7076+ } else {
7077+ ep->next_frame += ep->bInterval;
7078+
7079+ if(ep->next_frame & 0x1) {
7080+ depctl.b.setd1pid = 1;
7081+ } else {
7082+ depctl.b.setd0pid = 1;
7083+ }
7084+ }
7085+ depctl.b.epena = 1;
7086+ depctl.b.cnak = 1;
7087+
7088+ dwc_modify_reg32(addr, 0, depctl.d32);
7089+ depctl.d32 = dwc_read_reg32(addr);
7090+
7091+ if(ep->is_in && core_if->dma_enable == 0) {
7092+ write_isoc_frame_data(core_if, ep);
7093+ }
7094+
7095+}
7096+
7097+#endif //DWC_EN_ISOC
7098--- /dev/null
7099+++ b/drivers/usb/host/otg/dwc_otg_cil.h
7100@@ -0,0 +1,1119 @@
7101+/* ==========================================================================
7102+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_cil.h $
7103+ * $Revision: #91 $
7104+ * $Date: 2008/09/19 $
7105+ * $Change: 1099526 $
7106+ *
7107+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
7108+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
7109+ * otherwise expressly agreed to in writing between Synopsys and you.
7110+ *
7111+ * The Software IS NOT an item of Licensed Software or Licensed Product under
7112+ * any End User Software License Agreement or Agreement for Licensed Product
7113+ * with Synopsys or any supplement thereto. You are permitted to use and
7114+ * redistribute this Software in source and binary forms, with or without
7115+ * modification, provided that redistributions of source code must retain this
7116+ * notice. You may not view, use, disclose, copy or distribute this file or
7117+ * any information contained herein except pursuant to this license grant from
7118+ * Synopsys. If you do not agree with this notice, including the disclaimer
7119+ * below, then you are not authorized to use the Software.
7120+ *
7121+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
7122+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
7123+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
7124+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
7125+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
7126+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
7127+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
7128+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
7129+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
7130+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
7131+ * DAMAGE.
7132+ * ========================================================================== */
7133+
7134+#if !defined(__DWC_CIL_H__)
7135+#define __DWC_CIL_H__
7136+
7137+#include <linux/workqueue.h>
7138+#include <linux/version.h>
7139+#include <asm/param.h>
7140+//#include <asm/arch/regs-irq.h>
7141+
7142+#include "dwc_otg_plat.h"
7143+#include "dwc_otg_regs.h"
7144+#ifdef DEBUG
7145+#include "linux/timer.h"
7146+#endif
7147+
7148+/**
7149+ * @file
7150+ * This file contains the interface to the Core Interface Layer.
7151+ */
7152+
7153+
7154+/** Macros defined for DWC OTG HW Release verison */
7155+#define OTG_CORE_REV_2_00 0x4F542000
7156+#define OTG_CORE_REV_2_60a 0x4F54260A
7157+#define OTG_CORE_REV_2_71a 0x4F54271A
7158+#define OTG_CORE_REV_2_72a 0x4F54272A
7159+
7160+/**
7161+*/
7162+typedef struct iso_pkt_info
7163+{
7164+ uint32_t offset;
7165+ uint32_t length;
7166+ int32_t status;
7167+} iso_pkt_info_t;
7168+/**
7169+ * The <code>dwc_ep</code> structure represents the state of a single
7170+ * endpoint when acting in device mode. It contains the data items
7171+ * needed for an endpoint to be activated and transfer packets.
7172+ */
7173+typedef struct dwc_ep
7174+{
7175+ /** EP number used for register address lookup */
7176+ uint8_t num;
7177+ /** EP direction 0 = OUT */
7178+ unsigned is_in : 1;
7179+ /** EP active. */
7180+ unsigned active : 1;
7181+
7182+ /** Periodic Tx FIFO # for IN EPs For INTR EP set to 0 to use non-periodic Tx FIFO
7183+ If dedicated Tx FIFOs are enabled for all IN Eps - Tx FIFO # FOR IN EPs*/
7184+ unsigned tx_fifo_num : 4;
7185+ /** EP type: 0 - Control, 1 - ISOC, 2 - BULK, 3 - INTR */
7186+ unsigned type : 2;
7187+#define DWC_OTG_EP_TYPE_CONTROL 0
7188+#define DWC_OTG_EP_TYPE_ISOC 1
7189+#define DWC_OTG_EP_TYPE_BULK 2
7190+#define DWC_OTG_EP_TYPE_INTR 3
7191+
7192+ /** DATA start PID for INTR and BULK EP */
7193+ unsigned data_pid_start : 1;
7194+ /** Frame (even/odd) for ISOC EP */
7195+ unsigned even_odd_frame : 1;
7196+ /** Max Packet bytes */
7197+ unsigned maxpacket : 11;
7198+
7199+ /** Max Transfer size */
7200+ unsigned maxxfer : 16;
7201+
7202+ /** @name Transfer state */
7203+ /** @{ */
7204+
7205+ /**
7206+ * Pointer to the beginning of the transfer buffer -- do not modify
7207+ * during transfer.
7208+ */
7209+
7210+ uint32_t dma_addr;
7211+
7212+ uint32_t dma_desc_addr;
7213+ dwc_otg_dma_desc_t* desc_addr;
7214+
7215+
7216+ uint8_t *start_xfer_buff;
7217+ /** pointer to the transfer buffer */
7218+ uint8_t *xfer_buff;
7219+ /** Number of bytes to transfer */
7220+ unsigned xfer_len : 19;
7221+ /** Number of bytes transferred. */
7222+ unsigned xfer_count : 19;
7223+ /** Sent ZLP */
7224+ unsigned sent_zlp : 1;
7225+ /** Total len for control transfer */
7226+ unsigned total_len : 19;
7227+
7228+ /** stall clear flag */
7229+ unsigned stall_clear_flag : 1;
7230+
7231+ /** Allocated DMA Desc count */
7232+ uint32_t desc_cnt;
7233+
7234+ uint32_t aligned_dma_addr;
7235+ uint32_t aligned_buf_size;
7236+ uint8_t *aligned_buf;
7237+
7238+
7239+#ifdef DWC_EN_ISOC
7240+ /**
7241+ * Variables specific for ISOC EPs
7242+ *
7243+ */
7244+ /** DMA addresses of ISOC buffers */
7245+ uint32_t dma_addr0;
7246+ uint32_t dma_addr1;
7247+
7248+ uint32_t iso_dma_desc_addr;
7249+ dwc_otg_dma_desc_t* iso_desc_addr;
7250+
7251+ /** pointer to the transfer buffers */
7252+ uint8_t *xfer_buff0;
7253+ uint8_t *xfer_buff1;
7254+
7255+ /** number of ISOC Buffer is processing */
7256+ uint32_t proc_buf_num;
7257+ /** Interval of ISOC Buffer processing */
7258+ uint32_t buf_proc_intrvl;
7259+ /** Data size for regular frame */
7260+ uint32_t data_per_frame;
7261+
7262+ /* todo - pattern data support is to be implemented in the future */
7263+ /** Data size for pattern frame */
7264+ uint32_t data_pattern_frame;
7265+ /** Frame number of pattern data */
7266+ uint32_t sync_frame;
7267+
7268+ /** bInterval */
7269+ uint32_t bInterval;
7270+ /** ISO Packet number per frame */
7271+ uint32_t pkt_per_frm;
7272+ /** Next frame num for which will be setup DMA Desc */
7273+ uint32_t next_frame;
7274+ /** Number of packets per buffer processing */
7275+ uint32_t pkt_cnt;
7276+ /** Info for all isoc packets */
7277+ iso_pkt_info_t *pkt_info;
7278+ /** current pkt number */
7279+ uint32_t cur_pkt;
7280+ /** current pkt number */
7281+ uint8_t *cur_pkt_addr;
7282+ /** current pkt number */
7283+ uint32_t cur_pkt_dma_addr;
7284+#endif //DWC_EN_ISOC
7285+/** @} */
7286+} dwc_ep_t;
7287+
7288+/*
7289+ * Reasons for halting a host channel.
7290+ */
7291+typedef enum dwc_otg_halt_status
7292+{
7293+ DWC_OTG_HC_XFER_NO_HALT_STATUS,
7294+ DWC_OTG_HC_XFER_COMPLETE,
7295+ DWC_OTG_HC_XFER_URB_COMPLETE,
7296+ DWC_OTG_HC_XFER_ACK,
7297+ DWC_OTG_HC_XFER_NAK,
7298+ DWC_OTG_HC_XFER_NYET,
7299+ DWC_OTG_HC_XFER_STALL,
7300+ DWC_OTG_HC_XFER_XACT_ERR,
7301+ DWC_OTG_HC_XFER_FRAME_OVERRUN,
7302+ DWC_OTG_HC_XFER_BABBLE_ERR,
7303+ DWC_OTG_HC_XFER_DATA_TOGGLE_ERR,
7304+ DWC_OTG_HC_XFER_AHB_ERR,
7305+ DWC_OTG_HC_XFER_PERIODIC_INCOMPLETE,
7306+ DWC_OTG_HC_XFER_URB_DEQUEUE
7307+} dwc_otg_halt_status_e;
7308+
7309+/**
7310+ * Host channel descriptor. This structure represents the state of a single
7311+ * host channel when acting in host mode. It contains the data items needed to
7312+ * transfer packets to an endpoint via a host channel.
7313+ */
7314+typedef struct dwc_hc
7315+{
7316+ /** Host channel number used for register address lookup */
7317+ uint8_t hc_num;
7318+
7319+ /** Device to access */
7320+ unsigned dev_addr : 7;
7321+
7322+ /** EP to access */
7323+ unsigned ep_num : 4;
7324+
7325+ /** EP direction. 0: OUT, 1: IN */
7326+ unsigned ep_is_in : 1;
7327+
7328+ /**
7329+ * EP speed.
7330+ * One of the following values:
7331+ * - DWC_OTG_EP_SPEED_LOW
7332+ * - DWC_OTG_EP_SPEED_FULL
7333+ * - DWC_OTG_EP_SPEED_HIGH
7334+ */
7335+ unsigned speed : 2;
7336+#define DWC_OTG_EP_SPEED_LOW 0
7337+#define DWC_OTG_EP_SPEED_FULL 1
7338+#define DWC_OTG_EP_SPEED_HIGH 2
7339+
7340+ /**
7341+ * Endpoint type.
7342+ * One of the following values:
7343+ * - DWC_OTG_EP_TYPE_CONTROL: 0
7344+ * - DWC_OTG_EP_TYPE_ISOC: 1
7345+ * - DWC_OTG_EP_TYPE_BULK: 2
7346+ * - DWC_OTG_EP_TYPE_INTR: 3
7347+ */
7348+ unsigned ep_type : 2;
7349+
7350+ /** Max packet size in bytes */
7351+ unsigned max_packet : 11;
7352+
7353+ /**
7354+ * PID for initial transaction.
7355+ * 0: DATA0,<br>
7356+ * 1: DATA2,<br>
7357+ * 2: DATA1,<br>
7358+ * 3: MDATA (non-Control EP),
7359+ * SETUP (Control EP)
7360+ */
7361+ unsigned data_pid_start : 2;
7362+#define DWC_OTG_HC_PID_DATA0 0
7363+#define DWC_OTG_HC_PID_DATA2 1
7364+#define DWC_OTG_HC_PID_DATA1 2
7365+#define DWC_OTG_HC_PID_MDATA 3
7366+#define DWC_OTG_HC_PID_SETUP 3
7367+
7368+ /** Number of periodic transactions per (micro)frame */
7369+ unsigned multi_count: 2;
7370+
7371+ /** @name Transfer State */
7372+ /** @{ */
7373+
7374+ /** Pointer to the current transfer buffer position. */
7375+ uint8_t *xfer_buff;
7376+ /** Total number of bytes to transfer. */
7377+ uint32_t xfer_len;
7378+ /** Number of bytes transferred so far. */
7379+ uint32_t xfer_count;
7380+ /** Packet count at start of transfer.*/
7381+ uint16_t start_pkt_count;
7382+
7383+ /**
7384+ * Flag to indicate whether the transfer has been started. Set to 1 if
7385+ * it has been started, 0 otherwise.
7386+ */
7387+ uint8_t xfer_started;
7388+
7389+ /**
7390+ * Set to 1 to indicate that a PING request should be issued on this
7391+ * channel. If 0, process normally.
7392+ */
7393+ uint8_t do_ping;
7394+
7395+ /**
7396+ * Set to 1 to indicate that the error count for this transaction is
7397+ * non-zero. Set to 0 if the error count is 0.
7398+ */
7399+ uint8_t error_state;
7400+
7401+ /**
7402+ * Set to 1 to indicate that this channel should be halted the next
7403+ * time a request is queued for the channel. This is necessary in
7404+ * slave mode if no request queue space is available when an attempt
7405+ * is made to halt the channel.
7406+ */
7407+ uint8_t halt_on_queue;
7408+
7409+ /**
7410+ * Set to 1 if the host channel has been halted, but the core is not
7411+ * finished flushing queued requests. Otherwise 0.
7412+ */
7413+ uint8_t halt_pending;
7414+
7415+ /**
7416+ * Reason for halting the host channel.
7417+ */
7418+ dwc_otg_halt_status_e halt_status;
7419+
7420+ /*
7421+ * Split settings for the host channel
7422+ */
7423+ uint8_t do_split; /**< Enable split for the channel */
7424+ uint8_t complete_split; /**< Enable complete split */
7425+ uint8_t hub_addr; /**< Address of high speed hub */
7426+
7427+ uint8_t port_addr; /**< Port of the low/full speed device */
7428+ /** Split transaction position
7429+ * One of the following values:
7430+ * - DWC_HCSPLIT_XACTPOS_MID
7431+ * - DWC_HCSPLIT_XACTPOS_BEGIN
7432+ * - DWC_HCSPLIT_XACTPOS_END
7433+ * - DWC_HCSPLIT_XACTPOS_ALL */
7434+ uint8_t xact_pos;
7435+
7436+ /** Set when the host channel does a short read. */
7437+ uint8_t short_read;
7438+
7439+ /**
7440+ * Number of requests issued for this channel since it was assigned to
7441+ * the current transfer (not counting PINGs).
7442+ */
7443+ uint8_t requests;
7444+
7445+ /**
7446+ * Queue Head for the transfer being processed by this channel.
7447+ */
7448+ struct dwc_otg_qh *qh;
7449+
7450+ /** @} */
7451+
7452+ /** Entry in list of host channels. */
7453+ struct list_head hc_list_entry;
7454+} dwc_hc_t;
7455+
7456+/**
7457+ * The following parameters may be specified when starting the module. These
7458+ * parameters define how the DWC_otg controller should be configured.
7459+ * Parameter values are passed to the CIL initialization function
7460+ * dwc_otg_cil_init.
7461+ */
7462+typedef struct dwc_otg_core_params
7463+{
7464+ int32_t opt;
7465+#define dwc_param_opt_default 1
7466+
7467+ /**
7468+ * Specifies the OTG capabilities. The driver will automatically
7469+ * detect the value for this parameter if none is specified.
7470+ * 0 - HNP and SRP capable (default)
7471+ * 1 - SRP Only capable
7472+ * 2 - No HNP/SRP capable
7473+ */
7474+ int32_t otg_cap;
7475+#define DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE 0
7476+#define DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE 1
7477+#define DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE 2
7478+//#define dwc_param_otg_cap_default DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE
7479+#define dwc_param_otg_cap_default DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE
7480+
7481+ /**
7482+ * Specifies whether to use slave or DMA mode for accessing the data
7483+ * FIFOs. The driver will automatically detect the value for this
7484+ * parameter if none is specified.
7485+ * 0 - Slave
7486+ * 1 - DMA (default, if available)
7487+ */
7488+ int32_t dma_enable;
7489+#define dwc_param_dma_enable_default 1
7490+
7491+ /**
7492+ * When DMA mode is enabled specifies whether to use address DMA or DMA Descritor mode for accessing the data
7493+ * FIFOs in device mode. The driver will automatically detect the value for this
7494+ * parameter if none is specified.
7495+ * 0 - address DMA
7496+ * 1 - DMA Descriptor(default, if available)
7497+ */
7498+ int32_t dma_desc_enable;
7499+#define dwc_param_dma_desc_enable_default 0
7500+ /** The DMA Burst size (applicable only for External DMA
7501+ * Mode). 1, 4, 8 16, 32, 64, 128, 256 (default 32)
7502+ */
7503+ int32_t dma_burst_size; /* Translate this to GAHBCFG values */
7504+//#define dwc_param_dma_burst_size_default 32
7505+#define dwc_param_dma_burst_size_default 1
7506+
7507+ /**
7508+ * Specifies the maximum speed of operation in host and device mode.
7509+ * The actual speed depends on the speed of the attached device and
7510+ * the value of phy_type. The actual speed depends on the speed of the
7511+ * attached device.
7512+ * 0 - High Speed (default)
7513+ * 1 - Full Speed
7514+ */
7515+ int32_t speed;
7516+#define dwc_param_speed_default 0
7517+#define DWC_SPEED_PARAM_HIGH 0
7518+#define DWC_SPEED_PARAM_FULL 1
7519+
7520+ /** Specifies whether low power mode is supported when attached
7521+ * to a Full Speed or Low Speed device in host mode.
7522+ * 0 - Don't support low power mode (default)
7523+ * 1 - Support low power mode
7524+ */
7525+ int32_t host_support_fs_ls_low_power;
7526+#define dwc_param_host_support_fs_ls_low_power_default 0
7527+
7528+ /** Specifies the PHY clock rate in low power mode when connected to a
7529+ * Low Speed device in host mode. This parameter is applicable only if
7530+ * HOST_SUPPORT_FS_LS_LOW_POWER is enabled. If PHY_TYPE is set to FS
7531+ * then defaults to 6 MHZ otherwise 48 MHZ.
7532+ *
7533+ * 0 - 48 MHz
7534+ * 1 - 6 MHz
7535+ */
7536+ int32_t host_ls_low_power_phy_clk;
7537+#define dwc_param_host_ls_low_power_phy_clk_default 0
7538+#define DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ 0
7539+#define DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ 1
7540+
7541+ /**
7542+ * 0 - Use cC FIFO size parameters
7543+ * 1 - Allow dynamic FIFO sizing (default)
7544+ */
7545+ int32_t enable_dynamic_fifo;
7546+#define dwc_param_enable_dynamic_fifo_default 1
7547+
7548+ /** Total number of 4-byte words in the data FIFO memory. This
7549+ * memory includes the Rx FIFO, non-periodic Tx FIFO, and periodic
7550+ * Tx FIFOs.
7551+ * 32 to 32768 (default 8192)
7552+ * Note: The total FIFO memory depth in the FPGA configuration is 8192.
7553+ */
7554+ int32_t data_fifo_size;
7555+#define dwc_param_data_fifo_size_default 8192
7556+
7557+ /** Number of 4-byte words in the Rx FIFO in device mode when dynamic
7558+ * FIFO sizing is enabled.
7559+ * 16 to 32768 (default 1064)
7560+ */
7561+ int32_t dev_rx_fifo_size;
7562+//#define dwc_param_dev_rx_fifo_size_default 1064
7563+#define dwc_param_dev_rx_fifo_size_default 0x100
7564+
7565+ /**
7566+ * Specifies whether dedicated transmit FIFOs are
7567+ * enabled for non periodic IN endpoints in device mode
7568+ * 0 - No
7569+ * 1 - Yes
7570+ */
7571+ int32_t en_multiple_tx_fifo;
7572+#define dwc_param_en_multiple_tx_fifo_default 1
7573+
7574+ /** Number of 4-byte words in each of the Tx FIFOs in device
7575+ * mode when dynamic FIFO sizing is enabled.
7576+ * 4 to 768 (default 256)
7577+ */
7578+ uint32_t dev_tx_fifo_size[MAX_TX_FIFOS];
7579+//#define dwc_param_dev_tx_fifo_size_default 256
7580+#define dwc_param_dev_tx_fifo_size_default 0x80
7581+
7582+ /** Number of 4-byte words in the non-periodic Tx FIFO in device mode
7583+ * when dynamic FIFO sizing is enabled.
7584+ * 16 to 32768 (default 1024)
7585+ */
7586+ int32_t dev_nperio_tx_fifo_size;
7587+//#define dwc_param_dev_nperio_tx_fifo_size_default 1024
7588+#define dwc_param_dev_nperio_tx_fifo_size_default 0x80
7589+
7590+ /** Number of 4-byte words in each of the periodic Tx FIFOs in device
7591+ * mode when dynamic FIFO sizing is enabled.
7592+ * 4 to 768 (default 256)
7593+ */
7594+ uint32_t dev_perio_tx_fifo_size[MAX_PERIO_FIFOS];
7595+//#define dwc_param_dev_perio_tx_fifo_size_default 256
7596+#define dwc_param_dev_perio_tx_fifo_size_default 0x80
7597+
7598+ /** Number of 4-byte words in the Rx FIFO in host mode when dynamic
7599+ * FIFO sizing is enabled.
7600+ * 16 to 32768 (default 1024)
7601+ */
7602+ int32_t host_rx_fifo_size;
7603+//#define dwc_param_host_rx_fifo_size_default 1024
7604+#define dwc_param_host_rx_fifo_size_default 0x292
7605+
7606+ /** Number of 4-byte words in the non-periodic Tx FIFO in host mode
7607+ * when Dynamic FIFO sizing is enabled in the core.
7608+ * 16 to 32768 (default 1024)
7609+ */
7610+ int32_t host_nperio_tx_fifo_size;
7611+//#define dwc_param_host_nperio_tx_fifo_size_default 1024
7612+//#define dwc_param_host_nperio_tx_fifo_size_default 0x292
7613+#define dwc_param_host_nperio_tx_fifo_size_default 0x80
7614+
7615+ /** Number of 4-byte words in the host periodic Tx FIFO when dynamic
7616+ * FIFO sizing is enabled.
7617+ * 16 to 32768 (default 1024)
7618+ */
7619+ int32_t host_perio_tx_fifo_size;
7620+//#define dwc_param_host_perio_tx_fifo_size_default 1024
7621+#define dwc_param_host_perio_tx_fifo_size_default 0x292
7622+
7623+ /** The maximum transfer size supported in bytes.
7624+ * 2047 to 65,535 (default 65,535)
7625+ */
7626+ int32_t max_transfer_size;
7627+#define dwc_param_max_transfer_size_default 65535
7628+
7629+ /** The maximum number of packets in a transfer.
7630+ * 15 to 511 (default 511)
7631+ */
7632+ int32_t max_packet_count;
7633+#define dwc_param_max_packet_count_default 511
7634+
7635+ /** The number of host channel registers to use.
7636+ * 1 to 16 (default 12)
7637+ * Note: The FPGA configuration supports a maximum of 12 host channels.
7638+ */
7639+ int32_t host_channels;
7640+//#define dwc_param_host_channels_default 12
7641+#define dwc_param_host_channels_default 16
7642+
7643+ /** The number of endpoints in addition to EP0 available for device
7644+ * mode operations.
7645+ * 1 to 15 (default 6 IN and OUT)
7646+ * Note: The FPGA configuration supports a maximum of 6 IN and OUT
7647+ * endpoints in addition to EP0.
7648+ */
7649+ int32_t dev_endpoints;
7650+//#define dwc_param_dev_endpoints_default 6
7651+#define dwc_param_dev_endpoints_default 8
7652+
7653+ /**
7654+ * Specifies the type of PHY interface to use. By default, the driver
7655+ * will automatically detect the phy_type.
7656+ *
7657+ * 0 - Full Speed PHY
7658+ * 1 - UTMI+ (default)
7659+ * 2 - ULPI
7660+ */
7661+ int32_t phy_type;
7662+#define DWC_PHY_TYPE_PARAM_FS 0
7663+#define DWC_PHY_TYPE_PARAM_UTMI 1
7664+#define DWC_PHY_TYPE_PARAM_ULPI 2
7665+#define dwc_param_phy_type_default DWC_PHY_TYPE_PARAM_UTMI
7666+
7667+ /**
7668+ * Specifies the UTMI+ Data Width. This parameter is
7669+ * applicable for a PHY_TYPE of UTMI+ or ULPI. (For a ULPI
7670+ * PHY_TYPE, this parameter indicates the data width between
7671+ * the MAC and the ULPI Wrapper.) Also, this parameter is
7672+ * applicable only if the OTG_HSPHY_WIDTH cC parameter was set
7673+ * to "8 and 16 bits", meaning that the core has been
7674+ * configured to work at either data path width.
7675+ *
7676+ * 8 or 16 bits (default 16)
7677+ */
7678+ int32_t phy_utmi_width;
7679+#define dwc_param_phy_utmi_width_default 16
7680+
7681+ /**
7682+ * Specifies whether the ULPI operates at double or single
7683+ * data rate. This parameter is only applicable if PHY_TYPE is
7684+ * ULPI.
7685+ *
7686+ * 0 - single data rate ULPI interface with 8 bit wide data
7687+ * bus (default)
7688+ * 1 - double data rate ULPI interface with 4 bit wide data
7689+ * bus
7690+ */
7691+ int32_t phy_ulpi_ddr;
7692+#define dwc_param_phy_ulpi_ddr_default 0
7693+
7694+ /**
7695+ * Specifies whether to use the internal or external supply to
7696+ * drive the vbus with a ULPI phy.
7697+ */
7698+ int32_t phy_ulpi_ext_vbus;
7699+#define DWC_PHY_ULPI_INTERNAL_VBUS 0
7700+#define DWC_PHY_ULPI_EXTERNAL_VBUS 1
7701+#define dwc_param_phy_ulpi_ext_vbus_default DWC_PHY_ULPI_INTERNAL_VBUS
7702+
7703+ /**
7704+ * Specifies whether to use the I2Cinterface for full speed PHY. This
7705+ * parameter is only applicable if PHY_TYPE is FS.
7706+ * 0 - No (default)
7707+ * 1 - Yes
7708+ */
7709+ int32_t i2c_enable;
7710+#define dwc_param_i2c_enable_default 0
7711+
7712+ int32_t ulpi_fs_ls;
7713+#define dwc_param_ulpi_fs_ls_default 0
7714+
7715+ int32_t ts_dline;
7716+#define dwc_param_ts_dline_default 0
7717+
7718+ /** Thresholding enable flag-
7719+ * bit 0 - enable non-ISO Tx thresholding
7720+ * bit 1 - enable ISO Tx thresholding
7721+ * bit 2 - enable Rx thresholding
7722+ */
7723+ uint32_t thr_ctl;
7724+#define dwc_param_thr_ctl_default 0
7725+
7726+ /** Thresholding length for Tx
7727+ * FIFOs in 32 bit DWORDs
7728+ */
7729+ uint32_t tx_thr_length;
7730+#define dwc_param_tx_thr_length_default 64
7731+
7732+ /** Thresholding length for Rx
7733+ * FIFOs in 32 bit DWORDs
7734+ */
7735+ uint32_t rx_thr_length;
7736+#define dwc_param_rx_thr_length_default 64
7737+
7738+ /** Per Transfer Interrupt
7739+ * mode enable flag
7740+ * 1 - Enabled
7741+ * 0 - Disabled
7742+ */
7743+ uint32_t pti_enable;
7744+#define dwc_param_pti_enable_default 0
7745+
7746+ /** Molti Processor Interrupt
7747+ * mode enable flag
7748+ * 1 - Enabled
7749+ * 0 - Disabled
7750+ */
7751+ uint32_t mpi_enable;
7752+#define dwc_param_mpi_enable_default 0
7753+
7754+} dwc_otg_core_params_t;
7755+
7756+#ifdef DEBUG
7757+struct dwc_otg_core_if;
7758+typedef struct hc_xfer_info
7759+{
7760+ struct dwc_otg_core_if *core_if;
7761+ dwc_hc_t *hc;
7762+} hc_xfer_info_t;
7763+#endif
7764+
7765+/**
7766+ * The <code>dwc_otg_core_if</code> structure contains information needed to manage
7767+ * the DWC_otg controller acting in either host or device mode. It
7768+ * represents the programming view of the controller as a whole.
7769+ */
7770+typedef struct dwc_otg_core_if
7771+{
7772+ /** Parameters that define how the core should be configured.*/
7773+ dwc_otg_core_params_t *core_params;
7774+
7775+ /** Core Global registers starting at offset 000h. */
7776+ dwc_otg_core_global_regs_t *core_global_regs;
7777+
7778+ /** Device-specific information */
7779+ dwc_otg_dev_if_t *dev_if;
7780+ /** Host-specific information */
7781+ dwc_otg_host_if_t *host_if;
7782+
7783+ /** Value from SNPSID register */
7784+ uint32_t snpsid;
7785+
7786+ /*
7787+ * Set to 1 if the core PHY interface bits in USBCFG have been
7788+ * initialized.
7789+ */
7790+ uint8_t phy_init_done;
7791+
7792+ /*
7793+ * SRP Success flag, set by srp success interrupt in FS I2C mode
7794+ */
7795+ uint8_t srp_success;
7796+ uint8_t srp_timer_started;
7797+
7798+ /* Common configuration information */
7799+ /** Power and Clock Gating Control Register */
7800+ volatile uint32_t *pcgcctl;
7801+#define DWC_OTG_PCGCCTL_OFFSET 0xE00
7802+
7803+ /** Push/pop addresses for endpoints or host channels.*/
7804+ uint32_t *data_fifo[MAX_EPS_CHANNELS];
7805+#define DWC_OTG_DATA_FIFO_OFFSET 0x1000
7806+#define DWC_OTG_DATA_FIFO_SIZE 0x1000
7807+
7808+ /** Total RAM for FIFOs (Bytes) */
7809+ uint16_t total_fifo_size;
7810+ /** Size of Rx FIFO (Bytes) */
7811+ uint16_t rx_fifo_size;
7812+ /** Size of Non-periodic Tx FIFO (Bytes) */
7813+ uint16_t nperio_tx_fifo_size;
7814+
7815+
7816+ /** 1 if DMA is enabled, 0 otherwise. */
7817+ uint8_t dma_enable;
7818+
7819+ /** 1 if Descriptor DMA mode is enabled, 0 otherwise. */
7820+ uint8_t dma_desc_enable;
7821+
7822+ /** 1 if PTI Enhancement mode is enabled, 0 otherwise. */
7823+ uint8_t pti_enh_enable;
7824+
7825+ /** 1 if MPI Enhancement mode is enabled, 0 otherwise. */
7826+ uint8_t multiproc_int_enable;
7827+
7828+ /** 1 if dedicated Tx FIFOs are enabled, 0 otherwise. */
7829+ uint8_t en_multiple_tx_fifo;
7830+
7831+ /** Set to 1 if multiple packets of a high-bandwidth transfer is in
7832+ * process of being queued */
7833+ uint8_t queuing_high_bandwidth;
7834+
7835+ /** Hardware Configuration -- stored here for convenience.*/
7836+ hwcfg1_data_t hwcfg1;
7837+ hwcfg2_data_t hwcfg2;
7838+ hwcfg3_data_t hwcfg3;
7839+ hwcfg4_data_t hwcfg4;
7840+
7841+ /** Host and Device Configuration -- stored here for convenience.*/
7842+ hcfg_data_t hcfg;
7843+ dcfg_data_t dcfg;
7844+
7845+ /** The operational State, during transations
7846+ * (a_host>>a_peripherial and b_device=>b_host) this may not
7847+ * match the core but allows the software to determine
7848+ * transitions.
7849+ */
7850+ uint8_t op_state;
7851+
7852+ /**
7853+ * Set to 1 if the HCD needs to be restarted on a session request
7854+ * interrupt. This is required if no connector ID status change has
7855+ * occurred since the HCD was last disconnected.
7856+ */
7857+ uint8_t restart_hcd_on_session_req;
7858+
7859+ /** HCD callbacks */
7860+ /** A-Device is a_host */
7861+#define A_HOST (1)
7862+ /** A-Device is a_suspend */
7863+#define A_SUSPEND (2)
7864+ /** A-Device is a_peripherial */
7865+#define A_PERIPHERAL (3)
7866+ /** B-Device is operating as a Peripheral. */
7867+#define B_PERIPHERAL (4)
7868+ /** B-Device is operating as a Host. */
7869+#define B_HOST (5)
7870+
7871+ /** HCD callbacks */
7872+ struct dwc_otg_cil_callbacks *hcd_cb;
7873+ /** PCD callbacks */
7874+ struct dwc_otg_cil_callbacks *pcd_cb;
7875+
7876+ /** Device mode Periodic Tx FIFO Mask */
7877+ uint32_t p_tx_msk;
7878+ /** Device mode Periodic Tx FIFO Mask */
7879+ uint32_t tx_msk;
7880+
7881+ /** Workqueue object used for handling several interrupts */
7882+ struct workqueue_struct *wq_otg;
7883+
7884+ /** Work object used for handling "Connector ID Status Change" Interrupt */
7885+ struct work_struct w_conn_id;
7886+
7887+ /** Work object used for handling "Wakeup Detected" Interrupt */
7888+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
7889+ struct work_struct w_wkp;
7890+#else
7891+ struct delayed_work w_wkp;
7892+#endif
7893+
7894+#ifdef DEBUG
7895+ uint32_t start_hcchar_val[MAX_EPS_CHANNELS];
7896+
7897+ hc_xfer_info_t hc_xfer_info[MAX_EPS_CHANNELS];
7898+ struct timer_list hc_xfer_timer[MAX_EPS_CHANNELS];
7899+
7900+ uint32_t hfnum_7_samples;
7901+ uint64_t hfnum_7_frrem_accum;
7902+ uint32_t hfnum_0_samples;
7903+ uint64_t hfnum_0_frrem_accum;
7904+ uint32_t hfnum_other_samples;
7905+ uint64_t hfnum_other_frrem_accum;
7906+#endif
7907+
7908+
7909+} dwc_otg_core_if_t;
7910+
7911+/*We must clear S3C24XX_EINTPEND external interrupt register
7912+ * because after clearing in this register trigerred IRQ from
7913+ * H/W core in kernel interrupt can be occured again before OTG
7914+ * handlers clear all IRQ sources of Core registers because of
7915+ * timing latencies and Low Level IRQ Type.
7916+ */
7917+
7918+#ifdef CONFIG_MACH_IPMATE
7919+#define S3C2410X_CLEAR_EINTPEND() \
7920+do { \
7921+ if (!dwc_otg_read_core_intr(core_if)) { \
7922+ __raw_writel(1UL << 11,S3C24XX_EINTPEND); \
7923+ } \
7924+} while (0)
7925+#else
7926+#define S3C2410X_CLEAR_EINTPEND() do { } while (0)
7927+#endif
7928+
7929+/*
7930+ * The following functions are functions for works
7931+ * using during handling some interrupts
7932+ */
7933+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
7934+
7935+extern void w_conn_id_status_change(void *p);
7936+extern void w_wakeup_detected(void *p);
7937+
7938+#else
7939+
7940+extern void w_conn_id_status_change(struct work_struct *p);
7941+extern void w_wakeup_detected(struct work_struct *p);
7942+
7943+#endif
7944+
7945+
7946+/*
7947+ * The following functions support initialization of the CIL driver component
7948+ * and the DWC_otg controller.
7949+ */
7950+extern dwc_otg_core_if_t *dwc_otg_cil_init(const uint32_t *_reg_base_addr,
7951+ dwc_otg_core_params_t *_core_params);
7952+extern void dwc_otg_cil_remove(dwc_otg_core_if_t *_core_if);
7953+extern void dwc_otg_core_init(dwc_otg_core_if_t *_core_if);
7954+extern void dwc_otg_core_host_init(dwc_otg_core_if_t *_core_if);
7955+extern void dwc_otg_core_dev_init(dwc_otg_core_if_t *_core_if);
7956+extern void dwc_otg_enable_global_interrupts( dwc_otg_core_if_t *_core_if );
7957+extern void dwc_otg_disable_global_interrupts( dwc_otg_core_if_t *_core_if );
7958+
7959+/** @name Device CIL Functions
7960+ * The following functions support managing the DWC_otg controller in device
7961+ * mode.
7962+ */
7963+/**@{*/
7964+extern void dwc_otg_wakeup(dwc_otg_core_if_t *_core_if);
7965+extern void dwc_otg_read_setup_packet (dwc_otg_core_if_t *_core_if, uint32_t *_dest);
7966+extern uint32_t dwc_otg_get_frame_number(dwc_otg_core_if_t *_core_if);
7967+extern void dwc_otg_ep0_activate(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep);
7968+extern void dwc_otg_ep_activate(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep);
7969+extern void dwc_otg_ep_deactivate(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep);
7970+extern void dwc_otg_ep_start_transfer(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep);
7971+extern void dwc_otg_ep_start_zl_transfer(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep);
7972+extern void dwc_otg_ep0_start_transfer(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep);
7973+extern void dwc_otg_ep0_continue_transfer(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep);
7974+extern void dwc_otg_ep_write_packet(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep, int _dma);
7975+extern void dwc_otg_ep_set_stall(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep);
7976+extern void dwc_otg_ep_clear_stall(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep);
7977+extern void dwc_otg_enable_device_interrupts(dwc_otg_core_if_t *_core_if);
7978+extern void dwc_otg_dump_dev_registers(dwc_otg_core_if_t *_core_if);
7979+extern void dwc_otg_dump_spram(dwc_otg_core_if_t *_core_if);
7980+#ifdef DWC_EN_ISOC
7981+extern void dwc_otg_iso_ep_start_frm_transfer(dwc_otg_core_if_t *core_if, dwc_ep_t *ep);
7982+extern void dwc_otg_iso_ep_start_buf_transfer(dwc_otg_core_if_t *core_if, dwc_ep_t *ep);
7983+#endif //DWC_EN_ISOC
7984+/**@}*/
7985+
7986+/** @name Host CIL Functions
7987+ * The following functions support managing the DWC_otg controller in host
7988+ * mode.
7989+ */
7990+/**@{*/
7991+extern void dwc_otg_hc_init(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc);
7992+extern void dwc_otg_hc_halt(dwc_otg_core_if_t *_core_if,
7993+ dwc_hc_t *_hc,
7994+ dwc_otg_halt_status_e _halt_status);
7995+extern void dwc_otg_hc_cleanup(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc);
7996+extern void dwc_otg_hc_start_transfer(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc);
7997+extern int dwc_otg_hc_continue_transfer(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc);
7998+extern void dwc_otg_hc_do_ping(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc);
7999+extern void dwc_otg_hc_write_packet(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc);
8000+extern void dwc_otg_enable_host_interrupts(dwc_otg_core_if_t *_core_if);
8001+extern void dwc_otg_disable_host_interrupts(dwc_otg_core_if_t *_core_if);
8002+
8003+/**
8004+ * This function Reads HPRT0 in preparation to modify. It keeps the
8005+ * WC bits 0 so that if they are read as 1, they won't clear when you
8006+ * write it back
8007+ */
8008+static inline uint32_t dwc_otg_read_hprt0(dwc_otg_core_if_t *_core_if)
8009+{
8010+ hprt0_data_t hprt0;
8011+ hprt0.d32 = dwc_read_reg32(_core_if->host_if->hprt0);
8012+ hprt0.b.prtena = 0;
8013+ hprt0.b.prtconndet = 0;
8014+ hprt0.b.prtenchng = 0;
8015+ hprt0.b.prtovrcurrchng = 0;
8016+ return hprt0.d32;
8017+}
8018+
8019+extern void dwc_otg_dump_host_registers(dwc_otg_core_if_t *_core_if);
8020+/**@}*/
8021+
8022+/** @name Common CIL Functions
8023+ * The following functions support managing the DWC_otg controller in either
8024+ * device or host mode.
8025+ */
8026+/**@{*/
8027+
8028+extern void dwc_otg_read_packet(dwc_otg_core_if_t *core_if,
8029+ uint8_t *dest,
8030+ uint16_t bytes);
8031+
8032+extern void dwc_otg_dump_global_registers(dwc_otg_core_if_t *_core_if);
8033+
8034+extern void dwc_otg_flush_tx_fifo( dwc_otg_core_if_t *_core_if,
8035+ const int _num );
8036+extern void dwc_otg_flush_rx_fifo( dwc_otg_core_if_t *_core_if );
8037+extern void dwc_otg_core_reset( dwc_otg_core_if_t *_core_if );
8038+
8039+extern dwc_otg_dma_desc_t* dwc_otg_ep_alloc_desc_chain(uint32_t * dma_desc_addr, uint32_t count);
8040+extern void dwc_otg_ep_free_desc_chain(dwc_otg_dma_desc_t* desc_addr, uint32_t dma_desc_addr, uint32_t count);
8041+
8042+/**
8043+ * This function returns the Core Interrupt register.
8044+ */
8045+static inline uint32_t dwc_otg_read_core_intr(dwc_otg_core_if_t *_core_if)
8046+{
8047+ return (dwc_read_reg32(&_core_if->core_global_regs->gintsts) &
8048+ dwc_read_reg32(&_core_if->core_global_regs->gintmsk));
8049+}
8050+
8051+/**
8052+ * This function returns the OTG Interrupt register.
8053+ */
8054+static inline uint32_t dwc_otg_read_otg_intr (dwc_otg_core_if_t *_core_if)
8055+{
8056+ return (dwc_read_reg32 (&_core_if->core_global_regs->gotgint));
8057+}
8058+
8059+/**
8060+ * This function reads the Device All Endpoints Interrupt register and
8061+ * returns the IN endpoint interrupt bits.
8062+ */
8063+static inline uint32_t dwc_otg_read_dev_all_in_ep_intr(dwc_otg_core_if_t *core_if)
8064+{
8065+ uint32_t v;
8066+
8067+ if(core_if->multiproc_int_enable) {
8068+ v = dwc_read_reg32(&core_if->dev_if->dev_global_regs->deachint) &
8069+ dwc_read_reg32(&core_if->dev_if->dev_global_regs->deachintmsk);
8070+ } else {
8071+ v = dwc_read_reg32(&core_if->dev_if->dev_global_regs->daint) &
8072+ dwc_read_reg32(&core_if->dev_if->dev_global_regs->daintmsk);
8073+ }
8074+ return (v & 0xffff);
8075+
8076+}
8077+
8078+/**
8079+ * This function reads the Device All Endpoints Interrupt register and
8080+ * returns the OUT endpoint interrupt bits.
8081+ */
8082+static inline uint32_t dwc_otg_read_dev_all_out_ep_intr(dwc_otg_core_if_t *core_if)
8083+{
8084+ uint32_t v;
8085+
8086+ if(core_if->multiproc_int_enable) {
8087+ v = dwc_read_reg32(&core_if->dev_if->dev_global_regs->deachint) &
8088+ dwc_read_reg32(&core_if->dev_if->dev_global_regs->deachintmsk);
8089+ } else {
8090+ v = dwc_read_reg32(&core_if->dev_if->dev_global_regs->daint) &
8091+ dwc_read_reg32(&core_if->dev_if->dev_global_regs->daintmsk);
8092+ }
8093+
8094+ return ((v & 0xffff0000) >> 16);
8095+}
8096+
8097+/**
8098+ * This function returns the Device IN EP Interrupt register
8099+ */
8100+static inline uint32_t dwc_otg_read_dev_in_ep_intr(dwc_otg_core_if_t *core_if,
8101+ dwc_ep_t *ep)
8102+{
8103+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
8104+ uint32_t v, msk, emp;
8105+
8106+ if(core_if->multiproc_int_enable) {
8107+ msk = dwc_read_reg32(&dev_if->dev_global_regs->diepeachintmsk[ep->num]);
8108+ emp = dwc_read_reg32(&dev_if->dev_global_regs->dtknqr4_fifoemptymsk);
8109+ msk |= ((emp >> ep->num) & 0x1) << 7;
8110+ v = dwc_read_reg32(&dev_if->in_ep_regs[ep->num]->diepint) & msk;
8111+ } else {
8112+ msk = dwc_read_reg32(&dev_if->dev_global_regs->diepmsk);
8113+ emp = dwc_read_reg32(&dev_if->dev_global_regs->dtknqr4_fifoemptymsk);
8114+ msk |= ((emp >> ep->num) & 0x1) << 7;
8115+ v = dwc_read_reg32(&dev_if->in_ep_regs[ep->num]->diepint) & msk;
8116+ }
8117+
8118+
8119+ return v;
8120+}
8121+/**
8122+ * This function returns the Device OUT EP Interrupt register
8123+ */
8124+static inline uint32_t dwc_otg_read_dev_out_ep_intr(dwc_otg_core_if_t *_core_if,
8125+ dwc_ep_t *_ep)
8126+{
8127+ dwc_otg_dev_if_t *dev_if = _core_if->dev_if;
8128+ uint32_t v;
8129+ doepmsk_data_t msk = { .d32 = 0 };
8130+
8131+ if(_core_if->multiproc_int_enable) {
8132+ msk.d32 = dwc_read_reg32(&dev_if->dev_global_regs->doepeachintmsk[_ep->num]);
8133+ if(_core_if->pti_enh_enable) {
8134+ msk.b.pktdrpsts = 1;
8135+ }
8136+ v = dwc_read_reg32( &dev_if->out_ep_regs[_ep->num]->doepint) & msk.d32;
8137+ } else {
8138+ msk.d32 = dwc_read_reg32(&dev_if->dev_global_regs->doepmsk);
8139+ if(_core_if->pti_enh_enable) {
8140+ msk.b.pktdrpsts = 1;
8141+ }
8142+ v = dwc_read_reg32( &dev_if->out_ep_regs[_ep->num]->doepint) & msk.d32;
8143+ }
8144+ return v;
8145+}
8146+
8147+/**
8148+ * This function returns the Host All Channel Interrupt register
8149+ */
8150+static inline uint32_t dwc_otg_read_host_all_channels_intr (dwc_otg_core_if_t *_core_if)
8151+{
8152+ return (dwc_read_reg32 (&_core_if->host_if->host_global_regs->haint));
8153+}
8154+
8155+static inline uint32_t dwc_otg_read_host_channel_intr (dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc)
8156+{
8157+ return (dwc_read_reg32 (&_core_if->host_if->hc_regs[_hc->hc_num]->hcint));
8158+}
8159+
8160+
8161+/**
8162+ * This function returns the mode of the operation, host or device.
8163+ *
8164+ * @return 0 - Device Mode, 1 - Host Mode
8165+ */
8166+static inline uint32_t dwc_otg_mode(dwc_otg_core_if_t *_core_if)
8167+{
8168+ return (dwc_read_reg32( &_core_if->core_global_regs->gintsts ) & 0x1);
8169+}
8170+
8171+static inline uint8_t dwc_otg_is_device_mode(dwc_otg_core_if_t *_core_if)
8172+{
8173+ return (dwc_otg_mode(_core_if) != DWC_HOST_MODE);
8174+}
8175+static inline uint8_t dwc_otg_is_host_mode(dwc_otg_core_if_t *_core_if)
8176+{
8177+ return (dwc_otg_mode(_core_if) == DWC_HOST_MODE);
8178+}
8179+
8180+extern int32_t dwc_otg_handle_common_intr( dwc_otg_core_if_t *_core_if );
8181+
8182+
8183+/**@}*/
8184+
8185+/**
8186+ * DWC_otg CIL callback structure. This structure allows the HCD and
8187+ * PCD to register functions used for starting and stopping the PCD
8188+ * and HCD for role change on for a DRD.
8189+ */
8190+typedef struct dwc_otg_cil_callbacks
8191+{
8192+ /** Start function for role change */
8193+ int (*start) (void *_p);
8194+ /** Stop Function for role change */
8195+ int (*stop) (void *_p);
8196+ /** Disconnect Function for role change */
8197+ int (*disconnect) (void *_p);
8198+ /** Resume/Remote wakeup Function */
8199+ int (*resume_wakeup) (void *_p);
8200+ /** Suspend function */
8201+ int (*suspend) (void *_p);
8202+ /** Session Start (SRP) */
8203+ int (*session_start) (void *_p);
8204+ /** Pointer passed to start() and stop() */
8205+ void *p;
8206+} dwc_otg_cil_callbacks_t;
8207+
8208+extern void dwc_otg_cil_register_pcd_callbacks( dwc_otg_core_if_t *_core_if,
8209+ dwc_otg_cil_callbacks_t *_cb,
8210+ void *_p);
8211+extern void dwc_otg_cil_register_hcd_callbacks( dwc_otg_core_if_t *_core_if,
8212+ dwc_otg_cil_callbacks_t *_cb,
8213+ void *_p);
8214+#ifndef warn
8215+#define warn printk
8216+#endif
8217+
8218+#endif
8219+
8220--- /dev/null
8221+++ b/drivers/usb/host/otg/dwc_otg_cil_intr.c
8222@@ -0,0 +1,881 @@
8223+/* ==========================================================================
8224+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_cil_intr.c $
8225+ * $Revision: #10 $
8226+ * $Date: 2008/07/16 $
8227+ * $Change: 1065567 $
8228+ *
8229+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
8230+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
8231+ * otherwise expressly agreed to in writing between Synopsys and you.
8232+ *
8233+ * The Software IS NOT an item of Licensed Software or Licensed Product under
8234+ * any End User Software License Agreement or Agreement for Licensed Product
8235+ * with Synopsys or any supplement thereto. You are permitted to use and
8236+ * redistribute this Software in source and binary forms, with or without
8237+ * modification, provided that redistributions of source code must retain this
8238+ * notice. You may not view, use, disclose, copy or distribute this file or
8239+ * any information contained herein except pursuant to this license grant from
8240+ * Synopsys. If you do not agree with this notice, including the disclaimer
8241+ * below, then you are not authorized to use the Software.
8242+ *
8243+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
8244+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
8245+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
8246+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
8247+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
8248+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
8249+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
8250+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
8251+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
8252+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
8253+ * DAMAGE.
8254+ * ========================================================================== */
8255+
8256+/** @file
8257+ *
8258+ * The Core Interface Layer provides basic services for accessing and
8259+ * managing the DWC_otg hardware. These services are used by both the
8260+ * Host Controller Driver and the Peripheral Controller Driver.
8261+ *
8262+ * This file contains the Common Interrupt handlers.
8263+ */
8264+#include "dwc_otg_plat.h"
8265+#include "dwc_otg_regs.h"
8266+#include "dwc_otg_cil.h"
8267+#include "dwc_otg_pcd.h"
8268+
8269+#ifdef DEBUG
8270+inline const char *op_state_str(dwc_otg_core_if_t *core_if)
8271+{
8272+ return (core_if->op_state==A_HOST?"a_host":
8273+ (core_if->op_state==A_SUSPEND?"a_suspend":
8274+ (core_if->op_state==A_PERIPHERAL?"a_peripheral":
8275+ (core_if->op_state==B_PERIPHERAL?"b_peripheral":
8276+ (core_if->op_state==B_HOST?"b_host":
8277+ "unknown")))));
8278+}
8279+#endif
8280+
8281+/** This function will log a debug message
8282+ *
8283+ * @param core_if Programming view of DWC_otg controller.
8284+ */
8285+int32_t dwc_otg_handle_mode_mismatch_intr (dwc_otg_core_if_t *core_if)
8286+{
8287+ gintsts_data_t gintsts;
8288+ DWC_WARN("Mode Mismatch Interrupt: currently in %s mode\n",
8289+ dwc_otg_mode(core_if) ? "Host" : "Device");
8290+
8291+ /* Clear interrupt */
8292+ gintsts.d32 = 0;
8293+ gintsts.b.modemismatch = 1;
8294+ dwc_write_reg32 (&core_if->core_global_regs->gintsts, gintsts.d32);
8295+ return 1;
8296+}
8297+
8298+/** Start the HCD. Helper function for using the HCD callbacks.
8299+ *
8300+ * @param core_if Programming view of DWC_otg controller.
8301+ */
8302+static inline void hcd_start(dwc_otg_core_if_t *core_if)
8303+{
8304+ if (core_if->hcd_cb && core_if->hcd_cb->start) {
8305+ core_if->hcd_cb->start(core_if->hcd_cb->p);
8306+ }
8307+}
8308+/** Stop the HCD. Helper function for using the HCD callbacks.
8309+ *
8310+ * @param core_if Programming view of DWC_otg controller.
8311+ */
8312+static inline void hcd_stop(dwc_otg_core_if_t *core_if)
8313+{
8314+ if (core_if->hcd_cb && core_if->hcd_cb->stop) {
8315+ core_if->hcd_cb->stop(core_if->hcd_cb->p);
8316+ }
8317+}
8318+/** Disconnect the HCD. Helper function for using the HCD callbacks.
8319+ *
8320+ * @param core_if Programming view of DWC_otg controller.
8321+ */
8322+static inline void hcd_disconnect(dwc_otg_core_if_t *core_if)
8323+{
8324+ if (core_if->hcd_cb && core_if->hcd_cb->disconnect) {
8325+ core_if->hcd_cb->disconnect(core_if->hcd_cb->p);
8326+ }
8327+}
8328+/** Inform the HCD the a New Session has begun. Helper function for
8329+ * using the HCD callbacks.
8330+ *
8331+ * @param core_if Programming view of DWC_otg controller.
8332+ */
8333+static inline void hcd_session_start(dwc_otg_core_if_t *core_if)
8334+{
8335+ if (core_if->hcd_cb && core_if->hcd_cb->session_start) {
8336+ core_if->hcd_cb->session_start(core_if->hcd_cb->p);
8337+ }
8338+}
8339+
8340+/** Start the PCD. Helper function for using the PCD callbacks.
8341+ *
8342+ * @param core_if Programming view of DWC_otg controller.
8343+ */
8344+static inline void pcd_start(dwc_otg_core_if_t *core_if)
8345+{
8346+ if (core_if->pcd_cb && core_if->pcd_cb->start) {
8347+ core_if->pcd_cb->start(core_if->pcd_cb->p);
8348+ }
8349+}
8350+/** Stop the PCD. Helper function for using the PCD callbacks.
8351+ *
8352+ * @param core_if Programming view of DWC_otg controller.
8353+ */
8354+static inline void pcd_stop(dwc_otg_core_if_t *core_if)
8355+{
8356+ if (core_if->pcd_cb && core_if->pcd_cb->stop) {
8357+ core_if->pcd_cb->stop(core_if->pcd_cb->p);
8358+ }
8359+}
8360+/** Suspend the PCD. Helper function for using the PCD callbacks.
8361+ *
8362+ * @param core_if Programming view of DWC_otg controller.
8363+ */
8364+static inline void pcd_suspend(dwc_otg_core_if_t *core_if)
8365+{
8366+ if (core_if->pcd_cb && core_if->pcd_cb->suspend) {
8367+ core_if->pcd_cb->suspend(core_if->pcd_cb->p);
8368+ }
8369+}
8370+/** Resume the PCD. Helper function for using the PCD callbacks.
8371+ *
8372+ * @param core_if Programming view of DWC_otg controller.
8373+ */
8374+static inline void pcd_resume(dwc_otg_core_if_t *core_if)
8375+{
8376+ if (core_if->pcd_cb && core_if->pcd_cb->resume_wakeup) {
8377+ core_if->pcd_cb->resume_wakeup(core_if->pcd_cb->p);
8378+ }
8379+}
8380+
8381+/**
8382+ * This function handles the OTG Interrupts. It reads the OTG
8383+ * Interrupt Register (GOTGINT) to determine what interrupt has
8384+ * occurred.
8385+ *
8386+ * @param core_if Programming view of DWC_otg controller.
8387+ */
8388+int32_t dwc_otg_handle_otg_intr(dwc_otg_core_if_t *core_if)
8389+{
8390+ dwc_otg_core_global_regs_t *global_regs =
8391+ core_if->core_global_regs;
8392+ gotgint_data_t gotgint;
8393+ gotgctl_data_t gotgctl;
8394+ gintmsk_data_t gintmsk;
8395+
8396+ gotgint.d32 = dwc_read_reg32(&global_regs->gotgint);
8397+ gotgctl.d32 = dwc_read_reg32(&global_regs->gotgctl);
8398+ DWC_DEBUGPL(DBG_CIL, "++OTG Interrupt gotgint=%0x [%s]\n", gotgint.d32,
8399+ op_state_str(core_if));
8400+ //DWC_DEBUGPL(DBG_CIL, "gotgctl=%08x\n", gotgctl.d32);
8401+
8402+ if (gotgint.b.sesenddet) {
8403+ DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: "
8404+ "Session End Detected++ (%s)\n",
8405+ op_state_str(core_if));
8406+ gotgctl.d32 = dwc_read_reg32(&global_regs->gotgctl);
8407+
8408+ if (core_if->op_state == B_HOST) {
8409+
8410+ dwc_otg_pcd_t *pcd=(dwc_otg_pcd_t *)core_if->pcd_cb->p;
8411+ if(unlikely(!pcd)) {
8412+ DWC_ERROR("%s: data structure not initialized properly, core_if->pcd_cb->p = NULL!!!",__func__);
8413+ BUG();
8414+ }
8415+ SPIN_LOCK(&pcd->lock);
8416+
8417+ pcd_start(core_if);
8418+
8419+ SPIN_UNLOCK(&pcd->lock);
8420+ core_if->op_state = B_PERIPHERAL;
8421+ } else {
8422+ dwc_otg_pcd_t *pcd;
8423+
8424+ /* If not B_HOST and Device HNP still set. HNP
8425+ * Did not succeed!*/
8426+ if (gotgctl.b.devhnpen) {
8427+ DWC_DEBUGPL(DBG_ANY, "Session End Detected\n");
8428+ DWC_ERROR("Device Not Connected/Responding!\n");
8429+ }
8430+
8431+ /* If Session End Detected the B-Cable has
8432+ * been disconnected. */
8433+ /* Reset PCD and Gadget driver to a
8434+ * clean state. */
8435+
8436+ pcd=(dwc_otg_pcd_t *)core_if->pcd_cb->p;
8437+ if(unlikely(!pcd)) {
8438+ DWC_ERROR("%s: data structure not initialized properly, core_if->pcd_cb->p = NULL!!!",__func__);
8439+ BUG();
8440+ }
8441+ SPIN_LOCK(&pcd->lock);
8442+
8443+ pcd_stop(core_if);
8444+
8445+ SPIN_UNLOCK(&pcd->lock);
8446+ }
8447+ gotgctl.d32 = 0;
8448+ gotgctl.b.devhnpen = 1;
8449+ dwc_modify_reg32(&global_regs->gotgctl,
8450+ gotgctl.d32, 0);
8451+ }
8452+ if (gotgint.b.sesreqsucstschng) {
8453+ DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: "
8454+ "Session Reqeust Success Status Change++\n");
8455+ gotgctl.d32 = dwc_read_reg32(&global_regs->gotgctl);
8456+ if (gotgctl.b.sesreqscs) {
8457+ if ((core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS) &&
8458+ (core_if->core_params->i2c_enable)) {
8459+ core_if->srp_success = 1;
8460+ }
8461+ else {
8462+ dwc_otg_pcd_t *pcd=(dwc_otg_pcd_t *)core_if->pcd_cb->p;
8463+ if(unlikely(!pcd)) {
8464+ DWC_ERROR("%s: data structure not initialized properly, core_if->pcd_cb->p = NULL!!!",__func__);
8465+ BUG();
8466+ }
8467+ SPIN_LOCK(&pcd->lock);
8468+
8469+ pcd_resume(core_if);
8470+
8471+ SPIN_UNLOCK(&pcd->lock);
8472+ /* Clear Session Request */
8473+ gotgctl.d32 = 0;
8474+ gotgctl.b.sesreq = 1;
8475+ dwc_modify_reg32(&global_regs->gotgctl,
8476+ gotgctl.d32, 0);
8477+ }
8478+ }
8479+ }
8480+ if (gotgint.b.hstnegsucstschng) {
8481+ /* Print statements during the HNP interrupt handling
8482+ * can cause it to fail.*/
8483+ gotgctl.d32 = dwc_read_reg32(&global_regs->gotgctl);
8484+ if (gotgctl.b.hstnegscs) {
8485+ if (dwc_otg_is_host_mode(core_if)) {
8486+ dwc_otg_pcd_t *pcd;
8487+
8488+ core_if->op_state = B_HOST;
8489+ /*
8490+ * Need to disable SOF interrupt immediately.
8491+ * When switching from device to host, the PCD
8492+ * interrupt handler won't handle the
8493+ * interrupt if host mode is already set. The
8494+ * HCD interrupt handler won't get called if
8495+ * the HCD state is HALT. This means that the
8496+ * interrupt does not get handled and Linux
8497+ * complains loudly.
8498+ */
8499+ gintmsk.d32 = 0;
8500+ gintmsk.b.sofintr = 1;
8501+ dwc_modify_reg32(&global_regs->gintmsk,
8502+ gintmsk.d32, 0);
8503+
8504+ pcd=(dwc_otg_pcd_t *)core_if->pcd_cb->p;
8505+ if(unlikely(!pcd)) {
8506+ DWC_ERROR("%s: data structure not initialized properly, core_if->pcd_cb->p = NULL!!!",__func__);
8507+ BUG();
8508+ }
8509+ SPIN_LOCK(&pcd->lock);
8510+
8511+ pcd_stop(core_if);
8512+
8513+ SPIN_UNLOCK(&pcd->lock);
8514+ /*
8515+ * Initialize the Core for Host mode.
8516+ */
8517+ hcd_start(core_if);
8518+ core_if->op_state = B_HOST;
8519+ }
8520+ } else {
8521+ gotgctl.d32 = 0;
8522+ gotgctl.b.hnpreq = 1;
8523+ gotgctl.b.devhnpen = 1;
8524+ dwc_modify_reg32(&global_regs->gotgctl,
8525+ gotgctl.d32, 0);
8526+ DWC_DEBUGPL(DBG_ANY, "HNP Failed\n");
8527+ DWC_ERROR("Device Not Connected/Responding\n");
8528+ }
8529+ }
8530+ if (gotgint.b.hstnegdet) {
8531+ /* The disconnect interrupt is set at the same time as
8532+ * Host Negotiation Detected. During the mode
8533+ * switch all interrupts are cleared so the disconnect
8534+ * interrupt handler will not get executed.
8535+ */
8536+ DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: "
8537+ "Host Negotiation Detected++ (%s)\n",
8538+ (dwc_otg_is_host_mode(core_if)?"Host":"Device"));
8539+ if (dwc_otg_is_device_mode(core_if)){
8540+ dwc_otg_pcd_t *pcd;
8541+
8542+ DWC_DEBUGPL(DBG_ANY, "a_suspend->a_peripheral (%d)\n", core_if->op_state);
8543+ hcd_disconnect(core_if);
8544+
8545+ pcd=(dwc_otg_pcd_t *)core_if->pcd_cb->p;
8546+ if(unlikely(!pcd)) {
8547+ DWC_ERROR("%s: data structure not initialized properly, core_if->pcd_cb->p = NULL!!!",__func__);
8548+ BUG();
8549+ }
8550+ SPIN_LOCK(&pcd->lock);
8551+
8552+ pcd_start(core_if);
8553+
8554+ SPIN_UNLOCK(&pcd->lock);
8555+ core_if->op_state = A_PERIPHERAL;
8556+ } else {
8557+ dwc_otg_pcd_t *pcd;
8558+
8559+ /*
8560+ * Need to disable SOF interrupt immediately. When
8561+ * switching from device to host, the PCD interrupt
8562+ * handler won't handle the interrupt if host mode is
8563+ * already set. The HCD interrupt handler won't get
8564+ * called if the HCD state is HALT. This means that
8565+ * the interrupt does not get handled and Linux
8566+ * complains loudly.
8567+ */
8568+ gintmsk.d32 = 0;
8569+ gintmsk.b.sofintr = 1;
8570+ dwc_modify_reg32(&global_regs->gintmsk,
8571+ gintmsk.d32, 0);
8572+
8573+ pcd=(dwc_otg_pcd_t *)core_if->pcd_cb->p;
8574+ if(unlikely(!pcd)) {
8575+ DWC_ERROR("%s: data structure not initialized properly, core_if->pcd_cb->p = NULL!!!",__func__);
8576+ BUG();
8577+ }
8578+ SPIN_LOCK(&pcd->lock);
8579+
8580+ pcd_stop(core_if);
8581+
8582+ SPIN_UNLOCK(&pcd->lock);
8583+ hcd_start(core_if);
8584+ core_if->op_state = A_HOST;
8585+ }
8586+ }
8587+ if (gotgint.b.adevtoutchng) {
8588+ DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: "
8589+ "A-Device Timeout Change++\n");
8590+ }
8591+ if (gotgint.b.debdone) {
8592+ DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: "
8593+ "Debounce Done++\n");
8594+ }
8595+
8596+ /* Clear GOTGINT */
8597+ dwc_write_reg32 (&core_if->core_global_regs->gotgint, gotgint.d32);
8598+
8599+ return 1;
8600+}
8601+
8602+
8603+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
8604+
8605+void w_conn_id_status_change(void *p)
8606+{
8607+ dwc_otg_core_if_t *core_if = p;
8608+
8609+#else
8610+
8611+void w_conn_id_status_change(struct work_struct *p)
8612+{
8613+ dwc_otg_core_if_t *core_if = container_of(p, dwc_otg_core_if_t, w_conn_id);
8614+
8615+#endif
8616+
8617+
8618+ uint32_t count = 0;
8619+ gotgctl_data_t gotgctl = { .d32 = 0 };
8620+
8621+ gotgctl.d32 = dwc_read_reg32(&core_if->core_global_regs->gotgctl);
8622+ DWC_DEBUGPL(DBG_CIL, "gotgctl=%0x\n", gotgctl.d32);
8623+ DWC_DEBUGPL(DBG_CIL, "gotgctl.b.conidsts=%d\n", gotgctl.b.conidsts);
8624+
8625+ /* B-Device connector (Device Mode) */
8626+ if (gotgctl.b.conidsts) {
8627+ dwc_otg_pcd_t *pcd;
8628+
8629+ /* Wait for switch to device mode. */
8630+ while (!dwc_otg_is_device_mode(core_if)){
8631+ DWC_PRINT("Waiting for Peripheral Mode, Mode=%s\n",
8632+ (dwc_otg_is_host_mode(core_if)?"Host":"Peripheral"));
8633+ MDELAY(100);
8634+ if (++count > 10000) *(uint32_t*)NULL=0;
8635+ }
8636+ core_if->op_state = B_PERIPHERAL;
8637+ dwc_otg_core_init(core_if);
8638+ dwc_otg_enable_global_interrupts(core_if);
8639+
8640+ pcd=(dwc_otg_pcd_t *)core_if->pcd_cb->p;
8641+ if(unlikely(!pcd)) {
8642+ DWC_ERROR("%s: data structure not initialized properly, core_if->pcd_cb->p = NULL!!!",__func__);
8643+ BUG();
8644+ }
8645+ SPIN_LOCK(&pcd->lock);
8646+
8647+ pcd_start(core_if);
8648+
8649+ SPIN_UNLOCK(&pcd->lock);
8650+ } else {
8651+ /* A-Device connector (Host Mode) */
8652+ while (!dwc_otg_is_host_mode(core_if)) {
8653+ DWC_PRINT("Waiting for Host Mode, Mode=%s\n",
8654+ (dwc_otg_is_host_mode(core_if)?"Host":"Peripheral"));
8655+ MDELAY(100);
8656+ if (++count > 10000) *(uint32_t*)NULL=0;
8657+ }
8658+ core_if->op_state = A_HOST;
8659+ /*
8660+ * Initialize the Core for Host mode.
8661+ */
8662+ dwc_otg_core_init(core_if);
8663+ dwc_otg_enable_global_interrupts(core_if);
8664+ hcd_start(core_if);
8665+ }
8666+}
8667+
8668+
8669+/**
8670+ * This function handles the Connector ID Status Change Interrupt. It
8671+ * reads the OTG Interrupt Register (GOTCTL) to determine whether this
8672+ * is a Device to Host Mode transition or a Host Mode to Device
8673+ * Transition.
8674+ *
8675+ * This only occurs when the cable is connected/removed from the PHY
8676+ * connector.
8677+ *
8678+ * @param core_if Programming view of DWC_otg controller.
8679+ */
8680+int32_t dwc_otg_handle_conn_id_status_change_intr(dwc_otg_core_if_t *core_if)
8681+{
8682+
8683+ /*
8684+ * Need to disable SOF interrupt immediately. If switching from device
8685+ * to host, the PCD interrupt handler won't handle the interrupt if
8686+ * host mode is already set. The HCD interrupt handler won't get
8687+ * called if the HCD state is HALT. This means that the interrupt does
8688+ * not get handled and Linux complains loudly.
8689+ */
8690+ gintmsk_data_t gintmsk = { .d32 = 0 };
8691+ gintsts_data_t gintsts = { .d32 = 0 };
8692+
8693+ gintmsk.b.sofintr = 1;
8694+ dwc_modify_reg32(&core_if->core_global_regs->gintmsk, gintmsk.d32, 0);
8695+
8696+ DWC_DEBUGPL(DBG_CIL, " ++Connector ID Status Change Interrupt++ (%s)\n",
8697+ (dwc_otg_is_host_mode(core_if)?"Host":"Device"));
8698+
8699+ /*
8700+ * Need to schedule a work, as there are possible DELAY function calls
8701+ */
8702+ queue_work(core_if->wq_otg, &core_if->w_conn_id);
8703+
8704+ /* Set flag and clear interrupt */
8705+ gintsts.b.conidstschng = 1;
8706+ dwc_write_reg32 (&core_if->core_global_regs->gintsts, gintsts.d32);
8707+
8708+ return 1;
8709+}
8710+
8711+/**
8712+ * This interrupt indicates that a device is initiating the Session
8713+ * Request Protocol to request the host to turn on bus power so a new
8714+ * session can begin. The handler responds by turning on bus power. If
8715+ * the DWC_otg controller is in low power mode, the handler brings the
8716+ * controller out of low power mode before turning on bus power.
8717+ *
8718+ * @param core_if Programming view of DWC_otg controller.
8719+ */
8720+int32_t dwc_otg_handle_session_req_intr(dwc_otg_core_if_t *core_if)
8721+{
8722+ hprt0_data_t hprt0;
8723+ gintsts_data_t gintsts;
8724+
8725+#ifndef DWC_HOST_ONLY
8726+ DWC_DEBUGPL(DBG_ANY, "++Session Request Interrupt++\n");
8727+
8728+ if (dwc_otg_is_device_mode(core_if)) {
8729+ DWC_PRINT("SRP: Device mode\n");
8730+ } else {
8731+ DWC_PRINT("SRP: Host mode\n");
8732+
8733+ /* Turn on the port power bit. */
8734+ hprt0.d32 = dwc_otg_read_hprt0(core_if);
8735+ hprt0.b.prtpwr = 1;
8736+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
8737+
8738+ /* Start the Connection timer. So a message can be displayed
8739+ * if connect does not occur within 10 seconds. */
8740+ hcd_session_start(core_if);
8741+ }
8742+#endif
8743+
8744+ /* Clear interrupt */
8745+ gintsts.d32 = 0;
8746+ gintsts.b.sessreqintr = 1;
8747+ dwc_write_reg32 (&core_if->core_global_regs->gintsts, gintsts.d32);
8748+
8749+ return 1;
8750+}
8751+
8752+
8753+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
8754+void w_wakeup_detected(void *p)
8755+{
8756+ dwc_otg_core_if_t* core_if = p;
8757+
8758+#else
8759+
8760+void w_wakeup_detected(struct work_struct *p)
8761+{
8762+ struct delayed_work *dw = container_of(p, struct delayed_work, work);
8763+ dwc_otg_core_if_t *core_if = container_of(dw, dwc_otg_core_if_t, w_wkp);
8764+
8765+#endif
8766+ /*
8767+ * Clear the Resume after 70ms. (Need 20 ms minimum. Use 70 ms
8768+ * so that OPT tests pass with all PHYs).
8769+ */
8770+ hprt0_data_t hprt0 = {.d32=0};
8771+#if 0
8772+ pcgcctl_data_t pcgcctl = {.d32=0};
8773+ /* Restart the Phy Clock */
8774+ pcgcctl.b.stoppclk = 1;
8775+ dwc_modify_reg32(core_if->pcgcctl, pcgcctl.d32, 0);
8776+ UDELAY(10);
8777+#endif //0
8778+ hprt0.d32 = dwc_otg_read_hprt0(core_if);
8779+ DWC_DEBUGPL(DBG_ANY,"Resume: HPRT0=%0x\n", hprt0.d32);
8780+// MDELAY(70);
8781+ hprt0.b.prtres = 0; /* Resume */
8782+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
8783+ DWC_DEBUGPL(DBG_ANY,"Clear Resume: HPRT0=%0x\n", dwc_read_reg32(core_if->host_if->hprt0));
8784+}
8785+/**
8786+ * This interrupt indicates that the DWC_otg controller has detected a
8787+ * resume or remote wakeup sequence. If the DWC_otg controller is in
8788+ * low power mode, the handler must brings the controller out of low
8789+ * power mode. The controller automatically begins resume
8790+ * signaling. The handler schedules a time to stop resume signaling.
8791+ */
8792+int32_t dwc_otg_handle_wakeup_detected_intr(dwc_otg_core_if_t *core_if)
8793+{
8794+ gintsts_data_t gintsts;
8795+
8796+ DWC_DEBUGPL(DBG_ANY, "++Resume and Remote Wakeup Detected Interrupt++\n");
8797+
8798+ if (dwc_otg_is_device_mode(core_if)) {
8799+ dctl_data_t dctl = {.d32=0};
8800+ DWC_DEBUGPL(DBG_PCD, "DSTS=0x%0x\n",
8801+ dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts));
8802+#ifdef PARTIAL_POWER_DOWN
8803+ if (core_if->hwcfg4.b.power_optimiz) {
8804+ pcgcctl_data_t power = {.d32=0};
8805+
8806+ power.d32 = dwc_read_reg32(core_if->pcgcctl);
8807+ DWC_DEBUGPL(DBG_CIL, "PCGCCTL=%0x\n", power.d32);
8808+
8809+ power.b.stoppclk = 0;
8810+ dwc_write_reg32(core_if->pcgcctl, power.d32);
8811+
8812+ power.b.pwrclmp = 0;
8813+ dwc_write_reg32(core_if->pcgcctl, power.d32);
8814+
8815+ power.b.rstpdwnmodule = 0;
8816+ dwc_write_reg32(core_if->pcgcctl, power.d32);
8817+ }
8818+#endif
8819+ /* Clear the Remote Wakeup Signalling */
8820+ dctl.b.rmtwkupsig = 1;
8821+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->dctl,
8822+ dctl.d32, 0);
8823+
8824+ if (core_if->pcd_cb && core_if->pcd_cb->resume_wakeup) {
8825+ core_if->pcd_cb->resume_wakeup(core_if->pcd_cb->p);
8826+ }
8827+
8828+ } else {
8829+ pcgcctl_data_t pcgcctl = {.d32=0};
8830+
8831+ /* Restart the Phy Clock */
8832+ pcgcctl.b.stoppclk = 1;
8833+ dwc_modify_reg32(core_if->pcgcctl, pcgcctl.d32, 0);
8834+
8835+ queue_delayed_work(core_if->wq_otg, &core_if->w_wkp, ((70 * HZ / 1000) + 1));
8836+ }
8837+
8838+ /* Clear interrupt */
8839+ gintsts.d32 = 0;
8840+ gintsts.b.wkupintr = 1;
8841+ dwc_write_reg32 (&core_if->core_global_regs->gintsts, gintsts.d32);
8842+
8843+ return 1;
8844+}
8845+
8846+/**
8847+ * This interrupt indicates that a device has been disconnected from
8848+ * the root port.
8849+ */
8850+int32_t dwc_otg_handle_disconnect_intr(dwc_otg_core_if_t *core_if)
8851+{
8852+ gintsts_data_t gintsts;
8853+
8854+ DWC_DEBUGPL(DBG_ANY, "++Disconnect Detected Interrupt++ (%s) %s\n",
8855+ (dwc_otg_is_host_mode(core_if)?"Host":"Device"),
8856+ op_state_str(core_if));
8857+
8858+/** @todo Consolidate this if statement. */
8859+#ifndef DWC_HOST_ONLY
8860+ if (core_if->op_state == B_HOST) {
8861+ dwc_otg_pcd_t *pcd;
8862+
8863+ /* If in device mode Disconnect and stop the HCD, then
8864+ * start the PCD. */
8865+ hcd_disconnect(core_if);
8866+
8867+ pcd=(dwc_otg_pcd_t *)core_if->pcd_cb->p;
8868+ if(unlikely(!pcd)) {
8869+ DWC_ERROR("%s: data structure not initialized properly, core_if->pcd_cb->p = NULL!!!",__func__);
8870+ BUG();
8871+ }
8872+ SPIN_LOCK(&pcd->lock);
8873+
8874+ pcd_start(core_if);
8875+
8876+ SPIN_UNLOCK(&pcd->lock);
8877+ core_if->op_state = B_PERIPHERAL;
8878+ } else if (dwc_otg_is_device_mode(core_if)) {
8879+ gotgctl_data_t gotgctl = { .d32 = 0 };
8880+ gotgctl.d32 = dwc_read_reg32(&core_if->core_global_regs->gotgctl);
8881+ if (gotgctl.b.hstsethnpen==1) {
8882+ /* Do nothing, if HNP in process the OTG
8883+ * interrupt "Host Negotiation Detected"
8884+ * interrupt will do the mode switch.
8885+ */
8886+ } else if (gotgctl.b.devhnpen == 0) {
8887+ dwc_otg_pcd_t *pcd;
8888+
8889+ /* If in device mode Disconnect and stop the HCD, then
8890+ * start the PCD. */
8891+ hcd_disconnect(core_if);
8892+
8893+ pcd=(dwc_otg_pcd_t *)core_if->pcd_cb->p;
8894+ if(unlikely(!pcd)) {
8895+ DWC_ERROR("%s: data structure not initialized properly, core_if->pcd_cb->p = NULL!!!",__func__);
8896+ BUG();
8897+ }
8898+ SPIN_LOCK(&pcd->lock);
8899+
8900+ pcd_start(core_if);
8901+
8902+ SPIN_UNLOCK(&pcd->lock);
8903+
8904+ core_if->op_state = B_PERIPHERAL;
8905+ } else {
8906+ DWC_DEBUGPL(DBG_ANY,"!a_peripheral && !devhnpen\n");
8907+ }
8908+ } else {
8909+ if (core_if->op_state == A_HOST) {
8910+ /* A-Cable still connected but device disconnected. */
8911+ hcd_disconnect(core_if);
8912+ }
8913+ }
8914+#endif
8915+
8916+ gintsts.d32 = 0;
8917+ gintsts.b.disconnect = 1;
8918+ dwc_write_reg32 (&core_if->core_global_regs->gintsts, gintsts.d32);
8919+ return 1;
8920+}
8921+/**
8922+ * This interrupt indicates that SUSPEND state has been detected on
8923+ * the USB.
8924+ *
8925+ * For HNP the USB Suspend interrupt signals the change from
8926+ * "a_peripheral" to "a_host".
8927+ *
8928+ * When power management is enabled the core will be put in low power
8929+ * mode.
8930+ */
8931+int32_t dwc_otg_handle_usb_suspend_intr(dwc_otg_core_if_t *core_if)
8932+{
8933+ dsts_data_t dsts;
8934+ gintsts_data_t gintsts;
8935+
8936+ DWC_DEBUGPL(DBG_ANY,"USB SUSPEND\n");
8937+
8938+ if (dwc_otg_is_device_mode(core_if)) {
8939+ dwc_otg_pcd_t *pcd;
8940+
8941+ /* Check the Device status register to determine if the Suspend
8942+ * state is active. */
8943+ dsts.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts);
8944+ DWC_DEBUGPL(DBG_PCD, "DSTS=0x%0x\n", dsts.d32);
8945+ DWC_DEBUGPL(DBG_PCD, "DSTS.Suspend Status=%d "
8946+ "HWCFG4.power Optimize=%d\n",
8947+ dsts.b.suspsts, core_if->hwcfg4.b.power_optimiz);
8948+
8949+
8950+#ifdef PARTIAL_POWER_DOWN
8951+/** @todo Add a module parameter for power management. */
8952+
8953+ if (dsts.b.suspsts && core_if->hwcfg4.b.power_optimiz) {
8954+ pcgcctl_data_t power = {.d32=0};
8955+ DWC_DEBUGPL(DBG_CIL, "suspend\n");
8956+
8957+ power.b.pwrclmp = 1;
8958+ dwc_write_reg32(core_if->pcgcctl, power.d32);
8959+
8960+ power.b.rstpdwnmodule = 1;
8961+ dwc_modify_reg32(core_if->pcgcctl, 0, power.d32);
8962+
8963+ power.b.stoppclk = 1;
8964+ dwc_modify_reg32(core_if->pcgcctl, 0, power.d32);
8965+
8966+ } else {
8967+ DWC_DEBUGPL(DBG_ANY,"disconnect?\n");
8968+ }
8969+#endif
8970+ /* PCD callback for suspend. */
8971+ pcd=(dwc_otg_pcd_t *)core_if->pcd_cb->p;
8972+ if(unlikely(!pcd)) {
8973+ DWC_ERROR("%s: data structure not initialized properly, core_if->pcd_cb->p = NULL!!!",__func__);
8974+ BUG();
8975+ }
8976+ SPIN_LOCK(&pcd->lock);
8977+
8978+ pcd_suspend(core_if);
8979+
8980+ SPIN_UNLOCK(&pcd->lock);
8981+ } else {
8982+ if (core_if->op_state == A_PERIPHERAL) {
8983+ dwc_otg_pcd_t *pcd;
8984+
8985+ DWC_DEBUGPL(DBG_ANY,"a_peripheral->a_host\n");
8986+ /* Clear the a_peripheral flag, back to a_host. */
8987+
8988+ pcd=(dwc_otg_pcd_t *)core_if->pcd_cb->p;
8989+ if(unlikely(!pcd)) {
8990+ DWC_ERROR("%s: data structure not initialized properly, core_if->pcd_cb->p = NULL!!!",__func__);
8991+ BUG();
8992+ }
8993+ SPIN_LOCK(&pcd->lock);
8994+
8995+ pcd_stop(core_if);
8996+
8997+ SPIN_UNLOCK(&pcd->lock);
8998+
8999+ hcd_start(core_if);
9000+ core_if->op_state = A_HOST;
9001+ }
9002+ }
9003+
9004+ /* Clear interrupt */
9005+ gintsts.d32 = 0;
9006+ gintsts.b.usbsuspend = 1;
9007+ dwc_write_reg32(&core_if->core_global_regs->gintsts, gintsts.d32);
9008+
9009+ return 1;
9010+}
9011+
9012+
9013+/**
9014+ * This function returns the Core Interrupt register.
9015+ */
9016+static inline uint32_t dwc_otg_read_common_intr(dwc_otg_core_if_t *core_if)
9017+{
9018+ gintsts_data_t gintsts;
9019+ gintmsk_data_t gintmsk;
9020+ gintmsk_data_t gintmsk_common = {.d32=0};
9021+ gintmsk_common.b.wkupintr = 1;
9022+ gintmsk_common.b.sessreqintr = 1;
9023+ gintmsk_common.b.conidstschng = 1;
9024+ gintmsk_common.b.otgintr = 1;
9025+ gintmsk_common.b.modemismatch = 1;
9026+ gintmsk_common.b.disconnect = 1;
9027+ gintmsk_common.b.usbsuspend = 1;
9028+ /** @todo: The port interrupt occurs while in device
9029+ * mode. Added code to CIL to clear the interrupt for now!
9030+ */
9031+ gintmsk_common.b.portintr = 1;
9032+
9033+ gintsts.d32 = dwc_read_reg32(&core_if->core_global_regs->gintsts);
9034+ gintmsk.d32 = dwc_read_reg32(&core_if->core_global_regs->gintmsk);
9035+#ifdef DEBUG
9036+ /* if any common interrupts set */
9037+ if (gintsts.d32 & gintmsk_common.d32) {
9038+ DWC_DEBUGPL(DBG_ANY, "gintsts=%08x gintmsk=%08x\n",
9039+ gintsts.d32, gintmsk.d32);
9040+ }
9041+#endif
9042+
9043+ return ((gintsts.d32 & gintmsk.d32) & gintmsk_common.d32);
9044+
9045+}
9046+
9047+/**
9048+ * Common interrupt handler.
9049+ *
9050+ * The common interrupts are those that occur in both Host and Device mode.
9051+ * This handler handles the following interrupts:
9052+ * - Mode Mismatch Interrupt
9053+ * - Disconnect Interrupt
9054+ * - OTG Interrupt
9055+ * - Connector ID Status Change Interrupt
9056+ * - Session Request Interrupt.
9057+ * - Resume / Remote Wakeup Detected Interrupt.
9058+ *
9059+ */
9060+int32_t dwc_otg_handle_common_intr(dwc_otg_core_if_t *core_if)
9061+{
9062+ int retval = 0;
9063+ gintsts_data_t gintsts;
9064+
9065+ gintsts.d32 = dwc_otg_read_common_intr(core_if);
9066+
9067+ if (gintsts.b.modemismatch) {
9068+ retval |= dwc_otg_handle_mode_mismatch_intr(core_if);
9069+ }
9070+ if (gintsts.b.otgintr) {
9071+ retval |= dwc_otg_handle_otg_intr(core_if);
9072+ }
9073+ if (gintsts.b.conidstschng) {
9074+ retval |= dwc_otg_handle_conn_id_status_change_intr(core_if);
9075+ }
9076+ if (gintsts.b.disconnect) {
9077+ retval |= dwc_otg_handle_disconnect_intr(core_if);
9078+ }
9079+ if (gintsts.b.sessreqintr) {
9080+ retval |= dwc_otg_handle_session_req_intr(core_if);
9081+ }
9082+ if (gintsts.b.wkupintr) {
9083+ retval |= dwc_otg_handle_wakeup_detected_intr(core_if);
9084+ }
9085+ if (gintsts.b.usbsuspend) {
9086+ retval |= dwc_otg_handle_usb_suspend_intr(core_if);
9087+ }
9088+ if (gintsts.b.portintr && dwc_otg_is_device_mode(core_if)) {
9089+ /* The port interrupt occurs while in device mode with HPRT0
9090+ * Port Enable/Disable.
9091+ */
9092+ gintsts.d32 = 0;
9093+ gintsts.b.portintr = 1;
9094+ dwc_write_reg32(&core_if->core_global_regs->gintsts,
9095+ gintsts.d32);
9096+ retval |= 1;
9097+
9098+ }
9099+
9100+ S3C2410X_CLEAR_EINTPEND();
9101+
9102+ return retval;
9103+}
9104--- /dev/null
9105+++ b/drivers/usb/host/otg/dwc_otg_driver.c
9106@@ -0,0 +1,1283 @@
9107+/* ==========================================================================
9108+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_driver.c $
9109+ * $Revision: #63 $
9110+ * $Date: 2008/09/24 $
9111+ * $Change: 1101777 $
9112+ *
9113+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
9114+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
9115+ * otherwise expressly agreed to in writing between Synopsys and you.
9116+ *
9117+ * The Software IS NOT an item of Licensed Software or Licensed Product under
9118+ * any End User Software License Agreement or Agreement for Licensed Product
9119+ * with Synopsys or any supplement thereto. You are permitted to use and
9120+ * redistribute this Software in source and binary forms, with or without
9121+ * modification, provided that redistributions of source code must retain this
9122+ * notice. You may not view, use, disclose, copy or distribute this file or
9123+ * any information contained herein except pursuant to this license grant from
9124+ * Synopsys. If you do not agree with this notice, including the disclaimer
9125+ * below, then you are not authorized to use the Software.
9126+ *
9127+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
9128+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
9129+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
9130+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
9131+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
9132+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
9133+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
9134+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
9135+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
9136+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
9137+ * DAMAGE.
9138+ * ========================================================================== */
9139+
9140+/** @file
9141+ * The dwc_otg_driver module provides the initialization and cleanup entry
9142+ * points for the DWC_otg driver. This module will be dynamically installed
9143+ * after Linux is booted using the insmod command. When the module is
9144+ * installed, the dwc_otg_driver_init function is called. When the module is
9145+ * removed (using rmmod), the dwc_otg_driver_cleanup function is called.
9146+ *
9147+ * This module also defines a data structure for the dwc_otg_driver, which is
9148+ * used in conjunction with the standard ARM lm_device structure. These
9149+ * structures allow the OTG driver to comply with the standard Linux driver
9150+ * model in which devices and drivers are registered with a bus driver. This
9151+ * has the benefit that Linux can expose attributes of the driver and device
9152+ * in its special sysfs file system. Users can then read or write files in
9153+ * this file system to perform diagnostics on the driver components or the
9154+ * device.
9155+ */
9156+
9157+#include <linux/kernel.h>
9158+#include <linux/module.h>
9159+#include <linux/moduleparam.h>
9160+#include <linux/init.h>
9161+#include <linux/device.h>
9162+#include <linux/errno.h>
9163+#include <linux/types.h>
9164+#include <linux/stat.h> /* permission constants */
9165+#include <linux/version.h>
9166+
9167+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
9168+# include <linux/irq.h>
9169+#endif
9170+
9171+#include <asm/io.h>
9172+
9173+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
9174+# include <asm/irq.h>
9175+#endif
9176+
9177+//#include <asm/arch/lm.h>
9178+#include <mach/lm.h>
9179+#include <mach/board.h>
9180+#include <asm/sizes.h>
9181+#include <mach/pm.h>
9182+
9183+#include "dwc_otg_plat.h"
9184+#include "dwc_otg_attr.h"
9185+#include "dwc_otg_driver.h"
9186+#include "dwc_otg_cil.h"
9187+#include "dwc_otg_pcd.h"
9188+#include "dwc_otg_hcd.h"
9189+
9190+#define DWC_DRIVER_VERSION "2.72a 24-JUN-2008"
9191+#define DWC_DRIVER_DESC "HS OTG USB Controller driver"
9192+
9193+static const char dwc_driver_name[] = "dwc_otg";
9194+
9195+/*-------------------------------------------------------------------------*/
9196+/* Encapsulate the module parameter settings */
9197+
9198+static dwc_otg_core_params_t dwc_otg_module_params = {
9199+ .opt = -1,
9200+ .otg_cap = -1,
9201+ .dma_enable = -1,
9202+ .dma_desc_enable = -1,
9203+ .dma_burst_size = -1,
9204+ .speed = -1,
9205+ .host_support_fs_ls_low_power = -1,
9206+ .host_ls_low_power_phy_clk = -1,
9207+ .enable_dynamic_fifo = -1,
9208+ .data_fifo_size = -1,
9209+ .dev_rx_fifo_size = -1,
9210+ .dev_nperio_tx_fifo_size = -1,
9211+ .dev_perio_tx_fifo_size = {
9212+ /* dev_perio_tx_fifo_size_1 */
9213+ -1,
9214+ -1,
9215+ -1,
9216+ -1,
9217+ -1,
9218+ -1,
9219+ -1,
9220+ -1,
9221+ -1,
9222+ -1,
9223+ -1,
9224+ -1,
9225+ -1,
9226+ -1,
9227+ -1
9228+ /* 15 */
9229+ },
9230+ .host_rx_fifo_size = -1,
9231+ .host_nperio_tx_fifo_size = -1,
9232+ .host_perio_tx_fifo_size = -1,
9233+ .max_transfer_size = -1,
9234+ .max_packet_count = -1,
9235+ .host_channels = -1,
9236+ .dev_endpoints = -1,
9237+ .phy_type = -1,
9238+ .phy_utmi_width = -1,
9239+ .phy_ulpi_ddr = -1,
9240+ .phy_ulpi_ext_vbus = -1,
9241+ .i2c_enable = -1,
9242+ .ulpi_fs_ls = -1,
9243+ .ts_dline = -1,
9244+ .en_multiple_tx_fifo = -1,
9245+ .dev_tx_fifo_size = {
9246+ /* dev_tx_fifo_size */
9247+ -1,
9248+ -1,
9249+ -1,
9250+ -1,
9251+ -1,
9252+ -1,
9253+ -1,
9254+ -1,
9255+ -1,
9256+ -1,
9257+ -1,
9258+ -1,
9259+ -1,
9260+ -1,
9261+ -1
9262+ /* 15 */
9263+ },
9264+ .thr_ctl = -1,
9265+ .tx_thr_length = -1,
9266+ .rx_thr_length = -1,
9267+ .pti_enable = -1,
9268+ .mpi_enable = -1,
9269+};
9270+
9271+/**
9272+ * This function shows the Driver Version.
9273+ */
9274+static ssize_t version_show(struct device_driver *dev, char *buf)
9275+{
9276+ return snprintf(buf, sizeof(DWC_DRIVER_VERSION)+2, "%s\n",
9277+ DWC_DRIVER_VERSION);
9278+}
9279+static DRIVER_ATTR(version, S_IRUGO, version_show, NULL);
9280+
9281+/**
9282+ * Global Debug Level Mask.
9283+ */
9284+uint32_t g_dbg_lvl = 0; /* OFF */
9285+
9286+/**
9287+ * This function shows the driver Debug Level.
9288+ */
9289+static ssize_t dbg_level_show(struct device_driver *drv, char *buf)
9290+{
9291+ return sprintf(buf, "0x%0x\n", g_dbg_lvl);
9292+}
9293+
9294+/**
9295+ * This function stores the driver Debug Level.
9296+ */
9297+static ssize_t dbg_level_store(struct device_driver *drv, const char *buf,
9298+ size_t count)
9299+{
9300+ g_dbg_lvl = simple_strtoul(buf, NULL, 16);
9301+ return count;
9302+}
9303+static DRIVER_ATTR(debuglevel, S_IRUGO|S_IWUSR, dbg_level_show, dbg_level_store);
9304+
9305+/**
9306+ * This function is called during module intialization to verify that
9307+ * the module parameters are in a valid state.
9308+ */
9309+static int check_parameters(dwc_otg_core_if_t *core_if)
9310+{
9311+ int i;
9312+ int retval = 0;
9313+
9314+/* Checks if the parameter is outside of its valid range of values */
9315+#define DWC_OTG_PARAM_TEST(_param_, _low_, _high_) \
9316+ ((dwc_otg_module_params._param_ < (_low_)) || \
9317+ (dwc_otg_module_params._param_ > (_high_)))
9318+
9319+/* If the parameter has been set by the user, check that the parameter value is
9320+ * within the value range of values. If not, report a module error. */
9321+#define DWC_OTG_PARAM_ERR(_param_, _low_, _high_, _string_) \
9322+ do { \
9323+ if (dwc_otg_module_params._param_ != -1) { \
9324+ if (DWC_OTG_PARAM_TEST(_param_, (_low_), (_high_))) { \
9325+ DWC_ERROR("`%d' invalid for parameter `%s'\n", \
9326+ dwc_otg_module_params._param_, _string_); \
9327+ dwc_otg_module_params._param_ = dwc_param_##_param_##_default; \
9328+ retval++; \
9329+ } \
9330+ } \
9331+ } while (0)
9332+
9333+ DWC_OTG_PARAM_ERR(opt,0,1,"opt");
9334+ DWC_OTG_PARAM_ERR(otg_cap,0,2,"otg_cap");
9335+ DWC_OTG_PARAM_ERR(dma_enable,0,1,"dma_enable");
9336+ DWC_OTG_PARAM_ERR(dma_desc_enable,0,1,"dma_desc_enable");
9337+ DWC_OTG_PARAM_ERR(speed,0,1,"speed");
9338+ DWC_OTG_PARAM_ERR(host_support_fs_ls_low_power,0,1,"host_support_fs_ls_low_power");
9339+ DWC_OTG_PARAM_ERR(host_ls_low_power_phy_clk,0,1,"host_ls_low_power_phy_clk");
9340+ DWC_OTG_PARAM_ERR(enable_dynamic_fifo,0,1,"enable_dynamic_fifo");
9341+ DWC_OTG_PARAM_ERR(data_fifo_size,32,32768,"data_fifo_size");
9342+ DWC_OTG_PARAM_ERR(dev_rx_fifo_size,16,32768,"dev_rx_fifo_size");
9343+ DWC_OTG_PARAM_ERR(dev_nperio_tx_fifo_size,16,32768,"dev_nperio_tx_fifo_size");
9344+ DWC_OTG_PARAM_ERR(host_rx_fifo_size,16,32768,"host_rx_fifo_size");
9345+ DWC_OTG_PARAM_ERR(host_nperio_tx_fifo_size,16,32768,"host_nperio_tx_fifo_size");
9346+ DWC_OTG_PARAM_ERR(host_perio_tx_fifo_size,16,32768,"host_perio_tx_fifo_size");
9347+ DWC_OTG_PARAM_ERR(max_transfer_size,2047,524288,"max_transfer_size");
9348+ DWC_OTG_PARAM_ERR(max_packet_count,15,511,"max_packet_count");
9349+ DWC_OTG_PARAM_ERR(host_channels,1,16,"host_channels");
9350+ DWC_OTG_PARAM_ERR(dev_endpoints,1,15,"dev_endpoints");
9351+ DWC_OTG_PARAM_ERR(phy_type,0,2,"phy_type");
9352+ DWC_OTG_PARAM_ERR(phy_ulpi_ddr,0,1,"phy_ulpi_ddr");
9353+ DWC_OTG_PARAM_ERR(phy_ulpi_ext_vbus,0,1,"phy_ulpi_ext_vbus");
9354+ DWC_OTG_PARAM_ERR(i2c_enable,0,1,"i2c_enable");
9355+ DWC_OTG_PARAM_ERR(ulpi_fs_ls,0,1,"ulpi_fs_ls");
9356+ DWC_OTG_PARAM_ERR(ts_dline,0,1,"ts_dline");
9357+
9358+ if (dwc_otg_module_params.dma_burst_size != -1) {
9359+ if (DWC_OTG_PARAM_TEST(dma_burst_size,1,1) &&
9360+ DWC_OTG_PARAM_TEST(dma_burst_size,4,4) &&
9361+ DWC_OTG_PARAM_TEST(dma_burst_size,8,8) &&
9362+ DWC_OTG_PARAM_TEST(dma_burst_size,16,16) &&
9363+ DWC_OTG_PARAM_TEST(dma_burst_size,32,32) &&
9364+ DWC_OTG_PARAM_TEST(dma_burst_size,64,64) &&
9365+ DWC_OTG_PARAM_TEST(dma_burst_size,128,128) &&
9366+ DWC_OTG_PARAM_TEST(dma_burst_size,256,256)) {
9367+ DWC_ERROR("`%d' invalid for parameter `dma_burst_size'\n",
9368+ dwc_otg_module_params.dma_burst_size);
9369+ dwc_otg_module_params.dma_burst_size = 32;
9370+ retval++;
9371+ }
9372+
9373+ {
9374+ uint8_t brst_sz = 0;
9375+ while(dwc_otg_module_params.dma_burst_size > 1) {
9376+ brst_sz ++;
9377+ dwc_otg_module_params.dma_burst_size >>= 1;
9378+ }
9379+ dwc_otg_module_params.dma_burst_size = brst_sz;
9380+ }
9381+ }
9382+
9383+ if (dwc_otg_module_params.phy_utmi_width != -1) {
9384+ if (DWC_OTG_PARAM_TEST(phy_utmi_width, 8, 8) &&
9385+ DWC_OTG_PARAM_TEST(phy_utmi_width, 16, 16)) {
9386+ DWC_ERROR("`%d' invalid for parameter `phy_utmi_width'\n",
9387+ dwc_otg_module_params.phy_utmi_width);
9388+ dwc_otg_module_params.phy_utmi_width = 16;
9389+ retval++;
9390+ }
9391+ }
9392+
9393+ for (i = 0; i < 15; i++) {
9394+ /** @todo should be like above */
9395+ //DWC_OTG_PARAM_ERR(dev_perio_tx_fifo_size[i], 4, 768, "dev_perio_tx_fifo_size");
9396+ if (dwc_otg_module_params.dev_perio_tx_fifo_size[i] != -1) {
9397+ if (DWC_OTG_PARAM_TEST(dev_perio_tx_fifo_size[i], 4, 768)) {
9398+ DWC_ERROR("`%d' invalid for parameter `%s_%d'\n",
9399+ dwc_otg_module_params.dev_perio_tx_fifo_size[i], "dev_perio_tx_fifo_size", i);
9400+ dwc_otg_module_params.dev_perio_tx_fifo_size[i] = dwc_param_dev_perio_tx_fifo_size_default;
9401+ retval++;
9402+ }
9403+ }
9404+ }
9405+
9406+ DWC_OTG_PARAM_ERR(en_multiple_tx_fifo, 0, 1, "en_multiple_tx_fifo");
9407+
9408+ for (i = 0; i < 15; i++) {
9409+ /** @todo should be like above */
9410+ //DWC_OTG_PARAM_ERR(dev_tx_fifo_size[i], 4, 768, "dev_tx_fifo_size");
9411+ if (dwc_otg_module_params.dev_tx_fifo_size[i] != -1) {
9412+ if (DWC_OTG_PARAM_TEST(dev_tx_fifo_size[i], 4, 768)) {
9413+ DWC_ERROR("`%d' invalid for parameter `%s_%d'\n",
9414+ dwc_otg_module_params.dev_tx_fifo_size[i], "dev_tx_fifo_size", i);
9415+ dwc_otg_module_params.dev_tx_fifo_size[i] = dwc_param_dev_tx_fifo_size_default;
9416+ retval++;
9417+ }
9418+ }
9419+ }
9420+
9421+ DWC_OTG_PARAM_ERR(thr_ctl, 0, 7, "thr_ctl");
9422+ DWC_OTG_PARAM_ERR(tx_thr_length, 8, 128, "tx_thr_length");
9423+ DWC_OTG_PARAM_ERR(rx_thr_length, 8, 128, "rx_thr_length");
9424+
9425+ DWC_OTG_PARAM_ERR(pti_enable,0,1,"pti_enable");
9426+ DWC_OTG_PARAM_ERR(mpi_enable,0,1,"mpi_enable");
9427+
9428+ /* At this point, all module parameters that have been set by the user
9429+ * are valid, and those that have not are left unset. Now set their
9430+ * default values and/or check the parameters against the hardware
9431+ * configurations of the OTG core. */
9432+
9433+/* This sets the parameter to the default value if it has not been set by the
9434+ * user */
9435+#define DWC_OTG_PARAM_SET_DEFAULT(_param_) \
9436+ ({ \
9437+ int changed = 1; \
9438+ if (dwc_otg_module_params._param_ == -1) { \
9439+ changed = 0; \
9440+ dwc_otg_module_params._param_ = dwc_param_##_param_##_default; \
9441+ } \
9442+ changed; \
9443+ })
9444+
9445+/* This checks the macro agains the hardware configuration to see if it is
9446+ * valid. It is possible that the default value could be invalid. In this
9447+ * case, it will report a module error if the user touched the parameter.
9448+ * Otherwise it will adjust the value without any error. */
9449+#define DWC_OTG_PARAM_CHECK_VALID(_param_, _str_, _is_valid_, _set_valid_) \
9450+ ({ \
9451+ int changed = DWC_OTG_PARAM_SET_DEFAULT(_param_); \
9452+ int error = 0; \
9453+ if (!(_is_valid_)) { \
9454+ if (changed) { \
9455+ DWC_ERROR("`%d' invalid for parameter `%s'. Check HW configuration.\n", dwc_otg_module_params._param_, _str_); \
9456+ error = 1; \
9457+ } \
9458+ dwc_otg_module_params._param_ = (_set_valid_); \
9459+ } \
9460+ error; \
9461+ })
9462+
9463+ /* OTG Cap */
9464+ retval += DWC_OTG_PARAM_CHECK_VALID(otg_cap, "otg_cap",
9465+ ({
9466+ int valid;
9467+ valid = 1;
9468+ switch (dwc_otg_module_params.otg_cap) {
9469+ case DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE:
9470+ if (core_if->hwcfg2.b.op_mode != DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
9471+ valid = 0;
9472+ break;
9473+ case DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE:
9474+ if ((core_if->hwcfg2.b.op_mode != DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG) &&
9475+ (core_if->hwcfg2.b.op_mode != DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG) &&
9476+ (core_if->hwcfg2.b.op_mode != DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE) &&
9477+ (core_if->hwcfg2.b.op_mode != DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)) {
9478+ valid = 0;
9479+ }
9480+ break;
9481+ case DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE:
9482+ /* always valid */
9483+ break;
9484+ }
9485+ valid;
9486+ }),
9487+ (((core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG) ||
9488+ (core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG) ||
9489+ (core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE) ||
9490+ (core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)) ?
9491+ DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE :
9492+ DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE));
9493+
9494+ retval += DWC_OTG_PARAM_CHECK_VALID(dma_enable, "dma_enable",
9495+ ((dwc_otg_module_params.dma_enable == 1) && (core_if->hwcfg2.b.architecture == 0)) ? 0 : 1,
9496+ 0);
9497+
9498+ retval += DWC_OTG_PARAM_CHECK_VALID(dma_desc_enable, "dma_desc_enable",
9499+ ((dwc_otg_module_params.dma_desc_enable == 1) &&
9500+ ((dwc_otg_module_params.dma_enable == 0) || (core_if->hwcfg4.b.desc_dma == 0))) ? 0 : 1,
9501+ 0);
9502+
9503+ retval += DWC_OTG_PARAM_CHECK_VALID(opt, "opt", 1, 0);
9504+
9505+ DWC_OTG_PARAM_SET_DEFAULT(dma_burst_size);
9506+
9507+ retval += DWC_OTG_PARAM_CHECK_VALID(host_support_fs_ls_low_power,
9508+ "host_support_fs_ls_low_power",
9509+ 1, 0);
9510+
9511+ retval += DWC_OTG_PARAM_CHECK_VALID(enable_dynamic_fifo,
9512+ "enable_dynamic_fifo",
9513+ ((dwc_otg_module_params.enable_dynamic_fifo == 0) ||
9514+ (core_if->hwcfg2.b.dynamic_fifo == 1)), 0);
9515+
9516+ retval += DWC_OTG_PARAM_CHECK_VALID(data_fifo_size,
9517+ "data_fifo_size",
9518+ (dwc_otg_module_params.data_fifo_size <= core_if->hwcfg3.b.dfifo_depth),
9519+ core_if->hwcfg3.b.dfifo_depth);
9520+
9521+ retval += DWC_OTG_PARAM_CHECK_VALID(dev_rx_fifo_size,
9522+ "dev_rx_fifo_size",
9523+ (dwc_otg_module_params.dev_rx_fifo_size <= dwc_read_reg32(&core_if->core_global_regs->grxfsiz)),
9524+ dwc_read_reg32(&core_if->core_global_regs->grxfsiz));
9525+
9526+ retval += DWC_OTG_PARAM_CHECK_VALID(dev_nperio_tx_fifo_size,
9527+ "dev_nperio_tx_fifo_size",
9528+ (dwc_otg_module_params.dev_nperio_tx_fifo_size <= (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16)),
9529+ (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16));
9530+
9531+ retval += DWC_OTG_PARAM_CHECK_VALID(host_rx_fifo_size,
9532+ "host_rx_fifo_size",
9533+ (dwc_otg_module_params.host_rx_fifo_size <= dwc_read_reg32(&core_if->core_global_regs->grxfsiz)),
9534+ dwc_read_reg32(&core_if->core_global_regs->grxfsiz));
9535+
9536+ retval += DWC_OTG_PARAM_CHECK_VALID(host_nperio_tx_fifo_size,
9537+ "host_nperio_tx_fifo_size",
9538+ (dwc_otg_module_params.host_nperio_tx_fifo_size <= (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16)),
9539+ (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16));
9540+
9541+ retval += DWC_OTG_PARAM_CHECK_VALID(host_perio_tx_fifo_size,
9542+ "host_perio_tx_fifo_size",
9543+ (dwc_otg_module_params.host_perio_tx_fifo_size <= ((dwc_read_reg32(&core_if->core_global_regs->hptxfsiz) >> 16))),
9544+ ((dwc_read_reg32(&core_if->core_global_regs->hptxfsiz) >> 16)));
9545+
9546+ retval += DWC_OTG_PARAM_CHECK_VALID(max_transfer_size,
9547+ "max_transfer_size",
9548+ (dwc_otg_module_params.max_transfer_size < (1 << (core_if->hwcfg3.b.xfer_size_cntr_width + 11))),
9549+ ((1 << (core_if->hwcfg3.b.xfer_size_cntr_width + 11)) - 1));
9550+
9551+ retval += DWC_OTG_PARAM_CHECK_VALID(max_packet_count,
9552+ "max_packet_count",
9553+ (dwc_otg_module_params.max_packet_count < (1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4))),
9554+ ((1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4)) - 1));
9555+
9556+ retval += DWC_OTG_PARAM_CHECK_VALID(host_channels,
9557+ "host_channels",
9558+ (dwc_otg_module_params.host_channels <= (core_if->hwcfg2.b.num_host_chan + 1)),
9559+ (core_if->hwcfg2.b.num_host_chan + 1));
9560+
9561+ retval += DWC_OTG_PARAM_CHECK_VALID(dev_endpoints,
9562+ "dev_endpoints",
9563+ (dwc_otg_module_params.dev_endpoints <= (core_if->hwcfg2.b.num_dev_ep)),
9564+ core_if->hwcfg2.b.num_dev_ep);
9565+
9566+/*
9567+ * Define the following to disable the FS PHY Hardware checking. This is for
9568+ * internal testing only.
9569+ *
9570+ * #define NO_FS_PHY_HW_CHECKS
9571+ */
9572+
9573+#ifdef NO_FS_PHY_HW_CHECKS
9574+ retval += DWC_OTG_PARAM_CHECK_VALID(phy_type,
9575+ "phy_type", 1, 0);
9576+#else
9577+ retval += DWC_OTG_PARAM_CHECK_VALID(phy_type,
9578+ "phy_type",
9579+ ({
9580+ int valid = 0;
9581+ if ((dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_UTMI) &&
9582+ ((core_if->hwcfg2.b.hs_phy_type == 1) ||
9583+ (core_if->hwcfg2.b.hs_phy_type == 3))) {
9584+ valid = 1;
9585+ }
9586+ else if ((dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_ULPI) &&
9587+ ((core_if->hwcfg2.b.hs_phy_type == 2) ||
9588+ (core_if->hwcfg2.b.hs_phy_type == 3))) {
9589+ valid = 1;
9590+ }
9591+ else if ((dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_FS) &&
9592+ (core_if->hwcfg2.b.fs_phy_type == 1)) {
9593+ valid = 1;
9594+ }
9595+ valid;
9596+ }),
9597+ ({
9598+ int set = DWC_PHY_TYPE_PARAM_FS;
9599+ if (core_if->hwcfg2.b.hs_phy_type) {
9600+ if ((core_if->hwcfg2.b.hs_phy_type == 3) ||
9601+ (core_if->hwcfg2.b.hs_phy_type == 1)) {
9602+ set = DWC_PHY_TYPE_PARAM_UTMI;
9603+ }
9604+ else {
9605+ set = DWC_PHY_TYPE_PARAM_ULPI;
9606+ }
9607+ }
9608+ set;
9609+ }));
9610+#endif
9611+
9612+ retval += DWC_OTG_PARAM_CHECK_VALID(speed, "speed",
9613+ (dwc_otg_module_params.speed == 0) && (dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_FS) ? 0 : 1,
9614+ dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_FS ? 1 : 0);
9615+
9616+ retval += DWC_OTG_PARAM_CHECK_VALID(host_ls_low_power_phy_clk,
9617+ "host_ls_low_power_phy_clk",
9618+ ((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),
9619+ ((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));
9620+
9621+ DWC_OTG_PARAM_SET_DEFAULT(phy_ulpi_ddr);
9622+ DWC_OTG_PARAM_SET_DEFAULT(phy_ulpi_ext_vbus);
9623+ DWC_OTG_PARAM_SET_DEFAULT(phy_utmi_width);
9624+ DWC_OTG_PARAM_SET_DEFAULT(ulpi_fs_ls);
9625+ DWC_OTG_PARAM_SET_DEFAULT(ts_dline);
9626+
9627+#ifdef NO_FS_PHY_HW_CHECKS
9628+ retval += DWC_OTG_PARAM_CHECK_VALID(i2c_enable, "i2c_enable", 1, 0);
9629+#else
9630+ retval += DWC_OTG_PARAM_CHECK_VALID(i2c_enable,
9631+ "i2c_enable",
9632+ (dwc_otg_module_params.i2c_enable == 1) && (core_if->hwcfg3.b.i2c == 0) ? 0 : 1,
9633+ 0);
9634+#endif
9635+
9636+ for (i = 0; i < 15; i++) {
9637+ int changed = 1;
9638+ int error = 0;
9639+
9640+ if (dwc_otg_module_params.dev_perio_tx_fifo_size[i] == -1) {
9641+ changed = 0;
9642+ dwc_otg_module_params.dev_perio_tx_fifo_size[i] = dwc_param_dev_perio_tx_fifo_size_default;
9643+ }
9644+ if (!(dwc_otg_module_params.dev_perio_tx_fifo_size[i] <= (dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[i])))) {
9645+ if (changed) {
9646+ 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);
9647+ error = 1;
9648+ }
9649+ dwc_otg_module_params.dev_perio_tx_fifo_size[i] = dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[i]);
9650+ }
9651+ retval += error;
9652+ }
9653+
9654+ retval += DWC_OTG_PARAM_CHECK_VALID(en_multiple_tx_fifo, "en_multiple_tx_fifo",
9655+ ((dwc_otg_module_params.en_multiple_tx_fifo == 1) && (core_if->hwcfg4.b.ded_fifo_en == 0)) ? 0 : 1,
9656+ 0);
9657+
9658+ for (i = 0; i < 15; i++) {
9659+ int changed = 1;
9660+ int error = 0;
9661+
9662+ if (dwc_otg_module_params.dev_tx_fifo_size[i] == -1) {
9663+ changed = 0;
9664+ dwc_otg_module_params.dev_tx_fifo_size[i] = dwc_param_dev_tx_fifo_size_default;
9665+ }
9666+ if (!(dwc_otg_module_params.dev_tx_fifo_size[i] <= (dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[i])))) {
9667+ if (changed) {
9668+ 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);
9669+ error = 1;
9670+ }
9671+ dwc_otg_module_params.dev_tx_fifo_size[i] = dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[i]);
9672+ }
9673+ retval += error;
9674+ }
9675+
9676+ retval += DWC_OTG_PARAM_CHECK_VALID(thr_ctl, "thr_ctl",
9677+ ((dwc_otg_module_params.thr_ctl != 0) && ((dwc_otg_module_params.dma_enable == 0) || (core_if->hwcfg4.b.ded_fifo_en == 0))) ? 0 : 1,
9678+ 0);
9679+
9680+ DWC_OTG_PARAM_SET_DEFAULT(tx_thr_length);
9681+ DWC_OTG_PARAM_SET_DEFAULT(rx_thr_length);
9682+
9683+ retval += DWC_OTG_PARAM_CHECK_VALID(pti_enable, "pti_enable",
9684+ ((dwc_otg_module_params.pti_enable == 0) || ((dwc_otg_module_params.pti_enable == 1) && (core_if->snpsid >= 0x4F54272A))) ? 1 : 0,
9685+ 0);
9686+
9687+ retval += DWC_OTG_PARAM_CHECK_VALID(mpi_enable, "mpi_enable",
9688+ ((dwc_otg_module_params.mpi_enable == 0) || ((dwc_otg_module_params.mpi_enable == 1) && (core_if->hwcfg2.b.multi_proc_int == 1))) ? 1 : 0,
9689+ 0);
9690+ return retval;
9691+}
9692+
9693+/**
9694+ * This function is the top level interrupt handler for the Common
9695+ * (Device and host modes) interrupts.
9696+ */
9697+static irqreturn_t dwc_otg_common_irq(int irq, void *dev
9698+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
9699+ , struct pt_regs *r
9700+#endif
9701+ )
9702+{
9703+ dwc_otg_device_t *otg_dev = dev;
9704+ int32_t retval = IRQ_NONE;
9705+
9706+ retval = dwc_otg_handle_common_intr(otg_dev->core_if);
9707+ return IRQ_RETVAL(retval);
9708+}
9709+
9710+/**
9711+ * This function is called when a lm_device is unregistered with the
9712+ * dwc_otg_driver. This happens, for example, when the rmmod command is
9713+ * executed. The device may or may not be electrically present. If it is
9714+ * present, the driver stops device processing. Any resources used on behalf
9715+ * of this device are freed.
9716+ *
9717+ * @param[in] lmdev
9718+ */
9719+static void dwc_otg_driver_remove(struct lm_device *lmdev)
9720+{
9721+ dwc_otg_device_t *otg_dev = lm_get_drvdata(lmdev);
9722+ DWC_DEBUGPL(DBG_ANY, "%s(%p)\n", __func__, lmdev);
9723+
9724+ if (!otg_dev) {
9725+ /* Memory allocation for the dwc_otg_device failed. */
9726+ DWC_DEBUGPL(DBG_ANY, "%s: otg_dev NULL!\n", __func__);
9727+ return;
9728+ }
9729+
9730+ /*
9731+ * Free the IRQ
9732+ */
9733+ if (otg_dev->common_irq_installed) {
9734+ free_irq(lmdev->irq, otg_dev);
9735+ }
9736+
9737+#ifndef DWC_DEVICE_ONLY
9738+ if (otg_dev->hcd) {
9739+ dwc_otg_hcd_remove(lmdev);
9740+ } else {
9741+ DWC_DEBUGPL(DBG_ANY, "%s: otg_dev->hcd NULL!\n", __func__);
9742+ return;
9743+ }
9744+#endif
9745+
9746+#ifndef DWC_HOST_ONLY
9747+ if (otg_dev->pcd) {
9748+ dwc_otg_pcd_remove(lmdev);
9749+ }
9750+#endif
9751+ if (otg_dev->core_if) {
9752+ dwc_otg_cil_remove(otg_dev->core_if);
9753+ }
9754+
9755+ /*
9756+ * Remove the device attributes
9757+ */
9758+ dwc_otg_attr_remove(lmdev);
9759+
9760+ /*
9761+ * Return the memory.
9762+ */
9763+ if (otg_dev->base) {
9764+ cns3xxx_iounmap(otg_dev->base);
9765+ }
9766+ kfree(otg_dev);
9767+
9768+ /*
9769+ * Clear the drvdata pointer.
9770+ */
9771+ lm_set_drvdata(lmdev, 0);
9772+}
9773+
9774+/**
9775+ * This function is called when an lm_device is bound to a
9776+ * dwc_otg_driver. It creates the driver components required to
9777+ * control the device (CIL, HCD, and PCD) and it initializes the
9778+ * device. The driver components are stored in a dwc_otg_device
9779+ * structure. A reference to the dwc_otg_device is saved in the
9780+ * lm_device. This allows the driver to access the dwc_otg_device
9781+ * structure on subsequent calls to driver methods for this device.
9782+ *
9783+ * @param[in] lmdev lm_device definition
9784+ */
9785+static int dwc_otg_driver_probe(struct lm_device *lmdev)
9786+{
9787+ int retval = 0;
9788+ uint32_t snpsid;
9789+ dwc_otg_device_t *dwc_otg_device;
9790+ u_int32_t val;
9791+
9792+ dev_dbg(&lmdev->dev, "dwc_otg_driver_probe(%p)\n", lmdev);
9793+ dev_dbg(&lmdev->dev, "start=0x%08x\n", (unsigned)lmdev->resource.start);
9794+
9795+ dwc_otg_device = kmalloc(sizeof(dwc_otg_device_t), GFP_KERNEL);
9796+
9797+ if (!dwc_otg_device) {
9798+ dev_err(&lmdev->dev, "kmalloc of dwc_otg_device failed\n");
9799+ retval = -ENOMEM;
9800+ goto fail;
9801+ }
9802+
9803+ memset(dwc_otg_device, 0, sizeof(*dwc_otg_device));
9804+ dwc_otg_device->reg_offset = 0xFFFFFFFF;
9805+
9806+ /*
9807+ * Map the DWC_otg Core memory into virtual address space.
9808+ */
9809+#ifdef CNS3XXX_USBOTG_BASE_VIRT
9810+ dwc_otg_device->base = (void __iomem *) CNS3XXX_USBOTG_BASE_VIRT;
9811+#else
9812+ dwc_otg_device->base = ioremap(lmdev->resource.start, SZ_256K);
9813+#endif
9814+
9815+ if (!dwc_otg_device->base) {
9816+ dev_err(&lmdev->dev, "cns3xxx_ioremap() failed\n");
9817+ retval = -ENOMEM;
9818+ goto fail;
9819+ }
9820+ dev_dbg(&lmdev->dev, "base=0x%08x\n", (unsigned)dwc_otg_device->base);
9821+
9822+#ifdef CONFIG_SILICON
9823+#if 0
9824+ //OTG PHY
9825+ cns3xxx_pwr_power_up(1<<PM_PLL_HM_PD_CTRL_REG_OFFSET_USB_PHY0);
9826+ //USB
9827+ //cns3xxx_pwr_power_up(1<<PM_PLL_HM_PD_CTRL_REG_OFFSET_USB_PHY1);
9828+#endif
9829+ cns3xxx_pwr_power_up(1<<PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB);
9830+ cns3xxx_pwr_clk_en(1<<PM_CLK_GATE_REG_OFFSET_USB_OTG);
9831+ cns3xxx_pwr_soft_rst(1<<PM_SOFT_RST_REG_OFFST_USB_OTG);
9832+ //cns3xxx_pwr_clk_en(1<<PM_CLK_GATE_REG_OFFSET_USB_HOST);
9833+ //cns3xxx_pwr_soft_rst(1<<PM_SOFT_RST_REG_OFFST_USB_HOST);
9834+#ifdef CONFIG_USB_CNS3XXX_OTG_ENABLE_OTG_DRVVBUS
9835+ *((volatile u32*) (CNS3XXX_MISC_BASE_VIRT/*0x7600_0000*/+0x14)) |= (1<<3);
9836+#endif //#ifdef CONFIG_USB_CNS3XXX_OTG_ENABLE_OTG_DRVVBUS
9837+
9838+#endif //CONFIG_SILICON
9839+
9840+ /*
9841+ * Attempt to ensure this device is really a DWC_otg Controller.
9842+ * Read and verify the SNPSID register contents. The value should be
9843+ * 0x45F42XXX, which corresponds to "OT2", as in "OTG version 2.XX".
9844+ */
9845+ snpsid = dwc_read_reg32((uint32_t *)((uint8_t *)dwc_otg_device->base + 0x40));
9846+
9847+ if ((snpsid & 0xFFFFF000) != OTG_CORE_REV_2_00) {
9848+ dev_err(&lmdev->dev, "Bad value for SNPSID: 0x%08x\n", snpsid);
9849+ retval = -EINVAL;
9850+ goto fail;
9851+ }
9852+
9853+ DWC_PRINT("Core Release: %x.%x%x%x\n",
9854+ (snpsid >> 12 & 0xF),
9855+ (snpsid >> 8 & 0xF),
9856+ (snpsid >> 4 & 0xF),
9857+ (snpsid & 0xF));
9858+
9859+
9860+
9861+ // de-assert otgdisable
9862+ val=__raw_readl((void __iomem *)(CNS3XXX_MISC_BASE_VIRT + 0x0808));
9863+ __raw_writel(val&(~(1 << 10)), (void __iomem *)(CNS3XXX_MISC_BASE_VIRT + 0x0808));
9864+ val=__raw_readl((void __iomem *)(CNS3XXX_MISC_BASE_VIRT + 0x0808));
9865+ DWC_DEBUGPL(DBG_CIL, "de-assert otgdisable(bit10): MISC_USBPHY00_CFG_REG=%.8x\n",val);
9866+
9867+
9868+#ifdef ENDIAN_MODE_BIG_ENDIAN
9869+ // bit[18]:otg endian, bit[19]:usbh endian
9870+ val=__raw_readl((void __iomem *)(CNS3XXX_MISC_BASE_VIRT + 0x0800));
9871+ __raw_writel(val|(1 << 18), (void __iomem *)(CNS3XXX_MISC_BASE_VIRT + 0x0800));
9872+#endif
9873+ val=__raw_readl((void __iomem *)(CNS3XXX_MISC_BASE_VIRT + 0x0800));
9874+ DWC_DEBUGPL(DBG_CIL, "OTG endian(bit18): MISC_USB_CFG_REG=%.8x, OTG in %s endian mode\n",val,(val&(1<<18))?"big":"little");
9875+
9876+/*
9877+ // PMU control
9878+ HAL_PMU_POWER_ON_USB_PHY1();
9879+ HAL_PMU_POWER_ON_USB_PHY0();
9880+
9881+ HAL_PMU_POWER_ON_USB();
9882+
9883+ HAL_PMU_ENABLE_USB_OTG_CLOCK();
9884+ HAL_PMU_ENABLE_USB_HOST_CLOCK();
9885+
9886+ Hal_Pmu_Software_Reset(PMU_USB_OTG_SOFTWARE_RESET_BIT_INDEX);
9887+ Hal_Pmu_Software_Reset(PMU_USB_HOST_SOFTWARE_RESET_BIT_INDEX);
9888+*/
9889+
9890+ /*
9891+ * Initialize driver data to point to the global DWC_otg
9892+ * Device structure.
9893+ */
9894+ lm_set_drvdata(lmdev, dwc_otg_device);
9895+ dev_dbg(&lmdev->dev, "dwc_otg_device=0x%p\n", dwc_otg_device);
9896+
9897+ dwc_otg_device->core_if = dwc_otg_cil_init(dwc_otg_device->base,
9898+ &dwc_otg_module_params);
9899+
9900+ dwc_otg_device->core_if->snpsid = snpsid;
9901+
9902+ if (!dwc_otg_device->core_if) {
9903+ dev_err(&lmdev->dev, "CIL initialization failed!\n");
9904+ retval = -ENOMEM;
9905+ goto fail;
9906+ }
9907+
9908+ /*
9909+ * Validate parameter values.
9910+ */
9911+ if (check_parameters(dwc_otg_device->core_if)) {
9912+ retval = -EINVAL;
9913+ goto fail;
9914+ }
9915+
9916+ /*
9917+ * Create Device Attributes in sysfs
9918+ */
9919+ dwc_otg_attr_create(lmdev);
9920+
9921+ /*
9922+ * Disable the global interrupt until all the interrupt
9923+ * handlers are installed.
9924+ */
9925+ dwc_otg_disable_global_interrupts(dwc_otg_device->core_if);
9926+
9927+ /*
9928+ * Install the interrupt handler for the common interrupts before
9929+ * enabling common interrupts in core_init below.
9930+ */
9931+ DWC_DEBUGPL(DBG_CIL, "registering (common) handler for irq%d\n",
9932+ lmdev->irq);
9933+ retval = request_irq(lmdev->irq, dwc_otg_common_irq,
9934+ IRQF_SHARED, "dwc_otg", dwc_otg_device);
9935+ if (retval) {
9936+ DWC_ERROR("request of irq%d failed\n", lmdev->irq);
9937+ retval = -EBUSY;
9938+ goto fail;
9939+ } else {
9940+ dwc_otg_device->common_irq_installed = 1;
9941+ }
9942+
9943+ /*
9944+ * Initialize the DWC_otg core.
9945+ */
9946+ dwc_otg_core_init(dwc_otg_device->core_if);
9947+
9948+#ifndef DWC_HOST_ONLY
9949+ /*
9950+ * Initialize the PCD
9951+ */
9952+ retval = dwc_otg_pcd_init(lmdev);
9953+ if (retval != 0) {
9954+ DWC_ERROR("dwc_otg_pcd_init failed\n");
9955+ dwc_otg_device->pcd = NULL;
9956+ goto fail;
9957+ }
9958+#endif
9959+#ifndef DWC_DEVICE_ONLY
9960+ /*
9961+ * Initialize the HCD
9962+ */
9963+ retval = dwc_otg_hcd_init(lmdev);
9964+ if (retval != 0) {
9965+ DWC_ERROR("dwc_otg_hcd_init failed\n");
9966+ dwc_otg_device->hcd = NULL;
9967+ goto fail;
9968+ }
9969+#endif
9970+
9971+ /*
9972+ * Enable the global interrupt after all the interrupt
9973+ * handlers are installed.
9974+ */
9975+ dwc_otg_enable_global_interrupts(dwc_otg_device->core_if);
9976+
9977+ return 0;
9978+
9979+ fail:
9980+ dwc_otg_driver_remove(lmdev);
9981+ return retval;
9982+}
9983+
9984+/**
9985+ * This structure defines the methods to be called by a bus driver
9986+ * during the lifecycle of a device on that bus. Both drivers and
9987+ * devices are registered with a bus driver. The bus driver matches
9988+ * devices to drivers based on information in the device and driver
9989+ * structures.
9990+ *
9991+ * The probe function is called when the bus driver matches a device
9992+ * to this driver. The remove function is called when a device is
9993+ * unregistered with the bus driver.
9994+ */
9995+static struct lm_driver dwc_otg_driver = {
9996+ .drv = {
9997+ .name = (char *)dwc_driver_name,
9998+ },
9999+ .probe = dwc_otg_driver_probe,
10000+ .remove = dwc_otg_driver_remove,
10001+};
10002+
10003+/**
10004+ * This function is called when the dwc_otg_driver is installed with the
10005+ * insmod command. It registers the dwc_otg_driver structure with the
10006+ * appropriate bus driver. This will cause the dwc_otg_driver_probe function
10007+ * to be called. In addition, the bus driver will automatically expose
10008+ * attributes defined for the device and driver in the special sysfs file
10009+ * system.
10010+ *
10011+ * @return
10012+ */
10013+static int __init dwc_otg_driver_init(void)
10014+{
10015+ int retval = 0;
10016+ int error;
10017+ printk(KERN_INFO "%s: version %s\n", dwc_driver_name, DWC_DRIVER_VERSION);
10018+
10019+ retval = lm_driver_register(&dwc_otg_driver);
10020+ if (retval < 0) {
10021+ printk(KERN_ERR "%s retval=%d\n", __func__, retval);
10022+ return retval;
10023+ }
10024+ error = driver_create_file(&dwc_otg_driver.drv, &driver_attr_version);
10025+ error = driver_create_file(&dwc_otg_driver.drv, &driver_attr_debuglevel);
10026+
10027+ return retval;
10028+}
10029+module_init(dwc_otg_driver_init);
10030+
10031+/**
10032+ * This function is called when the driver is removed from the kernel
10033+ * with the rmmod command. The driver unregisters itself with its bus
10034+ * driver.
10035+ *
10036+ */
10037+static void __exit dwc_otg_driver_cleanup(void)
10038+{
10039+ printk(KERN_DEBUG "dwc_otg_driver_cleanup()\n");
10040+
10041+ driver_remove_file(&dwc_otg_driver.drv, &driver_attr_debuglevel);
10042+ driver_remove_file(&dwc_otg_driver.drv, &driver_attr_version);
10043+
10044+ lm_driver_unregister(&dwc_otg_driver);
10045+
10046+ printk(KERN_INFO "%s module removed\n", dwc_driver_name);
10047+}
10048+module_exit(dwc_otg_driver_cleanup);
10049+
10050+MODULE_DESCRIPTION(DWC_DRIVER_DESC);
10051+MODULE_AUTHOR("Synopsys Inc.");
10052+MODULE_LICENSE("GPL");
10053+
10054+module_param_named(otg_cap, dwc_otg_module_params.otg_cap, int, 0444);
10055+MODULE_PARM_DESC(otg_cap, "OTG Capabilities 0=HNP&SRP 1=SRP Only 2=None");
10056+module_param_named(opt, dwc_otg_module_params.opt, int, 0444);
10057+MODULE_PARM_DESC(opt, "OPT Mode");
10058+module_param_named(dma_enable, dwc_otg_module_params.dma_enable, int, 0444);
10059+MODULE_PARM_DESC(dma_enable, "DMA Mode 0=Slave 1=DMA enabled");
10060+
10061+module_param_named(dma_desc_enable, dwc_otg_module_params.dma_desc_enable, int, 0444);
10062+MODULE_PARM_DESC(dma_desc_enable, "DMA Desc Mode 0=Address DMA 1=DMA Descriptor enabled");
10063+
10064+module_param_named(dma_burst_size, dwc_otg_module_params.dma_burst_size, int, 0444);
10065+MODULE_PARM_DESC(dma_burst_size, "DMA Burst Size 1, 4, 8, 16, 32, 64, 128, 256");
10066+module_param_named(speed, dwc_otg_module_params.speed, int, 0444);
10067+MODULE_PARM_DESC(speed, "Speed 0=High Speed 1=Full Speed");
10068+module_param_named(host_support_fs_ls_low_power, dwc_otg_module_params.host_support_fs_ls_low_power, int, 0444);
10069+MODULE_PARM_DESC(host_support_fs_ls_low_power, "Support Low Power w/FS or LS 0=Support 1=Don't Support");
10070+module_param_named(host_ls_low_power_phy_clk, dwc_otg_module_params.host_ls_low_power_phy_clk, int, 0444);
10071+MODULE_PARM_DESC(host_ls_low_power_phy_clk, "Low Speed Low Power Clock 0=48Mhz 1=6Mhz");
10072+module_param_named(enable_dynamic_fifo, dwc_otg_module_params.enable_dynamic_fifo, int, 0444);
10073+MODULE_PARM_DESC(enable_dynamic_fifo, "0=cC Setting 1=Allow Dynamic Sizing");
10074+module_param_named(data_fifo_size, dwc_otg_module_params.data_fifo_size, int, 0444);
10075+MODULE_PARM_DESC(data_fifo_size, "Total number of words in the data FIFO memory 32-32768");
10076+module_param_named(dev_rx_fifo_size, dwc_otg_module_params.dev_rx_fifo_size, int, 0444);
10077+MODULE_PARM_DESC(dev_rx_fifo_size, "Number of words in the Rx FIFO 16-32768");
10078+module_param_named(dev_nperio_tx_fifo_size, dwc_otg_module_params.dev_nperio_tx_fifo_size, int, 0444);
10079+MODULE_PARM_DESC(dev_nperio_tx_fifo_size, "Number of words in the non-periodic Tx FIFO 16-32768");
10080+module_param_named(dev_perio_tx_fifo_size_1, dwc_otg_module_params.dev_perio_tx_fifo_size[0], int, 0444);
10081+MODULE_PARM_DESC(dev_perio_tx_fifo_size_1, "Number of words in the periodic Tx FIFO 4-768");
10082+module_param_named(dev_perio_tx_fifo_size_2, dwc_otg_module_params.dev_perio_tx_fifo_size[1], int, 0444);
10083+MODULE_PARM_DESC(dev_perio_tx_fifo_size_2, "Number of words in the periodic Tx FIFO 4-768");
10084+module_param_named(dev_perio_tx_fifo_size_3, dwc_otg_module_params.dev_perio_tx_fifo_size[2], int, 0444);
10085+MODULE_PARM_DESC(dev_perio_tx_fifo_size_3, "Number of words in the periodic Tx FIFO 4-768");
10086+module_param_named(dev_perio_tx_fifo_size_4, dwc_otg_module_params.dev_perio_tx_fifo_size[3], int, 0444);
10087+MODULE_PARM_DESC(dev_perio_tx_fifo_size_4, "Number of words in the periodic Tx FIFO 4-768");
10088+module_param_named(dev_perio_tx_fifo_size_5, dwc_otg_module_params.dev_perio_tx_fifo_size[4], int, 0444);
10089+MODULE_PARM_DESC(dev_perio_tx_fifo_size_5, "Number of words in the periodic Tx FIFO 4-768");
10090+module_param_named(dev_perio_tx_fifo_size_6, dwc_otg_module_params.dev_perio_tx_fifo_size[5], int, 0444);
10091+MODULE_PARM_DESC(dev_perio_tx_fifo_size_6, "Number of words in the periodic Tx FIFO 4-768");
10092+module_param_named(dev_perio_tx_fifo_size_7, dwc_otg_module_params.dev_perio_tx_fifo_size[6], int, 0444);
10093+MODULE_PARM_DESC(dev_perio_tx_fifo_size_7, "Number of words in the periodic Tx FIFO 4-768");
10094+module_param_named(dev_perio_tx_fifo_size_8, dwc_otg_module_params.dev_perio_tx_fifo_size[7], int, 0444);
10095+MODULE_PARM_DESC(dev_perio_tx_fifo_size_8, "Number of words in the periodic Tx FIFO 4-768");
10096+module_param_named(dev_perio_tx_fifo_size_9, dwc_otg_module_params.dev_perio_tx_fifo_size[8], int, 0444);
10097+MODULE_PARM_DESC(dev_perio_tx_fifo_size_9, "Number of words in the periodic Tx FIFO 4-768");
10098+module_param_named(dev_perio_tx_fifo_size_10, dwc_otg_module_params.dev_perio_tx_fifo_size[9], int, 0444);
10099+MODULE_PARM_DESC(dev_perio_tx_fifo_size_10, "Number of words in the periodic Tx FIFO 4-768");
10100+module_param_named(dev_perio_tx_fifo_size_11, dwc_otg_module_params.dev_perio_tx_fifo_size[10], int, 0444);
10101+MODULE_PARM_DESC(dev_perio_tx_fifo_size_11, "Number of words in the periodic Tx FIFO 4-768");
10102+module_param_named(dev_perio_tx_fifo_size_12, dwc_otg_module_params.dev_perio_tx_fifo_size[11], int, 0444);
10103+MODULE_PARM_DESC(dev_perio_tx_fifo_size_12, "Number of words in the periodic Tx FIFO 4-768");
10104+module_param_named(dev_perio_tx_fifo_size_13, dwc_otg_module_params.dev_perio_tx_fifo_size[12], int, 0444);
10105+MODULE_PARM_DESC(dev_perio_tx_fifo_size_13, "Number of words in the periodic Tx FIFO 4-768");
10106+module_param_named(dev_perio_tx_fifo_size_14, dwc_otg_module_params.dev_perio_tx_fifo_size[13], int, 0444);
10107+MODULE_PARM_DESC(dev_perio_tx_fifo_size_14, "Number of words in the periodic Tx FIFO 4-768");
10108+module_param_named(dev_perio_tx_fifo_size_15, dwc_otg_module_params.dev_perio_tx_fifo_size[14], int, 0444);
10109+MODULE_PARM_DESC(dev_perio_tx_fifo_size_15, "Number of words in the periodic Tx FIFO 4-768");
10110+module_param_named(host_rx_fifo_size, dwc_otg_module_params.host_rx_fifo_size, int, 0444);
10111+MODULE_PARM_DESC(host_rx_fifo_size, "Number of words in the Rx FIFO 16-32768");
10112+module_param_named(host_nperio_tx_fifo_size, dwc_otg_module_params.host_nperio_tx_fifo_size, int, 0444);
10113+MODULE_PARM_DESC(host_nperio_tx_fifo_size, "Number of words in the non-periodic Tx FIFO 16-32768");
10114+module_param_named(host_perio_tx_fifo_size, dwc_otg_module_params.host_perio_tx_fifo_size, int, 0444);
10115+MODULE_PARM_DESC(host_perio_tx_fifo_size, "Number of words in the host periodic Tx FIFO 16-32768");
10116+module_param_named(max_transfer_size, dwc_otg_module_params.max_transfer_size, int, 0444);
10117+/** @todo Set the max to 512K, modify checks */
10118+MODULE_PARM_DESC(max_transfer_size, "The maximum transfer size supported in bytes 2047-65535");
10119+module_param_named(max_packet_count, dwc_otg_module_params.max_packet_count, int, 0444);
10120+MODULE_PARM_DESC(max_packet_count, "The maximum number of packets in a transfer 15-511");
10121+module_param_named(host_channels, dwc_otg_module_params.host_channels, int, 0444);
10122+MODULE_PARM_DESC(host_channels, "The number of host channel registers to use 1-16");
10123+module_param_named(dev_endpoints, dwc_otg_module_params.dev_endpoints, int, 0444);
10124+MODULE_PARM_DESC(dev_endpoints, "The number of endpoints in addition to EP0 available for device mode 1-15");
10125+module_param_named(phy_type, dwc_otg_module_params.phy_type, int, 0444);
10126+MODULE_PARM_DESC(phy_type, "0=Reserved 1=UTMI+ 2=ULPI");
10127+module_param_named(phy_utmi_width, dwc_otg_module_params.phy_utmi_width, int, 0444);
10128+MODULE_PARM_DESC(phy_utmi_width, "Specifies the UTMI+ Data Width 8 or 16 bits");
10129+module_param_named(phy_ulpi_ddr, dwc_otg_module_params.phy_ulpi_ddr, int, 0444);
10130+MODULE_PARM_DESC(phy_ulpi_ddr, "ULPI at double or single data rate 0=Single 1=Double");
10131+module_param_named(phy_ulpi_ext_vbus, dwc_otg_module_params.phy_ulpi_ext_vbus, int, 0444);
10132+MODULE_PARM_DESC(phy_ulpi_ext_vbus, "ULPI PHY using internal or external vbus 0=Internal");
10133+module_param_named(i2c_enable, dwc_otg_module_params.i2c_enable, int, 0444);
10134+MODULE_PARM_DESC(i2c_enable, "FS PHY Interface");
10135+module_param_named(ulpi_fs_ls, dwc_otg_module_params.ulpi_fs_ls, int, 0444);
10136+MODULE_PARM_DESC(ulpi_fs_ls, "ULPI PHY FS/LS mode only");
10137+module_param_named(ts_dline, dwc_otg_module_params.ts_dline, int, 0444);
10138+MODULE_PARM_DESC(ts_dline, "Term select Dline pulsing for all PHYs");
10139+module_param_named(debug, g_dbg_lvl, int, 0444);
10140+MODULE_PARM_DESC(debug, "");
10141+
10142+module_param_named(en_multiple_tx_fifo, dwc_otg_module_params.en_multiple_tx_fifo, int, 0444);
10143+MODULE_PARM_DESC(en_multiple_tx_fifo, "Dedicated Non Periodic Tx FIFOs 0=disabled 1=enabled");
10144+module_param_named(dev_tx_fifo_size_1, dwc_otg_module_params.dev_tx_fifo_size[0], int, 0444);
10145+MODULE_PARM_DESC(dev_tx_fifo_size_1, "Number of words in the Tx FIFO 4-768");
10146+module_param_named(dev_tx_fifo_size_2, dwc_otg_module_params.dev_tx_fifo_size[1], int, 0444);
10147+MODULE_PARM_DESC(dev_tx_fifo_size_2, "Number of words in the Tx FIFO 4-768");
10148+module_param_named(dev_tx_fifo_size_3, dwc_otg_module_params.dev_tx_fifo_size[2], int, 0444);
10149+MODULE_PARM_DESC(dev_tx_fifo_size_3, "Number of words in the Tx FIFO 4-768");
10150+module_param_named(dev_tx_fifo_size_4, dwc_otg_module_params.dev_tx_fifo_size[3], int, 0444);
10151+MODULE_PARM_DESC(dev_tx_fifo_size_4, "Number of words in the Tx FIFO 4-768");
10152+module_param_named(dev_tx_fifo_size_5, dwc_otg_module_params.dev_tx_fifo_size[4], int, 0444);
10153+MODULE_PARM_DESC(dev_tx_fifo_size_5, "Number of words in the Tx FIFO 4-768");
10154+module_param_named(dev_tx_fifo_size_6, dwc_otg_module_params.dev_tx_fifo_size[5], int, 0444);
10155+MODULE_PARM_DESC(dev_tx_fifo_size_6, "Number of words in the Tx FIFO 4-768");
10156+module_param_named(dev_tx_fifo_size_7, dwc_otg_module_params.dev_tx_fifo_size[6], int, 0444);
10157+MODULE_PARM_DESC(dev_tx_fifo_size_7, "Number of words in the Tx FIFO 4-768");
10158+module_param_named(dev_tx_fifo_size_8, dwc_otg_module_params.dev_tx_fifo_size[7], int, 0444);
10159+MODULE_PARM_DESC(dev_tx_fifo_size_8, "Number of words in the Tx FIFO 4-768");
10160+module_param_named(dev_tx_fifo_size_9, dwc_otg_module_params.dev_tx_fifo_size[8], int, 0444);
10161+MODULE_PARM_DESC(dev_tx_fifo_size_9, "Number of words in the Tx FIFO 4-768");
10162+module_param_named(dev_tx_fifo_size_10, dwc_otg_module_params.dev_tx_fifo_size[9], int, 0444);
10163+MODULE_PARM_DESC(dev_tx_fifo_size_10, "Number of words in the Tx FIFO 4-768");
10164+module_param_named(dev_tx_fifo_size_11, dwc_otg_module_params.dev_tx_fifo_size[10], int, 0444);
10165+MODULE_PARM_DESC(dev_tx_fifo_size_11, "Number of words in the Tx FIFO 4-768");
10166+module_param_named(dev_tx_fifo_size_12, dwc_otg_module_params.dev_tx_fifo_size[11], int, 0444);
10167+MODULE_PARM_DESC(dev_tx_fifo_size_12, "Number of words in the Tx FIFO 4-768");
10168+module_param_named(dev_tx_fifo_size_13, dwc_otg_module_params.dev_tx_fifo_size[12], int, 0444);
10169+MODULE_PARM_DESC(dev_tx_fifo_size_13, "Number of words in the Tx FIFO 4-768");
10170+module_param_named(dev_tx_fifo_size_14, dwc_otg_module_params.dev_tx_fifo_size[13], int, 0444);
10171+MODULE_PARM_DESC(dev_tx_fifo_size_14, "Number of words in the Tx FIFO 4-768");
10172+module_param_named(dev_tx_fifo_size_15, dwc_otg_module_params.dev_tx_fifo_size[14], int, 0444);
10173+MODULE_PARM_DESC(dev_tx_fifo_size_15, "Number of words in the Tx FIFO 4-768");
10174+
10175+module_param_named(thr_ctl, dwc_otg_module_params.thr_ctl, int, 0444);
10176+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");
10177+module_param_named(tx_thr_length, dwc_otg_module_params.tx_thr_length, int, 0444);
10178+MODULE_PARM_DESC(tx_thr_length, "Tx Threshold length in 32 bit DWORDs");
10179+module_param_named(rx_thr_length, dwc_otg_module_params.rx_thr_length, int, 0444);
10180+MODULE_PARM_DESC(rx_thr_length, "Rx Threshold length in 32 bit DWORDs");
10181+
10182+module_param_named(pti_enable, dwc_otg_module_params.pti_enable, int, 0444);
10183+MODULE_PARM_DESC(pti_enable, "Per Transfer Interrupt mode 0=disabled 1=enabled");
10184+
10185+module_param_named(mpi_enable, dwc_otg_module_params.mpi_enable, int, 0444);
10186+MODULE_PARM_DESC(mpi_enable, "Multiprocessor Interrupt mode 0=disabled 1=enabled");
10187+
10188+/** @page "Module Parameters"
10189+ *
10190+ * The following parameters may be specified when starting the module.
10191+ * These parameters define how the DWC_otg controller should be
10192+ * configured. Parameter values are passed to the CIL initialization
10193+ * function dwc_otg_cil_init
10194+ *
10195+ * Example: <code>modprobe dwc_otg speed=1 otg_cap=1</code>
10196+ *
10197+
10198+ <table>
10199+ <tr><td>Parameter Name</td><td>Meaning</td></tr>
10200+
10201+ <tr>
10202+ <td>otg_cap</td>
10203+ <td>Specifies the OTG capabilities. The driver will automatically detect the
10204+ value for this parameter if none is specified.
10205+ - 0: HNP and SRP capable (default, if available)
10206+ - 1: SRP Only capable
10207+ - 2: No HNP/SRP capable
10208+ </td></tr>
10209+
10210+ <tr>
10211+ <td>dma_enable</td>
10212+ <td>Specifies whether to use slave or DMA mode for accessing the data FIFOs.
10213+ The driver will automatically detect the value for this parameter if none is
10214+ specified.
10215+ - 0: Slave
10216+ - 1: DMA (default, if available)
10217+ </td></tr>
10218+
10219+ <tr>
10220+ <td>dma_burst_size</td>
10221+ <td>The DMA Burst size (applicable only for External DMA Mode).
10222+ - Values: 1, 4, 8 16, 32, 64, 128, 256 (default 32)
10223+ </td></tr>
10224+
10225+ <tr>
10226+ <td>speed</td>
10227+ <td>Specifies the maximum speed of operation in host and device mode. The
10228+ actual speed depends on the speed of the attached device and the value of
10229+ phy_type.
10230+ - 0: High Speed (default)
10231+ - 1: Full Speed
10232+ </td></tr>
10233+
10234+ <tr>
10235+ <td>host_support_fs_ls_low_power</td>
10236+ <td>Specifies whether low power mode is supported when attached to a Full
10237+ Speed or Low Speed device in host mode.
10238+ - 0: Don't support low power mode (default)
10239+ - 1: Support low power mode
10240+ </td></tr>
10241+
10242+ <tr>
10243+ <td>host_ls_low_power_phy_clk</td>
10244+ <td>Specifies the PHY clock rate in low power mode when connected to a Low
10245+ Speed device in host mode. This parameter is applicable only if
10246+ HOST_SUPPORT_FS_LS_LOW_POWER is enabled.
10247+ - 0: 48 MHz (default)
10248+ - 1: 6 MHz
10249+ </td></tr>
10250+
10251+ <tr>
10252+ <td>enable_dynamic_fifo</td>
10253+ <td> Specifies whether FIFOs may be resized by the driver software.
10254+ - 0: Use cC FIFO size parameters
10255+ - 1: Allow dynamic FIFO sizing (default)
10256+ </td></tr>
10257+
10258+ <tr>
10259+ <td>data_fifo_size</td>
10260+ <td>Total number of 4-byte words in the data FIFO memory. This memory
10261+ includes the Rx FIFO, non-periodic Tx FIFO, and periodic Tx FIFOs.
10262+ - Values: 32 to 32768 (default 8192)
10263+
10264+ Note: The total FIFO memory depth in the FPGA configuration is 8192.
10265+ </td></tr>
10266+
10267+ <tr>
10268+ <td>dev_rx_fifo_size</td>
10269+ <td>Number of 4-byte words in the Rx FIFO in device mode when dynamic
10270+ FIFO sizing is enabled.
10271+ - Values: 16 to 32768 (default 1064)
10272+ </td></tr>
10273+
10274+ <tr>
10275+ <td>dev_nperio_tx_fifo_size</td>
10276+ <td>Number of 4-byte words in the non-periodic Tx FIFO in device mode when
10277+ dynamic FIFO sizing is enabled.
10278+ - Values: 16 to 32768 (default 1024)
10279+ </td></tr>
10280+
10281+ <tr>
10282+ <td>dev_perio_tx_fifo_size_n (n = 1 to 15)</td>
10283+ <td>Number of 4-byte words in each of the periodic Tx FIFOs in device mode
10284+ when dynamic FIFO sizing is enabled.
10285+ - Values: 4 to 768 (default 256)
10286+ </td></tr>
10287+
10288+ <tr>
10289+ <td>host_rx_fifo_size</td>
10290+ <td>Number of 4-byte words in the Rx FIFO in host mode when dynamic FIFO
10291+ sizing is enabled.
10292+ - Values: 16 to 32768 (default 1024)
10293+ </td></tr>
10294+
10295+ <tr>
10296+ <td>host_nperio_tx_fifo_size</td>
10297+ <td>Number of 4-byte words in the non-periodic Tx FIFO in host mode when
10298+ dynamic FIFO sizing is enabled in the core.
10299+ - Values: 16 to 32768 (default 1024)
10300+ </td></tr>
10301+
10302+ <tr>
10303+ <td>host_perio_tx_fifo_size</td>
10304+ <td>Number of 4-byte words in the host periodic Tx FIFO when dynamic FIFO
10305+ sizing is enabled.
10306+ - Values: 16 to 32768 (default 1024)
10307+ </td></tr>
10308+
10309+ <tr>
10310+ <td>max_transfer_size</td>
10311+ <td>The maximum transfer size supported in bytes.
10312+ - Values: 2047 to 65,535 (default 65,535)
10313+ </td></tr>
10314+
10315+ <tr>
10316+ <td>max_packet_count</td>
10317+ <td>The maximum number of packets in a transfer.
10318+ - Values: 15 to 511 (default 511)
10319+ </td></tr>
10320+
10321+ <tr>
10322+ <td>host_channels</td>
10323+ <td>The number of host channel registers to use.
10324+ - Values: 1 to 16 (default 12)
10325+
10326+ Note: The FPGA configuration supports a maximum of 12 host channels.
10327+ </td></tr>
10328+
10329+ <tr>
10330+ <td>dev_endpoints</td>
10331+ <td>The number of endpoints in addition to EP0 available for device mode
10332+ operations.
10333+ - Values: 1 to 15 (default 6 IN and OUT)
10334+
10335+ Note: The FPGA configuration supports a maximum of 6 IN and OUT endpoints in
10336+ addition to EP0.
10337+ </td></tr>
10338+
10339+ <tr>
10340+ <td>phy_type</td>
10341+ <td>Specifies the type of PHY interface to use. By default, the driver will
10342+ automatically detect the phy_type.
10343+ - 0: Full Speed
10344+ - 1: UTMI+ (default, if available)
10345+ - 2: ULPI
10346+ </td></tr>
10347+
10348+ <tr>
10349+ <td>phy_utmi_width</td>
10350+ <td>Specifies the UTMI+ Data Width. This parameter is applicable for a
10351+ phy_type of UTMI+. Also, this parameter is applicable only if the
10352+ OTG_HSPHY_WIDTH cC parameter was set to "8 and 16 bits", meaning that the
10353+ core has been configured to work at either data path width.
10354+ - Values: 8 or 16 bits (default 16)
10355+ </td></tr>
10356+
10357+ <tr>
10358+ <td>phy_ulpi_ddr</td>
10359+ <td>Specifies whether the ULPI operates at double or single data rate. This
10360+ parameter is only applicable if phy_type is ULPI.
10361+ - 0: single data rate ULPI interface with 8 bit wide data bus (default)
10362+ - 1: double data rate ULPI interface with 4 bit wide data bus
10363+ </td></tr>
10364+
10365+ <tr>
10366+ <td>i2c_enable</td>
10367+ <td>Specifies whether to use the I2C interface for full speed PHY. This
10368+ parameter is only applicable if PHY_TYPE is FS.
10369+ - 0: Disabled (default)
10370+ - 1: Enabled
10371+ </td></tr>
10372+
10373+ <tr>
10374+ <td>otg_en_multiple_tx_fifo</td>
10375+ <td>Specifies whether dedicatedto tx fifos are enabled for non periodic IN EPs.
10376+ The driver will automatically detect the value for this parameter if none is
10377+ specified.
10378+ - 0: Disabled
10379+ - 1: Enabled (default, if available)
10380+ </td></tr>
10381+
10382+ <tr>
10383+ <td>dev_tx_fifo_size_n (n = 1 to 15)</td>
10384+ <td>Number of 4-byte words in each of the Tx FIFOs in device mode
10385+ when dynamic FIFO sizing is enabled.
10386+ - Values: 4 to 768 (default 256)
10387+ </td></tr>
10388+
10389+*/
10390--- /dev/null
10391+++ b/drivers/usb/host/otg/dwc_otg_driver.h
10392@@ -0,0 +1,73 @@
10393+/* ==========================================================================
10394+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_driver.h $
10395+ * $Revision: #12 $
10396+ * $Date: 2008/07/15 $
10397+ * $Change: 1064918 $
10398+ *
10399+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
10400+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
10401+ * otherwise expressly agreed to in writing between Synopsys and you.
10402+ *
10403+ * The Software IS NOT an item of Licensed Software or Licensed Product under
10404+ * any End User Software License Agreement or Agreement for Licensed Product
10405+ * with Synopsys or any supplement thereto. You are permitted to use and
10406+ * redistribute this Software in source and binary forms, with or without
10407+ * modification, provided that redistributions of source code must retain this
10408+ * notice. You may not view, use, disclose, copy or distribute this file or
10409+ * any information contained herein except pursuant to this license grant from
10410+ * Synopsys. If you do not agree with this notice, including the disclaimer
10411+ * below, then you are not authorized to use the Software.
10412+ *
10413+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
10414+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
10415+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
10416+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
10417+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
10418+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
10419+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
10420+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
10421+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
10422+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
10423+ * DAMAGE.
10424+ * ========================================================================== */
10425+
10426+#ifndef __DWC_OTG_DRIVER_H__
10427+#define __DWC_OTG_DRIVER_H__
10428+
10429+/** @file
10430+ * This file contains the interface to the Linux driver.
10431+ */
10432+#include "dwc_otg_cil.h"
10433+
10434+/* Type declarations */
10435+struct dwc_otg_pcd;
10436+struct dwc_otg_hcd;
10437+
10438+/**
10439+ * This structure is a wrapper that encapsulates the driver components used to
10440+ * manage a single DWC_otg controller.
10441+ */
10442+typedef struct dwc_otg_device {
10443+ /** Base address returned from ioremap() */
10444+ void *base;
10445+
10446+ struct lm_device *lmdev;
10447+
10448+ /** Pointer to the core interface structure. */
10449+ dwc_otg_core_if_t *core_if;
10450+
10451+ /** Register offset for Diagnostic API. */
10452+ uint32_t reg_offset;
10453+
10454+ /** Pointer to the PCD structure. */
10455+ struct dwc_otg_pcd *pcd;
10456+
10457+ /** Pointer to the HCD structure. */
10458+ struct dwc_otg_hcd *hcd;
10459+
10460+ /** Flag to indicate whether the common IRQ handler is installed. */
10461+ uint8_t common_irq_installed;
10462+
10463+} dwc_otg_device_t;
10464+
10465+#endif
10466--- /dev/null
10467+++ b/drivers/usb/host/otg/dwc_otg_hcd.c
10468@@ -0,0 +1,2919 @@
10469+/* ==========================================================================
10470+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd.c $
10471+ * $Revision: #75 $
10472+ * $Date: 2008/07/15 $
10473+ * $Change: 1064940 $
10474+ *
10475+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
10476+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
10477+ * otherwise expressly agreed to in writing between Synopsys and you.
10478+ *
10479+ * The Software IS NOT an item of Licensed Software or Licensed Product under
10480+ * any End User Software License Agreement or Agreement for Licensed Product
10481+ * with Synopsys or any supplement thereto. You are permitted to use and
10482+ * redistribute this Software in source and binary forms, with or without
10483+ * modification, provided that redistributions of source code must retain this
10484+ * notice. You may not view, use, disclose, copy or distribute this file or
10485+ * any information contained herein except pursuant to this license grant from
10486+ * Synopsys. If you do not agree with this notice, including the disclaimer
10487+ * below, then you are not authorized to use the Software.
10488+ *
10489+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
10490+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
10491+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
10492+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
10493+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
10494+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
10495+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
10496+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
10497+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
10498+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
10499+ * DAMAGE.
10500+ * ========================================================================== */
10501+#ifndef DWC_DEVICE_ONLY
10502+
10503+/**
10504+ * @file
10505+ *
10506+ * This file contains the implementation of the HCD. In Linux, the HCD
10507+ * implements the hc_driver API.
10508+ */
10509+#include <linux/kernel.h>
10510+#include <linux/module.h>
10511+#include <linux/moduleparam.h>
10512+#include <linux/init.h>
10513+#include <linux/device.h>
10514+#include <linux/errno.h>
10515+#include <linux/list.h>
10516+#include <linux/interrupt.h>
10517+#include <linux/string.h>
10518+#include <linux/dma-mapping.h>
10519+#include <linux/version.h>
10520+
10521+#include <mach/lm.h>
10522+#include <mach/irqs.h>
10523+
10524+#include "dwc_otg_driver.h"
10525+#include "dwc_otg_hcd.h"
10526+#include "dwc_otg_regs.h"
10527+
10528+static const char dwc_otg_hcd_name[] = "dwc_otg_hcd";
10529+
10530+static const struct hc_driver dwc_otg_hc_driver = {
10531+
10532+ .description = dwc_otg_hcd_name,
10533+ .product_desc = "DWC OTG Controller",
10534+ .hcd_priv_size = sizeof(dwc_otg_hcd_t),
10535+
10536+ .irq = dwc_otg_hcd_irq,
10537+
10538+ .flags = HCD_MEMORY | HCD_USB2,
10539+
10540+ //.reset =
10541+ .start = dwc_otg_hcd_start,
10542+ //.suspend =
10543+ //.resume =
10544+ .stop = dwc_otg_hcd_stop,
10545+
10546+ .urb_enqueue = dwc_otg_hcd_urb_enqueue,
10547+ .urb_dequeue = dwc_otg_hcd_urb_dequeue,
10548+ .endpoint_disable = dwc_otg_hcd_endpoint_disable,
10549+
10550+ .get_frame_number = dwc_otg_hcd_get_frame_number,
10551+
10552+ .hub_status_data = dwc_otg_hcd_hub_status_data,
10553+ .hub_control = dwc_otg_hcd_hub_control,
10554+ //.hub_suspend =
10555+ //.hub_resume =
10556+};
10557+
10558+/**
10559+ * Work queue function for starting the HCD when A-Cable is connected.
10560+ * The dwc_otg_hcd_start() must be called in a process context.
10561+ */
10562+static void hcd_start_func(
10563+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
10564+ void *_vp
10565+#else
10566+ struct work_struct *_work
10567+#endif
10568+ )
10569+{
10570+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
10571+ struct usb_hcd *usb_hcd = (struct usb_hcd *)_vp;
10572+#else
10573+ struct delayed_work *dw = container_of(_work, struct delayed_work, work);
10574+ struct dwc_otg_hcd *otg_hcd = container_of(dw, struct dwc_otg_hcd, start_work);
10575+ struct usb_hcd *usb_hcd = container_of((void *)otg_hcd, struct usb_hcd, hcd_priv);
10576+#endif
10577+ DWC_DEBUGPL(DBG_HCDV, "%s() %p\n", __func__, usb_hcd);
10578+ if (usb_hcd) {
10579+ dwc_otg_hcd_start(usb_hcd);
10580+ }
10581+}
10582+
10583+/**
10584+ * HCD Callback function for starting the HCD when A-Cable is
10585+ * connected.
10586+ *
10587+ * @param p void pointer to the <code>struct usb_hcd</code>
10588+ */
10589+static int32_t dwc_otg_hcd_start_cb(void *p)
10590+{
10591+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(p);
10592+ dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
10593+ hprt0_data_t hprt0;
10594+
10595+ if (core_if->op_state == B_HOST) {
10596+ /*
10597+ * Reset the port. During a HNP mode switch the reset
10598+ * needs to occur within 1ms and have a duration of at
10599+ * least 50ms.
10600+ */
10601+ hprt0.d32 = dwc_otg_read_hprt0(core_if);
10602+ hprt0.b.prtrst = 1;
10603+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
10604+ ((struct usb_hcd *)p)->self.is_b_host = 1;
10605+ } else {
10606+ ((struct usb_hcd *)p)->self.is_b_host = 0;
10607+ }
10608+
10609+ /* Need to start the HCD in a non-interrupt context. */
10610+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
10611+ INIT_WORK(&dwc_otg_hcd->start_work, hcd_start_func, p);
10612+// INIT_DELAYED_WORK(&dwc_otg_hcd->start_work, hcd_start_func, p);
10613+#else
10614+// INIT_WORK(&dwc_otg_hcd->start_work, hcd_start_func);
10615+ INIT_DELAYED_WORK(&dwc_otg_hcd->start_work, hcd_start_func);
10616+#endif
10617+// schedule_work(&dwc_otg_hcd->start_work);
10618+ queue_delayed_work(core_if->wq_otg, &dwc_otg_hcd->start_work, 50 * HZ / 1000);
10619+
10620+ return 1;
10621+}
10622+
10623+/**
10624+ * HCD Callback function for stopping the HCD.
10625+ *
10626+ * @param p void pointer to the <code>struct usb_hcd</code>
10627+ */
10628+static int32_t dwc_otg_hcd_stop_cb(void *p)
10629+{
10630+ struct usb_hcd *usb_hcd = (struct usb_hcd *)p;
10631+ DWC_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, p);
10632+ dwc_otg_hcd_stop(usb_hcd);
10633+ return 1;
10634+}
10635+
10636+static void del_xfer_timers(dwc_otg_hcd_t *hcd)
10637+{
10638+#ifdef DEBUG
10639+ int i;
10640+ int num_channels = hcd->core_if->core_params->host_channels;
10641+ for (i = 0; i < num_channels; i++) {
10642+ del_timer(&hcd->core_if->hc_xfer_timer[i]);
10643+ }
10644+#endif
10645+}
10646+
10647+static void del_timers(dwc_otg_hcd_t *hcd)
10648+{
10649+ del_xfer_timers(hcd);
10650+ del_timer(&hcd->conn_timer);
10651+}
10652+
10653+/**
10654+ * Processes all the URBs in a single list of QHs. Completes them with
10655+ * -ETIMEDOUT and frees the QTD.
10656+ */
10657+static void kill_urbs_in_qh_list(dwc_otg_hcd_t *hcd, struct list_head *qh_list)
10658+{
10659+ struct list_head *qh_item;
10660+ dwc_otg_qh_t *qh;
10661+ struct list_head *qtd_item;
10662+ dwc_otg_qtd_t *qtd;
10663+
10664+ list_for_each(qh_item, qh_list) {
10665+ qh = list_entry(qh_item, dwc_otg_qh_t, qh_list_entry);
10666+ for (qtd_item = qh->qtd_list.next;
10667+ qtd_item != &qh->qtd_list;
10668+ qtd_item = qh->qtd_list.next) {
10669+ qtd = list_entry(qtd_item, dwc_otg_qtd_t, qtd_list_entry);
10670+ if (qtd->urb != NULL) {
10671+ dwc_otg_hcd_complete_urb(hcd, qtd->urb,
10672+ -ETIMEDOUT);
10673+ }
10674+ dwc_otg_hcd_qtd_remove_and_free(hcd, qtd);
10675+ }
10676+ }
10677+}
10678+
10679+/**
10680+ * Responds with an error status of ETIMEDOUT to all URBs in the non-periodic
10681+ * and periodic schedules. The QTD associated with each URB is removed from
10682+ * the schedule and freed. This function may be called when a disconnect is
10683+ * detected or when the HCD is being stopped.
10684+ */
10685+static void kill_all_urbs(dwc_otg_hcd_t *hcd)
10686+{
10687+ kill_urbs_in_qh_list(hcd, &hcd->non_periodic_sched_inactive);
10688+ kill_urbs_in_qh_list(hcd, &hcd->non_periodic_sched_active);
10689+ kill_urbs_in_qh_list(hcd, &hcd->periodic_sched_inactive);
10690+ kill_urbs_in_qh_list(hcd, &hcd->periodic_sched_ready);
10691+ kill_urbs_in_qh_list(hcd, &hcd->periodic_sched_assigned);
10692+ kill_urbs_in_qh_list(hcd, &hcd->periodic_sched_queued);
10693+}
10694+
10695+/**
10696+ * HCD Callback function for disconnect of the HCD.
10697+ *
10698+ * @param p void pointer to the <code>struct usb_hcd</code>
10699+ */
10700+static int32_t dwc_otg_hcd_disconnect_cb(void *p)
10701+{
10702+ gintsts_data_t intr;
10703+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(p);
10704+
10705+ //DWC_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, p);
10706+
10707+ /*
10708+ * Set status flags for the hub driver.
10709+ */
10710+ dwc_otg_hcd->flags.b.port_connect_status_change = 1;
10711+ dwc_otg_hcd->flags.b.port_connect_status = 0;
10712+
10713+ /*
10714+ * Shutdown any transfers in process by clearing the Tx FIFO Empty
10715+ * interrupt mask and status bits and disabling subsequent host
10716+ * channel interrupts.
10717+ */
10718+ intr.d32 = 0;
10719+ intr.b.nptxfempty = 1;
10720+ intr.b.ptxfempty = 1;
10721+ intr.b.hcintr = 1;
10722+ dwc_modify_reg32(&dwc_otg_hcd->core_if->core_global_regs->gintmsk, intr.d32, 0);
10723+ dwc_modify_reg32(&dwc_otg_hcd->core_if->core_global_regs->gintsts, intr.d32, 0);
10724+
10725+ del_timers(dwc_otg_hcd);
10726+
10727+ /*
10728+ * Turn off the vbus power only if the core has transitioned to device
10729+ * mode. If still in host mode, need to keep power on to detect a
10730+ * reconnection.
10731+ */
10732+ if (dwc_otg_is_device_mode(dwc_otg_hcd->core_if)) {
10733+ if (dwc_otg_hcd->core_if->op_state != A_SUSPEND) {
10734+ hprt0_data_t hprt0 = { .d32=0 };
10735+ DWC_PRINT("Disconnect: PortPower off\n");
10736+ hprt0.b.prtpwr = 0;
10737+ dwc_write_reg32(dwc_otg_hcd->core_if->host_if->hprt0, hprt0.d32);
10738+ }
10739+
10740+ dwc_otg_disable_host_interrupts(dwc_otg_hcd->core_if);
10741+ }
10742+
10743+ /* Respond with an error status to all URBs in the schedule. */
10744+ kill_all_urbs(dwc_otg_hcd);
10745+
10746+ if (dwc_otg_is_host_mode(dwc_otg_hcd->core_if)) {
10747+ /* Clean up any host channels that were in use. */
10748+ int num_channels;
10749+ int i;
10750+ dwc_hc_t *channel;
10751+ dwc_otg_hc_regs_t *hc_regs;
10752+ hcchar_data_t hcchar;
10753+
10754+ num_channels = dwc_otg_hcd->core_if->core_params->host_channels;
10755+
10756+ if (!dwc_otg_hcd->core_if->dma_enable) {
10757+ /* Flush out any channel requests in slave mode. */
10758+ for (i = 0; i < num_channels; i++) {
10759+ channel = dwc_otg_hcd->hc_ptr_array[i];
10760+ if (list_empty(&channel->hc_list_entry)) {
10761+ hc_regs = dwc_otg_hcd->core_if->host_if->hc_regs[i];
10762+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
10763+ if (hcchar.b.chen) {
10764+ hcchar.b.chen = 0;
10765+ hcchar.b.chdis = 1;
10766+ hcchar.b.epdir = 0;
10767+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
10768+ }
10769+ }
10770+ }
10771+ }
10772+
10773+ for (i = 0; i < num_channels; i++) {
10774+ channel = dwc_otg_hcd->hc_ptr_array[i];
10775+ if (list_empty(&channel->hc_list_entry)) {
10776+ hc_regs = dwc_otg_hcd->core_if->host_if->hc_regs[i];
10777+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
10778+ if (hcchar.b.chen) {
10779+ /* Halt the channel. */
10780+ hcchar.b.chdis = 1;
10781+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
10782+ }
10783+
10784+ dwc_otg_hc_cleanup(dwc_otg_hcd->core_if, channel);
10785+ list_add_tail(&channel->hc_list_entry,
10786+ &dwc_otg_hcd->free_hc_list);
10787+ }
10788+ }
10789+ }
10790+
10791+ /* A disconnect will end the session so the B-Device is no
10792+ * longer a B-host. */
10793+ ((struct usb_hcd *)p)->self.is_b_host = 0;
10794+ return 1;
10795+}
10796+
10797+/**
10798+ * Connection timeout function. An OTG host is required to display a
10799+ * message if the device does not connect within 10 seconds.
10800+ */
10801+void dwc_otg_hcd_connect_timeout(unsigned long ptr)
10802+{
10803+ DWC_DEBUGPL(DBG_HCDV, "%s(%x)\n", __func__, (int)ptr);
10804+ DWC_PRINT("Connect Timeout\n");
10805+ DWC_ERROR("Device Not Connected/Responding\n");
10806+}
10807+
10808+/**
10809+ * Start the connection timer. An OTG host is required to display a
10810+ * message if the device does not connect within 10 seconds. The
10811+ * timer is deleted if a port connect interrupt occurs before the
10812+ * timer expires.
10813+ */
10814+static void dwc_otg_hcd_start_connect_timer(dwc_otg_hcd_t *hcd)
10815+{
10816+ init_timer(&hcd->conn_timer);
10817+ hcd->conn_timer.function = dwc_otg_hcd_connect_timeout;
10818+ hcd->conn_timer.data = 0;
10819+ hcd->conn_timer.expires = jiffies + (HZ * 10);
10820+ add_timer(&hcd->conn_timer);
10821+}
10822+
10823+/**
10824+ * HCD Callback function for disconnect of the HCD.
10825+ *
10826+ * @param p void pointer to the <code>struct usb_hcd</code>
10827+ */
10828+static int32_t dwc_otg_hcd_session_start_cb(void *p)
10829+{
10830+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(p);
10831+ DWC_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, p);
10832+ dwc_otg_hcd_start_connect_timer(dwc_otg_hcd);
10833+ return 1;
10834+}
10835+
10836+/**
10837+ * HCD Callback structure for handling mode switching.
10838+ */
10839+static dwc_otg_cil_callbacks_t hcd_cil_callbacks = {
10840+ .start = dwc_otg_hcd_start_cb,
10841+ .stop = dwc_otg_hcd_stop_cb,
10842+ .disconnect = dwc_otg_hcd_disconnect_cb,
10843+ .session_start = dwc_otg_hcd_session_start_cb,
10844+ .p = 0,
10845+};
10846+
10847+/**
10848+ * Reset tasklet function
10849+ */
10850+static void reset_tasklet_func(unsigned long data)
10851+{
10852+ dwc_otg_hcd_t *dwc_otg_hcd = (dwc_otg_hcd_t *)data;
10853+ dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
10854+ hprt0_data_t hprt0;
10855+
10856+ DWC_DEBUGPL(DBG_HCDV, "USB RESET tasklet called\n");
10857+
10858+ hprt0.d32 = dwc_otg_read_hprt0(core_if);
10859+ hprt0.b.prtrst = 1;
10860+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
10861+ mdelay(60);
10862+
10863+ hprt0.b.prtrst = 0;
10864+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
10865+ dwc_otg_hcd->flags.b.port_reset_change = 1;
10866+}
10867+
10868+static struct tasklet_struct reset_tasklet = {
10869+ .next = NULL,
10870+ .state = 0,
10871+ .count = ATOMIC_INIT(0),
10872+ .func = reset_tasklet_func,
10873+ .data = 0,
10874+};
10875+
10876+/**
10877+ * Initializes the HCD. This function allocates memory for and initializes the
10878+ * static parts of the usb_hcd and dwc_otg_hcd structures. It also registers the
10879+ * USB bus with the core and calls the hc_driver->start() function. It returns
10880+ * a negative error on failure.
10881+ */
10882+int dwc_otg_hcd_init(struct lm_device *lmdev)
10883+{
10884+ struct usb_hcd *hcd = NULL;
10885+ dwc_otg_hcd_t *dwc_otg_hcd = NULL;
10886+ dwc_otg_device_t *otg_dev = lm_get_drvdata(lmdev);
10887+
10888+ int num_channels;
10889+ int i;
10890+ dwc_hc_t *channel;
10891+
10892+ int retval = 0;
10893+
10894+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT\n");
10895+
10896+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
10897+ /* 2.6.20+ requires dev.dma_mask to be set prior to calling usb_create_hcd() */
10898+
10899+ /* Set device flags indicating whether the HCD supports DMA. */
10900+ if (otg_dev->core_if->dma_enable) {
10901+ DWC_PRINT("Using DMA mode\n");
10902+#if 0
10903+//090707: setting dma_mask would cause kernel to fetch 0xffffffff, result in crash, at scsi_calculate_bounce_limit
10904+ lmdev->dev.dma_mask = (void *)~0;
10905+ lmdev->dev.coherent_dma_mask = ~0;
10906+#endif
10907+
10908+ if (otg_dev->core_if->dma_desc_enable) {
10909+ DWC_PRINT("Device using Descriptor DMA mode\n");
10910+ } else {
10911+ DWC_PRINT("Device using Buffer DMA mode\n");
10912+ }
10913+ } else {
10914+ DWC_PRINT("Using Slave mode\n");
10915+ lmdev->dev.dma_mask = (void *)0;
10916+ lmdev->dev.coherent_dma_mask = 0;
10917+ }
10918+#endif
10919+ /*
10920+ * Allocate memory for the base HCD plus the DWC OTG HCD.
10921+ * Initialize the base HCD.
10922+ */
10923+
10924+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)
10925+ hcd = usb_create_hcd(&dwc_otg_hc_driver, &lmdev->dev, lmdev->dev.bus_id);
10926+#else
10927+ hcd = usb_create_hcd(&dwc_otg_hc_driver, &lmdev->dev, "gadget");
10928+#endif
10929+ if (!hcd) {
10930+ retval = -ENOMEM;
10931+ goto error1;
10932+ }
10933+
10934+ hcd->regs = otg_dev->base;
10935+ hcd->self.otg_port = 1;
10936+
10937+ /* Initialize the DWC OTG HCD. */
10938+ dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
10939+ dwc_otg_hcd->core_if = otg_dev->core_if;
10940+ otg_dev->hcd = dwc_otg_hcd;
10941+
10942+ /* */
10943+ spin_lock_init(&dwc_otg_hcd->lock);
10944+
10945+ /* Register the HCD CIL Callbacks */
10946+ dwc_otg_cil_register_hcd_callbacks(otg_dev->core_if,
10947+ &hcd_cil_callbacks, hcd);
10948+
10949+ /* Initialize the non-periodic schedule. */
10950+ INIT_LIST_HEAD(&dwc_otg_hcd->non_periodic_sched_inactive);
10951+ INIT_LIST_HEAD(&dwc_otg_hcd->non_periodic_sched_active);
10952+
10953+ /* Initialize the periodic schedule. */
10954+ INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_inactive);
10955+ INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_ready);
10956+ INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_assigned);
10957+ INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_queued);
10958+
10959+ /*
10960+ * Create a host channel descriptor for each host channel implemented
10961+ * in the controller. Initialize the channel descriptor array.
10962+ */
10963+ INIT_LIST_HEAD(&dwc_otg_hcd->free_hc_list);
10964+ num_channels = dwc_otg_hcd->core_if->core_params->host_channels;
10965+ memset(dwc_otg_hcd->hc_ptr_array, 0, sizeof(dwc_otg_hcd->hc_ptr_array));
10966+ for (i = 0; i < num_channels; i++) {
10967+ channel = kmalloc(sizeof(dwc_hc_t), GFP_KERNEL);
10968+ if (channel == NULL) {
10969+ retval = -ENOMEM;
10970+ DWC_ERROR("%s: host channel allocation failed\n", __func__);
10971+ goto error2;
10972+ }
10973+ memset(channel, 0, sizeof(dwc_hc_t));
10974+ channel->hc_num = i;
10975+ dwc_otg_hcd->hc_ptr_array[i] = channel;
10976+#ifdef DEBUG
10977+ init_timer(&dwc_otg_hcd->core_if->hc_xfer_timer[i]);
10978+#endif
10979+ DWC_DEBUGPL(DBG_HCDV, "HCD Added channel #%d, hc=%p\n", i, channel);
10980+ }
10981+
10982+ /* Initialize the Connection timeout timer. */
10983+ init_timer(&dwc_otg_hcd->conn_timer);
10984+
10985+ /* Initialize reset tasklet. */
10986+ reset_tasklet.data = (unsigned long) dwc_otg_hcd;
10987+ dwc_otg_hcd->reset_tasklet = &reset_tasklet;
10988+
10989+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
10990+ /* Set device flags indicating whether the HCD supports DMA. */
10991+ if (otg_dev->core_if->dma_enable) {
10992+ DWC_PRINT("Using DMA mode\n");
10993+ lmdev->dev.dma_mask = (void *)~0;
10994+ lmdev->dev.coherent_dma_mask = ~0;
10995+
10996+ if (otg_dev->core_if->dma_desc_enable){
10997+ DWC_PRINT("Device using Descriptor DMA mode\n");
10998+ } else {
10999+ DWC_PRINT("Device using Buffer DMA mode\n");
11000+ }
11001+ } else {
11002+ DWC_PRINT("Using Slave mode\n");
11003+ lmdev->dev.dma_mask = (void *)0;
11004+ lmdev->dev.coherent_dma_mask = 0;
11005+ }
11006+#endif
11007+ /*
11008+ * Finish generic HCD initialization and start the HCD. This function
11009+ * allocates the DMA buffer pool, registers the USB bus, requests the
11010+ * IRQ line, and calls dwc_otg_hcd_start method.
11011+ */
11012+ retval = usb_add_hcd(hcd, lmdev->irq, IRQF_SHARED);
11013+ if (retval < 0) {
11014+ goto error2;
11015+ }
11016+
11017+ /*
11018+ * Allocate space for storing data on status transactions. Normally no
11019+ * data is sent, but this space acts as a bit bucket. This must be
11020+ * done after usb_add_hcd since that function allocates the DMA buffer
11021+ * pool.
11022+ */
11023+ if (otg_dev->core_if->dma_enable) {
11024+ dwc_otg_hcd->status_buf =
11025+ dma_alloc_coherent(&lmdev->dev,
11026+ DWC_OTG_HCD_STATUS_BUF_SIZE,
11027+ &dwc_otg_hcd->status_buf_dma,
11028+ GFP_KERNEL | GFP_DMA);
11029+ } else {
11030+ dwc_otg_hcd->status_buf = kmalloc(DWC_OTG_HCD_STATUS_BUF_SIZE,
11031+ GFP_KERNEL);
11032+ }
11033+ if (!dwc_otg_hcd->status_buf) {
11034+ retval = -ENOMEM;
11035+ DWC_ERROR("%s: status_buf allocation failed\n", __func__);
11036+ goto error3;
11037+ }
11038+
11039+ dwc_otg_hcd->otg_dev = otg_dev;
11040+
11041+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)
11042+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Initialized HCD, bus=%s, usbbus=%d\n",
11043+ lmdev->dev.bus_id, hcd->self.busnum);
11044+#else
11045+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Initialized HCD, usbbus=%d\n",
11046+ hcd->self.busnum);
11047+#endif
11048+ return 0;
11049+
11050+ /* Error conditions */
11051+ error3:
11052+ usb_remove_hcd(hcd);
11053+ error2:
11054+ dwc_otg_hcd_free(hcd);
11055+ usb_put_hcd(hcd);
11056+ error1:
11057+ return retval;
11058+}
11059+
11060+/**
11061+ * Removes the HCD.
11062+ * Frees memory and resources associated with the HCD and deregisters the bus.
11063+ */
11064+void dwc_otg_hcd_remove(struct lm_device *lmdev)
11065+{
11066+ dwc_otg_device_t *otg_dev = lm_get_drvdata(lmdev);
11067+ dwc_otg_hcd_t *dwc_otg_hcd;
11068+ struct usb_hcd *hcd;
11069+
11070+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD REMOVE\n");
11071+
11072+ if (!otg_dev) {
11073+ DWC_DEBUGPL(DBG_ANY, "%s: otg_dev NULL!\n", __func__);
11074+ return;
11075+ }
11076+
11077+ dwc_otg_hcd = otg_dev->hcd;
11078+
11079+ if (!dwc_otg_hcd) {
11080+ DWC_DEBUGPL(DBG_ANY, "%s: otg_dev->hcd NULL!\n", __func__);
11081+ return;
11082+ }
11083+
11084+ hcd = dwc_otg_hcd_to_hcd(dwc_otg_hcd);
11085+
11086+ if (!hcd) {
11087+ DWC_DEBUGPL(DBG_ANY, "%s: dwc_otg_hcd_to_hcd(dwc_otg_hcd) NULL!\n", __func__);
11088+ return;
11089+ }
11090+
11091+ /* Turn off all interrupts */
11092+ dwc_write_reg32(&dwc_otg_hcd->core_if->core_global_regs->gintmsk, 0);
11093+ dwc_modify_reg32(&dwc_otg_hcd->core_if->core_global_regs->gahbcfg, 1, 0);
11094+
11095+ usb_remove_hcd(hcd);
11096+ dwc_otg_hcd_free(hcd);
11097+ usb_put_hcd(hcd);
11098+}
11099+
11100+/* =========================================================================
11101+ * Linux HC Driver Functions
11102+ * ========================================================================= */
11103+
11104+/**
11105+ * Initializes dynamic portions of the DWC_otg HCD state.
11106+ */
11107+static void hcd_reinit(dwc_otg_hcd_t *hcd)
11108+{
11109+ struct list_head *item;
11110+ int num_channels;
11111+ int i;
11112+ dwc_hc_t *channel;
11113+
11114+ hcd->flags.d32 = 0;
11115+
11116+ hcd->non_periodic_qh_ptr = &hcd->non_periodic_sched_active;
11117+ hcd->non_periodic_channels = 0;
11118+ hcd->periodic_channels = 0;
11119+
11120+ /*
11121+ * Put all channels in the free channel list and clean up channel
11122+ * states.
11123+ */
11124+ item = hcd->free_hc_list.next;
11125+ while (item != &hcd->free_hc_list) {
11126+ list_del(item);
11127+ item = hcd->free_hc_list.next;
11128+ }
11129+ num_channels = hcd->core_if->core_params->host_channels;
11130+ for (i = 0; i < num_channels; i++) {
11131+ channel = hcd->hc_ptr_array[i];
11132+ list_add_tail(&channel->hc_list_entry, &hcd->free_hc_list);
11133+ dwc_otg_hc_cleanup(hcd->core_if, channel);
11134+ }
11135+
11136+ /* Initialize the DWC core for host mode operation. */
11137+ dwc_otg_core_host_init(hcd->core_if);
11138+}
11139+
11140+/** Initializes the DWC_otg controller and its root hub and prepares it for host
11141+ * mode operation. Activates the root port. Returns 0 on success and a negative
11142+ * error code on failure. */
11143+int dwc_otg_hcd_start(struct usb_hcd *hcd)
11144+{
11145+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
11146+ dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
11147+ struct usb_bus *bus;
11148+
11149+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
11150+ struct usb_device *udev;
11151+ int retval;
11152+#endif
11153+
11154+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD START\n");
11155+
11156+ bus = hcd_to_bus(hcd);
11157+
11158+ /* Initialize the bus state. If the core is in Device Mode
11159+ * HALT the USB bus and return. */
11160+ if (dwc_otg_is_device_mode(core_if)) {
11161+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
11162+ hcd->state = HC_STATE_HALT;
11163+#else
11164+ hcd->state = HC_STATE_RUNNING;
11165+#endif
11166+ return 0;
11167+ }
11168+ hcd->state = HC_STATE_RUNNING;
11169+
11170+ /* Initialize and connect root hub if one is not already attached */
11171+ if (bus->root_hub) {
11172+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Has Root Hub\n");
11173+ /* Inform the HUB driver to resume. */
11174+ usb_hcd_resume_root_hub(hcd);
11175+ }
11176+ else {
11177+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Does Not Have Root Hub\n");
11178+
11179+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
11180+ udev = usb_alloc_dev(NULL, bus, 0);
11181+ udev->speed = USB_SPEED_HIGH;
11182+ if (!udev) {
11183+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Error udev alloc\n");
11184+ return -ENODEV;
11185+ }
11186+ if ((retval = usb_hcd_register_root_hub(udev, hcd)) != 0) {
11187+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Error registering %d\n", retval);
11188+ return -ENODEV;
11189+ }
11190+#endif
11191+ }
11192+
11193+ hcd_reinit(dwc_otg_hcd);
11194+
11195+ return 0;
11196+}
11197+
11198+static void qh_list_free(dwc_otg_hcd_t *hcd, struct list_head *qh_list)
11199+{
11200+ struct list_head *item;
11201+ dwc_otg_qh_t *qh;
11202+
11203+ if (!qh_list->next) {
11204+ /* The list hasn't been initialized yet. */
11205+ return;
11206+ }
11207+
11208+ /* Ensure there are no QTDs or URBs left. */
11209+ kill_urbs_in_qh_list(hcd, qh_list);
11210+
11211+ for (item = qh_list->next; item != qh_list; item = qh_list->next) {
11212+ qh = list_entry(item, dwc_otg_qh_t, qh_list_entry);
11213+ dwc_otg_hcd_qh_remove_and_free(hcd, qh);
11214+ }
11215+}
11216+
11217+/**
11218+ * Halts the DWC_otg host mode operations in a clean manner. USB transfers are
11219+ * stopped.
11220+ */
11221+void dwc_otg_hcd_stop(struct usb_hcd *hcd)
11222+{
11223+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
11224+ hprt0_data_t hprt0 = { .d32=0 };
11225+
11226+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD STOP\n");
11227+
11228+ /* Turn off all host-specific interrupts. */
11229+ dwc_otg_disable_host_interrupts(dwc_otg_hcd->core_if);
11230+
11231+ /*
11232+ * The root hub should be disconnected before this function is called.
11233+ * The disconnect will clear the QTD lists (via ..._hcd_urb_dequeue)
11234+ * and the QH lists (via ..._hcd_endpoint_disable).
11235+ */
11236+
11237+ /* Turn off the vbus power */
11238+ DWC_PRINT("PortPower off\n");
11239+ hprt0.b.prtpwr = 0;
11240+ dwc_write_reg32(dwc_otg_hcd->core_if->host_if->hprt0, hprt0.d32);
11241+}
11242+
11243+/** Returns the current frame number. */
11244+int dwc_otg_hcd_get_frame_number(struct usb_hcd *hcd)
11245+{
11246+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
11247+ hfnum_data_t hfnum;
11248+
11249+ hfnum.d32 = dwc_read_reg32(&dwc_otg_hcd->core_if->
11250+ host_if->host_global_regs->hfnum);
11251+
11252+#ifdef DEBUG_SOF
11253+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD GET FRAME NUMBER %d\n", hfnum.b.frnum);
11254+#endif
11255+ return hfnum.b.frnum;
11256+}
11257+
11258+/**
11259+ * Frees secondary storage associated with the dwc_otg_hcd structure contained
11260+ * in the struct usb_hcd field.
11261+ */
11262+void dwc_otg_hcd_free(struct usb_hcd *hcd)
11263+{
11264+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
11265+ int i;
11266+
11267+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD FREE\n");
11268+
11269+ del_timers(dwc_otg_hcd);
11270+
11271+ /* Free memory for QH/QTD lists */
11272+ qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->non_periodic_sched_inactive);
11273+ qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->non_periodic_sched_active);
11274+ qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_inactive);
11275+ qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_ready);
11276+ qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_assigned);
11277+ qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_queued);
11278+
11279+ /* Free memory for the host channels. */
11280+ for (i = 0; i < MAX_EPS_CHANNELS; i++) {
11281+ dwc_hc_t *hc = dwc_otg_hcd->hc_ptr_array[i];
11282+ if (hc != NULL) {
11283+ DWC_DEBUGPL(DBG_HCDV, "HCD Free channel #%i, hc=%p\n", i, hc);
11284+ kfree(hc);
11285+ }
11286+ }
11287+
11288+ if (dwc_otg_hcd->core_if->dma_enable) {
11289+ if (dwc_otg_hcd->status_buf_dma) {
11290+ dma_free_coherent(hcd->self.controller,
11291+ DWC_OTG_HCD_STATUS_BUF_SIZE,
11292+ dwc_otg_hcd->status_buf,
11293+ dwc_otg_hcd->status_buf_dma);
11294+ }
11295+ } else if (dwc_otg_hcd->status_buf != NULL) {
11296+ kfree(dwc_otg_hcd->status_buf);
11297+ }
11298+}
11299+
11300+#ifdef DEBUG
11301+static void dump_urb_info(struct urb *urb, char* fn_name)
11302+{
11303+ DWC_PRINT("%s, urb %p\n", fn_name, urb);
11304+ DWC_PRINT(" Device address: %d\n", usb_pipedevice(urb->pipe));
11305+ DWC_PRINT(" Endpoint: %d, %s\n", usb_pipeendpoint(urb->pipe),
11306+ (usb_pipein(urb->pipe) ? "IN" : "OUT"));
11307+ DWC_PRINT(" Endpoint type: %s\n",
11308+ ({char *pipetype;
11309+ switch (usb_pipetype(urb->pipe)) {
11310+ case PIPE_CONTROL: pipetype = "CONTROL"; break;
11311+ case PIPE_BULK: pipetype = "BULK"; break;
11312+ case PIPE_INTERRUPT: pipetype = "INTERRUPT"; break;
11313+ case PIPE_ISOCHRONOUS: pipetype = "ISOCHRONOUS"; break;
11314+ default: pipetype = "UNKNOWN"; break;
11315+ }; pipetype;}));
11316+ DWC_PRINT(" Speed: %s\n",
11317+ ({char *speed;
11318+ switch (urb->dev->speed) {
11319+ case USB_SPEED_HIGH: speed = "HIGH"; break;
11320+ case USB_SPEED_FULL: speed = "FULL"; break;
11321+ case USB_SPEED_LOW: speed = "LOW"; break;
11322+ default: speed = "UNKNOWN"; break;
11323+ }; speed;}));
11324+ DWC_PRINT(" Max packet size: %d\n",
11325+ usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)));
11326+ DWC_PRINT(" Data buffer length: %d\n", urb->transfer_buffer_length);
11327+ DWC_PRINT(" Transfer buffer: %p, Transfer DMA: %p\n",
11328+ urb->transfer_buffer, (void *)urb->transfer_dma);
11329+ DWC_PRINT(" Setup buffer: %p, Setup DMA: %p\n",
11330+ urb->setup_packet, (void *)urb->setup_dma);
11331+ DWC_PRINT(" Interval: %d\n", urb->interval);
11332+ if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
11333+ int i;
11334+ for (i = 0; i < urb->number_of_packets; i++) {
11335+ DWC_PRINT(" ISO Desc %d:\n", i);
11336+ DWC_PRINT(" offset: %d, length %d\n",
11337+ urb->iso_frame_desc[i].offset,
11338+ urb->iso_frame_desc[i].length);
11339+ }
11340+ }
11341+}
11342+
11343+static void dump_channel_info(dwc_otg_hcd_t *hcd,
11344+ dwc_otg_qh_t *qh)
11345+{
11346+ if (qh->channel != NULL) {
11347+ dwc_hc_t *hc = qh->channel;
11348+ struct list_head *item;
11349+ dwc_otg_qh_t *qh_item;
11350+ int num_channels = hcd->core_if->core_params->host_channels;
11351+ int i;
11352+
11353+ dwc_otg_hc_regs_t *hc_regs;
11354+ hcchar_data_t hcchar;
11355+ hcsplt_data_t hcsplt;
11356+ hctsiz_data_t hctsiz;
11357+ uint32_t hcdma;
11358+
11359+ hc_regs = hcd->core_if->host_if->hc_regs[hc->hc_num];
11360+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
11361+ hcsplt.d32 = dwc_read_reg32(&hc_regs->hcsplt);
11362+ hctsiz.d32 = dwc_read_reg32(&hc_regs->hctsiz);
11363+ hcdma = dwc_read_reg32(&hc_regs->hcdma);
11364+
11365+ DWC_PRINT(" Assigned to channel %p:\n", hc);
11366+ DWC_PRINT(" hcchar 0x%08x, hcsplt 0x%08x\n", hcchar.d32, hcsplt.d32);
11367+ DWC_PRINT(" hctsiz 0x%08x, hcdma 0x%08x\n", hctsiz.d32, hcdma);
11368+ DWC_PRINT(" dev_addr: %d, ep_num: %d, ep_is_in: %d\n",
11369+ hc->dev_addr, hc->ep_num, hc->ep_is_in);
11370+ DWC_PRINT(" ep_type: %d\n", hc->ep_type);
11371+ DWC_PRINT(" max_packet: %d\n", hc->max_packet);
11372+ DWC_PRINT(" data_pid_start: %d\n", hc->data_pid_start);
11373+ DWC_PRINT(" xfer_started: %d\n", hc->xfer_started);
11374+ DWC_PRINT(" halt_status: %d\n", hc->halt_status);
11375+ DWC_PRINT(" xfer_buff: %p\n", hc->xfer_buff);
11376+ DWC_PRINT(" xfer_len: %d\n", hc->xfer_len);
11377+ DWC_PRINT(" qh: %p\n", hc->qh);
11378+ DWC_PRINT(" NP inactive sched:\n");
11379+ list_for_each(item, &hcd->non_periodic_sched_inactive) {
11380+ qh_item = list_entry(item, dwc_otg_qh_t, qh_list_entry);
11381+ DWC_PRINT(" %p\n", qh_item);
11382+ }
11383+ DWC_PRINT(" NP active sched:\n");
11384+ list_for_each(item, &hcd->non_periodic_sched_active) {
11385+ qh_item = list_entry(item, dwc_otg_qh_t, qh_list_entry);
11386+ DWC_PRINT(" %p\n", qh_item);
11387+ }
11388+ DWC_PRINT(" Channels: \n");
11389+ for (i = 0; i < num_channels; i++) {
11390+ dwc_hc_t *hc = hcd->hc_ptr_array[i];
11391+ DWC_PRINT(" %2d: %p\n", i, hc);
11392+ }
11393+ }
11394+}
11395+#endif
11396+
11397+
11398+//OTG host require the DMA addr is DWORD-aligned,
11399+//patch it if the buffer is not DWORD-aligned
11400+inline
11401+void hcd_check_and_patch_dma_addr(struct urb *urb){
11402+
11403+ if((!urb->transfer_buffer)||!urb->transfer_dma||urb->transfer_dma==0xffffffff)
11404+ return;
11405+
11406+ if(((u32)urb->transfer_buffer)& 0x3){
11407+ /*
11408+ printk("%s: "
11409+ "urb(%.8x) "
11410+ "transfer_buffer=%.8x, "
11411+ "transfer_dma=%.8x, "
11412+ "transfer_buffer_length=%d, "
11413+ "actual_length=%d(%x), "
11414+ "\n",
11415+ ((urb->transfer_flags & URB_DIR_MASK)==URB_DIR_OUT)?"OUT":"IN",
11416+ urb,
11417+ urb->transfer_buffer,
11418+ urb->transfer_dma,
11419+ urb->transfer_buffer_length,
11420+ urb->actual_length,urb->actual_length
11421+ );
11422+ */
11423+ if(!urb->aligned_transfer_buffer||urb->aligned_transfer_buffer_length<urb->transfer_buffer_length){
11424+ urb->aligned_transfer_buffer_length=urb->transfer_buffer_length;
11425+ if(urb->aligned_transfer_buffer) {
11426+ kfree(urb->aligned_transfer_buffer);
11427+ }
11428+ urb->aligned_transfer_buffer=kmalloc(urb->aligned_transfer_buffer_length,GFP_KERNEL|GFP_DMA|GFP_ATOMIC);
11429+ urb->aligned_transfer_dma=dma_map_single(NULL,(void *)(urb->aligned_transfer_buffer),(urb->aligned_transfer_buffer_length),DMA_FROM_DEVICE);
11430+ if(!urb->aligned_transfer_buffer){
11431+ DWC_ERROR("Cannot alloc required buffer!!\n");
11432+ BUG();
11433+ }
11434+ //printk(" new allocated aligned_buf=%.8x aligned_buf_len=%d\n", (u32)urb->aligned_transfer_buffer, urb->aligned_transfer_buffer_length);
11435+ }
11436+ urb->transfer_dma=urb->aligned_transfer_dma;
11437+ if((urb->transfer_flags & URB_DIR_MASK)==URB_DIR_OUT) {
11438+ memcpy(urb->aligned_transfer_buffer,urb->transfer_buffer,urb->transfer_buffer_length);
11439+ dma_sync_single_for_device(NULL,urb->transfer_dma,urb->transfer_buffer_length,DMA_TO_DEVICE);
11440+ }
11441+ }
11442+}
11443+
11444+
11445+
11446+/** Starts processing a USB transfer request specified by a USB Request Block
11447+ * (URB). mem_flags indicates the type of memory allocation to use while
11448+ * processing this URB. */
11449+int dwc_otg_hcd_urb_enqueue(struct usb_hcd *hcd,
11450+// struct usb_host_endpoint *ep,
11451+ struct urb *urb,
11452+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
11453+ int mem_flags
11454+#else
11455+ gfp_t mem_flags
11456+#endif
11457+ )
11458+{
11459+ int retval = 0;
11460+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
11461+ dwc_otg_qtd_t *qtd;
11462+
11463+#ifdef DEBUG
11464+ if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
11465+ dump_urb_info(urb, "dwc_otg_hcd_urb_enqueue");
11466+ }
11467+#endif
11468+ if (!dwc_otg_hcd->flags.b.port_connect_status) {
11469+ /* No longer connected. */
11470+ return -ENODEV;
11471+ }
11472+
11473+ hcd_check_and_patch_dma_addr(urb);
11474+ qtd = dwc_otg_hcd_qtd_create(urb);
11475+ if (qtd == NULL) {
11476+ DWC_ERROR("DWC OTG HCD URB Enqueue failed creating QTD\n");
11477+ return -ENOMEM;
11478+ }
11479+
11480+ retval = dwc_otg_hcd_qtd_add(qtd, dwc_otg_hcd);
11481+ if (retval < 0) {
11482+ DWC_ERROR("DWC OTG HCD URB Enqueue failed adding QTD. "
11483+ "Error status %d\n", retval);
11484+ dwc_otg_hcd_qtd_free(qtd);
11485+ }
11486+
11487+ return retval;
11488+}
11489+
11490+/** Aborts/cancels a USB transfer request. Always returns 0 to indicate
11491+ * success. */
11492+int dwc_otg_hcd_urb_dequeue(struct usb_hcd *hcd,
11493+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
11494+ struct usb_host_endpoint *ep,
11495+#endif
11496+ struct urb *urb, int status)
11497+{
11498+ unsigned long flags;
11499+ dwc_otg_hcd_t *dwc_otg_hcd;
11500+ dwc_otg_qtd_t *urb_qtd;
11501+ dwc_otg_qh_t *qh;
11502+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
11503+ struct usb_host_endpoint *ep = dwc_urb_to_endpoint(urb);
11504+#endif
11505+
11506+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD URB Dequeue\n");
11507+
11508+ dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
11509+
11510+ SPIN_LOCK_IRQSAVE(&dwc_otg_hcd->lock, flags);
11511+
11512+ urb_qtd = (dwc_otg_qtd_t *)urb->hcpriv;
11513+ qh = (dwc_otg_qh_t *)ep->hcpriv;
11514+
11515+#ifdef DEBUG
11516+ if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
11517+ dump_urb_info(urb, "dwc_otg_hcd_urb_dequeue");
11518+ if (urb_qtd == qh->qtd_in_process) {
11519+ dump_channel_info(dwc_otg_hcd, qh);
11520+ }
11521+ }
11522+#endif
11523+
11524+ if (urb_qtd == qh->qtd_in_process) {
11525+ /* The QTD is in process (it has been assigned to a channel). */
11526+
11527+ if (dwc_otg_hcd->flags.b.port_connect_status) {
11528+ /*
11529+ * If still connected (i.e. in host mode), halt the
11530+ * channel so it can be used for other transfers. If
11531+ * no longer connected, the host registers can't be
11532+ * written to halt the channel since the core is in
11533+ * device mode.
11534+ */
11535+ dwc_otg_hc_halt(dwc_otg_hcd->core_if, qh->channel,
11536+ DWC_OTG_HC_XFER_URB_DEQUEUE);
11537+ }
11538+ }
11539+
11540+ /*
11541+ * Free the QTD and clean up the associated QH. Leave the QH in the
11542+ * schedule if it has any remaining QTDs.
11543+ */
11544+ dwc_otg_hcd_qtd_remove_and_free(dwc_otg_hcd, urb_qtd);
11545+ if (urb_qtd == qh->qtd_in_process) {
11546+ dwc_otg_hcd_qh_deactivate(dwc_otg_hcd, qh, 0);
11547+ qh->channel = NULL;
11548+ qh->qtd_in_process = NULL;
11549+ } else if (list_empty(&qh->qtd_list)) {
11550+ dwc_otg_hcd_qh_remove(dwc_otg_hcd, qh);
11551+ }
11552+
11553+ SPIN_UNLOCK_IRQRESTORE(&dwc_otg_hcd->lock, flags);
11554+
11555+ urb->hcpriv = NULL;
11556+
11557+ /* Higher layer software sets URB status. */
11558+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
11559+ usb_hcd_giveback_urb(hcd, urb, status);
11560+#else
11561+ usb_hcd_giveback_urb(hcd, urb, NULL);
11562+#endif
11563+ if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
11564+ DWC_PRINT("Called usb_hcd_giveback_urb()\n");
11565+ DWC_PRINT(" urb->status = %d\n", urb->status);
11566+ }
11567+
11568+ return 0;
11569+}
11570+
11571+/** Frees resources in the DWC_otg controller related to a given endpoint. Also
11572+ * clears state in the HCD related to the endpoint. Any URBs for the endpoint
11573+ * must already be dequeued. */
11574+void dwc_otg_hcd_endpoint_disable(struct usb_hcd *hcd,
11575+ struct usb_host_endpoint *ep)
11576+{
11577+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
11578+ dwc_otg_qh_t *qh;
11579+
11580+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
11581+ unsigned long flags;
11582+ int retry = 0;
11583+#endif
11584+
11585+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD EP DISABLE: _bEndpointAddress=0x%02x, "
11586+ "endpoint=%d\n", ep->desc.bEndpointAddress,
11587+ dwc_ep_addr_to_endpoint(ep->desc.bEndpointAddress));
11588+
11589+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
11590+rescan:
11591+ SPIN_LOCK_IRQSAVE(&dwc_otg_hcd->lock, flags);
11592+ qh = (dwc_otg_qh_t *)(ep->hcpriv);
11593+ if (!qh)
11594+ goto done;
11595+
11596+ /** Check that the QTD list is really empty */
11597+ if (!list_empty(&qh->qtd_list)) {
11598+ if (retry++ < 250) {
11599+ SPIN_UNLOCK_IRQRESTORE(&dwc_otg_hcd->lock, flags);
11600+ schedule_timeout_uninterruptible(1);
11601+ goto rescan;
11602+ }
11603+
11604+ DWC_WARN("DWC OTG HCD EP DISABLE:"
11605+ " QTD List for this endpoint is not empty\n");
11606+ }
11607+
11608+ dwc_otg_hcd_qh_remove_and_free(dwc_otg_hcd, qh);
11609+ ep->hcpriv = NULL;
11610+done:
11611+ SPIN_UNLOCK_IRQRESTORE(&dwc_otg_hcd->lock, flags);
11612+
11613+#else // LINUX_VERSION_CODE
11614+
11615+ qh = (dwc_otg_qh_t *)(ep->hcpriv);
11616+ if (qh != NULL) {
11617+#ifdef DEBUG
11618+ /** Check that the QTD list is really empty */
11619+ if (!list_empty(&qh->qtd_list)) {
11620+ DWC_WARN("DWC OTG HCD EP DISABLE:"
11621+ " QTD List for this endpoint is not empty\n");
11622+ }
11623+#endif
11624+ dwc_otg_hcd_qh_remove_and_free(dwc_otg_hcd, qh);
11625+ ep->hcpriv = NULL;
11626+ }
11627+#endif // LINUX_VERSION_CODE
11628+}
11629+
11630+/** Handles host mode interrupts for the DWC_otg controller. Returns IRQ_NONE if
11631+ * there was no interrupt to handle. Returns IRQ_HANDLED if there was a valid
11632+ * interrupt.
11633+ *
11634+ * This function is called by the USB core when an interrupt occurs */
11635+irqreturn_t dwc_otg_hcd_irq(struct usb_hcd *hcd
11636+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
11637+ , struct pt_regs *regs
11638+#endif
11639+ )
11640+{
11641+ int retVal = 0;
11642+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
11643+ retVal = dwc_otg_hcd_handle_intr(dwc_otg_hcd);
11644+ if (dwc_otg_hcd->flags.b.port_connect_status_change == 1)
11645+ usb_hcd_poll_rh_status(hcd);
11646+ return IRQ_RETVAL(retVal);
11647+}
11648+
11649+/** Creates Status Change bitmap for the root hub and root port. The bitmap is
11650+ * returned in buf. Bit 0 is the status change indicator for the root hub. Bit 1
11651+ * is the status change indicator for the single root port. Returns 1 if either
11652+ * change indicator is 1, otherwise returns 0. */
11653+int dwc_otg_hcd_hub_status_data(struct usb_hcd *hcd, char *buf)
11654+{
11655+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
11656+
11657+ buf[0] = 0;
11658+ buf[0] |= (dwc_otg_hcd->flags.b.port_connect_status_change ||
11659+ dwc_otg_hcd->flags.b.port_reset_change ||
11660+ dwc_otg_hcd->flags.b.port_enable_change ||
11661+ dwc_otg_hcd->flags.b.port_suspend_change ||
11662+ dwc_otg_hcd->flags.b.port_over_current_change) << 1;
11663+
11664+#ifdef DEBUG
11665+ if (buf[0]) {
11666+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB STATUS DATA:"
11667+ " Root port status changed\n");
11668+ DWC_DEBUGPL(DBG_HCDV, " port_connect_status_change: %d\n",
11669+ dwc_otg_hcd->flags.b.port_connect_status_change);
11670+ DWC_DEBUGPL(DBG_HCDV, " port_reset_change: %d\n",
11671+ dwc_otg_hcd->flags.b.port_reset_change);
11672+ DWC_DEBUGPL(DBG_HCDV, " port_enable_change: %d\n",
11673+ dwc_otg_hcd->flags.b.port_enable_change);
11674+ DWC_DEBUGPL(DBG_HCDV, " port_suspend_change: %d\n",
11675+ dwc_otg_hcd->flags.b.port_suspend_change);
11676+ DWC_DEBUGPL(DBG_HCDV, " port_over_current_change: %d\n",
11677+ dwc_otg_hcd->flags.b.port_over_current_change);
11678+ }
11679+#endif
11680+ return (buf[0] != 0);
11681+}
11682+
11683+#ifdef DWC_HS_ELECT_TST
11684+/*
11685+ * Quick and dirty hack to implement the HS Electrical Test
11686+ * SINGLE_STEP_GET_DEVICE_DESCRIPTOR feature.
11687+ *
11688+ * This code was copied from our userspace app "hset". It sends a
11689+ * Get Device Descriptor control sequence in two parts, first the
11690+ * Setup packet by itself, followed some time later by the In and
11691+ * Ack packets. Rather than trying to figure out how to add this
11692+ * functionality to the normal driver code, we just hijack the
11693+ * hardware, using these two function to drive the hardware
11694+ * directly.
11695+ */
11696+
11697+dwc_otg_core_global_regs_t *global_regs;
11698+dwc_otg_host_global_regs_t *hc_global_regs;
11699+dwc_otg_hc_regs_t *hc_regs;
11700+uint32_t *data_fifo;
11701+
11702+static void do_setup(void)
11703+{
11704+ gintsts_data_t gintsts;
11705+ hctsiz_data_t hctsiz;
11706+ hcchar_data_t hcchar;
11707+ haint_data_t haint;
11708+ hcint_data_t hcint;
11709+
11710+ /* Enable HAINTs */
11711+ dwc_write_reg32(&hc_global_regs->haintmsk, 0x0001);
11712+
11713+ /* Enable HCINTs */
11714+ dwc_write_reg32(&hc_regs->hcintmsk, 0x04a3);
11715+
11716+ /* Read GINTSTS */
11717+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
11718+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
11719+
11720+ /* Read HAINT */
11721+ haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
11722+ //fprintf(stderr, "HAINT: %08x\n", haint.d32);
11723+
11724+ /* Read HCINT */
11725+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
11726+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
11727+
11728+ /* Read HCCHAR */
11729+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
11730+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
11731+
11732+ /* Clear HCINT */
11733+ dwc_write_reg32(&hc_regs->hcint, hcint.d32);
11734+
11735+ /* Clear HAINT */
11736+ dwc_write_reg32(&hc_global_regs->haint, haint.d32);
11737+
11738+ /* Clear GINTSTS */
11739+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
11740+
11741+ /* Read GINTSTS */
11742+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
11743+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
11744+
11745+ /*
11746+ * Send Setup packet (Get Device Descriptor)
11747+ */
11748+
11749+ /* Make sure channel is disabled */
11750+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
11751+ if (hcchar.b.chen) {
11752+ //fprintf(stderr, "Channel already enabled 1, HCCHAR = %08x\n", hcchar.d32);
11753+ hcchar.b.chdis = 1;
11754+// hcchar.b.chen = 1;
11755+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
11756+ //sleep(1);
11757+ mdelay(1000);
11758+
11759+ /* Read GINTSTS */
11760+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
11761+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
11762+
11763+ /* Read HAINT */
11764+ haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
11765+ //fprintf(stderr, "HAINT: %08x\n", haint.d32);
11766+
11767+ /* Read HCINT */
11768+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
11769+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
11770+
11771+ /* Read HCCHAR */
11772+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
11773+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
11774+
11775+ /* Clear HCINT */
11776+ dwc_write_reg32(&hc_regs->hcint, hcint.d32);
11777+
11778+ /* Clear HAINT */
11779+ dwc_write_reg32(&hc_global_regs->haint, haint.d32);
11780+
11781+ /* Clear GINTSTS */
11782+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
11783+
11784+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
11785+ //if (hcchar.b.chen) {
11786+ // fprintf(stderr, "** Channel _still_ enabled 1, HCCHAR = %08x **\n", hcchar.d32);
11787+ //}
11788+ }
11789+
11790+ /* Set HCTSIZ */
11791+ hctsiz.d32 = 0;
11792+ hctsiz.b.xfersize = 8;
11793+ hctsiz.b.pktcnt = 1;
11794+ hctsiz.b.pid = DWC_OTG_HC_PID_SETUP;
11795+ dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
11796+
11797+ /* Set HCCHAR */
11798+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
11799+ hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;
11800+ hcchar.b.epdir = 0;
11801+ hcchar.b.epnum = 0;
11802+ hcchar.b.mps = 8;
11803+ hcchar.b.chen = 1;
11804+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
11805+
11806+ /* Fill FIFO with Setup data for Get Device Descriptor */
11807+ data_fifo = (uint32_t *)((char *)global_regs + 0x1000);
11808+ dwc_write_reg32(data_fifo++, 0x01000680);
11809+ dwc_write_reg32(data_fifo++, 0x00080000);
11810+
11811+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
11812+ //fprintf(stderr, "Waiting for HCINTR intr 1, GINTSTS = %08x\n", gintsts.d32);
11813+
11814+ /* Wait for host channel interrupt */
11815+ do {
11816+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
11817+ } while (gintsts.b.hcintr == 0);
11818+
11819+ //fprintf(stderr, "Got HCINTR intr 1, GINTSTS = %08x\n", gintsts.d32);
11820+
11821+ /* Disable HCINTs */
11822+ dwc_write_reg32(&hc_regs->hcintmsk, 0x0000);
11823+
11824+ /* Disable HAINTs */
11825+ dwc_write_reg32(&hc_global_regs->haintmsk, 0x0000);
11826+
11827+ /* Read HAINT */
11828+ haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
11829+ //fprintf(stderr, "HAINT: %08x\n", haint.d32);
11830+
11831+ /* Read HCINT */
11832+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
11833+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
11834+
11835+ /* Read HCCHAR */
11836+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
11837+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
11838+
11839+ /* Clear HCINT */
11840+ dwc_write_reg32(&hc_regs->hcint, hcint.d32);
11841+
11842+ /* Clear HAINT */
11843+ dwc_write_reg32(&hc_global_regs->haint, haint.d32);
11844+
11845+ /* Clear GINTSTS */
11846+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
11847+
11848+ /* Read GINTSTS */
11849+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
11850+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
11851+}
11852+
11853+static void do_in_ack(void)
11854+{
11855+ gintsts_data_t gintsts;
11856+ hctsiz_data_t hctsiz;
11857+ hcchar_data_t hcchar;
11858+ haint_data_t haint;
11859+ hcint_data_t hcint;
11860+ host_grxsts_data_t grxsts;
11861+
11862+ /* Enable HAINTs */
11863+ dwc_write_reg32(&hc_global_regs->haintmsk, 0x0001);
11864+
11865+ /* Enable HCINTs */
11866+ dwc_write_reg32(&hc_regs->hcintmsk, 0x04a3);
11867+
11868+ /* Read GINTSTS */
11869+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
11870+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
11871+
11872+ /* Read HAINT */
11873+ haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
11874+ //fprintf(stderr, "HAINT: %08x\n", haint.d32);
11875+
11876+ /* Read HCINT */
11877+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
11878+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
11879+
11880+ /* Read HCCHAR */
11881+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
11882+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
11883+
11884+ /* Clear HCINT */
11885+ dwc_write_reg32(&hc_regs->hcint, hcint.d32);
11886+
11887+ /* Clear HAINT */
11888+ dwc_write_reg32(&hc_global_regs->haint, haint.d32);
11889+
11890+ /* Clear GINTSTS */
11891+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
11892+
11893+ /* Read GINTSTS */
11894+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
11895+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
11896+
11897+ /*
11898+ * Receive Control In packet
11899+ */
11900+
11901+ /* Make sure channel is disabled */
11902+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
11903+ if (hcchar.b.chen) {
11904+ //fprintf(stderr, "Channel already enabled 2, HCCHAR = %08x\n", hcchar.d32);
11905+ hcchar.b.chdis = 1;
11906+ hcchar.b.chen = 1;
11907+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
11908+ //sleep(1);
11909+ mdelay(1000);
11910+
11911+ /* Read GINTSTS */
11912+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
11913+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
11914+
11915+ /* Read HAINT */
11916+ haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
11917+ //fprintf(stderr, "HAINT: %08x\n", haint.d32);
11918+
11919+ /* Read HCINT */
11920+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
11921+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
11922+
11923+ /* Read HCCHAR */
11924+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
11925+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
11926+
11927+ /* Clear HCINT */
11928+ dwc_write_reg32(&hc_regs->hcint, hcint.d32);
11929+
11930+ /* Clear HAINT */
11931+ dwc_write_reg32(&hc_global_regs->haint, haint.d32);
11932+
11933+ /* Clear GINTSTS */
11934+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
11935+
11936+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
11937+ //if (hcchar.b.chen) {
11938+ // fprintf(stderr, "** Channel _still_ enabled 2, HCCHAR = %08x **\n", hcchar.d32);
11939+ //}
11940+ }
11941+
11942+ /* Set HCTSIZ */
11943+ hctsiz.d32 = 0;
11944+ hctsiz.b.xfersize = 8;
11945+ hctsiz.b.pktcnt = 1;
11946+ hctsiz.b.pid = DWC_OTG_HC_PID_DATA1;
11947+ dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
11948+
11949+ /* Set HCCHAR */
11950+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
11951+ hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;
11952+ hcchar.b.epdir = 1;
11953+ hcchar.b.epnum = 0;
11954+ hcchar.b.mps = 8;
11955+ hcchar.b.chen = 1;
11956+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
11957+
11958+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
11959+ //fprintf(stderr, "Waiting for RXSTSQLVL intr 1, GINTSTS = %08x\n", gintsts.d32);
11960+
11961+ /* Wait for receive status queue interrupt */
11962+ do {
11963+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
11964+ } while (gintsts.b.rxstsqlvl == 0);
11965+
11966+ //fprintf(stderr, "Got RXSTSQLVL intr 1, GINTSTS = %08x\n", gintsts.d32);
11967+
11968+ /* Read RXSTS */
11969+ grxsts.d32 = dwc_read_reg32(&global_regs->grxstsp);
11970+ //fprintf(stderr, "GRXSTS: %08x\n", grxsts.d32);
11971+
11972+ /* Clear RXSTSQLVL in GINTSTS */
11973+ gintsts.d32 = 0;
11974+ gintsts.b.rxstsqlvl = 1;
11975+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
11976+
11977+ switch (grxsts.b.pktsts) {
11978+ case DWC_GRXSTS_PKTSTS_IN:
11979+ /* Read the data into the host buffer */
11980+ if (grxsts.b.bcnt > 0) {
11981+ int i;
11982+ int word_count = (grxsts.b.bcnt + 3) / 4;
11983+
11984+ data_fifo = (uint32_t *)((char *)global_regs + 0x1000);
11985+
11986+ for (i = 0; i < word_count; i++) {
11987+ (void)dwc_read_reg32(data_fifo++);
11988+ }
11989+ }
11990+
11991+ //fprintf(stderr, "Received %u bytes\n", (unsigned)grxsts.b.bcnt);
11992+ break;
11993+
11994+ default:
11995+ //fprintf(stderr, "** Unexpected GRXSTS packet status 1 **\n");
11996+ break;
11997+ }
11998+
11999+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
12000+ //fprintf(stderr, "Waiting for RXSTSQLVL intr 2, GINTSTS = %08x\n", gintsts.d32);
12001+
12002+ /* Wait for receive status queue interrupt */
12003+ do {
12004+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
12005+ } while (gintsts.b.rxstsqlvl == 0);
12006+
12007+ //fprintf(stderr, "Got RXSTSQLVL intr 2, GINTSTS = %08x\n", gintsts.d32);
12008+
12009+ /* Read RXSTS */
12010+ grxsts.d32 = dwc_read_reg32(&global_regs->grxstsp);
12011+ //fprintf(stderr, "GRXSTS: %08x\n", grxsts.d32);
12012+
12013+ /* Clear RXSTSQLVL in GINTSTS */
12014+ gintsts.d32 = 0;
12015+ gintsts.b.rxstsqlvl = 1;
12016+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
12017+
12018+ switch (grxsts.b.pktsts) {
12019+ case DWC_GRXSTS_PKTSTS_IN_XFER_COMP:
12020+ break;
12021+
12022+ default:
12023+ //fprintf(stderr, "** Unexpected GRXSTS packet status 2 **\n");
12024+ break;
12025+ }
12026+
12027+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
12028+ //fprintf(stderr, "Waiting for HCINTR intr 2, GINTSTS = %08x\n", gintsts.d32);
12029+
12030+ /* Wait for host channel interrupt */
12031+ do {
12032+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
12033+ } while (gintsts.b.hcintr == 0);
12034+
12035+ //fprintf(stderr, "Got HCINTR intr 2, GINTSTS = %08x\n", gintsts.d32);
12036+
12037+ /* Read HAINT */
12038+ haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
12039+ //fprintf(stderr, "HAINT: %08x\n", haint.d32);
12040+
12041+ /* Read HCINT */
12042+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
12043+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
12044+
12045+ /* Read HCCHAR */
12046+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
12047+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
12048+
12049+ /* Clear HCINT */
12050+ dwc_write_reg32(&hc_regs->hcint, hcint.d32);
12051+
12052+ /* Clear HAINT */
12053+ dwc_write_reg32(&hc_global_regs->haint, haint.d32);
12054+
12055+ /* Clear GINTSTS */
12056+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
12057+
12058+ /* Read GINTSTS */
12059+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
12060+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
12061+
12062+// usleep(100000);
12063+// mdelay(100);
12064+ mdelay(1);
12065+
12066+ /*
12067+ * Send handshake packet
12068+ */
12069+
12070+ /* Read HAINT */
12071+ haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
12072+ //fprintf(stderr, "HAINT: %08x\n", haint.d32);
12073+
12074+ /* Read HCINT */
12075+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
12076+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
12077+
12078+ /* Read HCCHAR */
12079+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
12080+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
12081+
12082+ /* Clear HCINT */
12083+ dwc_write_reg32(&hc_regs->hcint, hcint.d32);
12084+
12085+ /* Clear HAINT */
12086+ dwc_write_reg32(&hc_global_regs->haint, haint.d32);
12087+
12088+ /* Clear GINTSTS */
12089+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
12090+
12091+ /* Read GINTSTS */
12092+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
12093+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
12094+
12095+ /* Make sure channel is disabled */
12096+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
12097+ if (hcchar.b.chen) {
12098+ //fprintf(stderr, "Channel already enabled 3, HCCHAR = %08x\n", hcchar.d32);
12099+ hcchar.b.chdis = 1;
12100+ hcchar.b.chen = 1;
12101+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
12102+ //sleep(1);
12103+ mdelay(1000);
12104+
12105+ /* Read GINTSTS */
12106+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
12107+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
12108+
12109+ /* Read HAINT */
12110+ haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
12111+ //fprintf(stderr, "HAINT: %08x\n", haint.d32);
12112+
12113+ /* Read HCINT */
12114+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
12115+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
12116+
12117+ /* Read HCCHAR */
12118+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
12119+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
12120+
12121+ /* Clear HCINT */
12122+ dwc_write_reg32(&hc_regs->hcint, hcint.d32);
12123+
12124+ /* Clear HAINT */
12125+ dwc_write_reg32(&hc_global_regs->haint, haint.d32);
12126+
12127+ /* Clear GINTSTS */
12128+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
12129+
12130+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
12131+ //if (hcchar.b.chen) {
12132+ // fprintf(stderr, "** Channel _still_ enabled 3, HCCHAR = %08x **\n", hcchar.d32);
12133+ //}
12134+ }
12135+
12136+ /* Set HCTSIZ */
12137+ hctsiz.d32 = 0;
12138+ hctsiz.b.xfersize = 0;
12139+ hctsiz.b.pktcnt = 1;
12140+ hctsiz.b.pid = DWC_OTG_HC_PID_DATA1;
12141+ dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
12142+
12143+ /* Set HCCHAR */
12144+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
12145+ hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;
12146+ hcchar.b.epdir = 0;
12147+ hcchar.b.epnum = 0;
12148+ hcchar.b.mps = 8;
12149+ hcchar.b.chen = 1;
12150+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
12151+
12152+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
12153+ //fprintf(stderr, "Waiting for HCINTR intr 3, GINTSTS = %08x\n", gintsts.d32);
12154+
12155+ /* Wait for host channel interrupt */
12156+ do {
12157+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
12158+ } while (gintsts.b.hcintr == 0);
12159+
12160+ //fprintf(stderr, "Got HCINTR intr 3, GINTSTS = %08x\n", gintsts.d32);
12161+
12162+ /* Disable HCINTs */
12163+ dwc_write_reg32(&hc_regs->hcintmsk, 0x0000);
12164+
12165+ /* Disable HAINTs */
12166+ dwc_write_reg32(&hc_global_regs->haintmsk, 0x0000);
12167+
12168+ /* Read HAINT */
12169+ haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
12170+ //fprintf(stderr, "HAINT: %08x\n", haint.d32);
12171+
12172+ /* Read HCINT */
12173+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
12174+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
12175+
12176+ /* Read HCCHAR */
12177+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
12178+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
12179+
12180+ /* Clear HCINT */
12181+ dwc_write_reg32(&hc_regs->hcint, hcint.d32);
12182+
12183+ /* Clear HAINT */
12184+ dwc_write_reg32(&hc_global_regs->haint, haint.d32);
12185+
12186+ /* Clear GINTSTS */
12187+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
12188+
12189+ /* Read GINTSTS */
12190+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
12191+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
12192+}
12193+#endif /* DWC_HS_ELECT_TST */
12194+
12195+/** Handles hub class-specific requests. */
12196+int dwc_otg_hcd_hub_control(struct usb_hcd *hcd,
12197+ u16 typeReq,
12198+ u16 wValue,
12199+ u16 wIndex,
12200+ char *buf,
12201+ u16 wLength)
12202+{
12203+ int retval = 0;
12204+
12205+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
12206+ dwc_otg_core_if_t *core_if = hcd_to_dwc_otg_hcd(hcd)->core_if;
12207+ struct usb_hub_descriptor *desc;
12208+ hprt0_data_t hprt0 = {.d32 = 0};
12209+
12210+ uint32_t port_status;
12211+
12212+ switch (typeReq) {
12213+ case ClearHubFeature:
12214+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
12215+ "ClearHubFeature 0x%x\n", wValue);
12216+ switch (wValue) {
12217+ case C_HUB_LOCAL_POWER:
12218+ case C_HUB_OVER_CURRENT:
12219+ /* Nothing required here */
12220+ break;
12221+ default:
12222+ retval = -EINVAL;
12223+ DWC_ERROR("DWC OTG HCD - "
12224+ "ClearHubFeature request %xh unknown\n", wValue);
12225+ }
12226+ break;
12227+ case ClearPortFeature:
12228+ if (!wIndex || wIndex > 1)
12229+ goto error;
12230+
12231+ switch (wValue) {
12232+ case USB_PORT_FEAT_ENABLE:
12233+ DWC_DEBUGPL(DBG_ANY, "DWC OTG HCD HUB CONTROL - "
12234+ "ClearPortFeature USB_PORT_FEAT_ENABLE\n");
12235+ hprt0.d32 = dwc_otg_read_hprt0(core_if);
12236+ hprt0.b.prtena = 1;
12237+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
12238+ break;
12239+ case USB_PORT_FEAT_SUSPEND:
12240+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
12241+ "ClearPortFeature USB_PORT_FEAT_SUSPEND\n");
12242+ hprt0.d32 = dwc_otg_read_hprt0(core_if);
12243+ hprt0.b.prtres = 1;
12244+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
12245+ /* Clear Resume bit */
12246+ mdelay(100);
12247+ hprt0.b.prtres = 0;
12248+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
12249+ break;
12250+ case USB_PORT_FEAT_POWER:
12251+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
12252+ "ClearPortFeature USB_PORT_FEAT_POWER\n");
12253+ hprt0.d32 = dwc_otg_read_hprt0(core_if);
12254+ hprt0.b.prtpwr = 0;
12255+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
12256+ break;
12257+ case USB_PORT_FEAT_INDICATOR:
12258+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
12259+ "ClearPortFeature USB_PORT_FEAT_INDICATOR\n");
12260+ /* Port inidicator not supported */
12261+ break;
12262+ case USB_PORT_FEAT_C_CONNECTION:
12263+ /* Clears drivers internal connect status change
12264+ * flag */
12265+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
12266+ "ClearPortFeature USB_PORT_FEAT_C_CONNECTION\n");
12267+ dwc_otg_hcd->flags.b.port_connect_status_change = 0;
12268+ break;
12269+ case USB_PORT_FEAT_C_RESET:
12270+ /* Clears the driver's internal Port Reset Change
12271+ * flag */
12272+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
12273+ "ClearPortFeature USB_PORT_FEAT_C_RESET\n");
12274+ dwc_otg_hcd->flags.b.port_reset_change = 0;
12275+ break;
12276+ case USB_PORT_FEAT_C_ENABLE:
12277+ /* Clears the driver's internal Port
12278+ * Enable/Disable Change flag */
12279+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
12280+ "ClearPortFeature USB_PORT_FEAT_C_ENABLE\n");
12281+ dwc_otg_hcd->flags.b.port_enable_change = 0;
12282+ break;
12283+ case USB_PORT_FEAT_C_SUSPEND:
12284+ /* Clears the driver's internal Port Suspend
12285+ * Change flag, which is set when resume signaling on
12286+ * the host port is complete */
12287+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
12288+ "ClearPortFeature USB_PORT_FEAT_C_SUSPEND\n");
12289+ dwc_otg_hcd->flags.b.port_suspend_change = 0;
12290+ break;
12291+ case USB_PORT_FEAT_C_OVER_CURRENT:
12292+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
12293+ "ClearPortFeature USB_PORT_FEAT_C_OVER_CURRENT\n");
12294+ dwc_otg_hcd->flags.b.port_over_current_change = 0;
12295+ break;
12296+ default:
12297+ retval = -EINVAL;
12298+ DWC_ERROR("DWC OTG HCD - "
12299+ "ClearPortFeature request %xh "
12300+ "unknown or unsupported\n", wValue);
12301+ }
12302+ break;
12303+ case GetHubDescriptor:
12304+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
12305+ "GetHubDescriptor\n");
12306+ desc = (struct usb_hub_descriptor *)buf;
12307+ desc->bDescLength = 9;
12308+ desc->bDescriptorType = 0x29;
12309+ desc->bNbrPorts = 1;
12310+ desc->wHubCharacteristics = 0x08;
12311+ desc->bPwrOn2PwrGood = 1;
12312+ desc->bHubContrCurrent = 0;
12313+ desc->bitmap[0] = 0;
12314+ desc->bitmap[1] = 0xff;
12315+ break;
12316+ case GetHubStatus:
12317+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
12318+ "GetHubStatus\n");
12319+ memset(buf, 0, 4);
12320+ break;
12321+ case GetPortStatus:
12322+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
12323+ "GetPortStatus\n");
12324+
12325+ if (!wIndex || wIndex > 1)
12326+ goto error;
12327+
12328+ port_status = 0;
12329+
12330+ if (dwc_otg_hcd->flags.b.port_connect_status_change)
12331+ port_status |= (1 << USB_PORT_FEAT_C_CONNECTION);
12332+
12333+ if (dwc_otg_hcd->flags.b.port_enable_change)
12334+ port_status |= (1 << USB_PORT_FEAT_C_ENABLE);
12335+
12336+ if (dwc_otg_hcd->flags.b.port_suspend_change)
12337+ port_status |= (1 << USB_PORT_FEAT_C_SUSPEND);
12338+
12339+ if (dwc_otg_hcd->flags.b.port_reset_change)
12340+ port_status |= (1 << USB_PORT_FEAT_C_RESET);
12341+
12342+ if (dwc_otg_hcd->flags.b.port_over_current_change) {
12343+ DWC_ERROR("Device Not Supported\n");
12344+ port_status |= (1 << USB_PORT_FEAT_C_OVER_CURRENT);
12345+ }
12346+
12347+ if (!dwc_otg_hcd->flags.b.port_connect_status) {
12348+ /*
12349+ * The port is disconnected, which means the core is
12350+ * either in device mode or it soon will be. Just
12351+ * return 0's for the remainder of the port status
12352+ * since the port register can't be read if the core
12353+ * is in device mode.
12354+ */
12355+ *((__le32 *) buf) = cpu_to_le32(port_status);
12356+ break;
12357+ }
12358+
12359+ hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
12360+ DWC_DEBUGPL(DBG_HCDV, " HPRT0: 0x%08x\n", hprt0.d32);
12361+
12362+ if (hprt0.b.prtconnsts)
12363+ port_status |= (1 << USB_PORT_FEAT_CONNECTION);
12364+
12365+ if (hprt0.b.prtena)
12366+ port_status |= (1 << USB_PORT_FEAT_ENABLE);
12367+
12368+ if (hprt0.b.prtsusp)
12369+ port_status |= (1 << USB_PORT_FEAT_SUSPEND);
12370+
12371+ if (hprt0.b.prtovrcurract)
12372+ port_status |= (1 << USB_PORT_FEAT_OVER_CURRENT);
12373+
12374+ if (hprt0.b.prtrst)
12375+ port_status |= (1 << USB_PORT_FEAT_RESET);
12376+
12377+ if (hprt0.b.prtpwr)
12378+ port_status |= (1 << USB_PORT_FEAT_POWER);
12379+
12380+ if (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_HIGH_SPEED)
12381+ port_status |= (1 << USB_PORT_FEAT_HIGHSPEED);
12382+ else if (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_LOW_SPEED)
12383+ port_status |= (1 << USB_PORT_FEAT_LOWSPEED);
12384+
12385+ if (hprt0.b.prttstctl)
12386+ port_status |= (1 << USB_PORT_FEAT_TEST);
12387+
12388+ /* USB_PORT_FEAT_INDICATOR unsupported always 0 */
12389+
12390+ *((__le32 *) buf) = cpu_to_le32(port_status);
12391+
12392+ break;
12393+ case SetHubFeature:
12394+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
12395+ "SetHubFeature\n");
12396+ /* No HUB features supported */
12397+ break;
12398+ case SetPortFeature:
12399+ if (wValue != USB_PORT_FEAT_TEST && (!wIndex || wIndex > 1))
12400+ goto error;
12401+
12402+ if (!dwc_otg_hcd->flags.b.port_connect_status) {
12403+ /*
12404+ * The port is disconnected, which means the core is
12405+ * either in device mode or it soon will be. Just
12406+ * return without doing anything since the port
12407+ * register can't be written if the core is in device
12408+ * mode.
12409+ */
12410+ break;
12411+ }
12412+
12413+ switch (wValue) {
12414+ case USB_PORT_FEAT_SUSPEND:
12415+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
12416+ "SetPortFeature - USB_PORT_FEAT_SUSPEND\n");
12417+ if (hcd->self.otg_port == wIndex &&
12418+ hcd->self.b_hnp_enable) {
12419+ gotgctl_data_t gotgctl = {.d32=0};
12420+ gotgctl.b.hstsethnpen = 1;
12421+ dwc_modify_reg32(&core_if->core_global_regs->gotgctl,
12422+ 0, gotgctl.d32);
12423+ core_if->op_state = A_SUSPEND;
12424+ }
12425+ hprt0.d32 = dwc_otg_read_hprt0(core_if);
12426+ hprt0.b.prtsusp = 1;
12427+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
12428+ //DWC_PRINT("SUSPEND: HPRT0=%0x\n", hprt0.d32);
12429+ /* Suspend the Phy Clock */
12430+ {
12431+ pcgcctl_data_t pcgcctl = {.d32=0};
12432+ pcgcctl.b.stoppclk = 1;
12433+ dwc_write_reg32(core_if->pcgcctl, pcgcctl.d32);
12434+ }
12435+
12436+ /* For HNP the bus must be suspended for at least 200ms. */
12437+ if (hcd->self.b_hnp_enable) {
12438+ mdelay(200);
12439+ //DWC_PRINT("SUSPEND: wait complete! (%d)\n", _hcd->state);
12440+ }
12441+ break;
12442+ case USB_PORT_FEAT_POWER:
12443+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
12444+ "SetPortFeature - USB_PORT_FEAT_POWER\n");
12445+ hprt0.d32 = dwc_otg_read_hprt0(core_if);
12446+ hprt0.b.prtpwr = 1;
12447+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
12448+ break;
12449+ case USB_PORT_FEAT_RESET:
12450+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
12451+ "SetPortFeature - USB_PORT_FEAT_RESET\n");
12452+ hprt0.d32 = dwc_otg_read_hprt0(core_if);
12453+ /* When B-Host the Port reset bit is set in
12454+ * the Start HCD Callback function, so that
12455+ * the reset is started within 1ms of the HNP
12456+ * success interrupt. */
12457+ if (!hcd->self.is_b_host) {
12458+ hprt0.b.prtrst = 1;
12459+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
12460+ }
12461+ /* Clear reset bit in 10ms (FS/LS) or 50ms (HS) */
12462+ MDELAY(60);
12463+ hprt0.b.prtrst = 0;
12464+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
12465+ break;
12466+
12467+#ifdef DWC_HS_ELECT_TST
12468+ case USB_PORT_FEAT_TEST:
12469+ {
12470+ uint32_t t;
12471+ gintmsk_data_t gintmsk;
12472+
12473+ t = (wIndex >> 8); /* MSB wIndex USB */
12474+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
12475+ "SetPortFeature - USB_PORT_FEAT_TEST %d\n", t);
12476+ warn("USB_PORT_FEAT_TEST %d\n", t);
12477+ if (t < 6) {
12478+ hprt0.d32 = dwc_otg_read_hprt0(core_if);
12479+ hprt0.b.prttstctl = t;
12480+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
12481+ } else {
12482+ /* Setup global vars with reg addresses (quick and
12483+ * dirty hack, should be cleaned up)
12484+ */
12485+ global_regs = core_if->core_global_regs;
12486+ hc_global_regs = core_if->host_if->host_global_regs;
12487+ hc_regs = (dwc_otg_hc_regs_t *)((char *)global_regs + 0x500);
12488+ data_fifo = (uint32_t *)((char *)global_regs + 0x1000);
12489+
12490+ if (t == 6) { /* HS_HOST_PORT_SUSPEND_RESUME */
12491+ /* Save current interrupt mask */
12492+ gintmsk.d32 = dwc_read_reg32(&global_regs->gintmsk);
12493+
12494+ /* Disable all interrupts while we muck with
12495+ * the hardware directly
12496+ */
12497+ dwc_write_reg32(&global_regs->gintmsk, 0);
12498+
12499+ /* 15 second delay per the test spec */
12500+ mdelay(15000);
12501+
12502+ /* Drive suspend on the root port */
12503+ hprt0.d32 = dwc_otg_read_hprt0(core_if);
12504+ hprt0.b.prtsusp = 1;
12505+ hprt0.b.prtres = 0;
12506+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
12507+
12508+ /* 15 second delay per the test spec */
12509+ mdelay(15000);
12510+
12511+ /* Drive resume on the root port */
12512+ hprt0.d32 = dwc_otg_read_hprt0(core_if);
12513+ hprt0.b.prtsusp = 0;
12514+ hprt0.b.prtres = 1;
12515+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
12516+ mdelay(100);
12517+
12518+ /* Clear the resume bit */
12519+ hprt0.b.prtres = 0;
12520+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
12521+
12522+ /* Restore interrupts */
12523+ dwc_write_reg32(&global_regs->gintmsk, gintmsk.d32);
12524+ } else if (t == 7) { /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR setup */
12525+ /* Save current interrupt mask */
12526+ gintmsk.d32 = dwc_read_reg32(&global_regs->gintmsk);
12527+
12528+ /* Disable all interrupts while we muck with
12529+ * the hardware directly
12530+ */
12531+ dwc_write_reg32(&global_regs->gintmsk, 0);
12532+
12533+ /* 15 second delay per the test spec */
12534+ mdelay(15000);
12535+
12536+ /* Send the Setup packet */
12537+ do_setup();
12538+
12539+ /* 15 second delay so nothing else happens for awhile */
12540+ mdelay(15000);
12541+
12542+ /* Restore interrupts */
12543+ dwc_write_reg32(&global_regs->gintmsk, gintmsk.d32);
12544+ } else if (t == 8) { /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR execute */
12545+ /* Save current interrupt mask */
12546+ gintmsk.d32 = dwc_read_reg32(&global_regs->gintmsk);
12547+
12548+ /* Disable all interrupts while we muck with
12549+ * the hardware directly
12550+ */
12551+ dwc_write_reg32(&global_regs->gintmsk, 0);
12552+
12553+ /* Send the Setup packet */
12554+ do_setup();
12555+
12556+ /* 15 second delay so nothing else happens for awhile */
12557+ mdelay(15000);
12558+
12559+ /* Send the In and Ack packets */
12560+ do_in_ack();
12561+
12562+ /* 15 second delay so nothing else happens for awhile */
12563+ mdelay(15000);
12564+
12565+ /* Restore interrupts */
12566+ dwc_write_reg32(&global_regs->gintmsk, gintmsk.d32);
12567+ }
12568+ }
12569+ break;
12570+ }
12571+#endif /* DWC_HS_ELECT_TST */
12572+
12573+ case USB_PORT_FEAT_INDICATOR:
12574+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
12575+ "SetPortFeature - USB_PORT_FEAT_INDICATOR\n");
12576+ /* Not supported */
12577+ break;
12578+ default:
12579+ retval = -EINVAL;
12580+ DWC_ERROR("DWC OTG HCD - "
12581+ "SetPortFeature request %xh "
12582+ "unknown or unsupported\n", wValue);
12583+ break;
12584+ }
12585+ break;
12586+ default:
12587+ error:
12588+ retval = -EINVAL;
12589+ DWC_WARN("DWC OTG HCD - "
12590+ "Unknown hub control request type or invalid typeReq: %xh wIndex: %xh wValue: %xh\n",
12591+ typeReq, wIndex, wValue);
12592+ break;
12593+ }
12594+
12595+ return retval;
12596+}
12597+
12598+/**
12599+ * Assigns transactions from a QTD to a free host channel and initializes the
12600+ * host channel to perform the transactions. The host channel is removed from
12601+ * the free list.
12602+ *
12603+ * @param hcd The HCD state structure.
12604+ * @param qh Transactions from the first QTD for this QH are selected and
12605+ * assigned to a free host channel.
12606+ */
12607+static void assign_and_init_hc(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh)
12608+{
12609+ dwc_hc_t *hc;
12610+ dwc_otg_qtd_t *qtd;
12611+ struct urb *urb;
12612+
12613+ DWC_DEBUGPL(DBG_HCDV, "%s(%p,%p)\n", __func__, hcd, qh);
12614+
12615+ hc = list_entry(hcd->free_hc_list.next, dwc_hc_t, hc_list_entry);
12616+
12617+ /* Remove the host channel from the free list. */
12618+ list_del_init(&hc->hc_list_entry);
12619+
12620+ qtd = list_entry(qh->qtd_list.next, dwc_otg_qtd_t, qtd_list_entry);
12621+ urb = qtd->urb;
12622+ qh->channel = hc;
12623+ qh->qtd_in_process = qtd;
12624+
12625+ /*
12626+ * Use usb_pipedevice to determine device address. This address is
12627+ * 0 before the SET_ADDRESS command and the correct address afterward.
12628+ */
12629+ hc->dev_addr = usb_pipedevice(urb->pipe);
12630+ hc->ep_num = usb_pipeendpoint(urb->pipe);
12631+
12632+ if (urb->dev->speed == USB_SPEED_LOW) {
12633+ hc->speed = DWC_OTG_EP_SPEED_LOW;
12634+ } else if (urb->dev->speed == USB_SPEED_FULL) {
12635+ hc->speed = DWC_OTG_EP_SPEED_FULL;
12636+ } else {
12637+ hc->speed = DWC_OTG_EP_SPEED_HIGH;
12638+ }
12639+
12640+ hc->max_packet = dwc_max_packet(qh->maxp);
12641+
12642+ hc->xfer_started = 0;
12643+ hc->halt_status = DWC_OTG_HC_XFER_NO_HALT_STATUS;
12644+ hc->error_state = (qtd->error_count > 0);
12645+ hc->halt_on_queue = 0;
12646+ hc->halt_pending = 0;
12647+ hc->requests = 0;
12648+
12649+ /*
12650+ * The following values may be modified in the transfer type section
12651+ * below. The xfer_len value may be reduced when the transfer is
12652+ * started to accommodate the max widths of the XferSize and PktCnt
12653+ * fields in the HCTSIZn register.
12654+ */
12655+ hc->do_ping = qh->ping_state;
12656+ hc->ep_is_in = (usb_pipein(urb->pipe) != 0);
12657+ hc->data_pid_start = qh->data_toggle;
12658+ hc->multi_count = 1;
12659+
12660+ if (hcd->core_if->dma_enable) {
12661+ hc->xfer_buff = (uint8_t *)urb->transfer_dma + urb->actual_length;
12662+ } else {
12663+ hc->xfer_buff = (uint8_t *)urb->transfer_buffer + urb->actual_length;
12664+ }
12665+ hc->xfer_len = urb->transfer_buffer_length - urb->actual_length;
12666+ hc->xfer_count = 0;
12667+
12668+ /*
12669+ * Set the split attributes
12670+ */
12671+ hc->do_split = 0;
12672+ if (qh->do_split) {
12673+ hc->do_split = 1;
12674+ hc->xact_pos = qtd->isoc_split_pos;
12675+ hc->complete_split = qtd->complete_split;
12676+ hc->hub_addr = urb->dev->tt->hub->devnum;
12677+ hc->port_addr = urb->dev->ttport;
12678+ }
12679+
12680+ switch (usb_pipetype(urb->pipe)) {
12681+ case PIPE_CONTROL:
12682+ hc->ep_type = DWC_OTG_EP_TYPE_CONTROL;
12683+ switch (qtd->control_phase) {
12684+ case DWC_OTG_CONTROL_SETUP:
12685+ DWC_DEBUGPL(DBG_HCDV, " Control setup transaction\n");
12686+ hc->do_ping = 0;
12687+ hc->ep_is_in = 0;
12688+ hc->data_pid_start = DWC_OTG_HC_PID_SETUP;
12689+ if (hcd->core_if->dma_enable) {
12690+ hc->xfer_buff = (uint8_t *)urb->setup_dma;
12691+ } else {
12692+ hc->xfer_buff = (uint8_t *)urb->setup_packet;
12693+ }
12694+ hc->xfer_len = 8;
12695+ break;
12696+ case DWC_OTG_CONTROL_DATA:
12697+ DWC_DEBUGPL(DBG_HCDV, " Control data transaction\n");
12698+ hc->data_pid_start = qtd->data_toggle;
12699+ break;
12700+ case DWC_OTG_CONTROL_STATUS:
12701+ /*
12702+ * Direction is opposite of data direction or IN if no
12703+ * data.
12704+ */
12705+ DWC_DEBUGPL(DBG_HCDV, " Control status transaction\n");
12706+ if (urb->transfer_buffer_length == 0) {
12707+ hc->ep_is_in = 1;
12708+ } else {
12709+ hc->ep_is_in = (usb_pipein(urb->pipe) != USB_DIR_IN);
12710+ }
12711+ if (hc->ep_is_in) {
12712+ hc->do_ping = 0;
12713+ }
12714+ hc->data_pid_start = DWC_OTG_HC_PID_DATA1;
12715+ hc->xfer_len = 0;
12716+ if (hcd->core_if->dma_enable) {
12717+ hc->xfer_buff = (uint8_t *)hcd->status_buf_dma;
12718+ } else {
12719+ hc->xfer_buff = (uint8_t *)hcd->status_buf;
12720+ }
12721+ break;
12722+ }
12723+ break;
12724+ case PIPE_BULK:
12725+ hc->ep_type = DWC_OTG_EP_TYPE_BULK;
12726+ break;
12727+ case PIPE_INTERRUPT:
12728+ hc->ep_type = DWC_OTG_EP_TYPE_INTR;
12729+ break;
12730+ case PIPE_ISOCHRONOUS:
12731+ {
12732+ struct usb_iso_packet_descriptor *frame_desc;
12733+ frame_desc = &urb->iso_frame_desc[qtd->isoc_frame_index];
12734+ hc->ep_type = DWC_OTG_EP_TYPE_ISOC;
12735+ if (hcd->core_if->dma_enable) {
12736+ hc->xfer_buff = (uint8_t *)urb->transfer_dma;
12737+ } else {
12738+ hc->xfer_buff = (uint8_t *)urb->transfer_buffer;
12739+ }
12740+ hc->xfer_buff += frame_desc->offset + qtd->isoc_split_offset;
12741+ hc->xfer_len = frame_desc->length - qtd->isoc_split_offset;
12742+
12743+ if (hc->xact_pos == DWC_HCSPLIT_XACTPOS_ALL) {
12744+ if (hc->xfer_len <= 188) {
12745+ hc->xact_pos = DWC_HCSPLIT_XACTPOS_ALL;
12746+ }
12747+ else {
12748+ hc->xact_pos = DWC_HCSPLIT_XACTPOS_BEGIN;
12749+ }
12750+ }
12751+ }
12752+ break;
12753+ }
12754+
12755+ if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
12756+ hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
12757+ /*
12758+ * This value may be modified when the transfer is started to
12759+ * reflect the actual transfer length.
12760+ */
12761+ hc->multi_count = dwc_hb_mult(qh->maxp);
12762+ }
12763+
12764+ dwc_otg_hc_init(hcd->core_if, hc);
12765+ hc->qh = qh;
12766+}
12767+
12768+/**
12769+ * This function selects transactions from the HCD transfer schedule and
12770+ * assigns them to available host channels. It is called from HCD interrupt
12771+ * handler functions.
12772+ *
12773+ * @param hcd The HCD state structure.
12774+ *
12775+ * @return The types of new transactions that were assigned to host channels.
12776+ */
12777+dwc_otg_transaction_type_e dwc_otg_hcd_select_transactions(dwc_otg_hcd_t *hcd)
12778+{
12779+ struct list_head *qh_ptr;
12780+ dwc_otg_qh_t *qh;
12781+ int num_channels;
12782+ dwc_otg_transaction_type_e ret_val = DWC_OTG_TRANSACTION_NONE;
12783+
12784+#ifdef DEBUG_SOF
12785+ DWC_DEBUGPL(DBG_HCD, " Select Transactions\n");
12786+#endif
12787+
12788+ /* Process entries in the periodic ready list. */
12789+ qh_ptr = hcd->periodic_sched_ready.next;
12790+ while (qh_ptr != &hcd->periodic_sched_ready &&
12791+ !list_empty(&hcd->free_hc_list)) {
12792+
12793+ qh = list_entry(qh_ptr, dwc_otg_qh_t, qh_list_entry);
12794+ assign_and_init_hc(hcd, qh);
12795+
12796+ /*
12797+ * Move the QH from the periodic ready schedule to the
12798+ * periodic assigned schedule.
12799+ */
12800+ qh_ptr = qh_ptr->next;
12801+ list_move(&qh->qh_list_entry, &hcd->periodic_sched_assigned);
12802+
12803+ ret_val = DWC_OTG_TRANSACTION_PERIODIC;
12804+ }
12805+
12806+ /*
12807+ * Process entries in the inactive portion of the non-periodic
12808+ * schedule. Some free host channels may not be used if they are
12809+ * reserved for periodic transfers.
12810+ */
12811+ qh_ptr = hcd->non_periodic_sched_inactive.next;
12812+ num_channels = hcd->core_if->core_params->host_channels;
12813+ while (qh_ptr != &hcd->non_periodic_sched_inactive &&
12814+ (hcd->non_periodic_channels <
12815+ num_channels - hcd->periodic_channels) &&
12816+ !list_empty(&hcd->free_hc_list)) {
12817+
12818+ qh = list_entry(qh_ptr, dwc_otg_qh_t, qh_list_entry);
12819+ assign_and_init_hc(hcd, qh);
12820+
12821+ /*
12822+ * Move the QH from the non-periodic inactive schedule to the
12823+ * non-periodic active schedule.
12824+ */
12825+ qh_ptr = qh_ptr->next;
12826+ list_move(&qh->qh_list_entry, &hcd->non_periodic_sched_active);
12827+
12828+ if (ret_val == DWC_OTG_TRANSACTION_NONE) {
12829+ ret_val = DWC_OTG_TRANSACTION_NON_PERIODIC;
12830+ } else {
12831+ ret_val = DWC_OTG_TRANSACTION_ALL;
12832+ }
12833+
12834+ hcd->non_periodic_channels++;
12835+ }
12836+
12837+ return ret_val;
12838+}
12839+
12840+/**
12841+ * Attempts to queue a single transaction request for a host channel
12842+ * associated with either a periodic or non-periodic transfer. This function
12843+ * assumes that there is space available in the appropriate request queue. For
12844+ * an OUT transfer or SETUP transaction in Slave mode, it checks whether space
12845+ * is available in the appropriate Tx FIFO.
12846+ *
12847+ * @param hcd The HCD state structure.
12848+ * @param hc Host channel descriptor associated with either a periodic or
12849+ * non-periodic transfer.
12850+ * @param fifo_dwords_avail Number of DWORDs available in the periodic Tx
12851+ * FIFO for periodic transfers or the non-periodic Tx FIFO for non-periodic
12852+ * transfers.
12853+ *
12854+ * @return 1 if a request is queued and more requests may be needed to
12855+ * complete the transfer, 0 if no more requests are required for this
12856+ * transfer, -1 if there is insufficient space in the Tx FIFO.
12857+ */
12858+static int queue_transaction(dwc_otg_hcd_t *hcd,
12859+ dwc_hc_t *hc,
12860+ uint16_t fifo_dwords_avail)
12861+{
12862+ int retval;
12863+
12864+ if (hcd->core_if->dma_enable) {
12865+ if (!hc->xfer_started) {
12866+ dwc_otg_hc_start_transfer(hcd->core_if, hc);
12867+ hc->qh->ping_state = 0;
12868+ }
12869+ retval = 0;
12870+ } else if (hc->halt_pending) {
12871+ /* Don't queue a request if the channel has been halted. */
12872+ retval = 0;
12873+ } else if (hc->halt_on_queue) {
12874+ dwc_otg_hc_halt(hcd->core_if, hc, hc->halt_status);
12875+ retval = 0;
12876+ } else if (hc->do_ping) {
12877+ if (!hc->xfer_started) {
12878+ dwc_otg_hc_start_transfer(hcd->core_if, hc);
12879+ }
12880+ retval = 0;
12881+ } else if (!hc->ep_is_in ||
12882+ hc->data_pid_start == DWC_OTG_HC_PID_SETUP) {
12883+ if ((fifo_dwords_avail * 4) >= hc->max_packet) {
12884+ if (!hc->xfer_started) {
12885+ dwc_otg_hc_start_transfer(hcd->core_if, hc);
12886+ retval = 1;
12887+ } else {
12888+ retval = dwc_otg_hc_continue_transfer(hcd->core_if, hc);
12889+ }
12890+ } else {
12891+ retval = -1;
12892+ }
12893+ } else {
12894+ if (!hc->xfer_started) {
12895+ dwc_otg_hc_start_transfer(hcd->core_if, hc);
12896+ retval = 1;
12897+ } else {
12898+ retval = dwc_otg_hc_continue_transfer(hcd->core_if, hc);
12899+ }
12900+ }
12901+
12902+ return retval;
12903+}
12904+
12905+/**
12906+ * Processes active non-periodic channels and queues transactions for these
12907+ * channels to the DWC_otg controller. After queueing transactions, the NP Tx
12908+ * FIFO Empty interrupt is enabled if there are more transactions to queue as
12909+ * NP Tx FIFO or request queue space becomes available. Otherwise, the NP Tx
12910+ * FIFO Empty interrupt is disabled.
12911+ */
12912+static void process_non_periodic_channels(dwc_otg_hcd_t *hcd)
12913+{
12914+ gnptxsts_data_t tx_status;
12915+ struct list_head *orig_qh_ptr;
12916+ dwc_otg_qh_t *qh;
12917+ int status;
12918+ int no_queue_space = 0;
12919+ int no_fifo_space = 0;
12920+ int more_to_do = 0;
12921+
12922+ dwc_otg_core_global_regs_t *global_regs = hcd->core_if->core_global_regs;
12923+
12924+ DWC_DEBUGPL(DBG_HCDV, "Queue non-periodic transactions\n");
12925+#ifdef DEBUG
12926+ tx_status.d32 = dwc_read_reg32(&global_regs->gnptxsts);
12927+ DWC_DEBUGPL(DBG_HCDV, " NP Tx Req Queue Space Avail (before queue): %d\n",
12928+ tx_status.b.nptxqspcavail);
12929+ DWC_DEBUGPL(DBG_HCDV, " NP Tx FIFO Space Avail (before queue): %d\n",
12930+ tx_status.b.nptxfspcavail);
12931+#endif
12932+ /*
12933+ * Keep track of the starting point. Skip over the start-of-list
12934+ * entry.
12935+ */
12936+ if (hcd->non_periodic_qh_ptr == &hcd->non_periodic_sched_active) {
12937+ hcd->non_periodic_qh_ptr = hcd->non_periodic_qh_ptr->next;
12938+ }
12939+ orig_qh_ptr = hcd->non_periodic_qh_ptr;
12940+
12941+ /*
12942+ * Process once through the active list or until no more space is
12943+ * available in the request queue or the Tx FIFO.
12944+ */
12945+ do {
12946+ tx_status.d32 = dwc_read_reg32(&global_regs->gnptxsts);
12947+ if (!hcd->core_if->dma_enable && tx_status.b.nptxqspcavail == 0) {
12948+ no_queue_space = 1;
12949+ break;
12950+ }
12951+
12952+ qh = list_entry(hcd->non_periodic_qh_ptr, dwc_otg_qh_t, qh_list_entry);
12953+ status = queue_transaction(hcd, qh->channel, tx_status.b.nptxfspcavail);
12954+
12955+ if (status > 0) {
12956+ more_to_do = 1;
12957+ } else if (status < 0) {
12958+ no_fifo_space = 1;
12959+ break;
12960+ }
12961+
12962+ /* Advance to next QH, skipping start-of-list entry. */
12963+ hcd->non_periodic_qh_ptr = hcd->non_periodic_qh_ptr->next;
12964+ if (hcd->non_periodic_qh_ptr == &hcd->non_periodic_sched_active) {
12965+ hcd->non_periodic_qh_ptr = hcd->non_periodic_qh_ptr->next;
12966+ }
12967+
12968+ } while (hcd->non_periodic_qh_ptr != orig_qh_ptr);
12969+
12970+ if (!hcd->core_if->dma_enable) {
12971+ gintmsk_data_t intr_mask = {.d32 = 0};
12972+ intr_mask.b.nptxfempty = 1;
12973+
12974+#ifdef DEBUG
12975+ tx_status.d32 = dwc_read_reg32(&global_regs->gnptxsts);
12976+ DWC_DEBUGPL(DBG_HCDV, " NP Tx Req Queue Space Avail (after queue): %d\n",
12977+ tx_status.b.nptxqspcavail);
12978+ DWC_DEBUGPL(DBG_HCDV, " NP Tx FIFO Space Avail (after queue): %d\n",
12979+ tx_status.b.nptxfspcavail);
12980+#endif
12981+ if (more_to_do || no_queue_space || no_fifo_space) {
12982+ /*
12983+ * May need to queue more transactions as the request
12984+ * queue or Tx FIFO empties. Enable the non-periodic
12985+ * Tx FIFO empty interrupt. (Always use the half-empty
12986+ * level to ensure that new requests are loaded as
12987+ * soon as possible.)
12988+ */
12989+ dwc_modify_reg32(&global_regs->gintmsk, 0, intr_mask.d32);
12990+ } else {
12991+ /*
12992+ * Disable the Tx FIFO empty interrupt since there are
12993+ * no more transactions that need to be queued right
12994+ * now. This function is called from interrupt
12995+ * handlers to queue more transactions as transfer
12996+ * states change.
12997+ */
12998+ dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, 0);
12999+ }
13000+ }
13001+}
13002+
13003+/**
13004+ * Processes periodic channels for the next frame and queues transactions for
13005+ * these channels to the DWC_otg controller. After queueing transactions, the
13006+ * Periodic Tx FIFO Empty interrupt is enabled if there are more transactions
13007+ * to queue as Periodic Tx FIFO or request queue space becomes available.
13008+ * Otherwise, the Periodic Tx FIFO Empty interrupt is disabled.
13009+ */
13010+static void process_periodic_channels(dwc_otg_hcd_t *hcd)
13011+{
13012+ hptxsts_data_t tx_status;
13013+ struct list_head *qh_ptr;
13014+ dwc_otg_qh_t *qh;
13015+ int status;
13016+ int no_queue_space = 0;
13017+ int no_fifo_space = 0;
13018+
13019+ dwc_otg_host_global_regs_t *host_regs;
13020+ host_regs = hcd->core_if->host_if->host_global_regs;
13021+
13022+ DWC_DEBUGPL(DBG_HCDV, "Queue periodic transactions\n");
13023+#ifdef DEBUG
13024+ tx_status.d32 = dwc_read_reg32(&host_regs->hptxsts);
13025+ DWC_DEBUGPL(DBG_HCDV, " P Tx Req Queue Space Avail (before queue): %d\n",
13026+ tx_status.b.ptxqspcavail);
13027+ DWC_DEBUGPL(DBG_HCDV, " P Tx FIFO Space Avail (before queue): %d\n",
13028+ tx_status.b.ptxfspcavail);
13029+#endif
13030+
13031+ qh_ptr = hcd->periodic_sched_assigned.next;
13032+ while (qh_ptr != &hcd->periodic_sched_assigned) {
13033+ tx_status.d32 = dwc_read_reg32(&host_regs->hptxsts);
13034+ if (tx_status.b.ptxqspcavail == 0) {
13035+ no_queue_space = 1;
13036+ break;
13037+ }
13038+
13039+ qh = list_entry(qh_ptr, dwc_otg_qh_t, qh_list_entry);
13040+
13041+ /*
13042+ * Set a flag if we're queuing high-bandwidth in slave mode.
13043+ * The flag prevents any halts to get into the request queue in
13044+ * the middle of multiple high-bandwidth packets getting queued.
13045+ */
13046+ if (!hcd->core_if->dma_enable &&
13047+ qh->channel->multi_count > 1)
13048+ {
13049+ hcd->core_if->queuing_high_bandwidth = 1;
13050+ }
13051+
13052+ status = queue_transaction(hcd, qh->channel, tx_status.b.ptxfspcavail);
13053+ if (status < 0) {
13054+ no_fifo_space = 1;
13055+ break;
13056+ }
13057+
13058+ /*
13059+ * In Slave mode, stay on the current transfer until there is
13060+ * nothing more to do or the high-bandwidth request count is
13061+ * reached. In DMA mode, only need to queue one request. The
13062+ * controller automatically handles multiple packets for
13063+ * high-bandwidth transfers.
13064+ */
13065+ if (hcd->core_if->dma_enable || status == 0 ||
13066+ qh->channel->requests == qh->channel->multi_count) {
13067+ qh_ptr = qh_ptr->next;
13068+ /*
13069+ * Move the QH from the periodic assigned schedule to
13070+ * the periodic queued schedule.
13071+ */
13072+ list_move(&qh->qh_list_entry, &hcd->periodic_sched_queued);
13073+
13074+ /* done queuing high bandwidth */
13075+ hcd->core_if->queuing_high_bandwidth = 0;
13076+ }
13077+ }
13078+
13079+ if (!hcd->core_if->dma_enable) {
13080+ dwc_otg_core_global_regs_t *global_regs;
13081+ gintmsk_data_t intr_mask = {.d32 = 0};
13082+
13083+ global_regs = hcd->core_if->core_global_regs;
13084+ intr_mask.b.ptxfempty = 1;
13085+#ifdef DEBUG
13086+ tx_status.d32 = dwc_read_reg32(&host_regs->hptxsts);
13087+ DWC_DEBUGPL(DBG_HCDV, " P Tx Req Queue Space Avail (after queue): %d\n",
13088+ tx_status.b.ptxqspcavail);
13089+ DWC_DEBUGPL(DBG_HCDV, " P Tx FIFO Space Avail (after queue): %d\n",
13090+ tx_status.b.ptxfspcavail);
13091+#endif
13092+ if (!list_empty(&hcd->periodic_sched_assigned) ||
13093+ no_queue_space || no_fifo_space) {
13094+ /*
13095+ * May need to queue more transactions as the request
13096+ * queue or Tx FIFO empties. Enable the periodic Tx
13097+ * FIFO empty interrupt. (Always use the half-empty
13098+ * level to ensure that new requests are loaded as
13099+ * soon as possible.)
13100+ */
13101+ dwc_modify_reg32(&global_regs->gintmsk, 0, intr_mask.d32);
13102+ } else {
13103+ /*
13104+ * Disable the Tx FIFO empty interrupt since there are
13105+ * no more transactions that need to be queued right
13106+ * now. This function is called from interrupt
13107+ * handlers to queue more transactions as transfer
13108+ * states change.
13109+ */
13110+ dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, 0);
13111+ }
13112+ }
13113+}
13114+
13115+/**
13116+ * This function processes the currently active host channels and queues
13117+ * transactions for these channels to the DWC_otg controller. It is called
13118+ * from HCD interrupt handler functions.
13119+ *
13120+ * @param hcd The HCD state structure.
13121+ * @param tr_type The type(s) of transactions to queue (non-periodic,
13122+ * periodic, or both).
13123+ */
13124+void dwc_otg_hcd_queue_transactions(dwc_otg_hcd_t *hcd,
13125+ dwc_otg_transaction_type_e tr_type)
13126+{
13127+#ifdef DEBUG_SOF
13128+ DWC_DEBUGPL(DBG_HCD, "Queue Transactions\n");
13129+#endif
13130+ /* Process host channels associated with periodic transfers. */
13131+ if ((tr_type == DWC_OTG_TRANSACTION_PERIODIC ||
13132+ tr_type == DWC_OTG_TRANSACTION_ALL) &&
13133+ !list_empty(&hcd->periodic_sched_assigned)) {
13134+
13135+ process_periodic_channels(hcd);
13136+ }
13137+
13138+ /* Process host channels associated with non-periodic transfers. */
13139+ if (tr_type == DWC_OTG_TRANSACTION_NON_PERIODIC ||
13140+ tr_type == DWC_OTG_TRANSACTION_ALL) {
13141+ if (!list_empty(&hcd->non_periodic_sched_active)) {
13142+ process_non_periodic_channels(hcd);
13143+ } else {
13144+ /*
13145+ * Ensure NP Tx FIFO empty interrupt is disabled when
13146+ * there are no non-periodic transfers to process.
13147+ */
13148+ gintmsk_data_t gintmsk = {.d32 = 0};
13149+ gintmsk.b.nptxfempty = 1;
13150+ dwc_modify_reg32(&hcd->core_if->core_global_regs->gintmsk,
13151+ gintmsk.d32, 0);
13152+ }
13153+ }
13154+}
13155+
13156+/**
13157+ * Sets the final status of an URB and returns it to the device driver. Any
13158+ * required cleanup of the URB is performed.
13159+ */
13160+void dwc_otg_hcd_complete_urb(dwc_otg_hcd_t *hcd, struct urb *urb, int status)
13161+{
13162+#ifdef DEBUG
13163+ if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
13164+ DWC_PRINT("%s: urb %p, device %d, ep %d %s, status=%d\n",
13165+ __func__, urb, usb_pipedevice(urb->pipe),
13166+ usb_pipeendpoint(urb->pipe),
13167+ usb_pipein(urb->pipe) ? "IN" : "OUT", status);
13168+ if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
13169+ int i;
13170+ for (i = 0; i < urb->number_of_packets; i++) {
13171+ DWC_PRINT(" ISO Desc %d status: %d\n",
13172+ i, urb->iso_frame_desc[i].status);
13173+ }
13174+ }
13175+ }
13176+#endif
13177+
13178+ //if we use the aligned buffer instead of the original unaligned buffer,
13179+ //for IN data, we have to move the data to the original buffer
13180+ if((urb->transfer_dma==urb->aligned_transfer_dma)&&((urb->transfer_flags & URB_DIR_MASK)==URB_DIR_IN)){
13181+ dma_sync_single_for_device(NULL,urb->transfer_dma,urb->actual_length,DMA_FROM_DEVICE);
13182+ memcpy(urb->transfer_buffer,urb->aligned_transfer_buffer,urb->actual_length);
13183+ }
13184+
13185+
13186+ urb->status = status;
13187+ urb->hcpriv = NULL;
13188+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
13189+ usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(hcd), urb, status);
13190+#else
13191+ usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(hcd), urb, NULL);
13192+#endif
13193+}
13194+
13195+/*
13196+ * Returns the Queue Head for an URB.
13197+ */
13198+dwc_otg_qh_t *dwc_urb_to_qh(struct urb *urb)
13199+{
13200+ struct usb_host_endpoint *ep = dwc_urb_to_endpoint(urb);
13201+ return (dwc_otg_qh_t *)ep->hcpriv;
13202+}
13203+
13204+#ifdef DEBUG
13205+void dwc_print_setup_data(uint8_t *setup)
13206+{
13207+ int i;
13208+ if (CHK_DEBUG_LEVEL(DBG_HCD)){
13209+ DWC_PRINT("Setup Data = MSB ");
13210+ for (i = 7; i >= 0; i--) DWC_PRINT("%02x ", setup[i]);
13211+ DWC_PRINT("\n");
13212+ DWC_PRINT(" bmRequestType Tranfer = %s\n", (setup[0] & 0x80) ? "Device-to-Host" : "Host-to-Device");
13213+ DWC_PRINT(" bmRequestType Type = ");
13214+ switch ((setup[0] & 0x60) >> 5) {
13215+ case 0: DWC_PRINT("Standard\n"); break;
13216+ case 1: DWC_PRINT("Class\n"); break;
13217+ case 2: DWC_PRINT("Vendor\n"); break;
13218+ case 3: DWC_PRINT("Reserved\n"); break;
13219+ }
13220+ DWC_PRINT(" bmRequestType Recipient = ");
13221+ switch (setup[0] & 0x1f) {
13222+ case 0: DWC_PRINT("Device\n"); break;
13223+ case 1: DWC_PRINT("Interface\n"); break;
13224+ case 2: DWC_PRINT("Endpoint\n"); break;
13225+ case 3: DWC_PRINT("Other\n"); break;
13226+ default: DWC_PRINT("Reserved\n"); break;
13227+ }
13228+ DWC_PRINT(" bRequest = 0x%0x\n", setup[1]);
13229+ DWC_PRINT(" wValue = 0x%0x\n", *((uint16_t *)&setup[2]));
13230+ DWC_PRINT(" wIndex = 0x%0x\n", *((uint16_t *)&setup[4]));
13231+ DWC_PRINT(" wLength = 0x%0x\n\n", *((uint16_t *)&setup[6]));
13232+ }
13233+}
13234+#endif
13235+
13236+void dwc_otg_hcd_dump_frrem(dwc_otg_hcd_t *hcd) {
13237+#if defined(DEBUG) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
13238+ DWC_PRINT("Frame remaining at SOF:\n");
13239+ DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
13240+ hcd->frrem_samples, hcd->frrem_accum,
13241+ (hcd->frrem_samples > 0) ?
13242+ hcd->frrem_accum/hcd->frrem_samples : 0);
13243+
13244+ DWC_PRINT("\n");
13245+ DWC_PRINT("Frame remaining at start_transfer (uframe 7):\n");
13246+ DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
13247+ hcd->core_if->hfnum_7_samples, hcd->core_if->hfnum_7_frrem_accum,
13248+ (hcd->core_if->hfnum_7_samples > 0) ?
13249+ hcd->core_if->hfnum_7_frrem_accum/hcd->core_if->hfnum_7_samples : 0);
13250+ DWC_PRINT("Frame remaining at start_transfer (uframe 0):\n");
13251+ DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
13252+ hcd->core_if->hfnum_0_samples, hcd->core_if->hfnum_0_frrem_accum,
13253+ (hcd->core_if->hfnum_0_samples > 0) ?
13254+ hcd->core_if->hfnum_0_frrem_accum/hcd->core_if->hfnum_0_samples : 0);
13255+ DWC_PRINT("Frame remaining at start_transfer (uframe 1-6):\n");
13256+ DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
13257+ hcd->core_if->hfnum_other_samples, hcd->core_if->hfnum_other_frrem_accum,
13258+ (hcd->core_if->hfnum_other_samples > 0) ?
13259+ hcd->core_if->hfnum_other_frrem_accum/hcd->core_if->hfnum_other_samples : 0);
13260+
13261+ DWC_PRINT("\n");
13262+ DWC_PRINT("Frame remaining at sample point A (uframe 7):\n");
13263+ DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
13264+ hcd->hfnum_7_samples_a, hcd->hfnum_7_frrem_accum_a,
13265+ (hcd->hfnum_7_samples_a > 0) ?
13266+ hcd->hfnum_7_frrem_accum_a/hcd->hfnum_7_samples_a : 0);
13267+ DWC_PRINT("Frame remaining at sample point A (uframe 0):\n");
13268+ DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
13269+ hcd->hfnum_0_samples_a, hcd->hfnum_0_frrem_accum_a,
13270+ (hcd->hfnum_0_samples_a > 0) ?
13271+ hcd->hfnum_0_frrem_accum_a/hcd->hfnum_0_samples_a : 0);
13272+ DWC_PRINT("Frame remaining at sample point A (uframe 1-6):\n");
13273+ DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
13274+ hcd->hfnum_other_samples_a, hcd->hfnum_other_frrem_accum_a,
13275+ (hcd->hfnum_other_samples_a > 0) ?
13276+ hcd->hfnum_other_frrem_accum_a/hcd->hfnum_other_samples_a : 0);
13277+
13278+ DWC_PRINT("\n");
13279+ DWC_PRINT("Frame remaining at sample point B (uframe 7):\n");
13280+ DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
13281+ hcd->hfnum_7_samples_b, hcd->hfnum_7_frrem_accum_b,
13282+ (hcd->hfnum_7_samples_b > 0) ?
13283+ hcd->hfnum_7_frrem_accum_b/hcd->hfnum_7_samples_b : 0);
13284+ DWC_PRINT("Frame remaining at sample point B (uframe 0):\n");
13285+ DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
13286+ hcd->hfnum_0_samples_b, hcd->hfnum_0_frrem_accum_b,
13287+ (hcd->hfnum_0_samples_b > 0) ?
13288+ hcd->hfnum_0_frrem_accum_b/hcd->hfnum_0_samples_b : 0);
13289+ DWC_PRINT("Frame remaining at sample point B (uframe 1-6):\n");
13290+ DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
13291+ hcd->hfnum_other_samples_b, hcd->hfnum_other_frrem_accum_b,
13292+ (hcd->hfnum_other_samples_b > 0) ?
13293+ hcd->hfnum_other_frrem_accum_b/hcd->hfnum_other_samples_b : 0);
13294+#endif
13295+}
13296+
13297+void dwc_otg_hcd_dump_state(dwc_otg_hcd_t *hcd)
13298+{
13299+#ifdef DEBUG
13300+ int num_channels;
13301+ int i;
13302+ gnptxsts_data_t np_tx_status;
13303+ hptxsts_data_t p_tx_status;
13304+
13305+ num_channels = hcd->core_if->core_params->host_channels;
13306+ DWC_PRINT("\n");
13307+ DWC_PRINT("************************************************************\n");
13308+ DWC_PRINT("HCD State:\n");
13309+ DWC_PRINT(" Num channels: %d\n", num_channels);
13310+ for (i = 0; i < num_channels; i++) {
13311+ dwc_hc_t *hc = hcd->hc_ptr_array[i];
13312+ DWC_PRINT(" Channel %d:\n", i);
13313+ DWC_PRINT(" dev_addr: %d, ep_num: %d, ep_is_in: %d\n",
13314+ hc->dev_addr, hc->ep_num, hc->ep_is_in);
13315+ DWC_PRINT(" speed: %d\n", hc->speed);
13316+ DWC_PRINT(" ep_type: %d\n", hc->ep_type);
13317+ DWC_PRINT(" max_packet: %d\n", hc->max_packet);
13318+ DWC_PRINT(" data_pid_start: %d\n", hc->data_pid_start);
13319+ DWC_PRINT(" multi_count: %d\n", hc->multi_count);
13320+ DWC_PRINT(" xfer_started: %d\n", hc->xfer_started);
13321+ DWC_PRINT(" xfer_buff: %p\n", hc->xfer_buff);
13322+ DWC_PRINT(" xfer_len: %d\n", hc->xfer_len);
13323+ DWC_PRINT(" xfer_count: %d\n", hc->xfer_count);
13324+ DWC_PRINT(" halt_on_queue: %d\n", hc->halt_on_queue);
13325+ DWC_PRINT(" halt_pending: %d\n", hc->halt_pending);
13326+ DWC_PRINT(" halt_status: %d\n", hc->halt_status);
13327+ DWC_PRINT(" do_split: %d\n", hc->do_split);
13328+ DWC_PRINT(" complete_split: %d\n", hc->complete_split);
13329+ DWC_PRINT(" hub_addr: %d\n", hc->hub_addr);
13330+ DWC_PRINT(" port_addr: %d\n", hc->port_addr);
13331+ DWC_PRINT(" xact_pos: %d\n", hc->xact_pos);
13332+ DWC_PRINT(" requests: %d\n", hc->requests);
13333+ DWC_PRINT(" qh: %p\n", hc->qh);
13334+ if (hc->xfer_started) {
13335+ hfnum_data_t hfnum;
13336+ hcchar_data_t hcchar;
13337+ hctsiz_data_t hctsiz;
13338+ hcint_data_t hcint;
13339+ hcintmsk_data_t hcintmsk;
13340+ hfnum.d32 = dwc_read_reg32(&hcd->core_if->host_if->host_global_regs->hfnum);
13341+ hcchar.d32 = dwc_read_reg32(&hcd->core_if->host_if->hc_regs[i]->hcchar);
13342+ hctsiz.d32 = dwc_read_reg32(&hcd->core_if->host_if->hc_regs[i]->hctsiz);
13343+ hcint.d32 = dwc_read_reg32(&hcd->core_if->host_if->hc_regs[i]->hcint);
13344+ hcintmsk.d32 = dwc_read_reg32(&hcd->core_if->host_if->hc_regs[i]->hcintmsk);
13345+ DWC_PRINT(" hfnum: 0x%08x\n", hfnum.d32);
13346+ DWC_PRINT(" hcchar: 0x%08x\n", hcchar.d32);
13347+ DWC_PRINT(" hctsiz: 0x%08x\n", hctsiz.d32);
13348+ DWC_PRINT(" hcint: 0x%08x\n", hcint.d32);
13349+ DWC_PRINT(" hcintmsk: 0x%08x\n", hcintmsk.d32);
13350+ }
13351+ if (hc->xfer_started && hc->qh && hc->qh->qtd_in_process) {
13352+ dwc_otg_qtd_t *qtd;
13353+ struct urb *urb;
13354+ qtd = hc->qh->qtd_in_process;
13355+ urb = qtd->urb;
13356+ DWC_PRINT(" URB Info:\n");
13357+ DWC_PRINT(" qtd: %p, urb: %p\n", qtd, urb);
13358+ if (urb) {
13359+ DWC_PRINT(" Dev: %d, EP: %d %s\n",
13360+ usb_pipedevice(urb->pipe), usb_pipeendpoint(urb->pipe),
13361+ usb_pipein(urb->pipe) ? "IN" : "OUT");
13362+ DWC_PRINT(" Max packet size: %d\n",
13363+ usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)));
13364+ DWC_PRINT(" transfer_buffer: %p\n", urb->transfer_buffer);
13365+ DWC_PRINT(" transfer_dma: %p\n", (void *)urb->transfer_dma);
13366+ DWC_PRINT(" transfer_buffer_length: %d\n", urb->transfer_buffer_length);
13367+ DWC_PRINT(" actual_length: %d\n", urb->actual_length);
13368+ }
13369+ }
13370+ }
13371+ DWC_PRINT(" non_periodic_channels: %d\n", hcd->non_periodic_channels);
13372+ DWC_PRINT(" periodic_channels: %d\n", hcd->periodic_channels);
13373+ DWC_PRINT(" periodic_usecs: %d\n", hcd->periodic_usecs);
13374+ np_tx_status.d32 = dwc_read_reg32(&hcd->core_if->core_global_regs->gnptxsts);
13375+ DWC_PRINT(" NP Tx Req Queue Space Avail: %d\n", np_tx_status.b.nptxqspcavail);
13376+ DWC_PRINT(" NP Tx FIFO Space Avail: %d\n", np_tx_status.b.nptxfspcavail);
13377+ p_tx_status.d32 = dwc_read_reg32(&hcd->core_if->host_if->host_global_regs->hptxsts);
13378+ DWC_PRINT(" P Tx Req Queue Space Avail: %d\n", p_tx_status.b.ptxqspcavail);
13379+ DWC_PRINT(" P Tx FIFO Space Avail: %d\n", p_tx_status.b.ptxfspcavail);
13380+ dwc_otg_hcd_dump_frrem(hcd);
13381+ dwc_otg_dump_global_registers(hcd->core_if);
13382+ dwc_otg_dump_host_registers(hcd->core_if);
13383+ DWC_PRINT("************************************************************\n");
13384+ DWC_PRINT("\n");
13385+#endif
13386+}
13387+#endif /* DWC_DEVICE_ONLY */
13388--- /dev/null
13389+++ b/drivers/usb/host/otg/dwc_otg_hcd.h
13390@@ -0,0 +1,663 @@
13391+/* ==========================================================================
13392+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd.h $
13393+ * $Revision: #45 $
13394+ * $Date: 2008/07/15 $
13395+ * $Change: 1064918 $
13396+ *
13397+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
13398+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
13399+ * otherwise expressly agreed to in writing between Synopsys and you.
13400+ *
13401+ * The Software IS NOT an item of Licensed Software or Licensed Product under
13402+ * any End User Software License Agreement or Agreement for Licensed Product
13403+ * with Synopsys or any supplement thereto. You are permitted to use and
13404+ * redistribute this Software in source and binary forms, with or without
13405+ * modification, provided that redistributions of source code must retain this
13406+ * notice. You may not view, use, disclose, copy or distribute this file or
13407+ * any information contained herein except pursuant to this license grant from
13408+ * Synopsys. If you do not agree with this notice, including the disclaimer
13409+ * below, then you are not authorized to use the Software.
13410+ *
13411+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
13412+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
13413+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
13414+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
13415+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
13416+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
13417+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
13418+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
13419+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
13420+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
13421+ * DAMAGE.
13422+ * ========================================================================== */
13423+#ifndef DWC_DEVICE_ONLY
13424+#ifndef __DWC_HCD_H__
13425+#define __DWC_HCD_H__
13426+
13427+#include <linux/list.h>
13428+#include <linux/usb.h>
13429+#include <../drivers/usb/core/hcd.h>
13430+
13431+struct lm_device;
13432+struct dwc_otg_device;
13433+
13434+#include "dwc_otg_cil.h"
13435+
13436+/**
13437+ * @file
13438+ *
13439+ * This file contains the structures, constants, and interfaces for
13440+ * the Host Contoller Driver (HCD).
13441+ *
13442+ * The Host Controller Driver (HCD) is responsible for translating requests
13443+ * from the USB Driver into the appropriate actions on the DWC_otg controller.
13444+ * It isolates the USBD from the specifics of the controller by providing an
13445+ * API to the USBD.
13446+ */
13447+
13448+/**
13449+ * Phases for control transfers.
13450+ */
13451+typedef enum dwc_otg_control_phase {
13452+ DWC_OTG_CONTROL_SETUP,
13453+ DWC_OTG_CONTROL_DATA,
13454+ DWC_OTG_CONTROL_STATUS
13455+} dwc_otg_control_phase_e;
13456+
13457+/** Transaction types. */
13458+typedef enum dwc_otg_transaction_type {
13459+ DWC_OTG_TRANSACTION_NONE,
13460+ DWC_OTG_TRANSACTION_PERIODIC,
13461+ DWC_OTG_TRANSACTION_NON_PERIODIC,
13462+ DWC_OTG_TRANSACTION_ALL
13463+} dwc_otg_transaction_type_e;
13464+
13465+/**
13466+ * A Queue Transfer Descriptor (QTD) holds the state of a bulk, control,
13467+ * interrupt, or isochronous transfer. A single QTD is created for each URB
13468+ * (of one of these types) submitted to the HCD. The transfer associated with
13469+ * a QTD may require one or multiple transactions.
13470+ *
13471+ * A QTD is linked to a Queue Head, which is entered in either the
13472+ * non-periodic or periodic schedule for execution. When a QTD is chosen for
13473+ * execution, some or all of its transactions may be executed. After
13474+ * execution, the state of the QTD is updated. The QTD may be retired if all
13475+ * its transactions are complete or if an error occurred. Otherwise, it
13476+ * remains in the schedule so more transactions can be executed later.
13477+ */
13478+typedef struct dwc_otg_qtd {
13479+ /**
13480+ * Determines the PID of the next data packet for the data phase of
13481+ * control transfers. Ignored for other transfer types.<br>
13482+ * One of the following values:
13483+ * - DWC_OTG_HC_PID_DATA0
13484+ * - DWC_OTG_HC_PID_DATA1
13485+ */
13486+ uint8_t data_toggle;
13487+
13488+ /** Current phase for control transfers (Setup, Data, or Status). */
13489+ dwc_otg_control_phase_e control_phase;
13490+
13491+ /** Keep track of the current split type
13492+ * for FS/LS endpoints on a HS Hub */
13493+ uint8_t complete_split;
13494+
13495+ /** How many bytes transferred during SSPLIT OUT */
13496+ uint32_t ssplit_out_xfer_count;
13497+
13498+ /**
13499+ * Holds the number of bus errors that have occurred for a transaction
13500+ * within this transfer.
13501+ */
13502+ uint8_t error_count;
13503+
13504+ /**
13505+ * Index of the next frame descriptor for an isochronous transfer. A
13506+ * frame descriptor describes the buffer position and length of the
13507+ * data to be transferred in the next scheduled (micro)frame of an
13508+ * isochronous transfer. It also holds status for that transaction.
13509+ * The frame index starts at 0.
13510+ */
13511+ int isoc_frame_index;
13512+
13513+ /** Position of the ISOC split on full/low speed */
13514+ uint8_t isoc_split_pos;
13515+
13516+ /** Position of the ISOC split in the buffer for the current frame */
13517+ uint16_t isoc_split_offset;
13518+
13519+ /** URB for this transfer */
13520+ struct urb *urb;
13521+
13522+ /** This list of QTDs */
13523+ struct list_head qtd_list_entry;
13524+
13525+} dwc_otg_qtd_t;
13526+
13527+/**
13528+ * A Queue Head (QH) holds the static characteristics of an endpoint and
13529+ * maintains a list of transfers (QTDs) for that endpoint. A QH structure may
13530+ * be entered in either the non-periodic or periodic schedule.
13531+ */
13532+typedef struct dwc_otg_qh {
13533+ /**
13534+ * Endpoint type.
13535+ * One of the following values:
13536+ * - USB_ENDPOINT_XFER_CONTROL
13537+ * - USB_ENDPOINT_XFER_ISOC
13538+ * - USB_ENDPOINT_XFER_BULK
13539+ * - USB_ENDPOINT_XFER_INT
13540+ */
13541+ uint8_t ep_type;
13542+ uint8_t ep_is_in;
13543+
13544+ /** wMaxPacketSize Field of Endpoint Descriptor. */
13545+ uint16_t maxp;
13546+
13547+ /**
13548+ * Determines the PID of the next data packet for non-control
13549+ * transfers. Ignored for control transfers.<br>
13550+ * One of the following values:
13551+ * - DWC_OTG_HC_PID_DATA0
13552+ * - DWC_OTG_HC_PID_DATA1
13553+ */
13554+ uint8_t data_toggle;
13555+
13556+ /** Ping state if 1. */
13557+ uint8_t ping_state;
13558+
13559+ /**
13560+ * List of QTDs for this QH.
13561+ */
13562+ struct list_head qtd_list;
13563+
13564+ /** Host channel currently processing transfers for this QH. */
13565+ dwc_hc_t *channel;
13566+
13567+ /** QTD currently assigned to a host channel for this QH. */
13568+ dwc_otg_qtd_t *qtd_in_process;
13569+
13570+ /** Full/low speed endpoint on high-speed hub requires split. */
13571+ uint8_t do_split;
13572+
13573+ /** @name Periodic schedule information */
13574+ /** @{ */
13575+
13576+ /** Bandwidth in microseconds per (micro)frame. */
13577+ uint8_t usecs;
13578+
13579+ /** Interval between transfers in (micro)frames. */
13580+ uint16_t interval;
13581+
13582+ /**
13583+ * (micro)frame to initialize a periodic transfer. The transfer
13584+ * executes in the following (micro)frame.
13585+ */
13586+ uint16_t sched_frame;
13587+
13588+ /** (micro)frame at which last start split was initialized. */
13589+ uint16_t start_split_frame;
13590+
13591+ /** @} */
13592+
13593+ /** Entry for QH in either the periodic or non-periodic schedule. */
13594+ struct list_head qh_list_entry;
13595+} dwc_otg_qh_t;
13596+
13597+/**
13598+ * This structure holds the state of the HCD, including the non-periodic and
13599+ * periodic schedules.
13600+ */
13601+typedef struct dwc_otg_hcd {
13602+ /** The DWC otg device pointer */
13603+ struct dwc_otg_device *otg_dev;
13604+
13605+ /** DWC OTG Core Interface Layer */
13606+ dwc_otg_core_if_t *core_if;
13607+
13608+ /** Internal DWC HCD Flags */
13609+ volatile union dwc_otg_hcd_internal_flags {
13610+ uint32_t d32;
13611+ struct {
13612+ unsigned port_connect_status_change : 1;
13613+ unsigned port_connect_status : 1;
13614+ unsigned port_reset_change : 1;
13615+ unsigned port_enable_change : 1;
13616+ unsigned port_suspend_change : 1;
13617+ unsigned port_over_current_change : 1;
13618+ unsigned reserved : 27;
13619+ } b;
13620+ } flags;
13621+
13622+ /**
13623+ * Inactive items in the non-periodic schedule. This is a list of
13624+ * Queue Heads. Transfers associated with these Queue Heads are not
13625+ * currently assigned to a host channel.
13626+ */
13627+ struct list_head non_periodic_sched_inactive;
13628+
13629+ /**
13630+ * Active items in the non-periodic schedule. This is a list of
13631+ * Queue Heads. Transfers associated with these Queue Heads are
13632+ * currently assigned to a host channel.
13633+ */
13634+ struct list_head non_periodic_sched_active;
13635+
13636+ /**
13637+ * Pointer to the next Queue Head to process in the active
13638+ * non-periodic schedule.
13639+ */
13640+ struct list_head *non_periodic_qh_ptr;
13641+
13642+ /**
13643+ * Inactive items in the periodic schedule. This is a list of QHs for
13644+ * periodic transfers that are _not_ scheduled for the next frame.
13645+ * Each QH in the list has an interval counter that determines when it
13646+ * needs to be scheduled for execution. This scheduling mechanism
13647+ * allows only a simple calculation for periodic bandwidth used (i.e.
13648+ * must assume that all periodic transfers may need to execute in the
13649+ * same frame). However, it greatly simplifies scheduling and should
13650+ * be sufficient for the vast majority of OTG hosts, which need to
13651+ * connect to a small number of peripherals at one time.
13652+ *
13653+ * Items move from this list to periodic_sched_ready when the QH
13654+ * interval counter is 0 at SOF.
13655+ */
13656+ struct list_head periodic_sched_inactive;
13657+
13658+ /**
13659+ * List of periodic QHs that are ready for execution in the next
13660+ * frame, but have not yet been assigned to host channels.
13661+ *
13662+ * Items move from this list to periodic_sched_assigned as host
13663+ * channels become available during the current frame.
13664+ */
13665+ struct list_head periodic_sched_ready;
13666+
13667+ /**
13668+ * List of periodic QHs to be executed in the next frame that are
13669+ * assigned to host channels.
13670+ *
13671+ * Items move from this list to periodic_sched_queued as the
13672+ * transactions for the QH are queued to the DWC_otg controller.
13673+ */
13674+ struct list_head periodic_sched_assigned;
13675+
13676+ /**
13677+ * List of periodic QHs that have been queued for execution.
13678+ *
13679+ * Items move from this list to either periodic_sched_inactive or
13680+ * periodic_sched_ready when the channel associated with the transfer
13681+ * is released. If the interval for the QH is 1, the item moves to
13682+ * periodic_sched_ready because it must be rescheduled for the next
13683+ * frame. Otherwise, the item moves to periodic_sched_inactive.
13684+ */
13685+ struct list_head periodic_sched_queued;
13686+
13687+ /**
13688+ * Total bandwidth claimed so far for periodic transfers. This value
13689+ * is in microseconds per (micro)frame. The assumption is that all
13690+ * periodic transfers may occur in the same (micro)frame.
13691+ */
13692+ uint16_t periodic_usecs;
13693+
13694+ /**
13695+ * Frame number read from the core at SOF. The value ranges from 0 to
13696+ * DWC_HFNUM_MAX_FRNUM.
13697+ */
13698+ uint16_t frame_number;
13699+
13700+ /**
13701+ * Free host channels in the controller. This is a list of
13702+ * dwc_hc_t items.
13703+ */
13704+ struct list_head free_hc_list;
13705+
13706+ /**
13707+ * Number of host channels assigned to periodic transfers. Currently
13708+ * assuming that there is a dedicated host channel for each periodic
13709+ * transaction and at least one host channel available for
13710+ * non-periodic transactions.
13711+ */
13712+ int periodic_channels;
13713+
13714+ /**
13715+ * Number of host channels assigned to non-periodic transfers.
13716+ */
13717+ int non_periodic_channels;
13718+
13719+ /**
13720+ * Array of pointers to the host channel descriptors. Allows accessing
13721+ * a host channel descriptor given the host channel number. This is
13722+ * useful in interrupt handlers.
13723+ */
13724+ dwc_hc_t *hc_ptr_array[MAX_EPS_CHANNELS];
13725+
13726+ /**
13727+ * Buffer to use for any data received during the status phase of a
13728+ * control transfer. Normally no data is transferred during the status
13729+ * phase. This buffer is used as a bit bucket.
13730+ */
13731+ uint8_t *status_buf;
13732+
13733+ /**
13734+ * DMA address for status_buf.
13735+ */
13736+ dma_addr_t status_buf_dma;
13737+#define DWC_OTG_HCD_STATUS_BUF_SIZE 64
13738+
13739+ /**
13740+ * Structure to allow starting the HCD in a non-interrupt context
13741+ * during an OTG role change.
13742+ */
13743+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
13744+ struct work_struct start_work;
13745+#else
13746+ struct delayed_work start_work;
13747+#endif
13748+
13749+ /**
13750+ * Connection timer. An OTG host must display a message if the device
13751+ * does not connect. Started when the VBus power is turned on via
13752+ * sysfs attribute "buspower".
13753+ */
13754+ struct timer_list conn_timer;
13755+
13756+ /* Tasket to do a reset */
13757+ struct tasklet_struct *reset_tasklet;
13758+
13759+ /* */
13760+ spinlock_t lock;
13761+
13762+#ifdef DEBUG
13763+ uint32_t frrem_samples;
13764+ uint64_t frrem_accum;
13765+
13766+ uint32_t hfnum_7_samples_a;
13767+ uint64_t hfnum_7_frrem_accum_a;
13768+ uint32_t hfnum_0_samples_a;
13769+ uint64_t hfnum_0_frrem_accum_a;
13770+ uint32_t hfnum_other_samples_a;
13771+ uint64_t hfnum_other_frrem_accum_a;
13772+
13773+ uint32_t hfnum_7_samples_b;
13774+ uint64_t hfnum_7_frrem_accum_b;
13775+ uint32_t hfnum_0_samples_b;
13776+ uint64_t hfnum_0_frrem_accum_b;
13777+ uint32_t hfnum_other_samples_b;
13778+ uint64_t hfnum_other_frrem_accum_b;
13779+#endif
13780+} dwc_otg_hcd_t;
13781+
13782+/** Gets the dwc_otg_hcd from a struct usb_hcd */
13783+static inline dwc_otg_hcd_t *hcd_to_dwc_otg_hcd(struct usb_hcd *hcd)
13784+{
13785+ return (dwc_otg_hcd_t *)(hcd->hcd_priv);
13786+}
13787+
13788+/** Gets the struct usb_hcd that contains a dwc_otg_hcd_t. */
13789+static inline struct usb_hcd *dwc_otg_hcd_to_hcd(dwc_otg_hcd_t *dwc_otg_hcd)
13790+{
13791+ return container_of((void *)dwc_otg_hcd, struct usb_hcd, hcd_priv);
13792+}
13793+
13794+/** @name HCD Create/Destroy Functions */
13795+/** @{ */
13796+extern int dwc_otg_hcd_init(struct lm_device *lmdev);
13797+extern void dwc_otg_hcd_remove(struct lm_device *lmdev);
13798+/** @} */
13799+
13800+/** @name Linux HC Driver API Functions */
13801+/** @{ */
13802+
13803+extern int dwc_otg_hcd_start(struct usb_hcd *hcd);
13804+extern void dwc_otg_hcd_stop(struct usb_hcd *hcd);
13805+extern int dwc_otg_hcd_get_frame_number(struct usb_hcd *hcd);
13806+extern void dwc_otg_hcd_free(struct usb_hcd *hcd);
13807+extern int dwc_otg_hcd_urb_enqueue(struct usb_hcd *hcd,
13808+ // struct usb_host_endpoint *ep,
13809+ struct urb *urb,
13810+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
13811+ int mem_flags
13812+#else
13813+ gfp_t mem_flags
13814+#endif
13815+ );
13816+extern int dwc_otg_hcd_urb_dequeue(struct usb_hcd *hcd,
13817+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
13818+ struct usb_host_endpoint *ep,
13819+#endif
13820+ struct urb *urb, int status);
13821+extern void dwc_otg_hcd_endpoint_disable(struct usb_hcd *hcd,
13822+ struct usb_host_endpoint *ep);
13823+extern irqreturn_t dwc_otg_hcd_irq(struct usb_hcd *hcd
13824+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
13825+ , struct pt_regs *regs
13826+#endif
13827+ );
13828+extern int dwc_otg_hcd_hub_status_data(struct usb_hcd *hcd,
13829+ char *buf);
13830+extern int dwc_otg_hcd_hub_control(struct usb_hcd *hcd,
13831+ u16 typeReq,
13832+ u16 wValue,
13833+ u16 wIndex,
13834+ char *buf,
13835+ u16 wLength);
13836+
13837+/** @} */
13838+
13839+/** @name Transaction Execution Functions */
13840+/** @{ */
13841+extern dwc_otg_transaction_type_e dwc_otg_hcd_select_transactions(dwc_otg_hcd_t *hcd);
13842+extern void dwc_otg_hcd_queue_transactions(dwc_otg_hcd_t *hcd,
13843+ dwc_otg_transaction_type_e tr_type);
13844+extern void dwc_otg_hcd_complete_urb(dwc_otg_hcd_t *_hcd, struct urb *urb,
13845+ int status);
13846+/** @} */
13847+
13848+/** @name Interrupt Handler Functions */
13849+/** @{ */
13850+extern int32_t dwc_otg_hcd_handle_intr(dwc_otg_hcd_t *dwc_otg_hcd);
13851+extern int32_t dwc_otg_hcd_handle_sof_intr(dwc_otg_hcd_t *dwc_otg_hcd);
13852+extern int32_t dwc_otg_hcd_handle_rx_status_q_level_intr(dwc_otg_hcd_t *dwc_otg_hcd);
13853+extern int32_t dwc_otg_hcd_handle_np_tx_fifo_empty_intr(dwc_otg_hcd_t *dwc_otg_hcd);
13854+extern int32_t dwc_otg_hcd_handle_perio_tx_fifo_empty_intr(dwc_otg_hcd_t *dwc_otg_hcd);
13855+extern int32_t dwc_otg_hcd_handle_incomplete_periodic_intr(dwc_otg_hcd_t *dwc_otg_hcd);
13856+extern int32_t dwc_otg_hcd_handle_port_intr(dwc_otg_hcd_t *dwc_otg_hcd);
13857+extern int32_t dwc_otg_hcd_handle_conn_id_status_change_intr(dwc_otg_hcd_t *dwc_otg_hcd);
13858+extern int32_t dwc_otg_hcd_handle_disconnect_intr(dwc_otg_hcd_t *dwc_otg_hcd);
13859+extern int32_t dwc_otg_hcd_handle_hc_intr(dwc_otg_hcd_t *dwc_otg_hcd);
13860+extern int32_t dwc_otg_hcd_handle_hc_n_intr(dwc_otg_hcd_t *dwc_otg_hcd, uint32_t num);
13861+extern int32_t dwc_otg_hcd_handle_session_req_intr(dwc_otg_hcd_t *dwc_otg_hcd);
13862+extern int32_t dwc_otg_hcd_handle_wakeup_detected_intr(dwc_otg_hcd_t *dwc_otg_hcd);
13863+/** @} */
13864+
13865+
13866+/** @name Schedule Queue Functions */
13867+/** @{ */
13868+
13869+/* Implemented in dwc_otg_hcd_queue.c */
13870+extern dwc_otg_qh_t *dwc_otg_hcd_qh_create(dwc_otg_hcd_t *hcd, struct urb *urb);
13871+extern void dwc_otg_hcd_qh_init(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh, struct urb *urb);
13872+extern void dwc_otg_hcd_qh_free(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh);
13873+extern int dwc_otg_hcd_qh_add(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh);
13874+extern void dwc_otg_hcd_qh_remove(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh);
13875+extern void dwc_otg_hcd_qh_deactivate(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh, int sched_csplit);
13876+
13877+/** Remove and free a QH */
13878+static inline void dwc_otg_hcd_qh_remove_and_free(dwc_otg_hcd_t *hcd,
13879+ dwc_otg_qh_t *qh)
13880+{
13881+ dwc_otg_hcd_qh_remove(hcd, qh);
13882+ dwc_otg_hcd_qh_free(hcd, qh);
13883+}
13884+
13885+/** Allocates memory for a QH structure.
13886+ * @return Returns the memory allocate or NULL on error. */
13887+static inline dwc_otg_qh_t *dwc_otg_hcd_qh_alloc(void)
13888+{
13889+ return (dwc_otg_qh_t *) kmalloc(sizeof(dwc_otg_qh_t), GFP_KERNEL);
13890+}
13891+
13892+extern dwc_otg_qtd_t *dwc_otg_hcd_qtd_create(struct urb *urb);
13893+extern void dwc_otg_hcd_qtd_init(dwc_otg_qtd_t *qtd, struct urb *urb);
13894+extern int dwc_otg_hcd_qtd_add(dwc_otg_qtd_t *qtd, dwc_otg_hcd_t *dwc_otg_hcd);
13895+
13896+/** Allocates memory for a QTD structure.
13897+ * @return Returns the memory allocate or NULL on error. */
13898+static inline dwc_otg_qtd_t *dwc_otg_hcd_qtd_alloc(void)
13899+{
13900+ return (dwc_otg_qtd_t *) kmalloc(sizeof(dwc_otg_qtd_t), GFP_KERNEL);
13901+}
13902+
13903+/** Frees the memory for a QTD structure. QTD should already be removed from
13904+ * list.
13905+ * @param[in] qtd QTD to free.*/
13906+static inline void dwc_otg_hcd_qtd_free(dwc_otg_qtd_t *qtd)
13907+{
13908+ kfree(qtd);
13909+}
13910+
13911+/** Removes a QTD from list.
13912+ * @param[in] hcd HCD instance.
13913+ * @param[in] qtd QTD to remove from list. */
13914+static inline void dwc_otg_hcd_qtd_remove(dwc_otg_hcd_t *hcd, dwc_otg_qtd_t *qtd)
13915+{
13916+ unsigned long flags;
13917+ SPIN_LOCK_IRQSAVE(&hcd->lock, flags);
13918+ list_del(&qtd->qtd_list_entry);
13919+ SPIN_UNLOCK_IRQRESTORE(&hcd->lock, flags);
13920+}
13921+
13922+/** Remove and free a QTD */
13923+static inline void dwc_otg_hcd_qtd_remove_and_free(dwc_otg_hcd_t *hcd, dwc_otg_qtd_t *qtd)
13924+{
13925+ dwc_otg_hcd_qtd_remove(hcd, qtd);
13926+ dwc_otg_hcd_qtd_free(qtd);
13927+}
13928+
13929+/** @} */
13930+
13931+
13932+/** @name Internal Functions */
13933+/** @{ */
13934+dwc_otg_qh_t *dwc_urb_to_qh(struct urb *urb);
13935+void dwc_otg_hcd_dump_frrem(dwc_otg_hcd_t *hcd);
13936+void dwc_otg_hcd_dump_state(dwc_otg_hcd_t *hcd);
13937+/** @} */
13938+
13939+/** Gets the usb_host_endpoint associated with an URB. */
13940+static inline struct usb_host_endpoint *dwc_urb_to_endpoint(struct urb *urb)
13941+{
13942+ struct usb_device *dev = urb->dev;
13943+ int ep_num = usb_pipeendpoint(urb->pipe);
13944+
13945+ if (usb_pipein(urb->pipe))
13946+ return dev->ep_in[ep_num];
13947+ else
13948+ return dev->ep_out[ep_num];
13949+}
13950+
13951+/**
13952+ * Gets the endpoint number from a _bEndpointAddress argument. The endpoint is
13953+ * qualified with its direction (possible 32 endpoints per device).
13954+ */
13955+#define dwc_ep_addr_to_endpoint(_bEndpointAddress_) ((_bEndpointAddress_ & USB_ENDPOINT_NUMBER_MASK) | \
13956+ ((_bEndpointAddress_ & USB_DIR_IN) != 0) << 4)
13957+
13958+/** Gets the QH that contains the list_head */
13959+#define dwc_list_to_qh(_list_head_ptr_) container_of(_list_head_ptr_, dwc_otg_qh_t, qh_list_entry)
13960+
13961+/** Gets the QTD that contains the list_head */
13962+#define dwc_list_to_qtd(_list_head_ptr_) container_of(_list_head_ptr_, dwc_otg_qtd_t, qtd_list_entry)
13963+
13964+/** Check if QH is non-periodic */
13965+#define dwc_qh_is_non_per(_qh_ptr_) ((_qh_ptr_->ep_type == USB_ENDPOINT_XFER_BULK) || \
13966+ (_qh_ptr_->ep_type == USB_ENDPOINT_XFER_CONTROL))
13967+
13968+/** High bandwidth multiplier as encoded in highspeed endpoint descriptors */
13969+#define dwc_hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
13970+
13971+/** Packet size for any kind of endpoint descriptor */
13972+#define dwc_max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff)
13973+
13974+/**
13975+ * Returns true if _frame1 is less than or equal to _frame2. The comparison is
13976+ * done modulo DWC_HFNUM_MAX_FRNUM. This accounts for the rollover of the
13977+ * frame number when the max frame number is reached.
13978+ */
13979+static inline int dwc_frame_num_le(uint16_t frame1, uint16_t frame2)
13980+{
13981+ return ((frame2 - frame1) & DWC_HFNUM_MAX_FRNUM) <=
13982+ (DWC_HFNUM_MAX_FRNUM >> 1);
13983+}
13984+
13985+/**
13986+ * Returns true if _frame1 is greater than _frame2. The comparison is done
13987+ * modulo DWC_HFNUM_MAX_FRNUM. This accounts for the rollover of the frame
13988+ * number when the max frame number is reached.
13989+ */
13990+static inline int dwc_frame_num_gt(uint16_t frame1, uint16_t frame2)
13991+{
13992+ return (frame1 != frame2) &&
13993+ (((frame1 - frame2) & DWC_HFNUM_MAX_FRNUM) <
13994+ (DWC_HFNUM_MAX_FRNUM >> 1));
13995+}
13996+
13997+/**
13998+ * Increments _frame by the amount specified by _inc. The addition is done
13999+ * modulo DWC_HFNUM_MAX_FRNUM. Returns the incremented value.
14000+ */
14001+static inline uint16_t dwc_frame_num_inc(uint16_t frame, uint16_t inc)
14002+{
14003+ return (frame + inc) & DWC_HFNUM_MAX_FRNUM;
14004+}
14005+
14006+static inline uint16_t dwc_full_frame_num(uint16_t frame)
14007+{
14008+ return (frame & DWC_HFNUM_MAX_FRNUM) >> 3;
14009+}
14010+
14011+static inline uint16_t dwc_micro_frame_num(uint16_t frame)
14012+{
14013+ return frame & 0x7;
14014+}
14015+
14016+#ifdef DEBUG
14017+/**
14018+ * Macro to sample the remaining PHY clocks left in the current frame. This
14019+ * may be used during debugging to determine the average time it takes to
14020+ * execute sections of code. There are two possible sample points, "a" and
14021+ * "b", so the _letter argument must be one of these values.
14022+ *
14023+ * To dump the average sample times, read the "hcd_frrem" sysfs attribute. For
14024+ * example, "cat /sys/devices/lm0/hcd_frrem".
14025+ */
14026+#define dwc_sample_frrem(_hcd, _qh, _letter) \
14027+{ \
14028+ hfnum_data_t hfnum; \
14029+ dwc_otg_qtd_t *qtd; \
14030+ qtd = list_entry(_qh->qtd_list.next, dwc_otg_qtd_t, qtd_list_entry); \
14031+ if (usb_pipeint(qtd->urb->pipe) && _qh->start_split_frame != 0 && !qtd->complete_split) { \
14032+ hfnum.d32 = dwc_read_reg32(&_hcd->core_if->host_if->host_global_regs->hfnum); \
14033+ switch (hfnum.b.frnum & 0x7) { \
14034+ case 7: \
14035+ _hcd->hfnum_7_samples_##_letter++; \
14036+ _hcd->hfnum_7_frrem_accum_##_letter += hfnum.b.frrem; \
14037+ break; \
14038+ case 0: \
14039+ _hcd->hfnum_0_samples_##_letter++; \
14040+ _hcd->hfnum_0_frrem_accum_##_letter += hfnum.b.frrem; \
14041+ break; \
14042+ default: \
14043+ _hcd->hfnum_other_samples_##_letter++; \
14044+ _hcd->hfnum_other_frrem_accum_##_letter += hfnum.b.frrem; \
14045+ break; \
14046+ } \
14047+ } \
14048+}
14049+#else
14050+#define dwc_sample_frrem(_hcd, _qh, _letter)
14051+#endif
14052+#endif
14053+#endif /* DWC_DEVICE_ONLY */
14054--- /dev/null
14055+++ b/drivers/usb/host/otg/dwc_otg_hcd_intr.c
14056@@ -0,0 +1,1829 @@
14057+/* ==========================================================================
14058+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd_intr.c $
14059+ * $Revision: #70 $
14060+ * $Date: 2008/10/16 $
14061+ * $Change: 1117667 $
14062+ *
14063+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
14064+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
14065+ * otherwise expressly agreed to in writing between Synopsys and you.
14066+ *
14067+ * The Software IS NOT an item of Licensed Software or Licensed Product under
14068+ * any End User Software License Agreement or Agreement for Licensed Product
14069+ * with Synopsys or any supplement thereto. You are permitted to use and
14070+ * redistribute this Software in source and binary forms, with or without
14071+ * modification, provided that redistributions of source code must retain this
14072+ * notice. You may not view, use, disclose, copy or distribute this file or
14073+ * any information contained herein except pursuant to this license grant from
14074+ * Synopsys. If you do not agree with this notice, including the disclaimer
14075+ * below, then you are not authorized to use the Software.
14076+ *
14077+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
14078+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14079+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
14080+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
14081+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
14082+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
14083+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
14084+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
14085+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
14086+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
14087+ * DAMAGE.
14088+ * ========================================================================== */
14089+#ifndef DWC_DEVICE_ONLY
14090+
14091+#include <linux/version.h>
14092+
14093+#include "dwc_otg_driver.h"
14094+#include "dwc_otg_hcd.h"
14095+#include "dwc_otg_regs.h"
14096+
14097+/** @file
14098+ * This file contains the implementation of the HCD Interrupt handlers.
14099+ */
14100+
14101+/** This function handles interrupts for the HCD. */
14102+int32_t dwc_otg_hcd_handle_intr(dwc_otg_hcd_t *dwc_otg_hcd)
14103+{
14104+ int retval = 0;
14105+
14106+ dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
14107+ gintsts_data_t gintsts;
14108+#ifdef DEBUG
14109+ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
14110+#endif
14111+
14112+ /* Check if HOST Mode */
14113+ if (dwc_otg_is_host_mode(core_if)) {
14114+ gintsts.d32 = dwc_otg_read_core_intr(core_if);
14115+ if (!gintsts.d32) {
14116+ return 0;
14117+ }
14118+
14119+#ifdef DEBUG
14120+ /* Don't print debug message in the interrupt handler on SOF */
14121+# ifndef DEBUG_SOF
14122+ if (gintsts.d32 != DWC_SOF_INTR_MASK)
14123+# endif
14124+ DWC_DEBUGPL(DBG_HCD, "\n");
14125+#endif
14126+
14127+#ifdef DEBUG
14128+# ifndef DEBUG_SOF
14129+ if (gintsts.d32 != DWC_SOF_INTR_MASK)
14130+# endif
14131+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Interrupt Detected gintsts&gintmsk=0x%08x\n", gintsts.d32);
14132+#endif
14133+ if (gintsts.b.usbreset) {
14134+ DWC_PRINT("Usb Reset In Host Mode\n");
14135+ }
14136+
14137+
14138+ if (gintsts.b.sofintr) {
14139+ retval |= dwc_otg_hcd_handle_sof_intr(dwc_otg_hcd);
14140+ }
14141+ if (gintsts.b.rxstsqlvl) {
14142+ retval |= dwc_otg_hcd_handle_rx_status_q_level_intr(dwc_otg_hcd);
14143+ }
14144+ if (gintsts.b.nptxfempty) {
14145+ retval |= dwc_otg_hcd_handle_np_tx_fifo_empty_intr(dwc_otg_hcd);
14146+ }
14147+ if (gintsts.b.i2cintr) {
14148+ /** @todo Implement i2cintr handler. */
14149+ }
14150+ if (gintsts.b.portintr) {
14151+ retval |= dwc_otg_hcd_handle_port_intr(dwc_otg_hcd);
14152+ }
14153+ if (gintsts.b.hcintr) {
14154+ retval |= dwc_otg_hcd_handle_hc_intr(dwc_otg_hcd);
14155+ }
14156+ if (gintsts.b.ptxfempty) {
14157+ retval |= dwc_otg_hcd_handle_perio_tx_fifo_empty_intr(dwc_otg_hcd);
14158+ }
14159+#ifdef DEBUG
14160+# ifndef DEBUG_SOF
14161+ if (gintsts.d32 != DWC_SOF_INTR_MASK)
14162+# endif
14163+ {
14164+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Finished Servicing Interrupts\n");
14165+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD gintsts=0x%08x\n",
14166+ dwc_read_reg32(&global_regs->gintsts));
14167+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD gintmsk=0x%08x\n",
14168+ dwc_read_reg32(&global_regs->gintmsk));
14169+ }
14170+#endif
14171+
14172+#ifdef DEBUG
14173+# ifndef DEBUG_SOF
14174+ if (gintsts.d32 != DWC_SOF_INTR_MASK)
14175+# endif
14176+ DWC_DEBUGPL(DBG_HCD, "\n");
14177+#endif
14178+
14179+ }
14180+
14181+ S3C2410X_CLEAR_EINTPEND();
14182+
14183+ return retval;
14184+}
14185+
14186+#ifdef DWC_TRACK_MISSED_SOFS
14187+#warning Compiling code to track missed SOFs
14188+#define FRAME_NUM_ARRAY_SIZE 1000
14189+/**
14190+ * This function is for debug only.
14191+ */
14192+static inline void track_missed_sofs(uint16_t curr_frame_number)
14193+{
14194+ static uint16_t frame_num_array[FRAME_NUM_ARRAY_SIZE];
14195+ static uint16_t last_frame_num_array[FRAME_NUM_ARRAY_SIZE];
14196+ static int frame_num_idx = 0;
14197+ static uint16_t last_frame_num = DWC_HFNUM_MAX_FRNUM;
14198+ static int dumped_frame_num_array = 0;
14199+
14200+ if (frame_num_idx < FRAME_NUM_ARRAY_SIZE) {
14201+ if (((last_frame_num + 1) & DWC_HFNUM_MAX_FRNUM) != curr_frame_number) {
14202+ frame_num_array[frame_num_idx] = curr_frame_number;
14203+ last_frame_num_array[frame_num_idx++] = last_frame_num;
14204+ }
14205+ } else if (!dumped_frame_num_array) {
14206+ int i;
14207+ printk(KERN_EMERG USB_DWC "Frame Last Frame\n");
14208+ printk(KERN_EMERG USB_DWC "----- ----------\n");
14209+ for (i = 0; i < FRAME_NUM_ARRAY_SIZE; i++) {
14210+ printk(KERN_EMERG USB_DWC "0x%04x 0x%04x\n",
14211+ frame_num_array[i], last_frame_num_array[i]);
14212+ }
14213+ dumped_frame_num_array = 1;
14214+ }
14215+ last_frame_num = curr_frame_number;
14216+}
14217+#endif
14218+
14219+/**
14220+ * Handles the start-of-frame interrupt in host mode. Non-periodic
14221+ * transactions may be queued to the DWC_otg controller for the current
14222+ * (micro)frame. Periodic transactions may be queued to the controller for the
14223+ * next (micro)frame.
14224+ */
14225+int32_t dwc_otg_hcd_handle_sof_intr(dwc_otg_hcd_t *hcd)
14226+{
14227+ hfnum_data_t hfnum;
14228+ struct list_head *qh_entry;
14229+ dwc_otg_qh_t *qh;
14230+ dwc_otg_transaction_type_e tr_type;
14231+ gintsts_data_t gintsts = {.d32 = 0};
14232+
14233+ hfnum.d32 = dwc_read_reg32(&hcd->core_if->host_if->host_global_regs->hfnum);
14234+
14235+#ifdef DEBUG_SOF
14236+ DWC_DEBUGPL(DBG_HCD, "--Start of Frame Interrupt--\n");
14237+#endif
14238+ hcd->frame_number = hfnum.b.frnum;
14239+
14240+#ifdef DEBUG
14241+ hcd->frrem_accum += hfnum.b.frrem;
14242+ hcd->frrem_samples++;
14243+#endif
14244+
14245+#ifdef DWC_TRACK_MISSED_SOFS
14246+ track_missed_sofs(hcd->frame_number);
14247+#endif
14248+
14249+ /* Determine whether any periodic QHs should be executed. */
14250+ qh_entry = hcd->periodic_sched_inactive.next;
14251+ while (qh_entry != &hcd->periodic_sched_inactive) {
14252+ qh = list_entry(qh_entry, dwc_otg_qh_t, qh_list_entry);
14253+ qh_entry = qh_entry->next;
14254+ if (dwc_frame_num_le(qh->sched_frame, hcd->frame_number)) {
14255+ /*
14256+ * Move QH to the ready list to be executed next
14257+ * (micro)frame.
14258+ */
14259+ list_move(&qh->qh_list_entry, &hcd->periodic_sched_ready);
14260+ }
14261+ }
14262+
14263+ tr_type = dwc_otg_hcd_select_transactions(hcd);
14264+ if (tr_type != DWC_OTG_TRANSACTION_NONE) {
14265+ dwc_otg_hcd_queue_transactions(hcd, tr_type);
14266+ }
14267+
14268+ /* Clear interrupt */
14269+ gintsts.b.sofintr = 1;
14270+ dwc_write_reg32(&hcd->core_if->core_global_regs->gintsts, gintsts.d32);
14271+
14272+ return 1;
14273+}
14274+
14275+/** Handles the Rx Status Queue Level Interrupt, which indicates that there is at
14276+ * least one packet in the Rx FIFO. The packets are moved from the FIFO to
14277+ * memory if the DWC_otg controller is operating in Slave mode. */
14278+int32_t dwc_otg_hcd_handle_rx_status_q_level_intr(dwc_otg_hcd_t *dwc_otg_hcd)
14279+{
14280+ host_grxsts_data_t grxsts;
14281+ dwc_hc_t *hc = NULL;
14282+
14283+ DWC_DEBUGPL(DBG_HCD, "--RxStsQ Level Interrupt--\n");
14284+
14285+ grxsts.d32 = dwc_read_reg32(&dwc_otg_hcd->core_if->core_global_regs->grxstsp);
14286+
14287+ hc = dwc_otg_hcd->hc_ptr_array[grxsts.b.chnum];
14288+
14289+ /* Packet Status */
14290+ DWC_DEBUGPL(DBG_HCDV, " Ch num = %d\n", grxsts.b.chnum);
14291+ DWC_DEBUGPL(DBG_HCDV, " Count = %d\n", grxsts.b.bcnt);
14292+ DWC_DEBUGPL(DBG_HCDV, " DPID = %d, hc.dpid = %d\n", grxsts.b.dpid, hc->data_pid_start);
14293+ DWC_DEBUGPL(DBG_HCDV, " PStatus = %d\n", grxsts.b.pktsts);
14294+
14295+ switch (grxsts.b.pktsts) {
14296+ case DWC_GRXSTS_PKTSTS_IN:
14297+ /* Read the data into the host buffer. */
14298+ if (grxsts.b.bcnt > 0) {
14299+ dwc_otg_read_packet(dwc_otg_hcd->core_if,
14300+ hc->xfer_buff,
14301+ grxsts.b.bcnt);
14302+
14303+ /* Update the HC fields for the next packet received. */
14304+ hc->xfer_count += grxsts.b.bcnt;
14305+ hc->xfer_buff += grxsts.b.bcnt;
14306+ }
14307+
14308+ case DWC_GRXSTS_PKTSTS_IN_XFER_COMP:
14309+ case DWC_GRXSTS_PKTSTS_DATA_TOGGLE_ERR:
14310+ case DWC_GRXSTS_PKTSTS_CH_HALTED:
14311+ /* Handled in interrupt, just ignore data */
14312+ break;
14313+ default:
14314+ DWC_ERROR("RX_STS_Q Interrupt: Unknown status %d\n", grxsts.b.pktsts);
14315+ break;
14316+ }
14317+
14318+ return 1;
14319+}
14320+
14321+/** This interrupt occurs when the non-periodic Tx FIFO is half-empty. More
14322+ * data packets may be written to the FIFO for OUT transfers. More requests
14323+ * may be written to the non-periodic request queue for IN transfers. This
14324+ * interrupt is enabled only in Slave mode. */
14325+int32_t dwc_otg_hcd_handle_np_tx_fifo_empty_intr(dwc_otg_hcd_t *dwc_otg_hcd)
14326+{
14327+ DWC_DEBUGPL(DBG_HCD, "--Non-Periodic TxFIFO Empty Interrupt--\n");
14328+ dwc_otg_hcd_queue_transactions(dwc_otg_hcd,
14329+ DWC_OTG_TRANSACTION_NON_PERIODIC);
14330+ return 1;
14331+}
14332+
14333+/** This interrupt occurs when the periodic Tx FIFO is half-empty. More data
14334+ * packets may be written to the FIFO for OUT transfers. More requests may be
14335+ * written to the periodic request queue for IN transfers. This interrupt is
14336+ * enabled only in Slave mode. */
14337+int32_t dwc_otg_hcd_handle_perio_tx_fifo_empty_intr(dwc_otg_hcd_t *dwc_otg_hcd)
14338+{
14339+ DWC_DEBUGPL(DBG_HCD, "--Periodic TxFIFO Empty Interrupt--\n");
14340+ dwc_otg_hcd_queue_transactions(dwc_otg_hcd,
14341+ DWC_OTG_TRANSACTION_PERIODIC);
14342+ return 1;
14343+}
14344+
14345+/** There are multiple conditions that can cause a port interrupt. This function
14346+ * determines which interrupt conditions have occurred and handles them
14347+ * appropriately. */
14348+int32_t dwc_otg_hcd_handle_port_intr(dwc_otg_hcd_t *dwc_otg_hcd)
14349+{
14350+ int retval = 0;
14351+ hprt0_data_t hprt0;
14352+ hprt0_data_t hprt0_modify;
14353+
14354+ hprt0.d32 = dwc_read_reg32(dwc_otg_hcd->core_if->host_if->hprt0);
14355+ hprt0_modify.d32 = dwc_read_reg32(dwc_otg_hcd->core_if->host_if->hprt0);
14356+
14357+ /* Clear appropriate bits in HPRT0 to clear the interrupt bit in
14358+ * GINTSTS */
14359+
14360+ hprt0_modify.b.prtena = 0;
14361+ hprt0_modify.b.prtconndet = 0;
14362+ hprt0_modify.b.prtenchng = 0;
14363+ hprt0_modify.b.prtovrcurrchng = 0;
14364+
14365+ /* Port Connect Detected
14366+ * Set flag and clear if detected */
14367+ if (hprt0.b.prtconndet) {
14368+ DWC_DEBUGPL(DBG_HCD, "--Port Interrupt HPRT0=0x%08x "
14369+ "Port Connect Detected--\n", hprt0.d32);
14370+ dwc_otg_hcd->flags.b.port_connect_status_change = 1;
14371+ dwc_otg_hcd->flags.b.port_connect_status = 1;
14372+ hprt0_modify.b.prtconndet = 1;
14373+
14374+ /* B-Device has connected, Delete the connection timer. */
14375+ del_timer( &dwc_otg_hcd->conn_timer );
14376+
14377+ /* The Hub driver asserts a reset when it sees port connect
14378+ * status change flag */
14379+ retval |= 1;
14380+ }
14381+
14382+ /* Port Enable Changed
14383+ * Clear if detected - Set internal flag if disabled */
14384+ if (hprt0.b.prtenchng) {
14385+ DWC_DEBUGPL(DBG_HCD, " --Port Interrupt HPRT0=0x%08x "
14386+ "Port Enable Changed--\n", hprt0.d32);
14387+ hprt0_modify.b.prtenchng = 1;
14388+ if (hprt0.b.prtena == 1) {
14389+ int do_reset = 0;
14390+ dwc_otg_core_params_t *params = dwc_otg_hcd->core_if->core_params;
14391+ dwc_otg_core_global_regs_t *global_regs = dwc_otg_hcd->core_if->core_global_regs;
14392+ dwc_otg_host_if_t *host_if = dwc_otg_hcd->core_if->host_if;
14393+
14394+ /* Check if we need to adjust the PHY clock speed for
14395+ * low power and adjust it */
14396+ if (params->host_support_fs_ls_low_power) {
14397+ gusbcfg_data_t usbcfg;
14398+
14399+ usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
14400+
14401+ if (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_LOW_SPEED ||
14402+ hprt0.b.prtspd == DWC_HPRT0_PRTSPD_FULL_SPEED) {
14403+ /*
14404+ * Low power
14405+ */
14406+ hcfg_data_t hcfg;
14407+ if (usbcfg.b.phylpwrclksel == 0) {
14408+ /* Set PHY low power clock select for FS/LS devices */
14409+ usbcfg.b.phylpwrclksel = 1;
14410+ dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
14411+ do_reset = 1;
14412+ }
14413+
14414+ hcfg.d32 = dwc_read_reg32(&host_if->host_global_regs->hcfg);
14415+
14416+ if (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_LOW_SPEED &&
14417+ params->host_ls_low_power_phy_clk ==
14418+ DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ) {
14419+ /* 6 MHZ */
14420+ DWC_DEBUGPL(DBG_CIL, "FS_PHY programming HCFG to 6 MHz (Low Power)\n");
14421+ if (hcfg.b.fslspclksel != DWC_HCFG_6_MHZ) {
14422+ hcfg.b.fslspclksel = DWC_HCFG_6_MHZ;
14423+ dwc_write_reg32(&host_if->host_global_regs->hcfg,
14424+ hcfg.d32);
14425+ do_reset = 1;
14426+ }
14427+ } else {
14428+ /* 48 MHZ */
14429+ DWC_DEBUGPL(DBG_CIL, "FS_PHY programming HCFG to 48 MHz ()\n");
14430+ if (hcfg.b.fslspclksel != DWC_HCFG_48_MHZ) {
14431+ hcfg.b.fslspclksel = DWC_HCFG_48_MHZ;
14432+ dwc_write_reg32(&host_if->host_global_regs->hcfg,
14433+ hcfg.d32);
14434+ do_reset = 1;
14435+ }
14436+ }
14437+ } else {
14438+ /*
14439+ * Not low power
14440+ */
14441+ if (usbcfg.b.phylpwrclksel == 1) {
14442+ usbcfg.b.phylpwrclksel = 0;
14443+ dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
14444+ do_reset = 1;
14445+ }
14446+ }
14447+
14448+ if (do_reset) {
14449+ tasklet_schedule(dwc_otg_hcd->reset_tasklet);
14450+ }
14451+ }
14452+
14453+ if (!do_reset) {
14454+ /* Port has been enabled set the reset change flag */
14455+ dwc_otg_hcd->flags.b.port_reset_change = 1;
14456+ }
14457+ } else {
14458+ dwc_otg_hcd->flags.b.port_enable_change = 1;
14459+ }
14460+ retval |= 1;
14461+ }
14462+
14463+ /** Overcurrent Change Interrupt */
14464+ if (hprt0.b.prtovrcurrchng) {
14465+ DWC_DEBUGPL(DBG_HCD, " --Port Interrupt HPRT0=0x%08x "
14466+ "Port Overcurrent Changed--\n", hprt0.d32);
14467+ dwc_otg_hcd->flags.b.port_over_current_change = 1;
14468+ hprt0_modify.b.prtovrcurrchng = 1;
14469+ retval |= 1;
14470+ }
14471+
14472+ /* Clear Port Interrupts */
14473+ dwc_write_reg32(dwc_otg_hcd->core_if->host_if->hprt0, hprt0_modify.d32);
14474+
14475+ return retval;
14476+}
14477+
14478+/** This interrupt indicates that one or more host channels has a pending
14479+ * interrupt. There are multiple conditions that can cause each host channel
14480+ * interrupt. This function determines which conditions have occurred for each
14481+ * host channel interrupt and handles them appropriately. */
14482+int32_t dwc_otg_hcd_handle_hc_intr(dwc_otg_hcd_t *dwc_otg_hcd)
14483+{
14484+ int i;
14485+ int retval = 0;
14486+ haint_data_t haint;
14487+
14488+ /* Clear appropriate bits in HCINTn to clear the interrupt bit in
14489+ * GINTSTS */
14490+
14491+ haint.d32 = dwc_otg_read_host_all_channels_intr(dwc_otg_hcd->core_if);
14492+
14493+ for (i = 0; i < dwc_otg_hcd->core_if->core_params->host_channels; i++) {
14494+ if (haint.b2.chint & (1 << i)) {
14495+ retval |= dwc_otg_hcd_handle_hc_n_intr(dwc_otg_hcd, i);
14496+ }
14497+ }
14498+
14499+ return retval;
14500+}
14501+
14502+/* Macro used to clear one channel interrupt */
14503+#define clear_hc_int(_hc_regs_, _intr_) \
14504+do { \
14505+ hcint_data_t hcint_clear = {.d32 = 0}; \
14506+ hcint_clear.b._intr_ = 1; \
14507+ dwc_write_reg32(&(_hc_regs_)->hcint, hcint_clear.d32); \
14508+} while (0)
14509+
14510+/*
14511+ * Macro used to disable one channel interrupt. Channel interrupts are
14512+ * disabled when the channel is halted or released by the interrupt handler.
14513+ * There is no need to handle further interrupts of that type until the
14514+ * channel is re-assigned. In fact, subsequent handling may cause crashes
14515+ * because the channel structures are cleaned up when the channel is released.
14516+ */
14517+#define disable_hc_int(_hc_regs_, _intr_) \
14518+do { \
14519+ hcintmsk_data_t hcintmsk = {.d32 = 0}; \
14520+ hcintmsk.b._intr_ = 1; \
14521+ dwc_modify_reg32(&(_hc_regs_)->hcintmsk, hcintmsk.d32, 0); \
14522+} while (0)
14523+
14524+/**
14525+ * Gets the actual length of a transfer after the transfer halts. _halt_status
14526+ * holds the reason for the halt.
14527+ *
14528+ * For IN transfers where halt_status is DWC_OTG_HC_XFER_COMPLETE,
14529+ * *short_read is set to 1 upon return if less than the requested
14530+ * number of bytes were transferred. Otherwise, *short_read is set to 0 upon
14531+ * return. short_read may also be NULL on entry, in which case it remains
14532+ * unchanged.
14533+ */
14534+static uint32_t get_actual_xfer_length(dwc_hc_t *hc,
14535+ dwc_otg_hc_regs_t *hc_regs,
14536+ dwc_otg_qtd_t *qtd,
14537+ dwc_otg_halt_status_e halt_status,
14538+ int *short_read)
14539+{
14540+ hctsiz_data_t hctsiz;
14541+ uint32_t length;
14542+
14543+ if (short_read != NULL) {
14544+ *short_read = 0;
14545+ }
14546+ hctsiz.d32 = dwc_read_reg32(&hc_regs->hctsiz);
14547+
14548+ if (halt_status == DWC_OTG_HC_XFER_COMPLETE) {
14549+ if (hc->ep_is_in) {
14550+ length = hc->xfer_len - hctsiz.b.xfersize;
14551+ if (short_read != NULL) {
14552+ *short_read = (hctsiz.b.xfersize != 0);
14553+ }
14554+ } else if (hc->qh->do_split) {
14555+ length = qtd->ssplit_out_xfer_count;
14556+ } else {
14557+ length = hc->xfer_len;
14558+ }
14559+ } else {
14560+ /*
14561+ * Must use the hctsiz.pktcnt field to determine how much data
14562+ * has been transferred. This field reflects the number of
14563+ * packets that have been transferred via the USB. This is
14564+ * always an integral number of packets if the transfer was
14565+ * halted before its normal completion. (Can't use the
14566+ * hctsiz.xfersize field because that reflects the number of
14567+ * bytes transferred via the AHB, not the USB).
14568+ */
14569+ length = (hc->start_pkt_count - hctsiz.b.pktcnt) * hc->max_packet;
14570+ }
14571+
14572+ return length;
14573+}
14574+
14575+/**
14576+ * Updates the state of the URB after a Transfer Complete interrupt on the
14577+ * host channel. Updates the actual_length field of the URB based on the
14578+ * number of bytes transferred via the host channel. Sets the URB status
14579+ * if the data transfer is finished.
14580+ *
14581+ * @return 1 if the data transfer specified by the URB is completely finished,
14582+ * 0 otherwise.
14583+ */
14584+static int update_urb_state_xfer_comp(dwc_hc_t *hc,
14585+ dwc_otg_hc_regs_t *hc_regs,
14586+ struct urb *urb,
14587+ dwc_otg_qtd_t *qtd)
14588+{
14589+ int xfer_done = 0;
14590+ int short_read = 0;
14591+
14592+ urb->actual_length += get_actual_xfer_length(hc, hc_regs, qtd,
14593+ DWC_OTG_HC_XFER_COMPLETE,
14594+ &short_read);
14595+
14596+ if (short_read || urb->actual_length == urb->transfer_buffer_length) {
14597+ xfer_done = 1;
14598+ if (short_read && (urb->transfer_flags & URB_SHORT_NOT_OK)) {
14599+ urb->status = -EREMOTEIO;
14600+ } else {
14601+ urb->status = 0;
14602+ }
14603+ }
14604+
14605+#ifdef DEBUG
14606+ {
14607+ hctsiz_data_t hctsiz;
14608+ hctsiz.d32 = dwc_read_reg32(&hc_regs->hctsiz);
14609+ DWC_DEBUGPL(DBG_HCDV, "DWC_otg: %s: %s, channel %d\n",
14610+ __func__, (hc->ep_is_in ? "IN" : "OUT"), hc->hc_num);
14611+ DWC_DEBUGPL(DBG_HCDV, " hc->xfer_len %d\n", hc->xfer_len);
14612+ DWC_DEBUGPL(DBG_HCDV, " hctsiz.xfersize %d\n", hctsiz.b.xfersize);
14613+ DWC_DEBUGPL(DBG_HCDV, " urb->transfer_buffer_length %d\n",
14614+ urb->transfer_buffer_length);
14615+ DWC_DEBUGPL(DBG_HCDV, " urb->actual_length %d\n", urb->actual_length);
14616+ DWC_DEBUGPL(DBG_HCDV, " short_read %d, xfer_done %d\n",
14617+ short_read, xfer_done);
14618+ }
14619+#endif
14620+
14621+ return xfer_done;
14622+}
14623+
14624+/*
14625+ * Save the starting data toggle for the next transfer. The data toggle is
14626+ * saved in the QH for non-control transfers and it's saved in the QTD for
14627+ * control transfers.
14628+ */
14629+static void save_data_toggle(dwc_hc_t *hc,
14630+ dwc_otg_hc_regs_t *hc_regs,
14631+ dwc_otg_qtd_t *qtd)
14632+{
14633+ hctsiz_data_t hctsiz;
14634+ hctsiz.d32 = dwc_read_reg32(&hc_regs->hctsiz);
14635+
14636+ if (hc->ep_type != DWC_OTG_EP_TYPE_CONTROL) {
14637+ dwc_otg_qh_t *qh = hc->qh;
14638+ if (hctsiz.b.pid == DWC_HCTSIZ_DATA0) {
14639+ qh->data_toggle = DWC_OTG_HC_PID_DATA0;
14640+ } else {
14641+ qh->data_toggle = DWC_OTG_HC_PID_DATA1;
14642+ }
14643+ } else {
14644+ if (hctsiz.b.pid == DWC_HCTSIZ_DATA0) {
14645+ qtd->data_toggle = DWC_OTG_HC_PID_DATA0;
14646+ } else {
14647+ qtd->data_toggle = DWC_OTG_HC_PID_DATA1;
14648+ }
14649+ }
14650+}
14651+
14652+/**
14653+ * Frees the first QTD in the QH's list if free_qtd is 1. For non-periodic
14654+ * QHs, removes the QH from the active non-periodic schedule. If any QTDs are
14655+ * still linked to the QH, the QH is added to the end of the inactive
14656+ * non-periodic schedule. For periodic QHs, removes the QH from the periodic
14657+ * schedule if no more QTDs are linked to the QH.
14658+ */
14659+static void deactivate_qh(dwc_otg_hcd_t *hcd,
14660+ dwc_otg_qh_t *qh,
14661+ int free_qtd)
14662+{
14663+ int continue_split = 0;
14664+ dwc_otg_qtd_t *qtd;
14665+
14666+ DWC_DEBUGPL(DBG_HCDV, " %s(%p,%p,%d)\n", __func__, hcd, qh, free_qtd);
14667+
14668+ qtd = list_entry(qh->qtd_list.next, dwc_otg_qtd_t, qtd_list_entry);
14669+
14670+ if (qtd->complete_split) {
14671+ continue_split = 1;
14672+ } else if (qtd->isoc_split_pos == DWC_HCSPLIT_XACTPOS_MID ||
14673+ qtd->isoc_split_pos == DWC_HCSPLIT_XACTPOS_END) {
14674+ continue_split = 1;
14675+ }
14676+
14677+ if (free_qtd) {
14678+ dwc_otg_hcd_qtd_remove_and_free(hcd, qtd);
14679+ continue_split = 0;
14680+ }
14681+
14682+ qh->channel = NULL;
14683+ qh->qtd_in_process = NULL;
14684+ dwc_otg_hcd_qh_deactivate(hcd, qh, continue_split);
14685+}
14686+
14687+/**
14688+ * Updates the state of an Isochronous URB when the transfer is stopped for
14689+ * any reason. The fields of the current entry in the frame descriptor array
14690+ * are set based on the transfer state and the input _halt_status. Completes
14691+ * the Isochronous URB if all the URB frames have been completed.
14692+ *
14693+ * @return DWC_OTG_HC_XFER_COMPLETE if there are more frames remaining to be
14694+ * transferred in the URB. Otherwise return DWC_OTG_HC_XFER_URB_COMPLETE.
14695+ */
14696+static dwc_otg_halt_status_e
14697+update_isoc_urb_state(dwc_otg_hcd_t *hcd,
14698+ dwc_hc_t *hc,
14699+ dwc_otg_hc_regs_t *hc_regs,
14700+ dwc_otg_qtd_t *qtd,
14701+ dwc_otg_halt_status_e halt_status)
14702+{
14703+ struct urb *urb = qtd->urb;
14704+ dwc_otg_halt_status_e ret_val = halt_status;
14705+ struct usb_iso_packet_descriptor *frame_desc;
14706+
14707+ frame_desc = &urb->iso_frame_desc[qtd->isoc_frame_index];
14708+ switch (halt_status) {
14709+ case DWC_OTG_HC_XFER_COMPLETE:
14710+ frame_desc->status = 0;
14711+ frame_desc->actual_length =
14712+ get_actual_xfer_length(hc, hc_regs, qtd,
14713+ halt_status, NULL);
14714+ break;
14715+ case DWC_OTG_HC_XFER_FRAME_OVERRUN:
14716+ urb->error_count++;
14717+ if (hc->ep_is_in) {
14718+ frame_desc->status = -ENOSR;
14719+ } else {
14720+ frame_desc->status = -ECOMM;
14721+ }
14722+ frame_desc->actual_length = 0;
14723+ break;
14724+ case DWC_OTG_HC_XFER_BABBLE_ERR:
14725+ urb->error_count++;
14726+ frame_desc->status = -EOVERFLOW;
14727+ /* Don't need to update actual_length in this case. */
14728+ break;
14729+ case DWC_OTG_HC_XFER_XACT_ERR:
14730+ urb->error_count++;
14731+ frame_desc->status = -EPROTO;
14732+ frame_desc->actual_length =
14733+ get_actual_xfer_length(hc, hc_regs, qtd,
14734+ halt_status, NULL);
14735+ default:
14736+ DWC_ERROR("%s: Unhandled _halt_status (%d)\n", __func__,
14737+ halt_status);
14738+ BUG();
14739+ break;
14740+ }
14741+
14742+ if (++qtd->isoc_frame_index == urb->number_of_packets) {
14743+ /*
14744+ * urb->status is not used for isoc transfers.
14745+ * The individual frame_desc statuses are used instead.
14746+ */
14747+ dwc_otg_hcd_complete_urb(hcd, urb, 0);
14748+ ret_val = DWC_OTG_HC_XFER_URB_COMPLETE;
14749+ } else {
14750+ ret_val = DWC_OTG_HC_XFER_COMPLETE;
14751+ }
14752+
14753+ return ret_val;
14754+}
14755+
14756+/**
14757+ * Releases a host channel for use by other transfers. Attempts to select and
14758+ * queue more transactions since at least one host channel is available.
14759+ *
14760+ * @param hcd The HCD state structure.
14761+ * @param hc The host channel to release.
14762+ * @param qtd The QTD associated with the host channel. This QTD may be freed
14763+ * if the transfer is complete or an error has occurred.
14764+ * @param halt_status Reason the channel is being released. This status
14765+ * determines the actions taken by this function.
14766+ */
14767+static void release_channel(dwc_otg_hcd_t *hcd,
14768+ dwc_hc_t *hc,
14769+ dwc_otg_qtd_t *qtd,
14770+ dwc_otg_halt_status_e halt_status)
14771+{
14772+ dwc_otg_transaction_type_e tr_type;
14773+ int free_qtd;
14774+
14775+ DWC_DEBUGPL(DBG_HCDV, " %s: channel %d, halt_status %d\n",
14776+ __func__, hc->hc_num, halt_status);
14777+
14778+ switch (halt_status) {
14779+ case DWC_OTG_HC_XFER_URB_COMPLETE:
14780+ free_qtd = 1;
14781+ break;
14782+ case DWC_OTG_HC_XFER_AHB_ERR:
14783+ case DWC_OTG_HC_XFER_STALL:
14784+ case DWC_OTG_HC_XFER_BABBLE_ERR:
14785+ free_qtd = 1;
14786+ break;
14787+ case DWC_OTG_HC_XFER_XACT_ERR:
14788+ if (qtd->error_count >= 3) {
14789+ DWC_DEBUGPL(DBG_HCDV, " Complete URB with transaction error\n");
14790+ free_qtd = 1;
14791+ qtd->urb->status = -EPROTO;
14792+ dwc_otg_hcd_complete_urb(hcd, qtd->urb, -EPROTO);
14793+ } else {
14794+ free_qtd = 0;
14795+ }
14796+ break;
14797+ case DWC_OTG_HC_XFER_URB_DEQUEUE:
14798+ /*
14799+ * The QTD has already been removed and the QH has been
14800+ * deactivated. Don't want to do anything except release the
14801+ * host channel and try to queue more transfers.
14802+ */
14803+ goto cleanup;
14804+ case DWC_OTG_HC_XFER_NO_HALT_STATUS:
14805+ DWC_ERROR("%s: No halt_status, channel %d\n", __func__, hc->hc_num);
14806+ free_qtd = 0;
14807+ break;
14808+ default:
14809+ free_qtd = 0;
14810+ break;
14811+ }
14812+
14813+ deactivate_qh(hcd, hc->qh, free_qtd);
14814+
14815+ cleanup:
14816+ /*
14817+ * Release the host channel for use by other transfers. The cleanup
14818+ * function clears the channel interrupt enables and conditions, so
14819+ * there's no need to clear the Channel Halted interrupt separately.
14820+ */
14821+ dwc_otg_hc_cleanup(hcd->core_if, hc);
14822+ list_add_tail(&hc->hc_list_entry, &hcd->free_hc_list);
14823+
14824+ switch (hc->ep_type) {
14825+ case DWC_OTG_EP_TYPE_CONTROL:
14826+ case DWC_OTG_EP_TYPE_BULK:
14827+ hcd->non_periodic_channels--;
14828+ break;
14829+
14830+ default:
14831+ /*
14832+ * Don't release reservations for periodic channels here.
14833+ * That's done when a periodic transfer is descheduled (i.e.
14834+ * when the QH is removed from the periodic schedule).
14835+ */
14836+ break;
14837+ }
14838+
14839+ /* Try to queue more transfers now that there's a free channel. */
14840+ tr_type = dwc_otg_hcd_select_transactions(hcd);
14841+ if (tr_type != DWC_OTG_TRANSACTION_NONE) {
14842+ dwc_otg_hcd_queue_transactions(hcd, tr_type);
14843+ }
14844+}
14845+
14846+/**
14847+ * Halts a host channel. If the channel cannot be halted immediately because
14848+ * the request queue is full, this function ensures that the FIFO empty
14849+ * interrupt for the appropriate queue is enabled so that the halt request can
14850+ * be queued when there is space in the request queue.
14851+ *
14852+ * This function may also be called in DMA mode. In that case, the channel is
14853+ * simply released since the core always halts the channel automatically in
14854+ * DMA mode.
14855+ */
14856+static void halt_channel(dwc_otg_hcd_t *hcd,
14857+ dwc_hc_t *hc,
14858+ dwc_otg_qtd_t *qtd,
14859+ dwc_otg_halt_status_e halt_status)
14860+{
14861+ if (hcd->core_if->dma_enable) {
14862+ release_channel(hcd, hc, qtd, halt_status);
14863+ return;
14864+ }
14865+
14866+ /* Slave mode processing... */
14867+ dwc_otg_hc_halt(hcd->core_if, hc, halt_status);
14868+
14869+ if (hc->halt_on_queue) {
14870+ gintmsk_data_t gintmsk = {.d32 = 0};
14871+ dwc_otg_core_global_regs_t *global_regs;
14872+ global_regs = hcd->core_if->core_global_regs;
14873+
14874+ if (hc->ep_type == DWC_OTG_EP_TYPE_CONTROL ||
14875+ hc->ep_type == DWC_OTG_EP_TYPE_BULK) {
14876+ /*
14877+ * Make sure the Non-periodic Tx FIFO empty interrupt
14878+ * is enabled so that the non-periodic schedule will
14879+ * be processed.
14880+ */
14881+ gintmsk.b.nptxfempty = 1;
14882+ dwc_modify_reg32(&global_regs->gintmsk, 0, gintmsk.d32);
14883+ } else {
14884+ /*
14885+ * Move the QH from the periodic queued schedule to
14886+ * the periodic assigned schedule. This allows the
14887+ * halt to be queued when the periodic schedule is
14888+ * processed.
14889+ */
14890+ list_move(&hc->qh->qh_list_entry,
14891+ &hcd->periodic_sched_assigned);
14892+
14893+ /*
14894+ * Make sure the Periodic Tx FIFO Empty interrupt is
14895+ * enabled so that the periodic schedule will be
14896+ * processed.
14897+ */
14898+ gintmsk.b.ptxfempty = 1;
14899+ dwc_modify_reg32(&global_regs->gintmsk, 0, gintmsk.d32);
14900+ }
14901+ }
14902+}
14903+
14904+/**
14905+ * Performs common cleanup for non-periodic transfers after a Transfer
14906+ * Complete interrupt. This function should be called after any endpoint type
14907+ * specific handling is finished to release the host channel.
14908+ */
14909+static void complete_non_periodic_xfer(dwc_otg_hcd_t *hcd,
14910+ dwc_hc_t *hc,
14911+ dwc_otg_hc_regs_t *hc_regs,
14912+ dwc_otg_qtd_t *qtd,
14913+ dwc_otg_halt_status_e halt_status)
14914+{
14915+ hcint_data_t hcint;
14916+
14917+ qtd->error_count = 0;
14918+
14919+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
14920+ if (hcint.b.nyet) {
14921+ /*
14922+ * Got a NYET on the last transaction of the transfer. This
14923+ * means that the endpoint should be in the PING state at the
14924+ * beginning of the next transfer.
14925+ */
14926+ hc->qh->ping_state = 1;
14927+ clear_hc_int(hc_regs, nyet);
14928+ }
14929+
14930+ /*
14931+ * Always halt and release the host channel to make it available for
14932+ * more transfers. There may still be more phases for a control
14933+ * transfer or more data packets for a bulk transfer at this point,
14934+ * but the host channel is still halted. A channel will be reassigned
14935+ * to the transfer when the non-periodic schedule is processed after
14936+ * the channel is released. This allows transactions to be queued
14937+ * properly via dwc_otg_hcd_queue_transactions, which also enables the
14938+ * Tx FIFO Empty interrupt if necessary.
14939+ */
14940+ if (hc->ep_is_in) {
14941+ /*
14942+ * IN transfers in Slave mode require an explicit disable to
14943+ * halt the channel. (In DMA mode, this call simply releases
14944+ * the channel.)
14945+ */
14946+ halt_channel(hcd, hc, qtd, halt_status);
14947+ } else {
14948+ /*
14949+ * The channel is automatically disabled by the core for OUT
14950+ * transfers in Slave mode.
14951+ */
14952+ release_channel(hcd, hc, qtd, halt_status);
14953+ }
14954+}
14955+
14956+/**
14957+ * Performs common cleanup for periodic transfers after a Transfer Complete
14958+ * interrupt. This function should be called after any endpoint type specific
14959+ * handling is finished to release the host channel.
14960+ */
14961+static void complete_periodic_xfer(dwc_otg_hcd_t *hcd,
14962+ dwc_hc_t *hc,
14963+ dwc_otg_hc_regs_t *hc_regs,
14964+ dwc_otg_qtd_t *qtd,
14965+ dwc_otg_halt_status_e halt_status)
14966+{
14967+ hctsiz_data_t hctsiz;
14968+ qtd->error_count = 0;
14969+
14970+ hctsiz.d32 = dwc_read_reg32(&hc_regs->hctsiz);
14971+ if (!hc->ep_is_in || hctsiz.b.pktcnt == 0) {
14972+ /* Core halts channel in these cases. */
14973+ release_channel(hcd, hc, qtd, halt_status);
14974+ } else {
14975+ /* Flush any outstanding requests from the Tx queue. */
14976+ halt_channel(hcd, hc, qtd, halt_status);
14977+ }
14978+}
14979+
14980+/**
14981+ * Handles a host channel Transfer Complete interrupt. This handler may be
14982+ * called in either DMA mode or Slave mode.
14983+ */
14984+static int32_t handle_hc_xfercomp_intr(dwc_otg_hcd_t *hcd,
14985+ dwc_hc_t *hc,
14986+ dwc_otg_hc_regs_t *hc_regs,
14987+ dwc_otg_qtd_t *qtd)
14988+{
14989+ int urb_xfer_done;
14990+ dwc_otg_halt_status_e halt_status = DWC_OTG_HC_XFER_COMPLETE;
14991+ struct urb *urb = qtd->urb;
14992+ int pipe_type = usb_pipetype(urb->pipe);
14993+
14994+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
14995+ "Transfer Complete--\n", hc->hc_num);
14996+
14997+ /*
14998+ * Handle xfer complete on CSPLIT.
14999+ */
15000+ if (hc->qh->do_split) {
15001+ qtd->complete_split = 0;
15002+ }
15003+
15004+ /* Update the QTD and URB states. */
15005+ switch (pipe_type) {
15006+ case PIPE_CONTROL:
15007+ switch (qtd->control_phase) {
15008+ case DWC_OTG_CONTROL_SETUP:
15009+ if (urb->transfer_buffer_length > 0) {
15010+ qtd->control_phase = DWC_OTG_CONTROL_DATA;
15011+ } else {
15012+ qtd->control_phase = DWC_OTG_CONTROL_STATUS;
15013+ }
15014+ DWC_DEBUGPL(DBG_HCDV, " Control setup transaction done\n");
15015+ halt_status = DWC_OTG_HC_XFER_COMPLETE;
15016+ break;
15017+ case DWC_OTG_CONTROL_DATA: {
15018+ urb_xfer_done = update_urb_state_xfer_comp(hc, hc_regs, urb, qtd);
15019+ if (urb_xfer_done) {
15020+ qtd->control_phase = DWC_OTG_CONTROL_STATUS;
15021+ DWC_DEBUGPL(DBG_HCDV, " Control data transfer done\n");
15022+ } else {
15023+ save_data_toggle(hc, hc_regs, qtd);
15024+ }
15025+ halt_status = DWC_OTG_HC_XFER_COMPLETE;
15026+ break;
15027+ }
15028+ case DWC_OTG_CONTROL_STATUS:
15029+ DWC_DEBUGPL(DBG_HCDV, " Control transfer complete\n");
15030+ if (urb->status == -EINPROGRESS) {
15031+ urb->status = 0;
15032+ }
15033+ dwc_otg_hcd_complete_urb(hcd, urb, urb->status);
15034+ halt_status = DWC_OTG_HC_XFER_URB_COMPLETE;
15035+ break;
15036+ }
15037+
15038+ complete_non_periodic_xfer(hcd, hc, hc_regs, qtd, halt_status);
15039+ break;
15040+ case PIPE_BULK:
15041+ DWC_DEBUGPL(DBG_HCDV, " Bulk transfer complete\n");
15042+ urb_xfer_done = update_urb_state_xfer_comp(hc, hc_regs, urb, qtd);
15043+ if (urb_xfer_done) {
15044+ dwc_otg_hcd_complete_urb(hcd, urb, urb->status);
15045+ halt_status = DWC_OTG_HC_XFER_URB_COMPLETE;
15046+ } else {
15047+ halt_status = DWC_OTG_HC_XFER_COMPLETE;
15048+ }
15049+
15050+ save_data_toggle(hc, hc_regs, qtd);
15051+ complete_non_periodic_xfer(hcd, hc, hc_regs, qtd, halt_status);
15052+ break;
15053+ case PIPE_INTERRUPT:
15054+ DWC_DEBUGPL(DBG_HCDV, " Interrupt transfer complete\n");
15055+ update_urb_state_xfer_comp(hc, hc_regs, urb, qtd);
15056+
15057+ /*
15058+ * Interrupt URB is done on the first transfer complete
15059+ * interrupt.
15060+ */
15061+ dwc_otg_hcd_complete_urb(hcd, urb, urb->status);
15062+ save_data_toggle(hc, hc_regs, qtd);
15063+ complete_periodic_xfer(hcd, hc, hc_regs, qtd,
15064+ DWC_OTG_HC_XFER_URB_COMPLETE);
15065+ break;
15066+ case PIPE_ISOCHRONOUS:
15067+ DWC_DEBUGPL(DBG_HCDV, " Isochronous transfer complete\n");
15068+ if (qtd->isoc_split_pos == DWC_HCSPLIT_XACTPOS_ALL) {
15069+ halt_status = update_isoc_urb_state(hcd, hc, hc_regs, qtd,
15070+ DWC_OTG_HC_XFER_COMPLETE);
15071+ }
15072+ complete_periodic_xfer(hcd, hc, hc_regs, qtd, halt_status);
15073+ break;
15074+ }
15075+
15076+ disable_hc_int(hc_regs, xfercompl);
15077+
15078+ return 1;
15079+}
15080+
15081+/**
15082+ * Handles a host channel STALL interrupt. This handler may be called in
15083+ * either DMA mode or Slave mode.
15084+ */
15085+static int32_t handle_hc_stall_intr(dwc_otg_hcd_t *hcd,
15086+ dwc_hc_t *hc,
15087+ dwc_otg_hc_regs_t *hc_regs,
15088+ dwc_otg_qtd_t *qtd)
15089+{
15090+ struct urb *urb = qtd->urb;
15091+ int pipe_type = usb_pipetype(urb->pipe);
15092+
15093+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
15094+ "STALL Received--\n", hc->hc_num);
15095+
15096+ if (pipe_type == PIPE_CONTROL) {
15097+ dwc_otg_hcd_complete_urb(hcd, urb, -EPIPE);
15098+ }
15099+
15100+ if (pipe_type == PIPE_BULK || pipe_type == PIPE_INTERRUPT) {
15101+ dwc_otg_hcd_complete_urb(hcd, urb, -EPIPE);
15102+ /*
15103+ * USB protocol requires resetting the data toggle for bulk
15104+ * and interrupt endpoints when a CLEAR_FEATURE(ENDPOINT_HALT)
15105+ * setup command is issued to the endpoint. Anticipate the
15106+ * CLEAR_FEATURE command since a STALL has occurred and reset
15107+ * the data toggle now.
15108+ */
15109+ hc->qh->data_toggle = 0;
15110+ }
15111+
15112+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_STALL);
15113+
15114+ disable_hc_int(hc_regs, stall);
15115+
15116+ return 1;
15117+}
15118+
15119+/*
15120+ * Updates the state of the URB when a transfer has been stopped due to an
15121+ * abnormal condition before the transfer completes. Modifies the
15122+ * actual_length field of the URB to reflect the number of bytes that have
15123+ * actually been transferred via the host channel.
15124+ */
15125+static void update_urb_state_xfer_intr(dwc_hc_t *hc,
15126+ dwc_otg_hc_regs_t *hc_regs,
15127+ struct urb *urb,
15128+ dwc_otg_qtd_t *qtd,
15129+ dwc_otg_halt_status_e halt_status)
15130+{
15131+ uint32_t bytes_transferred = get_actual_xfer_length(hc, hc_regs, qtd,
15132+ halt_status, NULL);
15133+ urb->actual_length += bytes_transferred;
15134+
15135+#ifdef DEBUG
15136+ {
15137+ hctsiz_data_t hctsiz;
15138+ hctsiz.d32 = dwc_read_reg32(&hc_regs->hctsiz);
15139+ DWC_DEBUGPL(DBG_HCDV, "DWC_otg: %s: %s, channel %d\n",
15140+ __func__, (hc->ep_is_in ? "IN" : "OUT"), hc->hc_num);
15141+ DWC_DEBUGPL(DBG_HCDV, " hc->start_pkt_count %d\n", hc->start_pkt_count);
15142+ DWC_DEBUGPL(DBG_HCDV, " hctsiz.pktcnt %d\n", hctsiz.b.pktcnt);
15143+ DWC_DEBUGPL(DBG_HCDV, " hc->max_packet %d\n", hc->max_packet);
15144+ DWC_DEBUGPL(DBG_HCDV, " bytes_transferred %d\n", bytes_transferred);
15145+ DWC_DEBUGPL(DBG_HCDV, " urb->actual_length %d\n", urb->actual_length);
15146+ DWC_DEBUGPL(DBG_HCDV, " urb->transfer_buffer_length %d\n",
15147+ urb->transfer_buffer_length);
15148+ }
15149+#endif
15150+}
15151+
15152+/**
15153+ * Handles a host channel NAK interrupt. This handler may be called in either
15154+ * DMA mode or Slave mode.
15155+ */
15156+static int32_t handle_hc_nak_intr(dwc_otg_hcd_t *hcd,
15157+ dwc_hc_t *hc,
15158+ dwc_otg_hc_regs_t *hc_regs,
15159+ dwc_otg_qtd_t *qtd)
15160+{
15161+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
15162+ "NAK Received--\n", hc->hc_num);
15163+
15164+ /*
15165+ * Handle NAK for IN/OUT SSPLIT/CSPLIT transfers, bulk, control, and
15166+ * interrupt. Re-start the SSPLIT transfer.
15167+ */
15168+ if (hc->do_split) {
15169+ if (hc->complete_split) {
15170+ qtd->error_count = 0;
15171+ }
15172+ qtd->complete_split = 0;
15173+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NAK);
15174+ goto handle_nak_done;
15175+ }
15176+
15177+ switch (usb_pipetype(qtd->urb->pipe)) {
15178+ case PIPE_CONTROL:
15179+ case PIPE_BULK:
15180+ if (hcd->core_if->dma_enable && hc->ep_is_in) {
15181+ /*
15182+ * NAK interrupts are enabled on bulk/control IN
15183+ * transfers in DMA mode for the sole purpose of
15184+ * resetting the error count after a transaction error
15185+ * occurs. The core will continue transferring data.
15186+ */
15187+ qtd->error_count = 0;
15188+ goto handle_nak_done;
15189+ }
15190+
15191+ /*
15192+ * NAK interrupts normally occur during OUT transfers in DMA
15193+ * or Slave mode. For IN transfers, more requests will be
15194+ * queued as request queue space is available.
15195+ */
15196+ qtd->error_count = 0;
15197+
15198+ if (!hc->qh->ping_state) {
15199+ update_urb_state_xfer_intr(hc, hc_regs, qtd->urb,
15200+ qtd, DWC_OTG_HC_XFER_NAK);
15201+ save_data_toggle(hc, hc_regs, qtd);
15202+ if (qtd->urb->dev->speed == USB_SPEED_HIGH) {
15203+ hc->qh->ping_state = 1;
15204+ }
15205+ }
15206+
15207+ /*
15208+ * Halt the channel so the transfer can be re-started from
15209+ * the appropriate point or the PING protocol will
15210+ * start/continue.
15211+ */
15212+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NAK);
15213+ break;
15214+ case PIPE_INTERRUPT:
15215+ qtd->error_count = 0;
15216+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NAK);
15217+ break;
15218+ case PIPE_ISOCHRONOUS:
15219+ /* Should never get called for isochronous transfers. */
15220+ BUG();
15221+ break;
15222+ }
15223+
15224+ handle_nak_done:
15225+ disable_hc_int(hc_regs, nak);
15226+
15227+ return 1;
15228+}
15229+
15230+/**
15231+ * Handles a host channel ACK interrupt. This interrupt is enabled when
15232+ * performing the PING protocol in Slave mode, when errors occur during
15233+ * either Slave mode or DMA mode, and during Start Split transactions.
15234+ */
15235+static int32_t handle_hc_ack_intr(dwc_otg_hcd_t *hcd,
15236+ dwc_hc_t *hc,
15237+ dwc_otg_hc_regs_t *hc_regs,
15238+ dwc_otg_qtd_t *qtd)
15239+{
15240+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
15241+ "ACK Received--\n", hc->hc_num);
15242+
15243+ if (hc->do_split) {
15244+ /*
15245+ * Handle ACK on SSPLIT.
15246+ * ACK should not occur in CSPLIT.
15247+ */
15248+ if (!hc->ep_is_in && hc->data_pid_start != DWC_OTG_HC_PID_SETUP) {
15249+ qtd->ssplit_out_xfer_count = hc->xfer_len;
15250+ }
15251+ if (!(hc->ep_type == DWC_OTG_EP_TYPE_ISOC && !hc->ep_is_in)) {
15252+ /* Don't need complete for isochronous out transfers. */
15253+ qtd->complete_split = 1;
15254+ }
15255+
15256+ /* ISOC OUT */
15257+ if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC && !hc->ep_is_in) {
15258+ switch (hc->xact_pos) {
15259+ case DWC_HCSPLIT_XACTPOS_ALL:
15260+ break;
15261+ case DWC_HCSPLIT_XACTPOS_END:
15262+ qtd->isoc_split_pos = DWC_HCSPLIT_XACTPOS_ALL;
15263+ qtd->isoc_split_offset = 0;
15264+ break;
15265+ case DWC_HCSPLIT_XACTPOS_BEGIN:
15266+ case DWC_HCSPLIT_XACTPOS_MID:
15267+ /*
15268+ * For BEGIN or MID, calculate the length for
15269+ * the next microframe to determine the correct
15270+ * SSPLIT token, either MID or END.
15271+ */
15272+ {
15273+ struct usb_iso_packet_descriptor *frame_desc;
15274+
15275+ frame_desc = &qtd->urb->iso_frame_desc[qtd->isoc_frame_index];
15276+ qtd->isoc_split_offset += 188;
15277+
15278+ if ((frame_desc->length - qtd->isoc_split_offset) <= 188) {
15279+ qtd->isoc_split_pos = DWC_HCSPLIT_XACTPOS_END;
15280+ } else {
15281+ qtd->isoc_split_pos = DWC_HCSPLIT_XACTPOS_MID;
15282+ }
15283+
15284+ }
15285+ break;
15286+ }
15287+ } else {
15288+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_ACK);
15289+ }
15290+ } else {
15291+ qtd->error_count = 0;
15292+
15293+ if (hc->qh->ping_state) {
15294+ hc->qh->ping_state = 0;
15295+ /*
15296+ * Halt the channel so the transfer can be re-started
15297+ * from the appropriate point. This only happens in
15298+ * Slave mode. In DMA mode, the ping_state is cleared
15299+ * when the transfer is started because the core
15300+ * automatically executes the PING, then the transfer.
15301+ */
15302+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_ACK);
15303+ }
15304+ }
15305+
15306+ /*
15307+ * If the ACK occurred when _not_ in the PING state, let the channel
15308+ * continue transferring data after clearing the error count.
15309+ */
15310+
15311+ disable_hc_int(hc_regs, ack);
15312+
15313+ return 1;
15314+}
15315+
15316+/**
15317+ * Handles a host channel NYET interrupt. This interrupt should only occur on
15318+ * Bulk and Control OUT endpoints and for complete split transactions. If a
15319+ * NYET occurs at the same time as a Transfer Complete interrupt, it is
15320+ * handled in the xfercomp interrupt handler, not here. This handler may be
15321+ * called in either DMA mode or Slave mode.
15322+ */
15323+static int32_t handle_hc_nyet_intr(dwc_otg_hcd_t *hcd,
15324+ dwc_hc_t *hc,
15325+ dwc_otg_hc_regs_t *hc_regs,
15326+ dwc_otg_qtd_t *qtd)
15327+{
15328+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
15329+ "NYET Received--\n", hc->hc_num);
15330+
15331+ /*
15332+ * NYET on CSPLIT
15333+ * re-do the CSPLIT immediately on non-periodic
15334+ */
15335+ if (hc->do_split && hc->complete_split) {
15336+ if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
15337+ hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
15338+ int frnum = dwc_otg_hcd_get_frame_number(dwc_otg_hcd_to_hcd(hcd));
15339+
15340+ if (dwc_full_frame_num(frnum) !=
15341+ dwc_full_frame_num(hc->qh->sched_frame)) {
15342+ /*
15343+ * No longer in the same full speed frame.
15344+ * Treat this as a transaction error.
15345+ */
15346+#if 0
15347+ /** @todo Fix system performance so this can
15348+ * be treated as an error. Right now complete
15349+ * splits cannot be scheduled precisely enough
15350+ * due to other system activity, so this error
15351+ * occurs regularly in Slave mode.
15352+ */
15353+ qtd->error_count++;
15354+#endif
15355+ qtd->complete_split = 0;
15356+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_XACT_ERR);
15357+ /** @todo add support for isoc release */
15358+ goto handle_nyet_done;
15359+ }
15360+ }
15361+
15362+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NYET);
15363+ goto handle_nyet_done;
15364+ }
15365+
15366+ hc->qh->ping_state = 1;
15367+ qtd->error_count = 0;
15368+
15369+ update_urb_state_xfer_intr(hc, hc_regs, qtd->urb, qtd,
15370+ DWC_OTG_HC_XFER_NYET);
15371+ save_data_toggle(hc, hc_regs, qtd);
15372+
15373+ /*
15374+ * Halt the channel and re-start the transfer so the PING
15375+ * protocol will start.
15376+ */
15377+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NYET);
15378+
15379+handle_nyet_done:
15380+ disable_hc_int(hc_regs, nyet);
15381+ return 1;
15382+}
15383+
15384+/**
15385+ * Handles a host channel babble interrupt. This handler may be called in
15386+ * either DMA mode or Slave mode.
15387+ */
15388+static int32_t handle_hc_babble_intr(dwc_otg_hcd_t *hcd,
15389+ dwc_hc_t *hc,
15390+ dwc_otg_hc_regs_t *hc_regs,
15391+ dwc_otg_qtd_t *qtd)
15392+{
15393+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
15394+ "Babble Error--\n", hc->hc_num);
15395+ if (hc->ep_type != DWC_OTG_EP_TYPE_ISOC) {
15396+ dwc_otg_hcd_complete_urb(hcd, qtd->urb, -EOVERFLOW);
15397+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_BABBLE_ERR);
15398+ } else {
15399+ dwc_otg_halt_status_e halt_status;
15400+ halt_status = update_isoc_urb_state(hcd, hc, hc_regs, qtd,
15401+ DWC_OTG_HC_XFER_BABBLE_ERR);
15402+ halt_channel(hcd, hc, qtd, halt_status);
15403+ }
15404+ disable_hc_int(hc_regs, bblerr);
15405+ return 1;
15406+}
15407+
15408+/**
15409+ * Handles a host channel AHB error interrupt. This handler is only called in
15410+ * DMA mode.
15411+ */
15412+static int32_t handle_hc_ahberr_intr(dwc_otg_hcd_t *hcd,
15413+ dwc_hc_t *hc,
15414+ dwc_otg_hc_regs_t *hc_regs,
15415+ dwc_otg_qtd_t *qtd)
15416+{
15417+ hcchar_data_t hcchar;
15418+ hcsplt_data_t hcsplt;
15419+ hctsiz_data_t hctsiz;
15420+ uint32_t hcdma;
15421+ struct urb *urb = qtd->urb;
15422+
15423+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
15424+ "AHB Error--\n", hc->hc_num);
15425+
15426+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
15427+ hcsplt.d32 = dwc_read_reg32(&hc_regs->hcsplt);
15428+ hctsiz.d32 = dwc_read_reg32(&hc_regs->hctsiz);
15429+ hcdma = dwc_read_reg32(&hc_regs->hcdma);
15430+
15431+ DWC_ERROR("AHB ERROR, Channel %d\n", hc->hc_num);
15432+ DWC_ERROR(" hcchar 0x%08x, hcsplt 0x%08x\n", hcchar.d32, hcsplt.d32);
15433+ DWC_ERROR(" hctsiz 0x%08x, hcdma 0x%08x\n", hctsiz.d32, hcdma);
15434+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD URB Enqueue\n");
15435+ DWC_ERROR(" Device address: %d\n", usb_pipedevice(urb->pipe));
15436+ DWC_ERROR(" Endpoint: %d, %s\n", usb_pipeendpoint(urb->pipe),
15437+ (usb_pipein(urb->pipe) ? "IN" : "OUT"));
15438+ DWC_ERROR(" Endpoint type: %s\n",
15439+ ({char *pipetype;
15440+ switch (usb_pipetype(urb->pipe)) {
15441+ case PIPE_CONTROL: pipetype = "CONTROL"; break;
15442+ case PIPE_BULK: pipetype = "BULK"; break;
15443+ case PIPE_INTERRUPT: pipetype = "INTERRUPT"; break;
15444+ case PIPE_ISOCHRONOUS: pipetype = "ISOCHRONOUS"; break;
15445+ default: pipetype = "UNKNOWN"; break;
15446+ }; pipetype;}));
15447+ DWC_ERROR(" Speed: %s\n",
15448+ ({char *speed;
15449+ switch (urb->dev->speed) {
15450+ case USB_SPEED_HIGH: speed = "HIGH"; break;
15451+ case USB_SPEED_FULL: speed = "FULL"; break;
15452+ case USB_SPEED_LOW: speed = "LOW"; break;
15453+ default: speed = "UNKNOWN"; break;
15454+ }; speed;}));
15455+ DWC_ERROR(" Max packet size: %d\n",
15456+ usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)));
15457+ DWC_ERROR(" Data buffer length: %d\n", urb->transfer_buffer_length);
15458+ DWC_ERROR(" Transfer buffer: %p, Transfer DMA: %p\n",
15459+ urb->transfer_buffer, (void *)urb->transfer_dma);
15460+ DWC_ERROR(" Setup buffer: %p, Setup DMA: %p\n",
15461+ urb->setup_packet, (void *)urb->setup_dma);
15462+ DWC_ERROR(" Interval: %d\n", urb->interval);
15463+
15464+ dwc_otg_hcd_complete_urb(hcd, urb, -EIO);
15465+
15466+ /*
15467+ * Force a channel halt. Don't call halt_channel because that won't
15468+ * write to the HCCHARn register in DMA mode to force the halt.
15469+ */
15470+ dwc_otg_hc_halt(hcd->core_if, hc, DWC_OTG_HC_XFER_AHB_ERR);
15471+
15472+ disable_hc_int(hc_regs, ahberr);
15473+ return 1;
15474+}
15475+
15476+/**
15477+ * Handles a host channel transaction error interrupt. This handler may be
15478+ * called in either DMA mode or Slave mode.
15479+ */
15480+static int32_t handle_hc_xacterr_intr(dwc_otg_hcd_t *hcd,
15481+ dwc_hc_t *hc,
15482+ dwc_otg_hc_regs_t *hc_regs,
15483+ dwc_otg_qtd_t *qtd)
15484+{
15485+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
15486+ "Transaction Error--\n", hc->hc_num);
15487+
15488+ switch (usb_pipetype(qtd->urb->pipe)) {
15489+ case PIPE_CONTROL:
15490+ case PIPE_BULK:
15491+ qtd->error_count++;
15492+ if (!hc->qh->ping_state) {
15493+ update_urb_state_xfer_intr(hc, hc_regs, qtd->urb,
15494+ qtd, DWC_OTG_HC_XFER_XACT_ERR);
15495+ save_data_toggle(hc, hc_regs, qtd);
15496+ if (!hc->ep_is_in && qtd->urb->dev->speed == USB_SPEED_HIGH) {
15497+ hc->qh->ping_state = 1;
15498+ }
15499+ }
15500+
15501+ /*
15502+ * Halt the channel so the transfer can be re-started from
15503+ * the appropriate point or the PING protocol will start.
15504+ */
15505+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_XACT_ERR);
15506+ break;
15507+ case PIPE_INTERRUPT:
15508+ qtd->error_count++;
15509+ if (hc->do_split && hc->complete_split) {
15510+ qtd->complete_split = 0;
15511+ }
15512+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_XACT_ERR);
15513+ break;
15514+ case PIPE_ISOCHRONOUS:
15515+ {
15516+ dwc_otg_halt_status_e halt_status;
15517+ halt_status = update_isoc_urb_state(hcd, hc, hc_regs, qtd,
15518+ DWC_OTG_HC_XFER_XACT_ERR);
15519+
15520+ halt_channel(hcd, hc, qtd, halt_status);
15521+ }
15522+ break;
15523+ }
15524+
15525+ disable_hc_int(hc_regs, xacterr);
15526+
15527+ return 1;
15528+}
15529+
15530+/**
15531+ * Handles a host channel frame overrun interrupt. This handler may be called
15532+ * in either DMA mode or Slave mode.
15533+ */
15534+static int32_t handle_hc_frmovrun_intr(dwc_otg_hcd_t *hcd,
15535+ dwc_hc_t *hc,
15536+ dwc_otg_hc_regs_t *hc_regs,
15537+ dwc_otg_qtd_t *qtd)
15538+{
15539+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
15540+ "Frame Overrun--\n", hc->hc_num);
15541+
15542+ switch (usb_pipetype(qtd->urb->pipe)) {
15543+ case PIPE_CONTROL:
15544+ case PIPE_BULK:
15545+ break;
15546+ case PIPE_INTERRUPT:
15547+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_FRAME_OVERRUN);
15548+ break;
15549+ case PIPE_ISOCHRONOUS:
15550+ {
15551+ dwc_otg_halt_status_e halt_status;
15552+ halt_status = update_isoc_urb_state(hcd, hc, hc_regs, qtd,
15553+ DWC_OTG_HC_XFER_FRAME_OVERRUN);
15554+
15555+ halt_channel(hcd, hc, qtd, halt_status);
15556+ }
15557+ break;
15558+ }
15559+
15560+ disable_hc_int(hc_regs, frmovrun);
15561+
15562+ return 1;
15563+}
15564+
15565+/**
15566+ * Handles a host channel data toggle error interrupt. This handler may be
15567+ * called in either DMA mode or Slave mode.
15568+ */
15569+static int32_t handle_hc_datatglerr_intr(dwc_otg_hcd_t *hcd,
15570+ dwc_hc_t *hc,
15571+ dwc_otg_hc_regs_t *hc_regs,
15572+ dwc_otg_qtd_t *qtd)
15573+{
15574+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
15575+ "Data Toggle Error--\n", hc->hc_num);
15576+
15577+ if (hc->ep_is_in) {
15578+ qtd->error_count = 0;
15579+ } else {
15580+ DWC_ERROR("Data Toggle Error on OUT transfer,"
15581+ "channel %d\n", hc->hc_num);
15582+ }
15583+
15584+ disable_hc_int(hc_regs, datatglerr);
15585+
15586+ return 1;
15587+}
15588+
15589+#ifdef DEBUG
15590+/**
15591+ * This function is for debug only. It checks that a valid halt status is set
15592+ * and that HCCHARn.chdis is clear. If there's a problem, corrective action is
15593+ * taken and a warning is issued.
15594+ * @return 1 if halt status is ok, 0 otherwise.
15595+ */
15596+static inline int halt_status_ok(dwc_otg_hcd_t *hcd,
15597+ dwc_hc_t *hc,
15598+ dwc_otg_hc_regs_t *hc_regs,
15599+ dwc_otg_qtd_t *qtd)
15600+{
15601+ hcchar_data_t hcchar;
15602+ hctsiz_data_t hctsiz;
15603+ hcint_data_t hcint;
15604+ hcintmsk_data_t hcintmsk;
15605+ hcsplt_data_t hcsplt;
15606+
15607+ if (hc->halt_status == DWC_OTG_HC_XFER_NO_HALT_STATUS) {
15608+ /*
15609+ * This code is here only as a check. This condition should
15610+ * never happen. Ignore the halt if it does occur.
15611+ */
15612+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
15613+ hctsiz.d32 = dwc_read_reg32(&hc_regs->hctsiz);
15614+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
15615+ hcintmsk.d32 = dwc_read_reg32(&hc_regs->hcintmsk);
15616+ hcsplt.d32 = dwc_read_reg32(&hc_regs->hcsplt);
15617+ DWC_WARN("%s: hc->halt_status == DWC_OTG_HC_XFER_NO_HALT_STATUS, "
15618+ "channel %d, hcchar 0x%08x, hctsiz 0x%08x, "
15619+ "hcint 0x%08x, hcintmsk 0x%08x, "
15620+ "hcsplt 0x%08x, qtd->complete_split %d\n",
15621+ __func__, hc->hc_num, hcchar.d32, hctsiz.d32,
15622+ hcint.d32, hcintmsk.d32,
15623+ hcsplt.d32, qtd->complete_split);
15624+
15625+ DWC_WARN("%s: no halt status, channel %d, ignoring interrupt\n",
15626+ __func__, hc->hc_num);
15627+ DWC_WARN("\n");
15628+ clear_hc_int(hc_regs, chhltd);
15629+ return 0;
15630+ }
15631+
15632+ /*
15633+ * This code is here only as a check. hcchar.chdis should
15634+ * never be set when the halt interrupt occurs. Halt the
15635+ * channel again if it does occur.
15636+ */
15637+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
15638+ if (hcchar.b.chdis) {
15639+ DWC_WARN("%s: hcchar.chdis set unexpectedly, "
15640+ "hcchar 0x%08x, trying to halt again\n",
15641+ __func__, hcchar.d32);
15642+ clear_hc_int(hc_regs, chhltd);
15643+ hc->halt_pending = 0;
15644+ halt_channel(hcd, hc, qtd, hc->halt_status);
15645+ return 0;
15646+ }
15647+
15648+ return 1;
15649+}
15650+#endif
15651+
15652+/**
15653+ * Handles a host Channel Halted interrupt in DMA mode. This handler
15654+ * determines the reason the channel halted and proceeds accordingly.
15655+ */
15656+static void handle_hc_chhltd_intr_dma(dwc_otg_hcd_t *hcd,
15657+ dwc_hc_t *hc,
15658+ dwc_otg_hc_regs_t *hc_regs,
15659+ dwc_otg_qtd_t *qtd)
15660+{
15661+ hcint_data_t hcint;
15662+ hcintmsk_data_t hcintmsk;
15663+ int out_nak_enh = 0;
15664+
15665+ /* For core with OUT NAK enhancement, the flow for high-
15666+ * speed CONTROL/BULK OUT is handled a little differently.
15667+ */
15668+ if (hcd->core_if->snpsid >= 0x4F54271A) {
15669+ if (hc->speed == DWC_OTG_EP_SPEED_HIGH && !hc->ep_is_in &&
15670+ (hc->ep_type == DWC_OTG_EP_TYPE_CONTROL ||
15671+ hc->ep_type == DWC_OTG_EP_TYPE_BULK)) {
15672+ DWC_DEBUGPL(DBG_HCD, "OUT NAK enhancement enabled\n");
15673+ out_nak_enh = 1;
15674+ } else {
15675+ DWC_DEBUGPL(DBG_HCD, "OUT NAK enhancement disabled, not HS Ctrl/Bulk OUT EP\n");
15676+ }
15677+ } else {
15678+ DWC_DEBUGPL(DBG_HCD, "OUT NAK enhancement disabled, no core support\n");
15679+ }
15680+
15681+ if (hc->halt_status == DWC_OTG_HC_XFER_URB_DEQUEUE ||
15682+ hc->halt_status == DWC_OTG_HC_XFER_AHB_ERR) {
15683+ /*
15684+ * Just release the channel. A dequeue can happen on a
15685+ * transfer timeout. In the case of an AHB Error, the channel
15686+ * was forced to halt because there's no way to gracefully
15687+ * recover.
15688+ */
15689+ release_channel(hcd, hc, qtd, hc->halt_status);
15690+ return;
15691+ }
15692+
15693+ /* Read the HCINTn register to determine the cause for the halt. */
15694+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
15695+ hcintmsk.d32 = dwc_read_reg32(&hc_regs->hcintmsk);
15696+
15697+ if (hcint.b.xfercomp) {
15698+ /** @todo This is here because of a possible hardware bug. Spec
15699+ * says that on SPLIT-ISOC OUT transfers in DMA mode that a HALT
15700+ * interrupt w/ACK bit set should occur, but I only see the
15701+ * XFERCOMP bit, even with it masked out. This is a workaround
15702+ * for that behavior. Should fix this when hardware is fixed.
15703+ */
15704+ if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC && !hc->ep_is_in) {
15705+ handle_hc_ack_intr(hcd, hc, hc_regs, qtd);
15706+ }
15707+ handle_hc_xfercomp_intr(hcd, hc, hc_regs, qtd);
15708+ } else if (hcint.b.stall) {
15709+ handle_hc_stall_intr(hcd, hc, hc_regs, qtd);
15710+ } else if (hcint.b.xacterr) {
15711+ if (out_nak_enh) {
15712+ if (hcint.b.nyet || hcint.b.nak || hcint.b.ack) {
15713+ printk(KERN_DEBUG "XactErr with NYET/NAK/ACK\n");
15714+ qtd->error_count = 0;
15715+ } else {
15716+ printk(KERN_DEBUG "XactErr without NYET/NAK/ACK\n");
15717+ }
15718+ }
15719+
15720+ /*
15721+ * Must handle xacterr before nak or ack. Could get a xacterr
15722+ * at the same time as either of these on a BULK/CONTROL OUT
15723+ * that started with a PING. The xacterr takes precedence.
15724+ */
15725+ handle_hc_xacterr_intr(hcd, hc, hc_regs, qtd);
15726+ } else if (!out_nak_enh) {
15727+ if (hcint.b.nyet) {
15728+ /*
15729+ * Must handle nyet before nak or ack. Could get a nyet at the
15730+ * same time as either of those on a BULK/CONTROL OUT that
15731+ * started with a PING. The nyet takes precedence.
15732+ */
15733+ handle_hc_nyet_intr(hcd, hc, hc_regs, qtd);
15734+ } else if (hcint.b.bblerr) {
15735+ handle_hc_babble_intr(hcd, hc, hc_regs, qtd);
15736+ } else if (hcint.b.frmovrun) {
15737+ handle_hc_frmovrun_intr(hcd, hc, hc_regs, qtd);
15738+ } else if (hcint.b.nak && !hcintmsk.b.nak) {
15739+ /*
15740+ * If nak is not masked, it's because a non-split IN transfer
15741+ * is in an error state. In that case, the nak is handled by
15742+ * the nak interrupt handler, not here. Handle nak here for
15743+ * BULK/CONTROL OUT transfers, which halt on a NAK to allow
15744+ * rewinding the buffer pointer.
15745+ */
15746+ handle_hc_nak_intr(hcd, hc, hc_regs, qtd);
15747+ } else if (hcint.b.ack && !hcintmsk.b.ack) {
15748+ /*
15749+ * If ack is not masked, it's because a non-split IN transfer
15750+ * is in an error state. In that case, the ack is handled by
15751+ * the ack interrupt handler, not here. Handle ack here for
15752+ * split transfers. Start splits halt on ACK.
15753+ */
15754+ handle_hc_ack_intr(hcd, hc, hc_regs, qtd);
15755+ } else {
15756+ if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
15757+ hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
15758+ /*
15759+ * A periodic transfer halted with no other channel
15760+ * interrupts set. Assume it was halted by the core
15761+ * because it could not be completed in its scheduled
15762+ * (micro)frame.
15763+ */
15764+#ifdef DEBUG
15765+ DWC_PRINT("%s: Halt channel %d (assume incomplete periodic transfer)\n",
15766+ __func__, hc->hc_num);
15767+#endif
15768+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_PERIODIC_INCOMPLETE);
15769+ } else {
15770+ DWC_ERROR("%s: Channel %d, DMA Mode -- ChHltd set, but reason "
15771+ "for halting is unknown, hcint 0x%08x, intsts 0x%08x\n",
15772+ __func__, hc->hc_num, hcint.d32,
15773+ dwc_read_reg32(&hcd->core_if->core_global_regs->gintsts));
15774+ }
15775+ }
15776+ } else {
15777+ printk(KERN_DEBUG "NYET/NAK/ACK/other in non-error case, 0x%08x\n", hcint.d32);
15778+ }
15779+}
15780+
15781+/**
15782+ * Handles a host channel Channel Halted interrupt.
15783+ *
15784+ * In slave mode, this handler is called only when the driver specifically
15785+ * requests a halt. This occurs during handling other host channel interrupts
15786+ * (e.g. nak, xacterr, stall, nyet, etc.).
15787+ *
15788+ * In DMA mode, this is the interrupt that occurs when the core has finished
15789+ * processing a transfer on a channel. Other host channel interrupts (except
15790+ * ahberr) are disabled in DMA mode.
15791+ */
15792+static int32_t handle_hc_chhltd_intr(dwc_otg_hcd_t *hcd,
15793+ dwc_hc_t *hc,
15794+ dwc_otg_hc_regs_t *hc_regs,
15795+ dwc_otg_qtd_t *qtd)
15796+{
15797+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
15798+ "Channel Halted--\n", hc->hc_num);
15799+
15800+ if (hcd->core_if->dma_enable) {
15801+ handle_hc_chhltd_intr_dma(hcd, hc, hc_regs, qtd);
15802+ } else {
15803+#ifdef DEBUG
15804+ if (!halt_status_ok(hcd, hc, hc_regs, qtd)) {
15805+ return 1;
15806+ }
15807+#endif
15808+ release_channel(hcd, hc, qtd, hc->halt_status);
15809+ }
15810+
15811+ return 1;
15812+}
15813+
15814+/** Handles interrupt for a specific Host Channel */
15815+int32_t dwc_otg_hcd_handle_hc_n_intr(dwc_otg_hcd_t *dwc_otg_hcd, uint32_t num)
15816+{
15817+ int retval = 0;
15818+ hcint_data_t hcint;
15819+ hcintmsk_data_t hcintmsk;
15820+ dwc_hc_t *hc;
15821+ dwc_otg_hc_regs_t *hc_regs;
15822+ dwc_otg_qtd_t *qtd;
15823+
15824+ DWC_DEBUGPL(DBG_HCDV, "--Host Channel Interrupt--, Channel %d\n", num);
15825+
15826+ hc = dwc_otg_hcd->hc_ptr_array[num];
15827+ hc_regs = dwc_otg_hcd->core_if->host_if->hc_regs[num];
15828+ qtd = list_entry(hc->qh->qtd_list.next, dwc_otg_qtd_t, qtd_list_entry);
15829+
15830+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
15831+ hcintmsk.d32 = dwc_read_reg32(&hc_regs->hcintmsk);
15832+ DWC_DEBUGPL(DBG_HCDV, " hcint 0x%08x, hcintmsk 0x%08x, hcint&hcintmsk 0x%08x\n",
15833+ hcint.d32, hcintmsk.d32, (hcint.d32 & hcintmsk.d32));
15834+ hcint.d32 = hcint.d32 & hcintmsk.d32;
15835+
15836+ if (!dwc_otg_hcd->core_if->dma_enable) {
15837+ if (hcint.b.chhltd && hcint.d32 != 0x2) {
15838+ hcint.b.chhltd = 0;
15839+ }
15840+ }
15841+
15842+ if (hcint.b.xfercomp) {
15843+ retval |= handle_hc_xfercomp_intr(dwc_otg_hcd, hc, hc_regs, qtd);
15844+ /*
15845+ * If NYET occurred at same time as Xfer Complete, the NYET is
15846+ * handled by the Xfer Complete interrupt handler. Don't want
15847+ * to call the NYET interrupt handler in this case.
15848+ */
15849+ hcint.b.nyet = 0;
15850+ }
15851+ if (hcint.b.chhltd) {
15852+ retval |= handle_hc_chhltd_intr(dwc_otg_hcd, hc, hc_regs, qtd);
15853+ }
15854+ if (hcint.b.ahberr) {
15855+ retval |= handle_hc_ahberr_intr(dwc_otg_hcd, hc, hc_regs, qtd);
15856+ }
15857+ if (hcint.b.stall) {
15858+ retval |= handle_hc_stall_intr(dwc_otg_hcd, hc, hc_regs, qtd);
15859+ }
15860+ if (hcint.b.nak) {
15861+ retval |= handle_hc_nak_intr(dwc_otg_hcd, hc, hc_regs, qtd);
15862+ }
15863+ if (hcint.b.ack) {
15864+ retval |= handle_hc_ack_intr(dwc_otg_hcd, hc, hc_regs, qtd);
15865+ }
15866+ if (hcint.b.nyet) {
15867+ retval |= handle_hc_nyet_intr(dwc_otg_hcd, hc, hc_regs, qtd);
15868+ }
15869+ if (hcint.b.xacterr) {
15870+ retval |= handle_hc_xacterr_intr(dwc_otg_hcd, hc, hc_regs, qtd);
15871+ }
15872+ if (hcint.b.bblerr) {
15873+ retval |= handle_hc_babble_intr(dwc_otg_hcd, hc, hc_regs, qtd);
15874+ }
15875+ if (hcint.b.frmovrun) {
15876+ retval |= handle_hc_frmovrun_intr(dwc_otg_hcd, hc, hc_regs, qtd);
15877+ }
15878+ if (hcint.b.datatglerr) {
15879+ retval |= handle_hc_datatglerr_intr(dwc_otg_hcd, hc, hc_regs, qtd);
15880+ }
15881+
15882+ return retval;
15883+}
15884+
15885+#endif /* DWC_DEVICE_ONLY */
15886--- /dev/null
15887+++ b/drivers/usb/host/otg/dwc_otg_hcd_queue.c
15888@@ -0,0 +1,716 @@
15889+/* ==========================================================================
15890+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd_queue.c $
15891+ * $Revision: #33 $
15892+ * $Date: 2008/07/15 $
15893+ * $Change: 1064918 $
15894+ *
15895+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
15896+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
15897+ * otherwise expressly agreed to in writing between Synopsys and you.
15898+ *
15899+ * The Software IS NOT an item of Licensed Software or Licensed Product under
15900+ * any End User Software License Agreement or Agreement for Licensed Product
15901+ * with Synopsys or any supplement thereto. You are permitted to use and
15902+ * redistribute this Software in source and binary forms, with or without
15903+ * modification, provided that redistributions of source code must retain this
15904+ * notice. You may not view, use, disclose, copy or distribute this file or
15905+ * any information contained herein except pursuant to this license grant from
15906+ * Synopsys. If you do not agree with this notice, including the disclaimer
15907+ * below, then you are not authorized to use the Software.
15908+ *
15909+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
15910+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15911+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
15912+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
15913+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
15914+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
15915+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
15916+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
15917+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
15918+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
15919+ * DAMAGE.
15920+ * ========================================================================== */
15921+#ifndef DWC_DEVICE_ONLY
15922+
15923+/**
15924+ * @file
15925+ *
15926+ * This file contains the functions to manage Queue Heads and Queue
15927+ * Transfer Descriptors.
15928+ */
15929+#include <linux/kernel.h>
15930+#include <linux/module.h>
15931+#include <linux/moduleparam.h>
15932+#include <linux/init.h>
15933+#include <linux/device.h>
15934+#include <linux/errno.h>
15935+#include <linux/list.h>
15936+#include <linux/interrupt.h>
15937+#include <linux/string.h>
15938+#include <linux/version.h>
15939+
15940+#include <mach/lm.h>
15941+#include <mach/irqs.h>
15942+
15943+#include "dwc_otg_driver.h"
15944+#include "dwc_otg_hcd.h"
15945+#include "dwc_otg_regs.h"
15946+
15947+/**
15948+ * This function allocates and initializes a QH.
15949+ *
15950+ * @param hcd The HCD state structure for the DWC OTG controller.
15951+ * @param[in] urb Holds the information about the device/endpoint that we need
15952+ * to initialize the QH.
15953+ *
15954+ * @return Returns pointer to the newly allocated QH, or NULL on error. */
15955+dwc_otg_qh_t *dwc_otg_hcd_qh_create (dwc_otg_hcd_t *hcd, struct urb *urb)
15956+{
15957+ dwc_otg_qh_t *qh;
15958+
15959+ /* Allocate memory */
15960+ /** @todo add memflags argument */
15961+ qh = dwc_otg_hcd_qh_alloc ();
15962+ if (qh == NULL) {
15963+ return NULL;
15964+ }
15965+
15966+ dwc_otg_hcd_qh_init (hcd, qh, urb);
15967+ return qh;
15968+}
15969+
15970+/** Free each QTD in the QH's QTD-list then free the QH. QH should already be
15971+ * removed from a list. QTD list should already be empty if called from URB
15972+ * Dequeue.
15973+ *
15974+ * @param[in] hcd HCD instance.
15975+ * @param[in] qh The QH to free.
15976+ */
15977+void dwc_otg_hcd_qh_free (dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh)
15978+{
15979+ dwc_otg_qtd_t *qtd;
15980+ struct list_head *pos;
15981+ //unsigned long flags;
15982+
15983+ /* Free each QTD in the QTD list */
15984+
15985+#if CONFIG_SMP
15986+ //the spinlock is locked before this function get called,
15987+ //but in case the lock is needed, the check function is preserved
15988+
15989+ //but in non-SMP mode, all spinlock is lockable.
15990+ //don't do the test in non-SMP mode
15991+
15992+ if(spin_trylock(&hcd->lock)) {
15993+ printk("%s: It is not supposed to be lockable!!\n",__func__);
15994+ BUG();
15995+ }
15996+#endif
15997+// SPIN_LOCK_IRQSAVE(&hcd->lock, flags)
15998+ for (pos = qh->qtd_list.next;
15999+ pos != &qh->qtd_list;
16000+ pos = qh->qtd_list.next)
16001+ {
16002+ list_del (pos);
16003+ qtd = dwc_list_to_qtd (pos);
16004+ dwc_otg_hcd_qtd_free (qtd);
16005+ }
16006+// SPIN_UNLOCK_IRQRESTORE(&hcd->lock, flags)
16007+
16008+ kfree (qh);
16009+ return;
16010+}
16011+
16012+/** Initializes a QH structure.
16013+ *
16014+ * @param[in] hcd The HCD state structure for the DWC OTG controller.
16015+ * @param[in] qh The QH to init.
16016+ * @param[in] urb Holds the information about the device/endpoint that we need
16017+ * to initialize the QH. */
16018+#define SCHEDULE_SLOP 10
16019+void dwc_otg_hcd_qh_init(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh, struct urb *urb)
16020+{
16021+ char *speed, *type;
16022+ memset (qh, 0, sizeof (dwc_otg_qh_t));
16023+
16024+ /* Initialize QH */
16025+ switch (usb_pipetype(urb->pipe)) {
16026+ case PIPE_CONTROL:
16027+ qh->ep_type = USB_ENDPOINT_XFER_CONTROL;
16028+ break;
16029+ case PIPE_BULK:
16030+ qh->ep_type = USB_ENDPOINT_XFER_BULK;
16031+ break;
16032+ case PIPE_ISOCHRONOUS:
16033+ qh->ep_type = USB_ENDPOINT_XFER_ISOC;
16034+ break;
16035+ case PIPE_INTERRUPT:
16036+ qh->ep_type = USB_ENDPOINT_XFER_INT;
16037+ break;
16038+ }
16039+
16040+ qh->ep_is_in = usb_pipein(urb->pipe) ? 1 : 0;
16041+
16042+ qh->data_toggle = DWC_OTG_HC_PID_DATA0;
16043+ qh->maxp = usb_maxpacket(urb->dev, urb->pipe, !(usb_pipein(urb->pipe)));
16044+ INIT_LIST_HEAD(&qh->qtd_list);
16045+ INIT_LIST_HEAD(&qh->qh_list_entry);
16046+ qh->channel = NULL;
16047+
16048+ /* FS/LS Enpoint on HS Hub
16049+ * NOT virtual root hub */
16050+ qh->do_split = 0;
16051+ if (((urb->dev->speed == USB_SPEED_LOW) ||
16052+ (urb->dev->speed == USB_SPEED_FULL)) &&
16053+ (urb->dev->tt) && (urb->dev->tt->hub) && (urb->dev->tt->hub->devnum != 1))
16054+ {
16055+ DWC_DEBUGPL(DBG_HCD, "QH init: EP %d: TT found at hub addr %d, for port %d\n",
16056+ usb_pipeendpoint(urb->pipe), urb->dev->tt->hub->devnum,
16057+ urb->dev->ttport);
16058+ qh->do_split = 1;
16059+ }
16060+
16061+ if (qh->ep_type == USB_ENDPOINT_XFER_INT ||
16062+ qh->ep_type == USB_ENDPOINT_XFER_ISOC) {
16063+ /* Compute scheduling parameters once and save them. */
16064+ hprt0_data_t hprt;
16065+
16066+ /** @todo Account for split transfers in the bus time. */
16067+ int bytecount = dwc_hb_mult(qh->maxp) * dwc_max_packet(qh->maxp);
16068+ qh->usecs = usb_calc_bus_time(urb->dev->speed,
16069+ usb_pipein(urb->pipe),
16070+ (qh->ep_type == USB_ENDPOINT_XFER_ISOC),
16071+ bytecount);
16072+
16073+ /* Start in a slightly future (micro)frame. */
16074+ qh->sched_frame = dwc_frame_num_inc(hcd->frame_number,
16075+ SCHEDULE_SLOP);
16076+ qh->interval = urb->interval;
16077+#if 0
16078+ /* Increase interrupt polling rate for debugging. */
16079+ if (qh->ep_type == USB_ENDPOINT_XFER_INT) {
16080+ qh->interval = 8;
16081+ }
16082+#endif
16083+ hprt.d32 = dwc_read_reg32(hcd->core_if->host_if->hprt0);
16084+ if ((hprt.b.prtspd == DWC_HPRT0_PRTSPD_HIGH_SPEED) &&
16085+ ((urb->dev->speed == USB_SPEED_LOW) ||
16086+ (urb->dev->speed == USB_SPEED_FULL))) {
16087+ qh->interval *= 8;
16088+ qh->sched_frame |= 0x7;
16089+ qh->start_split_frame = qh->sched_frame;
16090+ }
16091+
16092+ }
16093+
16094+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD QH Initialized\n");
16095+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - qh = %p\n", qh);
16096+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - Device Address = %d\n",
16097+ urb->dev->devnum);
16098+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - Endpoint %d, %s\n",
16099+ usb_pipeendpoint(urb->pipe),
16100+ usb_pipein(urb->pipe) == USB_DIR_IN ? "IN" : "OUT");
16101+
16102+ switch(urb->dev->speed) {
16103+ case USB_SPEED_LOW:
16104+ speed = "low";
16105+ break;
16106+ case USB_SPEED_FULL:
16107+ speed = "full";
16108+ break;
16109+ case USB_SPEED_HIGH:
16110+ speed = "high";
16111+ break;
16112+ default:
16113+ speed = "?";
16114+ break;
16115+ }
16116+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - Speed = %s\n", speed);
16117+
16118+ switch (qh->ep_type) {
16119+ case USB_ENDPOINT_XFER_ISOC:
16120+ type = "isochronous";
16121+ break;
16122+ case USB_ENDPOINT_XFER_INT:
16123+ type = "interrupt";
16124+ break;
16125+ case USB_ENDPOINT_XFER_CONTROL:
16126+ type = "control";
16127+ break;
16128+ case USB_ENDPOINT_XFER_BULK:
16129+ type = "bulk";
16130+ break;
16131+ default:
16132+ type = "?";
16133+ break;
16134+ }
16135+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - Type = %s\n",type);
16136+
16137+#ifdef DEBUG
16138+ if (qh->ep_type == USB_ENDPOINT_XFER_INT) {
16139+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - usecs = %d\n",
16140+ qh->usecs);
16141+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - interval = %d\n",
16142+ qh->interval);
16143+ }
16144+#endif
16145+
16146+ return;
16147+}
16148+
16149+/**
16150+ * Checks that a channel is available for a periodic transfer.
16151+ *
16152+ * @return 0 if successful, negative error code otherise.
16153+ */
16154+static int periodic_channel_available(dwc_otg_hcd_t *hcd)
16155+{
16156+ /*
16157+ * Currently assuming that there is a dedicated host channnel for each
16158+ * periodic transaction plus at least one host channel for
16159+ * non-periodic transactions.
16160+ */
16161+ int status;
16162+ int num_channels;
16163+
16164+ num_channels = hcd->core_if->core_params->host_channels;
16165+ if ((hcd->periodic_channels + hcd->non_periodic_channels < num_channels) &&
16166+ (hcd->periodic_channels < num_channels - 1)) {
16167+ status = 0;
16168+ }
16169+ else {
16170+ DWC_NOTICE("%s: Total channels: %d, Periodic: %d, Non-periodic: %d\n",
16171+ __func__, num_channels, hcd->periodic_channels,
16172+ hcd->non_periodic_channels);
16173+ status = -ENOSPC;
16174+ }
16175+
16176+ return status;
16177+}
16178+
16179+/**
16180+ * Checks that there is sufficient bandwidth for the specified QH in the
16181+ * periodic schedule. For simplicity, this calculation assumes that all the
16182+ * transfers in the periodic schedule may occur in the same (micro)frame.
16183+ *
16184+ * @param hcd The HCD state structure for the DWC OTG controller.
16185+ * @param qh QH containing periodic bandwidth required.
16186+ *
16187+ * @return 0 if successful, negative error code otherwise.
16188+ */
16189+static int check_periodic_bandwidth(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh)
16190+{
16191+ int status;
16192+ uint16_t max_claimed_usecs;
16193+
16194+ status = 0;
16195+
16196+ if (hcd->core_if->core_params->speed == DWC_SPEED_PARAM_HIGH) {
16197+ /*
16198+ * High speed mode.
16199+ * Max periodic usecs is 80% x 125 usec = 100 usec.
16200+ */
16201+ max_claimed_usecs = 100 - qh->usecs;
16202+ } else {
16203+ /*
16204+ * Full speed mode.
16205+ * Max periodic usecs is 90% x 1000 usec = 900 usec.
16206+ */
16207+ max_claimed_usecs = 900 - qh->usecs;
16208+ }
16209+
16210+ if (hcd->periodic_usecs > max_claimed_usecs) {
16211+ DWC_NOTICE("%s: already claimed usecs %d, required usecs %d\n",
16212+ __func__, hcd->periodic_usecs, qh->usecs);
16213+ status = -ENOSPC;
16214+ }
16215+
16216+ return status;
16217+}
16218+
16219+/**
16220+ * Checks that the max transfer size allowed in a host channel is large enough
16221+ * to handle the maximum data transfer in a single (micro)frame for a periodic
16222+ * transfer.
16223+ *
16224+ * @param hcd The HCD state structure for the DWC OTG controller.
16225+ * @param qh QH for a periodic endpoint.
16226+ *
16227+ * @return 0 if successful, negative error code otherwise.
16228+ */
16229+static int check_max_xfer_size(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh)
16230+{
16231+ int status;
16232+ uint32_t max_xfer_size;
16233+ uint32_t max_channel_xfer_size;
16234+
16235+ status = 0;
16236+
16237+ max_xfer_size = dwc_max_packet(qh->maxp) * dwc_hb_mult(qh->maxp);
16238+ max_channel_xfer_size = hcd->core_if->core_params->max_transfer_size;
16239+
16240+ if (max_xfer_size > max_channel_xfer_size) {
16241+ DWC_NOTICE("%s: Periodic xfer length %d > "
16242+ "max xfer length for channel %d\n",
16243+ __func__, max_xfer_size, max_channel_xfer_size);
16244+ status = -ENOSPC;
16245+ }
16246+
16247+ return status;
16248+}
16249+
16250+/**
16251+ * Schedules an interrupt or isochronous transfer in the periodic schedule.
16252+ *
16253+ * @param hcd The HCD state structure for the DWC OTG controller.
16254+ * @param qh QH for the periodic transfer. The QH should already contain the
16255+ * scheduling information.
16256+ *
16257+ * @return 0 if successful, negative error code otherwise.
16258+ */
16259+static int schedule_periodic(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh)
16260+{
16261+ int status = 0;
16262+
16263+ status = periodic_channel_available(hcd);
16264+ if (status) {
16265+ DWC_NOTICE("%s: No host channel available for periodic "
16266+ "transfer.\n", __func__);
16267+ return status;
16268+ }
16269+
16270+ status = check_periodic_bandwidth(hcd, qh);
16271+ if (status) {
16272+ DWC_NOTICE("%s: Insufficient periodic bandwidth for "
16273+ "periodic transfer.\n", __func__);
16274+ return status;
16275+ }
16276+
16277+ status = check_max_xfer_size(hcd, qh);
16278+ if (status) {
16279+ DWC_NOTICE("%s: Channel max transfer size too small "
16280+ "for periodic transfer.\n", __func__);
16281+ return status;
16282+ }
16283+
16284+ /* Always start in the inactive schedule. */
16285+ list_add_tail(&qh->qh_list_entry, &hcd->periodic_sched_inactive);
16286+
16287+ /* Reserve the periodic channel. */
16288+ hcd->periodic_channels++;
16289+
16290+ /* Update claimed usecs per (micro)frame. */
16291+ hcd->periodic_usecs += qh->usecs;
16292+
16293+ /* Update average periodic bandwidth claimed and # periodic reqs for usbfs. */
16294+ hcd_to_bus(dwc_otg_hcd_to_hcd(hcd))->bandwidth_allocated += qh->usecs / qh->interval;
16295+ if (qh->ep_type == USB_ENDPOINT_XFER_INT) {
16296+ hcd_to_bus(dwc_otg_hcd_to_hcd(hcd))->bandwidth_int_reqs++;
16297+ DWC_DEBUGPL(DBG_HCD, "Scheduled intr: qh %p, usecs %d, period %d\n",
16298+ qh, qh->usecs, qh->interval);
16299+ } else {
16300+ hcd_to_bus(dwc_otg_hcd_to_hcd(hcd))->bandwidth_isoc_reqs++;
16301+ DWC_DEBUGPL(DBG_HCD, "Scheduled isoc: qh %p, usecs %d, period %d\n",
16302+ qh, qh->usecs, qh->interval);
16303+ }
16304+
16305+ return status;
16306+}
16307+
16308+/**
16309+ * This function adds a QH to either the non periodic or periodic schedule if
16310+ * it is not already in the schedule. If the QH is already in the schedule, no
16311+ * action is taken.
16312+ *
16313+ * @return 0 if successful, negative error code otherwise.
16314+ */
16315+int dwc_otg_hcd_qh_add (dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh)
16316+{
16317+ //unsigned long flags;
16318+ int status = 0;
16319+
16320+#if CONFIG_SMP
16321+ //the spinlock is locked before this function get called,
16322+ //but in case the lock is needed, the check function is preserved
16323+
16324+ //but in non-SMP mode, all spinlock is lockable.
16325+ //don't do the test in non-SMP mode
16326+
16327+ if(spin_trylock(&hcd->lock)) {
16328+ printk("%s: It is not supposed to be lockable!!\n",__func__);
16329+ BUG();
16330+ }
16331+#endif
16332+// SPIN_LOCK_IRQSAVE(&hcd->lock, flags)
16333+
16334+ if (!list_empty(&qh->qh_list_entry)) {
16335+ /* QH already in a schedule. */
16336+ goto done;
16337+ }
16338+
16339+ /* Add the new QH to the appropriate schedule */
16340+ if (dwc_qh_is_non_per(qh)) {
16341+ /* Always start in the inactive schedule. */
16342+ list_add_tail(&qh->qh_list_entry, &hcd->non_periodic_sched_inactive);
16343+ } else {
16344+ status = schedule_periodic(hcd, qh);
16345+ }
16346+
16347+ done:
16348+// SPIN_UNLOCK_IRQRESTORE(&hcd->lock, flags)
16349+
16350+ return status;
16351+}
16352+
16353+/**
16354+ * Removes an interrupt or isochronous transfer from the periodic schedule.
16355+ *
16356+ * @param hcd The HCD state structure for the DWC OTG controller.
16357+ * @param qh QH for the periodic transfer.
16358+ */
16359+static void deschedule_periodic(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh)
16360+{
16361+ list_del_init(&qh->qh_list_entry);
16362+
16363+ /* Release the periodic channel reservation. */
16364+ hcd->periodic_channels--;
16365+
16366+ /* Update claimed usecs per (micro)frame. */
16367+ hcd->periodic_usecs -= qh->usecs;
16368+
16369+ /* Update average periodic bandwidth claimed and # periodic reqs for usbfs. */
16370+ hcd_to_bus(dwc_otg_hcd_to_hcd(hcd))->bandwidth_allocated -= qh->usecs / qh->interval;
16371+
16372+ if (qh->ep_type == USB_ENDPOINT_XFER_INT) {
16373+ hcd_to_bus(dwc_otg_hcd_to_hcd(hcd))->bandwidth_int_reqs--;
16374+ DWC_DEBUGPL(DBG_HCD, "Descheduled intr: qh %p, usecs %d, period %d\n",
16375+ qh, qh->usecs, qh->interval);
16376+ } else {
16377+ hcd_to_bus(dwc_otg_hcd_to_hcd(hcd))->bandwidth_isoc_reqs--;
16378+ DWC_DEBUGPL(DBG_HCD, "Descheduled isoc: qh %p, usecs %d, period %d\n",
16379+ qh, qh->usecs, qh->interval);
16380+ }
16381+}
16382+
16383+/**
16384+ * Removes a QH from either the non-periodic or periodic schedule. Memory is
16385+ * not freed.
16386+ *
16387+ * @param[in] hcd The HCD state structure.
16388+ * @param[in] qh QH to remove from schedule. */
16389+void dwc_otg_hcd_qh_remove (dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh)
16390+{
16391+ //unsigned long flags;
16392+
16393+#if CONFIG_SMP
16394+ //the spinlock is locked before this function get called,
16395+ //but in case the lock is needed, the check function is preserved
16396+
16397+ //but in non-SMP mode, all spinlock is lockable.
16398+ //don't do the test in non-SMP mode
16399+
16400+ if(spin_trylock(&hcd->lock)) {
16401+ printk("%s: It is not supposed to be lockable!!\n",__func__);
16402+ BUG();
16403+ }
16404+#endif
16405+// SPIN_LOCK_IRQSAVE(&hcd->lock, flags);
16406+
16407+ if (list_empty(&qh->qh_list_entry)) {
16408+ /* QH is not in a schedule. */
16409+ goto done;
16410+ }
16411+
16412+ if (dwc_qh_is_non_per(qh)) {
16413+ if (hcd->non_periodic_qh_ptr == &qh->qh_list_entry) {
16414+ hcd->non_periodic_qh_ptr = hcd->non_periodic_qh_ptr->next;
16415+ }
16416+ list_del_init(&qh->qh_list_entry);
16417+ } else {
16418+ deschedule_periodic(hcd, qh);
16419+ }
16420+
16421+ done:
16422+// SPIN_UNLOCK_IRQRESTORE(&hcd->lock, flags);
16423+ return;
16424+}
16425+
16426+/**
16427+ * Deactivates a QH. For non-periodic QHs, removes the QH from the active
16428+ * non-periodic schedule. The QH is added to the inactive non-periodic
16429+ * schedule if any QTDs are still attached to the QH.
16430+ *
16431+ * For periodic QHs, the QH is removed from the periodic queued schedule. If
16432+ * there are any QTDs still attached to the QH, the QH is added to either the
16433+ * periodic inactive schedule or the periodic ready schedule and its next
16434+ * scheduled frame is calculated. The QH is placed in the ready schedule if
16435+ * the scheduled frame has been reached already. Otherwise it's placed in the
16436+ * inactive schedule. If there are no QTDs attached to the QH, the QH is
16437+ * completely removed from the periodic schedule.
16438+ */
16439+void dwc_otg_hcd_qh_deactivate(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh, int sched_next_periodic_split)
16440+{
16441+ unsigned long flags;
16442+ SPIN_LOCK_IRQSAVE(&hcd->lock, flags);
16443+
16444+ if (dwc_qh_is_non_per(qh)) {
16445+ dwc_otg_hcd_qh_remove(hcd, qh);
16446+ if (!list_empty(&qh->qtd_list)) {
16447+ /* Add back to inactive non-periodic schedule. */
16448+ dwc_otg_hcd_qh_add(hcd, qh);
16449+ }
16450+ } else {
16451+ uint16_t frame_number = dwc_otg_hcd_get_frame_number(dwc_otg_hcd_to_hcd(hcd));
16452+
16453+ if (qh->do_split) {
16454+ /* Schedule the next continuing periodic split transfer */
16455+ if (sched_next_periodic_split) {
16456+
16457+ qh->sched_frame = frame_number;
16458+ if (dwc_frame_num_le(frame_number,
16459+ dwc_frame_num_inc(qh->start_split_frame, 1))) {
16460+ /*
16461+ * Allow one frame to elapse after start
16462+ * split microframe before scheduling
16463+ * complete split, but DONT if we are
16464+ * doing the next start split in the
16465+ * same frame for an ISOC out.
16466+ */
16467+ if ((qh->ep_type != USB_ENDPOINT_XFER_ISOC) || (qh->ep_is_in != 0)) {
16468+ qh->sched_frame = dwc_frame_num_inc(qh->sched_frame, 1);
16469+ }
16470+ }
16471+ } else {
16472+ qh->sched_frame = dwc_frame_num_inc(qh->start_split_frame,
16473+ qh->interval);
16474+ if (dwc_frame_num_le(qh->sched_frame, frame_number)) {
16475+ qh->sched_frame = frame_number;
16476+ }
16477+ qh->sched_frame |= 0x7;
16478+ qh->start_split_frame = qh->sched_frame;
16479+ }
16480+ } else {
16481+ qh->sched_frame = dwc_frame_num_inc(qh->sched_frame, qh->interval);
16482+ if (dwc_frame_num_le(qh->sched_frame, frame_number)) {
16483+ qh->sched_frame = frame_number;
16484+ }
16485+ }
16486+
16487+ if (list_empty(&qh->qtd_list)) {
16488+ dwc_otg_hcd_qh_remove(hcd, qh);
16489+ } else {
16490+ /*
16491+ * Remove from periodic_sched_queued and move to
16492+ * appropriate queue.
16493+ */
16494+ if (qh->sched_frame == frame_number) {
16495+ list_move(&qh->qh_list_entry,
16496+ &hcd->periodic_sched_ready);
16497+ } else {
16498+ list_move(&qh->qh_list_entry,
16499+ &hcd->periodic_sched_inactive);
16500+ }
16501+ }
16502+ }
16503+
16504+ SPIN_UNLOCK_IRQRESTORE(&hcd->lock, flags);
16505+}
16506+
16507+/**
16508+ * This function allocates and initializes a QTD.
16509+ *
16510+ * @param[in] urb The URB to create a QTD from. Each URB-QTD pair will end up
16511+ * pointing to each other so each pair should have a unique correlation.
16512+ *
16513+ * @return Returns pointer to the newly allocated QTD, or NULL on error. */
16514+dwc_otg_qtd_t *dwc_otg_hcd_qtd_create (struct urb *urb)
16515+{
16516+ dwc_otg_qtd_t *qtd;
16517+
16518+ qtd = dwc_otg_hcd_qtd_alloc ();
16519+ if (qtd == NULL) {
16520+ return NULL;
16521+ }
16522+
16523+ dwc_otg_hcd_qtd_init (qtd, urb);
16524+ return qtd;
16525+}
16526+
16527+/**
16528+ * Initializes a QTD structure.
16529+ *
16530+ * @param[in] qtd The QTD to initialize.
16531+ * @param[in] urb The URB to use for initialization. */
16532+void dwc_otg_hcd_qtd_init (dwc_otg_qtd_t *qtd, struct urb *urb)
16533+{
16534+ memset (qtd, 0, sizeof (dwc_otg_qtd_t));
16535+ qtd->urb = urb;
16536+ if (usb_pipecontrol(urb->pipe)) {
16537+ /*
16538+ * The only time the QTD data toggle is used is on the data
16539+ * phase of control transfers. This phase always starts with
16540+ * DATA1.
16541+ */
16542+ qtd->data_toggle = DWC_OTG_HC_PID_DATA1;
16543+ qtd->control_phase = DWC_OTG_CONTROL_SETUP;
16544+ }
16545+
16546+ /* start split */
16547+ qtd->complete_split = 0;
16548+ qtd->isoc_split_pos = DWC_HCSPLIT_XACTPOS_ALL;
16549+ qtd->isoc_split_offset = 0;
16550+
16551+ /* Store the qtd ptr in the urb to reference what QTD. */
16552+ urb->hcpriv = qtd;
16553+ return;
16554+}
16555+
16556+/**
16557+ * This function adds a QTD to the QTD-list of a QH. It will find the correct
16558+ * QH to place the QTD into. If it does not find a QH, then it will create a
16559+ * new QH. If the QH to which the QTD is added is not currently scheduled, it
16560+ * is placed into the proper schedule based on its EP type.
16561+ *
16562+ * @param[in] qtd The QTD to add
16563+ * @param[in] dwc_otg_hcd The DWC HCD structure
16564+ *
16565+ * @return 0 if successful, negative error code otherwise.
16566+ */
16567+int dwc_otg_hcd_qtd_add (dwc_otg_qtd_t *qtd,
16568+ dwc_otg_hcd_t *dwc_otg_hcd)
16569+{
16570+ struct usb_host_endpoint *ep;
16571+ dwc_otg_qh_t *qh;
16572+ unsigned long flags;
16573+ int retval = 0;
16574+
16575+ struct urb *urb = qtd->urb;
16576+
16577+ SPIN_LOCK_IRQSAVE(&dwc_otg_hcd->lock, flags);
16578+
16579+ /*
16580+ * Get the QH which holds the QTD-list to insert to. Create QH if it
16581+ * doesn't exist.
16582+ */
16583+ ep = dwc_urb_to_endpoint(urb);
16584+ qh = (dwc_otg_qh_t *)ep->hcpriv;
16585+ if (qh == NULL) {
16586+ qh = dwc_otg_hcd_qh_create (dwc_otg_hcd, urb);
16587+ if (qh == NULL) {
16588+ goto done;
16589+ }
16590+ ep->hcpriv = qh;
16591+ }
16592+
16593+ retval = dwc_otg_hcd_qh_add(dwc_otg_hcd, qh);
16594+ if (retval == 0) {
16595+ list_add_tail(&qtd->qtd_list_entry, &qh->qtd_list);
16596+ }
16597+
16598+ done:
16599+ SPIN_UNLOCK_IRQRESTORE(&dwc_otg_hcd->lock, flags);
16600+
16601+ return retval;
16602+}
16603+
16604+#endif /* DWC_DEVICE_ONLY */
16605--- /dev/null
16606+++ b/drivers/usb/host/otg/dwc_otg_pcd.c
16607@@ -0,0 +1,2542 @@
16608+/* ==========================================================================
16609+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_pcd.c $
16610+ * $Revision: #70 $
16611+ * $Date: 2008/10/14 $
16612+ * $Change: 1115682 $
16613+ *
16614+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
16615+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
16616+ * otherwise expressly agreed to in writing between Synopsys and you.
16617+ *
16618+ * The Software IS NOT an item of Licensed Software or Licensed Product under
16619+ * any End User Software License Agreement or Agreement for Licensed Product
16620+ * with Synopsys or any supplement thereto. You are permitted to use and
16621+ * redistribute this Software in source and binary forms, with or without
16622+ * modification, provided that redistributions of source code must retain this
16623+ * notice. You may not view, use, disclose, copy or distribute this file or
16624+ * any information contained herein except pursuant to this license grant from
16625+ * Synopsys. If you do not agree with this notice, including the disclaimer
16626+ * below, then you are not authorized to use the Software.
16627+ *
16628+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
16629+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16630+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16631+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
16632+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16633+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
16634+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
16635+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
16636+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
16637+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
16638+ * DAMAGE.
16639+ * ========================================================================== */
16640+#ifndef DWC_HOST_ONLY
16641+
16642+/** @file
16643+ * This file implements the Peripheral Controller Driver.
16644+ *
16645+ * The Peripheral Controller Driver (PCD) is responsible for
16646+ * translating requests from the Function Driver into the appropriate
16647+ * actions on the DWC_otg controller. It isolates the Function Driver
16648+ * from the specifics of the controller by providing an API to the
16649+ * Function Driver.
16650+ *
16651+ * The Peripheral Controller Driver for Linux will implement the
16652+ * Gadget API, so that the existing Gadget drivers can be used.
16653+ * (Gadget Driver is the Linux terminology for a Function Driver.)
16654+ *
16655+ * The Linux Gadget API is defined in the header file
16656+ * <code><linux/usb_gadget.h></code>. The USB EP operations API is
16657+ * defined in the structure <code>usb_ep_ops</code> and the USB
16658+ * Controller API is defined in the structure
16659+ * <code>usb_gadget_ops</code>.
16660+ *
16661+ * An important function of the PCD is managing interrupts generated
16662+ * by the DWC_otg controller. The implementation of the DWC_otg device
16663+ * mode interrupt service routines is in dwc_otg_pcd_intr.c.
16664+ *
16665+ * @todo Add Device Mode test modes (Test J mode, Test K mode, etc).
16666+ * @todo Does it work when the request size is greater than DEPTSIZ
16667+ * transfer size
16668+ *
16669+ */
16670+
16671+
16672+#include <linux/kernel.h>
16673+#include <linux/module.h>
16674+#include <linux/moduleparam.h>
16675+#include <linux/init.h>
16676+#include <linux/device.h>
16677+#include <linux/errno.h>
16678+#include <linux/list.h>
16679+#include <linux/interrupt.h>
16680+#include <linux/string.h>
16681+#include <linux/dma-mapping.h>
16682+#include <linux/version.h>
16683+
16684+//#include <asm/arch/lm.h>
16685+#include <mach/lm.h>
16686+#include <mach/irqs.h>
16687+
16688+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
16689+# include <linux/usb/ch9.h>
16690+#else
16691+# include <linux/usb_ch9.h>
16692+#endif
16693+
16694+//#include <linux/usb_gadget.h>
16695+
16696+
16697+
16698+#include "dwc_otg_driver.h"
16699+#include "dwc_otg_pcd.h"
16700+
16701+
16702+
16703+/**
16704+ * Static PCD pointer for use in usb_gadget_register_driver and
16705+ * usb_gadget_unregister_driver. Initialized in dwc_otg_pcd_init.
16706+ */
16707+static dwc_otg_pcd_t *s_pcd = 0;
16708+
16709+
16710+/* Display the contents of the buffer */
16711+extern void dump_msg(const u8 *buf, unsigned int length);
16712+
16713+
16714+/**
16715+ * This function completes a request. It call's the request call back.
16716+ */
16717+void dwc_otg_request_done(dwc_otg_pcd_ep_t *ep, dwc_otg_pcd_request_t *req,
16718+ int status)
16719+{
16720+ unsigned stopped = ep->stopped;
16721+
16722+ DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, ep);
16723+ list_del_init(&req->queue);
16724+
16725+ if (req->req.status == -EINPROGRESS) {
16726+ req->req.status = status;
16727+ } else {
16728+ status = req->req.status;
16729+ }
16730+
16731+ /* don't modify queue heads during completion callback */
16732+ ep->stopped = 1;
16733+ SPIN_UNLOCK(&ep->pcd->lock);
16734+ req->req.complete(&ep->ep, &req->req);
16735+ SPIN_LOCK(&ep->pcd->lock);
16736+
16737+ if (ep->pcd->request_pending > 0) {
16738+ --ep->pcd->request_pending;
16739+ }
16740+
16741+ ep->stopped = stopped;
16742+}
16743+
16744+/**
16745+ * This function terminates all the requsts in the EP request queue.
16746+ */
16747+void dwc_otg_request_nuke(dwc_otg_pcd_ep_t *ep)
16748+{
16749+ dwc_otg_pcd_request_t *req;
16750+
16751+ ep->stopped = 1;
16752+
16753+ /* called with irqs blocked?? */
16754+ while (!list_empty(&ep->queue)) {
16755+ req = list_entry(ep->queue.next, dwc_otg_pcd_request_t,
16756+ queue);
16757+ dwc_otg_request_done(ep, req, -ESHUTDOWN);
16758+ }
16759+}
16760+
16761+/* USB Endpoint Operations */
16762+/*
16763+ * The following sections briefly describe the behavior of the Gadget
16764+ * API endpoint operations implemented in the DWC_otg driver
16765+ * software. Detailed descriptions of the generic behavior of each of
16766+ * these functions can be found in the Linux header file
16767+ * include/linux/usb_gadget.h.
16768+ *
16769+ * The Gadget API provides wrapper functions for each of the function
16770+ * pointers defined in usb_ep_ops. The Gadget Driver calls the wrapper
16771+ * function, which then calls the underlying PCD function. The
16772+ * following sections are named according to the wrapper
16773+ * functions. Within each section, the corresponding DWC_otg PCD
16774+ * function name is specified.
16775+ *
16776+ */
16777+
16778+/**
16779+ * This function assigns periodic Tx FIFO to an periodic EP
16780+ * in shared Tx FIFO mode
16781+ */
16782+static uint32_t assign_perio_tx_fifo(dwc_otg_core_if_t *core_if)
16783+{
16784+ uint32_t PerTxMsk = 1;
16785+ int i;
16786+ for(i = 0; i < core_if->hwcfg4.b.num_dev_perio_in_ep; ++i)
16787+ {
16788+ if((PerTxMsk & core_if->p_tx_msk) == 0) {
16789+ core_if->p_tx_msk |= PerTxMsk;
16790+ return i + 1;
16791+ }
16792+ PerTxMsk <<= 1;
16793+ }
16794+ return 0;
16795+}
16796+/**
16797+ * This function releases periodic Tx FIFO
16798+ * in shared Tx FIFO mode
16799+ */
16800+static void release_perio_tx_fifo(dwc_otg_core_if_t *core_if, uint32_t fifo_num)
16801+{
16802+ core_if->p_tx_msk = (core_if->p_tx_msk & (1 << (fifo_num - 1))) ^ core_if->p_tx_msk;
16803+}
16804+/**
16805+ * This function assigns periodic Tx FIFO to an periodic EP
16806+ * in shared Tx FIFO mode
16807+ */
16808+static uint32_t assign_tx_fifo(dwc_otg_core_if_t *core_if)
16809+{
16810+ uint32_t TxMsk = 1;
16811+ int i;
16812+
16813+ for(i = 0; i < core_if->hwcfg4.b.num_in_eps; ++i)
16814+ {
16815+ if((TxMsk & core_if->tx_msk) == 0) {
16816+ core_if->tx_msk |= TxMsk;
16817+ return i + 1;
16818+ }
16819+ TxMsk <<= 1;
16820+ }
16821+ return 0;
16822+}
16823+/**
16824+ * This function releases periodic Tx FIFO
16825+ * in shared Tx FIFO mode
16826+ */
16827+static void release_tx_fifo(dwc_otg_core_if_t *core_if, uint32_t fifo_num)
16828+{
16829+ core_if->tx_msk = (core_if->tx_msk & (1 << (fifo_num - 1))) ^ core_if->tx_msk;
16830+}
16831+
16832+/**
16833+ * This function is called by the Gadget Driver for each EP to be
16834+ * configured for the current configuration (SET_CONFIGURATION).
16835+ *
16836+ * This function initializes the dwc_otg_ep_t data structure, and then
16837+ * calls dwc_otg_ep_activate.
16838+ */
16839+static int dwc_otg_pcd_ep_enable(struct usb_ep *usb_ep,
16840+ const struct usb_endpoint_descriptor *ep_desc)
16841+{
16842+ dwc_otg_pcd_ep_t *ep = 0;
16843+ dwc_otg_pcd_t *pcd = 0;
16844+ unsigned long flags;
16845+
16846+ DWC_DEBUGPL(DBG_PCDV,"%s(%p,%p)\n", __func__, usb_ep, ep_desc);
16847+
16848+ ep = container_of(usb_ep, dwc_otg_pcd_ep_t, ep);
16849+ if (!usb_ep || !ep_desc || ep->desc ||
16850+ ep_desc->bDescriptorType != USB_DT_ENDPOINT) {
16851+ DWC_WARN("%s, bad ep or descriptor\n", __func__);
16852+ return -EINVAL;
16853+ }
16854+ if (ep == &ep->pcd->ep0) {
16855+ DWC_WARN("%s, bad ep(0)\n", __func__);
16856+ return -EINVAL;
16857+ }
16858+
16859+ /* Check FIFO size? */
16860+ if (!ep_desc->wMaxPacketSize) {
16861+ DWC_WARN("%s, bad %s maxpacket\n", __func__, usb_ep->name);
16862+ return -ERANGE;
16863+ }
16864+
16865+ pcd = ep->pcd;
16866+ if (!pcd->driver || pcd->gadget.speed == USB_SPEED_UNKNOWN) {
16867+ DWC_WARN("%s, bogus device state\n", __func__);
16868+ return -ESHUTDOWN;
16869+ }
16870+
16871+ SPIN_LOCK_IRQSAVE(&pcd->lock, flags);
16872+
16873+ ep->desc = ep_desc;
16874+ ep->ep.maxpacket = le16_to_cpu (ep_desc->wMaxPacketSize);
16875+
16876+ /*
16877+ * Activate the EP
16878+ */
16879+ ep->stopped = 0;
16880+
16881+ ep->dwc_ep.is_in = (USB_DIR_IN & ep_desc->bEndpointAddress) != 0;
16882+ ep->dwc_ep.maxpacket = ep->ep.maxpacket;
16883+
16884+ ep->dwc_ep.type = ep_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
16885+
16886+ if(ep->dwc_ep.is_in) {
16887+ if(!pcd->otg_dev->core_if->en_multiple_tx_fifo) {
16888+ ep->dwc_ep.tx_fifo_num = 0;
16889+
16890+ if (ep->dwc_ep.type == USB_ENDPOINT_XFER_ISOC) {
16891+ /*
16892+ * if ISOC EP then assign a Periodic Tx FIFO.
16893+ */
16894+ ep->dwc_ep.tx_fifo_num = assign_perio_tx_fifo(pcd->otg_dev->core_if);
16895+ }
16896+ } else {
16897+ /*
16898+ * if Dedicated FIFOs mode is on then assign a Tx FIFO.
16899+ */
16900+ ep->dwc_ep.tx_fifo_num = assign_tx_fifo(pcd->otg_dev->core_if);
16901+
16902+ }
16903+ }
16904+ /* Set initial data PID. */
16905+ if (ep->dwc_ep.type == USB_ENDPOINT_XFER_BULK) {
16906+ ep->dwc_ep.data_pid_start = 0;
16907+ }
16908+
16909+ DWC_DEBUGPL(DBG_PCD, "Activate %s-%s: type=%d, mps=%d desc=%p\n",
16910+ ep->ep.name, (ep->dwc_ep.is_in ?"IN":"OUT"),
16911+ ep->dwc_ep.type, ep->dwc_ep.maxpacket, ep->desc);
16912+
16913+ if(ep->dwc_ep.type != USB_ENDPOINT_XFER_ISOC) {
16914+ ep->dwc_ep.desc_addr = dwc_otg_ep_alloc_desc_chain(&ep->dwc_ep.dma_desc_addr, MAX_DMA_DESC_CNT);
16915+ }
16916+
16917+ dwc_otg_ep_activate(GET_CORE_IF(pcd), &ep->dwc_ep);
16918+ SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
16919+
16920+ return 0;
16921+}
16922+
16923+/**
16924+ * This function is called when an EP is disabled due to disconnect or
16925+ * change in configuration. Any pending requests will terminate with a
16926+ * status of -ESHUTDOWN.
16927+ *
16928+ * This function modifies the dwc_otg_ep_t data structure for this EP,
16929+ * and then calls dwc_otg_ep_deactivate.
16930+ */
16931+static int dwc_otg_pcd_ep_disable(struct usb_ep *usb_ep)
16932+{
16933+ dwc_otg_pcd_ep_t *ep;
16934+ dwc_otg_pcd_t *pcd = 0;
16935+ unsigned long flags;
16936+
16937+ DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, usb_ep);
16938+ ep = container_of(usb_ep, dwc_otg_pcd_ep_t, ep);
16939+ if (!usb_ep || !ep->desc) {
16940+ DWC_DEBUGPL(DBG_PCD, "%s, %s not enabled\n", __func__,
16941+ usb_ep ? ep->ep.name : NULL);
16942+ return -EINVAL;
16943+ }
16944+
16945+ SPIN_LOCK_IRQSAVE(&ep->pcd->lock, flags);
16946+
16947+ dwc_otg_request_nuke(ep);
16948+
16949+ dwc_otg_ep_deactivate(GET_CORE_IF(ep->pcd), &ep->dwc_ep);
16950+ ep->desc = 0;
16951+ ep->stopped = 1;
16952+
16953+ if(ep->dwc_ep.is_in) {
16954+ dwc_otg_flush_tx_fifo(GET_CORE_IF(ep->pcd), ep->dwc_ep.tx_fifo_num);
16955+ release_perio_tx_fifo(GET_CORE_IF(ep->pcd), ep->dwc_ep.tx_fifo_num);
16956+ release_tx_fifo(GET_CORE_IF(ep->pcd), ep->dwc_ep.tx_fifo_num);
16957+ }
16958+
16959+ /* Free DMA Descriptors */
16960+ pcd = ep->pcd;
16961+
16962+ SPIN_UNLOCK_IRQRESTORE(&ep->pcd->lock, flags);
16963+
16964+ if(ep->dwc_ep.type != USB_ENDPOINT_XFER_ISOC && ep->dwc_ep.desc_addr) {
16965+ dwc_otg_ep_free_desc_chain(ep->dwc_ep.desc_addr, ep->dwc_ep.dma_desc_addr, MAX_DMA_DESC_CNT);
16966+ }
16967+
16968+ DWC_DEBUGPL(DBG_PCD, "%s disabled\n", usb_ep->name);
16969+ return 0;
16970+}
16971+
16972+
16973+/**
16974+ * This function allocates a request object to use with the specified
16975+ * endpoint.
16976+ *
16977+ * @param ep The endpoint to be used with with the request
16978+ * @param gfp_flags the GFP_* flags to use.
16979+ */
16980+static struct usb_request *dwc_otg_pcd_alloc_request(struct usb_ep *ep,
16981+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
16982+ int gfp_flags
16983+#else
16984+ gfp_t gfp_flags
16985+#endif
16986+ )
16987+{
16988+ dwc_otg_pcd_request_t *req;
16989+
16990+ DWC_DEBUGPL(DBG_PCDV,"%s(%p,%d)\n", __func__, ep, gfp_flags);
16991+ if (0 == ep) {
16992+ DWC_WARN("%s() %s\n", __func__, "Invalid EP!\n");
16993+ return 0;
16994+ }
16995+ req = kmalloc(sizeof(dwc_otg_pcd_request_t), gfp_flags);
16996+ if (0 == req) {
16997+ DWC_WARN("%s() %s\n", __func__,
16998+ "request allocation failed!\n");
16999+ return 0;
17000+ }
17001+ memset(req, 0, sizeof(dwc_otg_pcd_request_t));
17002+ req->req.dma = DMA_ADDR_INVALID;
17003+ INIT_LIST_HEAD(&req->queue);
17004+ return &req->req;
17005+}
17006+
17007+/**
17008+ * This function frees a request object.
17009+ *
17010+ * @param ep The endpoint associated with the request
17011+ * @param req The request being freed
17012+ */
17013+static void dwc_otg_pcd_free_request(struct usb_ep *ep,
17014+ struct usb_request *req)
17015+{
17016+ dwc_otg_pcd_request_t *request;
17017+ DWC_DEBUGPL(DBG_PCDV,"%s(%p,%p)\n", __func__, ep, req);
17018+
17019+ if (0 == ep || 0 == req) {
17020+ DWC_WARN("%s() %s\n", __func__,
17021+ "Invalid ep or req argument!\n");
17022+ return;
17023+ }
17024+
17025+ request = container_of(req, dwc_otg_pcd_request_t, req);
17026+ kfree(request);
17027+}
17028+
17029+#if 0
17030+/**
17031+ * This function allocates an I/O buffer to be used for a transfer
17032+ * to/from the specified endpoint.
17033+ *
17034+ * @param usb_ep The endpoint to be used with with the request
17035+ * @param bytes The desired number of bytes for the buffer
17036+ * @param dma Pointer to the buffer's DMA address; must be valid
17037+ * @param gfp_flags the GFP_* flags to use.
17038+ * @return address of a new buffer or null is buffer could not be allocated.
17039+ */
17040+static void *dwc_otg_pcd_alloc_buffer(struct usb_ep *usb_ep, unsigned bytes,
17041+ dma_addr_t *dma,
17042+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
17043+ int gfp_flags
17044+#else
17045+ gfp_t gfp_flags
17046+#endif
17047+ )
17048+{
17049+ void *buf;
17050+ dwc_otg_pcd_ep_t *ep;
17051+ dwc_otg_pcd_t *pcd = 0;
17052+
17053+ ep = container_of(usb_ep, dwc_otg_pcd_ep_t, ep);
17054+ pcd = ep->pcd;
17055+
17056+ DWC_DEBUGPL(DBG_PCDV,"%s(%p,%d,%p,%0x)\n", __func__, usb_ep, bytes,
17057+ dma, gfp_flags);
17058+
17059+ /* Check dword alignment */
17060+ if ((bytes & 0x3UL) != 0) {
17061+ DWC_WARN("%s() Buffer size is not a multiple of"
17062+ "DWORD size (%d)",__func__, bytes);
17063+ }
17064+
17065+ if (GET_CORE_IF(pcd)->dma_enable) {
17066+ buf = dma_alloc_coherent (NULL, bytes, dma, gfp_flags);
17067+ }
17068+ else {
17069+ buf = kmalloc(bytes, gfp_flags);
17070+ }
17071+
17072+ /* Check dword alignment */
17073+ if (((int)buf & 0x3UL) != 0) {
17074+ DWC_WARN("%s() Buffer is not DWORD aligned (%p)",
17075+ __func__, buf);
17076+ }
17077+
17078+ return buf;
17079+}
17080+
17081+/**
17082+ * This function frees an I/O buffer that was allocated by alloc_buffer.
17083+ *
17084+ * @param usb_ep the endpoint associated with the buffer
17085+ * @param buf address of the buffer
17086+ * @param dma The buffer's DMA address
17087+ * @param bytes The number of bytes of the buffer
17088+ */
17089+static void dwc_otg_pcd_free_buffer(struct usb_ep *usb_ep, void *buf,
17090+ dma_addr_t dma, unsigned bytes)
17091+{
17092+ dwc_otg_pcd_ep_t *ep;
17093+ dwc_otg_pcd_t *pcd = 0;
17094+
17095+ ep = container_of(usb_ep, dwc_otg_pcd_ep_t, ep);
17096+ pcd = ep->pcd;
17097+
17098+ DWC_DEBUGPL(DBG_PCDV,"%s(%p,%p,%0x,%d)\n", __func__, ep, buf, dma, bytes);
17099+
17100+ if (GET_CORE_IF(pcd)->dma_enable) {
17101+ dma_free_coherent (NULL, bytes, buf, dma);
17102+ }
17103+ else {
17104+ kfree(buf);
17105+ }
17106+}
17107+#endif
17108+
17109+/**
17110+ * This function is used to submit an I/O Request to an EP.
17111+ *
17112+ * - When the request completes the request's completion callback
17113+ * is called to return the request to the driver.
17114+ * - An EP, except control EPs, may have multiple requests
17115+ * pending.
17116+ * - Once submitted the request cannot be examined or modified.
17117+ * - Each request is turned into one or more packets.
17118+ * - A BULK EP can queue any amount of data; the transfer is
17119+ * packetized.
17120+ * - Zero length Packets are specified with the request 'zero'
17121+ * flag.
17122+ */
17123+static int dwc_otg_pcd_ep_queue(struct usb_ep *usb_ep,
17124+ struct usb_request *usb_req,
17125+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
17126+ int gfp_flags
17127+#else
17128+ gfp_t gfp_flags
17129+#endif
17130+ )
17131+{
17132+ int prevented = 0;
17133+ dwc_otg_pcd_request_t *req;
17134+ dwc_otg_pcd_ep_t *ep;
17135+ dwc_otg_pcd_t *pcd;
17136+ unsigned long flags = 0;
17137+
17138+ DWC_DEBUGPL(DBG_PCDV,"%s(%p,%p,%d)\n",
17139+ __func__, usb_ep, usb_req, gfp_flags);
17140+
17141+ req = container_of(usb_req, dwc_otg_pcd_request_t, req);
17142+ if (!usb_req || !usb_req->complete || !usb_req->buf ||
17143+ !list_empty(&req->queue)) {
17144+ DWC_WARN("%s, bad params\n", __func__);
17145+ return -EINVAL;
17146+ }
17147+
17148+ ep = container_of(usb_ep, dwc_otg_pcd_ep_t, ep);
17149+ if (!usb_ep || (!ep->desc && ep->dwc_ep.num != 0)/* || ep->stopped != 0*/) {
17150+ DWC_WARN("%s, bad ep\n", __func__);
17151+ return -EINVAL;
17152+ }
17153+
17154+ pcd = ep->pcd;
17155+ if (!pcd->driver || pcd->gadget.speed == USB_SPEED_UNKNOWN) {
17156+ DWC_DEBUGPL(DBG_PCDV, "gadget.speed=%d\n", pcd->gadget.speed);
17157+ DWC_WARN("%s, bogus device state\n", __func__);
17158+ return -ESHUTDOWN;
17159+ }
17160+
17161+
17162+ DWC_DEBUGPL(DBG_PCD, "%s queue req %p, len %d buf %p\n",
17163+ usb_ep->name, usb_req, usb_req->length, usb_req->buf);
17164+
17165+ if (!GET_CORE_IF(pcd)->core_params->opt) {
17166+ if (ep->dwc_ep.num != 0) {
17167+ DWC_ERROR("%s queue req %p, len %d buf %p\n",
17168+ usb_ep->name, usb_req, usb_req->length, usb_req->buf);
17169+ }
17170+ }
17171+
17172+ SPIN_LOCK_IRQSAVE(&ep->pcd->lock, flags);
17173+
17174+#if defined(DEBUG) & defined(VERBOSE)
17175+ dump_msg(usb_req->buf, usb_req->length);
17176+#endif
17177+
17178+ usb_req->status = -EINPROGRESS;
17179+ usb_req->actual = 0;
17180+
17181+ /*
17182+ * For EP0 IN without premature status, zlp is required?
17183+ */
17184+ if (ep->dwc_ep.num == 0 && ep->dwc_ep.is_in) {
17185+ DWC_DEBUGPL(DBG_PCDV, "%s-OUT ZLP\n", usb_ep->name);
17186+ //_req->zero = 1;
17187+ }
17188+
17189+ /* Start the transfer */
17190+ if (list_empty(&ep->queue) && !ep->stopped) {
17191+ /* EP0 Transfer? */
17192+ if (ep->dwc_ep.num == 0) {
17193+ switch (pcd->ep0state) {
17194+ case EP0_IN_DATA_PHASE:
17195+ DWC_DEBUGPL(DBG_PCD,
17196+ "%s ep0: EP0_IN_DATA_PHASE\n",
17197+ __func__);
17198+ break;
17199+
17200+ case EP0_OUT_DATA_PHASE:
17201+ DWC_DEBUGPL(DBG_PCD,
17202+ "%s ep0: EP0_OUT_DATA_PHASE\n",
17203+ __func__);
17204+ if (pcd->request_config) {
17205+ /* Complete STATUS PHASE */
17206+ ep->dwc_ep.is_in = 1;
17207+ pcd->ep0state = EP0_IN_STATUS_PHASE;
17208+ }
17209+ break;
17210+
17211+ case EP0_IN_STATUS_PHASE:
17212+ DWC_DEBUGPL(DBG_PCD,
17213+ "%s ep0: EP0_IN_STATUS_PHASE\n",
17214+ __func__);
17215+ break;
17216+
17217+ default:
17218+ DWC_DEBUGPL(DBG_ANY, "ep0: odd state %d\n",
17219+ pcd->ep0state);
17220+ SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
17221+ return -EL2HLT;
17222+ }
17223+ ep->dwc_ep.dma_addr = usb_req->dma;
17224+ ep->dwc_ep.start_xfer_buff = usb_req->buf;
17225+ ep->dwc_ep.xfer_buff = usb_req->buf;
17226+ ep->dwc_ep.xfer_len = usb_req->length;
17227+ ep->dwc_ep.xfer_count = 0;
17228+ ep->dwc_ep.sent_zlp = 0;
17229+ ep->dwc_ep.total_len = ep->dwc_ep.xfer_len;
17230+
17231+ if(usb_req->zero) {
17232+ if((ep->dwc_ep.xfer_len % ep->dwc_ep.maxpacket == 0)
17233+ && (ep->dwc_ep.xfer_len != 0)) {
17234+ ep->dwc_ep.sent_zlp = 1;
17235+ }
17236+
17237+ }
17238+
17239+ ep_check_and_patch_dma_addr(ep);
17240+ dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep->dwc_ep);
17241+ }
17242+ else {
17243+
17244+ uint32_t max_transfer = GET_CORE_IF(ep->pcd)->core_params->max_transfer_size;
17245+
17246+ /* Setup and start the Transfer */
17247+ ep->dwc_ep.dma_addr = usb_req->dma;
17248+ ep->dwc_ep.start_xfer_buff = usb_req->buf;
17249+ ep->dwc_ep.xfer_buff = usb_req->buf;
17250+ ep->dwc_ep.sent_zlp = 0;
17251+ ep->dwc_ep.total_len = usb_req->length;
17252+ ep->dwc_ep.xfer_len = 0;
17253+ ep->dwc_ep.xfer_count = 0;
17254+
17255+ if(max_transfer > MAX_TRANSFER_SIZE) {
17256+ ep->dwc_ep.maxxfer = max_transfer - (max_transfer % ep->dwc_ep.maxpacket);
17257+ } else {
17258+ ep->dwc_ep.maxxfer = max_transfer;
17259+ }
17260+
17261+ if(usb_req->zero) {
17262+ if((ep->dwc_ep.total_len % ep->dwc_ep.maxpacket == 0)
17263+ && (ep->dwc_ep.total_len != 0)) {
17264+ ep->dwc_ep.sent_zlp = 1;
17265+ }
17266+
17267+ }
17268+
17269+ ep_check_and_patch_dma_addr(ep);
17270+ dwc_otg_ep_start_transfer(GET_CORE_IF(pcd), &ep->dwc_ep);
17271+ }
17272+ }
17273+
17274+ if ((req != 0) || prevented) {
17275+ ++pcd->request_pending;
17276+ list_add_tail(&req->queue, &ep->queue);
17277+ if (ep->dwc_ep.is_in && ep->stopped && !(GET_CORE_IF(pcd)->dma_enable)) {
17278+ /** @todo NGS Create a function for this. */
17279+ diepmsk_data_t diepmsk = { .d32 = 0};
17280+ diepmsk.b.intktxfemp = 1;
17281+ if(&GET_CORE_IF(pcd)->multiproc_int_enable) {
17282+ dwc_modify_reg32(&GET_CORE_IF(pcd)->dev_if->dev_global_regs->diepeachintmsk[ep->dwc_ep.num],
17283+ 0, diepmsk.d32);
17284+ } else {
17285+ dwc_modify_reg32(&GET_CORE_IF(pcd)->dev_if->dev_global_regs->diepmsk, 0, diepmsk.d32);
17286+ }
17287+ }
17288+ }
17289+
17290+ SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
17291+ return 0;
17292+}
17293+
17294+/**
17295+ * This function cancels an I/O request from an EP.
17296+ */
17297+static int dwc_otg_pcd_ep_dequeue(struct usb_ep *usb_ep,
17298+ struct usb_request *usb_req)
17299+{
17300+ dwc_otg_pcd_request_t *req;
17301+ dwc_otg_pcd_ep_t *ep;
17302+ dwc_otg_pcd_t *pcd;
17303+ unsigned long flags;
17304+
17305+ DWC_DEBUGPL(DBG_PCDV,"%s(%p,%p)\n", __func__, usb_ep, usb_req);
17306+
17307+ ep = container_of(usb_ep, dwc_otg_pcd_ep_t, ep);
17308+ if (!usb_ep || !usb_req || (!ep->desc && ep->dwc_ep.num != 0)) {
17309+ DWC_WARN("%s, bad argument\n", __func__);
17310+ return -EINVAL;
17311+ }
17312+ pcd = ep->pcd;
17313+ if (!pcd->driver || pcd->gadget.speed == USB_SPEED_UNKNOWN) {
17314+ DWC_WARN("%s, bogus device state\n", __func__);
17315+ return -ESHUTDOWN;
17316+ }
17317+
17318+ SPIN_LOCK_IRQSAVE(&pcd->lock, flags);
17319+ DWC_DEBUGPL(DBG_PCDV, "%s %s %s %p\n", __func__, usb_ep->name,
17320+ ep->dwc_ep.is_in ? "IN" : "OUT",
17321+ usb_req);
17322+
17323+ /* make sure it's actually queued on this endpoint */
17324+ list_for_each_entry(req, &ep->queue, queue)
17325+ {
17326+ if (&req->req == usb_req) {
17327+ break;
17328+ }
17329+ }
17330+
17331+ if (&req->req != usb_req) {
17332+ SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
17333+ return -EINVAL;
17334+ }
17335+
17336+ if (!list_empty(&req->queue)) {
17337+ dwc_otg_request_done(ep, req, -ECONNRESET);
17338+ }
17339+ else {
17340+ req = 0;
17341+ }
17342+
17343+ SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
17344+
17345+ return req ? 0 : -EOPNOTSUPP;
17346+}
17347+
17348+/**
17349+ * usb_ep_set_halt stalls an endpoint.
17350+ *
17351+ * usb_ep_clear_halt clears an endpoint halt and resets its data
17352+ * toggle.
17353+ *
17354+ * Both of these functions are implemented with the same underlying
17355+ * function. The behavior depends on the value argument.
17356+ *
17357+ * @param[in] usb_ep the Endpoint to halt or clear halt.
17358+ * @param[in] value
17359+ * - 0 means clear_halt.
17360+ * - 1 means set_halt,
17361+ * - 2 means clear stall lock flag.
17362+ * - 3 means set stall lock flag.
17363+ */
17364+static int dwc_otg_pcd_ep_set_halt(struct usb_ep *usb_ep, int value)
17365+{
17366+ int retval = 0;
17367+ unsigned long flags;
17368+ dwc_otg_pcd_ep_t *ep = 0;
17369+
17370+
17371+ DWC_DEBUGPL(DBG_PCD,"HALT %s %d\n", usb_ep->name, value);
17372+
17373+ ep = container_of(usb_ep, dwc_otg_pcd_ep_t, ep);
17374+
17375+ if (!usb_ep || (!ep->desc && ep != &ep->pcd->ep0) ||
17376+ ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
17377+ DWC_WARN("%s, bad ep\n", __func__);
17378+ return -EINVAL;
17379+ }
17380+
17381+ SPIN_LOCK_IRQSAVE(&ep->pcd->lock, flags);
17382+ if (!list_empty(&ep->queue)) {
17383+ DWC_WARN("%s() %s XFer In process\n", __func__, usb_ep->name);
17384+ retval = -EAGAIN;
17385+ }
17386+ else if (value == 0) {
17387+ dwc_otg_ep_clear_stall(ep->pcd->otg_dev->core_if,
17388+ &ep->dwc_ep);
17389+ }
17390+ else if(value == 1) {
17391+ if (ep->dwc_ep.is_in == 1 && ep->pcd->otg_dev->core_if->dma_desc_enable) {
17392+ dtxfsts_data_t txstatus;
17393+ fifosize_data_t txfifosize;
17394+
17395+ txfifosize.d32 = dwc_read_reg32(&ep->pcd->otg_dev->core_if->core_global_regs->dptxfsiz_dieptxf[ep->dwc_ep.tx_fifo_num]);
17396+ txstatus.d32 = dwc_read_reg32(&ep->pcd->otg_dev->core_if->dev_if->in_ep_regs[ep->dwc_ep.num]->dtxfsts);
17397+
17398+ if(txstatus.b.txfspcavail < txfifosize.b.depth) {
17399+ DWC_WARN("%s() %s Data In Tx Fifo\n", __func__, usb_ep->name);
17400+ retval = -EAGAIN;
17401+ }
17402+ else {
17403+ if (ep->dwc_ep.num == 0) {
17404+ ep->pcd->ep0state = EP0_STALL;
17405+ }
17406+
17407+ ep->stopped = 1;
17408+ dwc_otg_ep_set_stall(ep->pcd->otg_dev->core_if,
17409+ &ep->dwc_ep);
17410+ }
17411+ }
17412+ else {
17413+ if (ep->dwc_ep.num == 0) {
17414+ ep->pcd->ep0state = EP0_STALL;
17415+ }
17416+
17417+ ep->stopped = 1;
17418+ dwc_otg_ep_set_stall(ep->pcd->otg_dev->core_if,
17419+ &ep->dwc_ep);
17420+ }
17421+ }
17422+ else if (value == 2) {
17423+ ep->dwc_ep.stall_clear_flag = 0;
17424+ }
17425+ else if (value == 3) {
17426+ ep->dwc_ep.stall_clear_flag = 1;
17427+ }
17428+
17429+ SPIN_UNLOCK_IRQRESTORE(&ep->pcd->lock, flags);
17430+ return retval;
17431+}
17432+
17433+/**
17434+ * This function allocates a DMA Descriptor chain for the Endpoint
17435+ * buffer to be used for a transfer to/from the specified endpoint.
17436+ */
17437+dwc_otg_dma_desc_t* dwc_otg_ep_alloc_desc_chain(uint32_t * dma_desc_addr, uint32_t count)
17438+{
17439+
17440+ return dma_alloc_coherent(NULL, count * sizeof(dwc_otg_dma_desc_t), dma_desc_addr, GFP_KERNEL);
17441+}
17442+
17443+LIST_HEAD(tofree_list);
17444+spinlock_t tofree_list_lock=SPIN_LOCK_UNLOCKED;
17445+
17446+struct free_param {
17447+ struct list_head list;
17448+
17449+ void* addr;
17450+ dma_addr_t dma_addr;
17451+ uint32_t size;
17452+};
17453+void free_list_agent_fn(void *data){
17454+ struct list_head free_list;
17455+ struct free_param *cur,*next;
17456+
17457+ spin_lock(&tofree_list_lock);
17458+ list_add(&free_list,&tofree_list);
17459+ list_del_init(&tofree_list);
17460+ spin_unlock(&tofree_list_lock);
17461+
17462+ list_for_each_entry_safe(cur,next,&free_list,list){
17463+ if(cur==&free_list) break;
17464+ dma_free_coherent(NULL,cur->size,cur->addr,cur->dma_addr);
17465+ list_del(&cur->list);
17466+ kfree(cur);
17467+ }
17468+}
17469+DECLARE_WORK(free_list_agent,free_list_agent_fn);
17470+/**
17471+ * This function frees a DMA Descriptor chain that was allocated by ep_alloc_desc.
17472+ */
17473+void dwc_otg_ep_free_desc_chain(dwc_otg_dma_desc_t* desc_addr, uint32_t dma_desc_addr, uint32_t count)
17474+{
17475+ if(irqs_disabled()){
17476+ struct free_param* fp=kmalloc(sizeof(struct free_param),GFP_KERNEL);
17477+ fp->addr=desc_addr;
17478+ fp->dma_addr=dma_desc_addr;
17479+ fp->size=count*sizeof(dwc_otg_dma_desc_t);
17480+
17481+ spin_lock(&tofree_list_lock);
17482+ list_add(&fp->list,&tofree_list);
17483+ spin_unlock(&tofree_list_lock);
17484+
17485+ schedule_work(&free_list_agent);
17486+ return ;
17487+ }
17488+ dma_free_coherent(NULL, count * sizeof(dwc_otg_dma_desc_t), desc_addr, dma_desc_addr);
17489+}
17490+
17491+#ifdef DWC_EN_ISOC
17492+
17493+/**
17494+ * This function initializes a descriptor chain for Isochronous transfer
17495+ *
17496+ * @param core_if Programming view of DWC_otg controller.
17497+ * @param dwc_ep The EP to start the transfer on.
17498+ *
17499+ */
17500+void dwc_otg_iso_ep_start_ddma_transfer(dwc_otg_core_if_t *core_if, dwc_ep_t *dwc_ep)
17501+{
17502+
17503+ dsts_data_t dsts = { .d32 = 0};
17504+ depctl_data_t depctl = { .d32 = 0 };
17505+ volatile uint32_t *addr;
17506+ int i, j;
17507+
17508+ if(dwc_ep->is_in)
17509+ dwc_ep->desc_cnt = dwc_ep->buf_proc_intrvl / dwc_ep->bInterval;
17510+ else
17511+ dwc_ep->desc_cnt = dwc_ep->buf_proc_intrvl * dwc_ep->pkt_per_frm / dwc_ep->bInterval;
17512+
17513+
17514+ /** Allocate descriptors for double buffering */
17515+ dwc_ep->iso_desc_addr = dwc_otg_ep_alloc_desc_chain(&dwc_ep->iso_dma_desc_addr,dwc_ep->desc_cnt*2);
17516+ if(dwc_ep->desc_addr) {
17517+ DWC_WARN("%s, can't allocate DMA descriptor chain\n", __func__);
17518+ return;
17519+ }
17520+
17521+ dsts.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts);
17522+
17523+ /** ISO OUT EP */
17524+ if(dwc_ep->is_in == 0) {
17525+ desc_sts_data_t sts = { .d32 =0 };
17526+ dwc_otg_dma_desc_t* dma_desc = dwc_ep->iso_desc_addr;
17527+ dma_addr_t dma_ad;
17528+ uint32_t data_per_desc;
17529+ dwc_otg_dev_out_ep_regs_t *out_regs =
17530+ core_if->dev_if->out_ep_regs[dwc_ep->num];
17531+ int offset;
17532+
17533+ addr = &core_if->dev_if->out_ep_regs[dwc_ep->num]->doepctl;
17534+ dma_ad = (dma_addr_t)dwc_read_reg32(&(out_regs->doepdma));
17535+
17536+ /** Buffer 0 descriptors setup */
17537+ dma_ad = dwc_ep->dma_addr0;
17538+
17539+ sts.b_iso_out.bs = BS_HOST_READY;
17540+ sts.b_iso_out.rxsts = 0;
17541+ sts.b_iso_out.l = 0;
17542+ sts.b_iso_out.sp = 0;
17543+ sts.b_iso_out.ioc = 0;
17544+ sts.b_iso_out.pid = 0;
17545+ sts.b_iso_out.framenum = 0;
17546+
17547+ offset = 0;
17548+ for(i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm; i+= dwc_ep->pkt_per_frm)
17549+ {
17550+
17551+ for(j = 0; j < dwc_ep->pkt_per_frm; ++j)
17552+ {
17553+ data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
17554+ dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
17555+
17556+ data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
17557+ sts.b_iso_out.rxbytes = data_per_desc;
17558+ writel((uint32_t)dma_ad, &dma_desc->buf);
17559+ writel(sts.d32, &dma_desc->status);
17560+
17561+ offset += data_per_desc;
17562+ dma_desc ++;
17563+ //(uint32_t)dma_ad += data_per_desc;
17564+ dma_ad = (uint32_t)dma_ad + data_per_desc;
17565+ }
17566+ }
17567+
17568+ for(j = 0; j < dwc_ep->pkt_per_frm - 1; ++j)
17569+ {
17570+ data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
17571+ dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
17572+ data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
17573+ sts.b_iso_out.rxbytes = data_per_desc;
17574+ writel((uint32_t)dma_ad, &dma_desc->buf);
17575+ writel(sts.d32, &dma_desc->status);
17576+
17577+ offset += data_per_desc;
17578+ dma_desc ++;
17579+ //(uint32_t)dma_ad += data_per_desc;
17580+ dma_ad = (uint32_t)dma_ad + data_per_desc;
17581+ }
17582+
17583+ sts.b_iso_out.ioc = 1;
17584+ data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
17585+ dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
17586+ data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
17587+ sts.b_iso_out.rxbytes = data_per_desc;
17588+
17589+ writel((uint32_t)dma_ad, &dma_desc->buf);
17590+ writel(sts.d32, &dma_desc->status);
17591+ dma_desc ++;
17592+
17593+ /** Buffer 1 descriptors setup */
17594+ sts.b_iso_out.ioc = 0;
17595+ dma_ad = dwc_ep->dma_addr1;
17596+
17597+ offset = 0;
17598+ for(i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm; i+= dwc_ep->pkt_per_frm)
17599+ {
17600+ for(j = 0; j < dwc_ep->pkt_per_frm; ++j)
17601+ {
17602+ data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
17603+ dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
17604+ data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
17605+ sts.b_iso_out.rxbytes = data_per_desc;
17606+ writel((uint32_t)dma_ad, &dma_desc->buf);
17607+ writel(sts.d32, &dma_desc->status);
17608+
17609+ offset += data_per_desc;
17610+ dma_desc ++;
17611+ //(uint32_t)dma_ad += data_per_desc;
17612+ dma_ad = (uint32_t)dma_ad + data_per_desc;
17613+ }
17614+ }
17615+ for(j = 0; j < dwc_ep->pkt_per_frm - 1; ++j)
17616+ {
17617+ data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
17618+ dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
17619+ data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
17620+ sts.b_iso_out.rxbytes = data_per_desc;
17621+ writel((uint32_t)dma_ad, &dma_desc->buf);
17622+ writel(sts.d32, &dma_desc->status);
17623+
17624+ offset += data_per_desc;
17625+ dma_desc ++;
17626+ //(uint32_t)dma_ad += data_per_desc;
17627+ dma_ad = (uint32_t)dma_ad + data_per_desc;
17628+ }
17629+
17630+ sts.b_iso_out.ioc = 1;
17631+ sts.b_iso_out.l = 1;
17632+ data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
17633+ dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
17634+ data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
17635+ sts.b_iso_out.rxbytes = data_per_desc;
17636+
17637+ writel((uint32_t)dma_ad, &dma_desc->buf);
17638+ writel(sts.d32, &dma_desc->status);
17639+
17640+ dwc_ep->next_frame = 0;
17641+
17642+ /** Write dma_ad into DOEPDMA register */
17643+ dwc_write_reg32(&(out_regs->doepdma),(uint32_t)dwc_ep->iso_dma_desc_addr);
17644+
17645+ }
17646+ /** ISO IN EP */
17647+ else {
17648+ desc_sts_data_t sts = { .d32 =0 };
17649+ dwc_otg_dma_desc_t* dma_desc = dwc_ep->iso_desc_addr;
17650+ dma_addr_t dma_ad;
17651+ dwc_otg_dev_in_ep_regs_t *in_regs =
17652+ core_if->dev_if->in_ep_regs[dwc_ep->num];
17653+ unsigned int frmnumber;
17654+ fifosize_data_t txfifosize,rxfifosize;
17655+
17656+ txfifosize.d32 = dwc_read_reg32(&core_if->dev_if->in_ep_regs[dwc_ep->num]->dtxfsts);
17657+ rxfifosize.d32 = dwc_read_reg32(&core_if->core_global_regs->grxfsiz);
17658+
17659+
17660+ addr = &core_if->dev_if->in_ep_regs[dwc_ep->num]->diepctl;
17661+
17662+ dma_ad = dwc_ep->dma_addr0;
17663+
17664+ dsts.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts);
17665+
17666+ sts.b_iso_in.bs = BS_HOST_READY;
17667+ sts.b_iso_in.txsts = 0;
17668+ sts.b_iso_in.sp = (dwc_ep->data_per_frame % dwc_ep->maxpacket)? 1 : 0;
17669+ sts.b_iso_in.ioc = 0;
17670+ sts.b_iso_in.pid = dwc_ep->pkt_per_frm;
17671+
17672+
17673+ frmnumber = dwc_ep->next_frame;
17674+
17675+ sts.b_iso_in.framenum = frmnumber;
17676+ sts.b_iso_in.txbytes = dwc_ep->data_per_frame;
17677+ sts.b_iso_in.l = 0;
17678+
17679+ /** Buffer 0 descriptors setup */
17680+ for(i = 0; i < dwc_ep->desc_cnt - 1; i++)
17681+ {
17682+ writel((uint32_t)dma_ad, &dma_desc->buf);
17683+ writel(sts.d32, &dma_desc->status);
17684+ dma_desc ++;
17685+
17686+ //(uint32_t)dma_ad += dwc_ep->data_per_frame;
17687+ dma_ad = (uint32_t)dma_ad + dwc_ep->data_per_frame;
17688+ sts.b_iso_in.framenum += dwc_ep->bInterval;
17689+ }
17690+
17691+ sts.b_iso_in.ioc = 1;
17692+ writel((uint32_t)dma_ad, &dma_desc->buf);
17693+ writel(sts.d32, &dma_desc->status);
17694+ ++dma_desc;
17695+
17696+ /** Buffer 1 descriptors setup */
17697+ sts.b_iso_in.ioc = 0;
17698+ dma_ad = dwc_ep->dma_addr1;
17699+
17700+ for(i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm; i+= dwc_ep->pkt_per_frm)
17701+ {
17702+ writel((uint32_t)dma_ad, &dma_desc->buf);
17703+ writel(sts.d32, &dma_desc->status);
17704+ dma_desc ++;
17705+
17706+ //(uint32_t)dma_ad += dwc_ep->data_per_frame;
17707+ dma_ad = (uint32_t)dma_ad + dwc_ep->data_per_frame;
17708+ sts.b_iso_in.framenum += dwc_ep->bInterval;
17709+
17710+ sts.b_iso_in.ioc = 0;
17711+ }
17712+ sts.b_iso_in.ioc = 1;
17713+ sts.b_iso_in.l = 1;
17714+
17715+ writel((uint32_t)dma_ad, &dma_desc->buf);
17716+ writel(sts.d32, &dma_desc->status);
17717+
17718+ dwc_ep->next_frame = sts.b_iso_in.framenum + dwc_ep->bInterval;
17719+
17720+ /** Write dma_ad into diepdma register */
17721+ dwc_write_reg32(&(in_regs->diepdma),(uint32_t)dwc_ep->iso_dma_desc_addr);
17722+ }
17723+ /** Enable endpoint, clear nak */
17724+ depctl.d32 = 0;
17725+ depctl.b.epena = 1;
17726+ depctl.b.usbactep = 1;
17727+ depctl.b.cnak = 1;
17728+
17729+ dwc_modify_reg32(addr, depctl.d32,depctl.d32);
17730+ depctl.d32 = dwc_read_reg32(addr);
17731+}
17732+
17733+/**
17734+ * This function initializes a descriptor chain for Isochronous transfer
17735+ *
17736+ * @param core_if Programming view of DWC_otg controller.
17737+ * @param ep The EP to start the transfer on.
17738+ *
17739+ */
17740+
17741+void dwc_otg_iso_ep_start_buf_transfer(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
17742+{
17743+ depctl_data_t depctl = { .d32 = 0 };
17744+ volatile uint32_t *addr;
17745+
17746+
17747+ if(ep->is_in) {
17748+ addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl;
17749+ } else {
17750+ addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl;
17751+ }
17752+
17753+
17754+ if(core_if->dma_enable == 0 || core_if->dma_desc_enable!= 0) {
17755+ return;
17756+ } else {
17757+ deptsiz_data_t deptsiz = { .d32 = 0 };
17758+
17759+ ep->xfer_len = ep->data_per_frame * ep->buf_proc_intrvl / ep->bInterval;
17760+ ep->pkt_cnt = (ep->xfer_len - 1 + ep->maxpacket) /
17761+ ep->maxpacket;
17762+ ep->xfer_count = 0;
17763+ ep->xfer_buff = (ep->proc_buf_num) ? ep->xfer_buff1 : ep->xfer_buff0;
17764+ ep->dma_addr = (ep->proc_buf_num) ? ep->dma_addr1 : ep->dma_addr0;
17765+
17766+ if(ep->is_in) {
17767+ /* Program the transfer size and packet count
17768+ * as follows: xfersize = N * maxpacket +
17769+ * short_packet pktcnt = N + (short_packet
17770+ * exist ? 1 : 0)
17771+ */
17772+ deptsiz.b.mc = ep->pkt_per_frm;
17773+ deptsiz.b.xfersize = ep->xfer_len;
17774+ deptsiz.b.pktcnt =
17775+ (ep->xfer_len - 1 + ep->maxpacket) /
17776+ ep->maxpacket;
17777+ dwc_write_reg32(&core_if->dev_if->in_ep_regs[ep->num]->dieptsiz, deptsiz.d32);
17778+
17779+ /* Write the DMA register */
17780+ dwc_write_reg32 (&(core_if->dev_if->in_ep_regs[ep->num]->diepdma), (uint32_t)ep->dma_addr);
17781+
17782+ } else {
17783+ deptsiz.b.pktcnt =
17784+ (ep->xfer_len + (ep->maxpacket - 1)) /
17785+ ep->maxpacket;
17786+ deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket;
17787+
17788+ dwc_write_reg32(&core_if->dev_if->out_ep_regs[ep->num]->doeptsiz, deptsiz.d32);
17789+
17790+ /* Write the DMA register */
17791+ dwc_write_reg32 (&(core_if->dev_if->out_ep_regs[ep->num]->doepdma), (uint32_t)ep->dma_addr);
17792+
17793+ }
17794+ /** Enable endpoint, clear nak */
17795+ depctl.d32 = 0;
17796+ dwc_modify_reg32(addr, depctl.d32,depctl.d32);
17797+
17798+ depctl.b.epena = 1;
17799+ depctl.b.cnak = 1;
17800+
17801+ dwc_modify_reg32(addr, depctl.d32,depctl.d32);
17802+ }
17803+}
17804+
17805+
17806+/**
17807+ * This function does the setup for a data transfer for an EP and
17808+ * starts the transfer. For an IN transfer, the packets will be
17809+ * loaded into the appropriate Tx FIFO in the ISR. For OUT transfers,
17810+ * the packets are unloaded from the Rx FIFO in the ISR. the ISR.
17811+ *
17812+ * @param core_if Programming view of DWC_otg controller.
17813+ * @param ep The EP to start the transfer on.
17814+ */
17815+
17816+void dwc_otg_iso_ep_start_transfer(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
17817+{
17818+ if(core_if->dma_enable) {
17819+ if(core_if->dma_desc_enable) {
17820+ if(ep->is_in) {
17821+ ep->desc_cnt = ep->pkt_cnt / ep->pkt_per_frm;
17822+ } else {
17823+ ep->desc_cnt = ep->pkt_cnt;
17824+ }
17825+ dwc_otg_iso_ep_start_ddma_transfer(core_if, ep);
17826+ } else {
17827+ if(core_if->pti_enh_enable) {
17828+ dwc_otg_iso_ep_start_buf_transfer(core_if, ep);
17829+ } else {
17830+ ep->cur_pkt_addr = (ep->proc_buf_num) ? ep->xfer_buff1 : ep->xfer_buff0;
17831+ ep->cur_pkt_dma_addr = (ep->proc_buf_num) ? ep->dma_addr1 : ep->dma_addr0;
17832+ dwc_otg_iso_ep_start_frm_transfer(core_if, ep);
17833+ }
17834+ }
17835+ } else {
17836+ ep->cur_pkt_addr = (ep->proc_buf_num) ? ep->xfer_buff1 : ep->xfer_buff0;
17837+ ep->cur_pkt_dma_addr = (ep->proc_buf_num) ? ep->dma_addr1 : ep->dma_addr0;
17838+ dwc_otg_iso_ep_start_frm_transfer(core_if, ep);
17839+ }
17840+}
17841+
17842+/**
17843+ * This function does the setup for a data transfer for an EP and
17844+ * starts the transfer. For an IN transfer, the packets will be
17845+ * loaded into the appropriate Tx FIFO in the ISR. For OUT transfers,
17846+ * the packets are unloaded from the Rx FIFO in the ISR. the ISR.
17847+ *
17848+ * @param core_if Programming view of DWC_otg controller.
17849+ * @param ep The EP to start the transfer on.
17850+ */
17851+
17852+void dwc_otg_iso_ep_stop_transfer(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
17853+{
17854+ depctl_data_t depctl = { .d32 = 0 };
17855+ volatile uint32_t *addr;
17856+
17857+ if(ep->is_in == 1) {
17858+ addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl;
17859+ }
17860+ else {
17861+ addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl;
17862+ }
17863+
17864+ /* disable the ep */
17865+ depctl.d32 = dwc_read_reg32(addr);
17866+
17867+ depctl.b.epdis = 1;
17868+ depctl.b.snak = 1;
17869+
17870+ dwc_write_reg32(addr, depctl.d32);
17871+
17872+ if(core_if->dma_desc_enable &&
17873+ ep->iso_desc_addr && ep->iso_dma_desc_addr) {
17874+ dwc_otg_ep_free_desc_chain(ep->iso_desc_addr,ep->iso_dma_desc_addr,ep->desc_cnt * 2);
17875+ }
17876+
17877+ /* reset varibales */
17878+ ep->dma_addr0 = 0;
17879+ ep->dma_addr1 = 0;
17880+ ep->xfer_buff0 = 0;
17881+ ep->xfer_buff1 = 0;
17882+ ep->data_per_frame = 0;
17883+ ep->data_pattern_frame = 0;
17884+ ep->sync_frame = 0;
17885+ ep->buf_proc_intrvl = 0;
17886+ ep->bInterval = 0;
17887+ ep->proc_buf_num = 0;
17888+ ep->pkt_per_frm = 0;
17889+ ep->pkt_per_frm = 0;
17890+ ep->desc_cnt = 0;
17891+ ep->iso_desc_addr = 0;
17892+ ep->iso_dma_desc_addr = 0;
17893+}
17894+
17895+
17896+/**
17897+ * This function is used to submit an ISOC Transfer Request to an EP.
17898+ *
17899+ * - Every time a sync period completes the request's completion callback
17900+ * is called to provide data to the gadget driver.
17901+ * - Once submitted the request cannot be modified.
17902+ * - Each request is turned into periodic data packets untill ISO
17903+ * Transfer is stopped..
17904+ */
17905+static int dwc_otg_pcd_iso_ep_start(struct usb_ep *usb_ep, struct usb_iso_request *req,
17906+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
17907+ int gfp_flags
17908+#else
17909+ gfp_t gfp_flags
17910+#endif
17911+)
17912+{
17913+ dwc_otg_pcd_ep_t *ep;
17914+ dwc_otg_pcd_t *pcd;
17915+ dwc_ep_t *dwc_ep;
17916+ unsigned long flags = 0;
17917+ int32_t frm_data;
17918+ dwc_otg_core_if_t *core_if;
17919+ dcfg_data_t dcfg;
17920+ dsts_data_t dsts;
17921+
17922+
17923+ if (!req || !req->process_buffer || !req->buf0 || !req->buf1) {
17924+ DWC_WARN("%s, bad params\n", __func__);
17925+ return -EINVAL;
17926+ }
17927+
17928+ ep = container_of(usb_ep, dwc_otg_pcd_ep_t, ep);
17929+
17930+ if (!usb_ep || !ep->desc || ep->dwc_ep.num == 0) {
17931+ DWC_WARN("%s, bad ep\n", __func__);
17932+ return -EINVAL;
17933+ }
17934+
17935+ pcd = ep->pcd;
17936+ core_if = GET_CORE_IF(pcd);
17937+
17938+ dcfg.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dcfg);
17939+
17940+ if (!pcd->driver || pcd->gadget.speed == USB_SPEED_UNKNOWN) {
17941+ DWC_DEBUGPL(DBG_PCDV, "gadget.speed=%d\n", pcd->gadget.speed);
17942+ DWC_WARN("%s, bogus device state\n", __func__);
17943+ return -ESHUTDOWN;
17944+ }
17945+
17946+ SPIN_LOCK_IRQSAVE(&ep->pcd->lock, flags);
17947+
17948+ dwc_ep = &ep->dwc_ep;
17949+
17950+ if(ep->iso_req) {
17951+ DWC_WARN("%s, iso request in progress\n", __func__);
17952+ }
17953+ req->status = -EINPROGRESS;
17954+
17955+ dwc_ep->dma_addr0 = req->dma0;
17956+ dwc_ep->dma_addr1 = req->dma1;
17957+
17958+ dwc_ep->xfer_buff0 = req->buf0;
17959+ dwc_ep->xfer_buff1 = req->buf1;
17960+
17961+ ep->iso_req = req;
17962+
17963+ dwc_ep->data_per_frame = req->data_per_frame;
17964+
17965+ /** @todo - pattern data support is to be implemented in the future */
17966+ dwc_ep->data_pattern_frame = req->data_pattern_frame;
17967+ dwc_ep->sync_frame = req->sync_frame;
17968+
17969+ dwc_ep->buf_proc_intrvl = req->buf_proc_intrvl;
17970+
17971+ dwc_ep->bInterval = 1 << (ep->desc->bInterval - 1);
17972+
17973+ dwc_ep->proc_buf_num = 0;
17974+
17975+ dwc_ep->pkt_per_frm = 0;
17976+ frm_data = ep->dwc_ep.data_per_frame;
17977+ while(frm_data > 0) {
17978+ dwc_ep->pkt_per_frm++;
17979+ frm_data -= ep->dwc_ep.maxpacket;
17980+ }
17981+
17982+ dsts.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts);
17983+
17984+ if(req->flags & USB_REQ_ISO_ASAP) {
17985+ dwc_ep->next_frame = dsts.b.soffn + 1;
17986+ if(dwc_ep->bInterval != 1){
17987+ dwc_ep->next_frame = dwc_ep->next_frame + (dwc_ep->bInterval - 1 - dwc_ep->next_frame % dwc_ep->bInterval);
17988+ }
17989+ } else {
17990+ dwc_ep->next_frame = req->start_frame;
17991+ }
17992+
17993+
17994+ if(!core_if->pti_enh_enable) {
17995+ dwc_ep->pkt_cnt = dwc_ep->buf_proc_intrvl * dwc_ep->pkt_per_frm / dwc_ep->bInterval;
17996+ } else {
17997+ dwc_ep->pkt_cnt =
17998+ (dwc_ep->data_per_frame * (dwc_ep->buf_proc_intrvl / dwc_ep->bInterval)
17999+ - 1 + dwc_ep->maxpacket) / dwc_ep->maxpacket;
18000+ }
18001+
18002+ if(core_if->dma_desc_enable) {
18003+ dwc_ep->desc_cnt =
18004+ dwc_ep->buf_proc_intrvl * dwc_ep->pkt_per_frm / dwc_ep->bInterval;
18005+ }
18006+
18007+ dwc_ep->pkt_info = kmalloc(sizeof(iso_pkt_info_t) * dwc_ep->pkt_cnt, GFP_KERNEL);
18008+ if(!dwc_ep->pkt_info) {
18009+ return -ENOMEM;
18010+ }
18011+ if(core_if->pti_enh_enable) {
18012+ memset(dwc_ep->pkt_info, 0, sizeof(iso_pkt_info_t) * dwc_ep->pkt_cnt);
18013+ }
18014+
18015+ dwc_ep->cur_pkt = 0;
18016+
18017+ SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
18018+
18019+ dwc_otg_iso_ep_start_transfer(core_if, dwc_ep);
18020+
18021+ return 0;
18022+}
18023+
18024+/**
18025+ * This function stops ISO EP Periodic Data Transfer.
18026+ */
18027+static int dwc_otg_pcd_iso_ep_stop(struct usb_ep *usb_ep, struct usb_iso_request *req)
18028+{
18029+ dwc_otg_pcd_ep_t *ep;
18030+ dwc_otg_pcd_t *pcd;
18031+ dwc_ep_t *dwc_ep;
18032+ unsigned long flags;
18033+
18034+ ep = container_of(usb_ep, dwc_otg_pcd_ep_t, ep);
18035+
18036+ if (!usb_ep || !ep->desc || ep->dwc_ep.num == 0) {
18037+ DWC_WARN("%s, bad ep\n", __func__);
18038+ return -EINVAL;
18039+ }
18040+
18041+ pcd = ep->pcd;
18042+
18043+ if (!pcd->driver || pcd->gadget.speed == USB_SPEED_UNKNOWN) {
18044+ DWC_DEBUGPL(DBG_PCDV, "gadget.speed=%d\n", pcd->gadget.speed);
18045+ DWC_WARN("%s, bogus device state\n", __func__);
18046+ return -ESHUTDOWN;
18047+ }
18048+
18049+ dwc_ep = &ep->dwc_ep;
18050+
18051+ dwc_otg_iso_ep_stop_transfer(GET_CORE_IF(pcd), dwc_ep);
18052+
18053+ kfree(dwc_ep->pkt_info);
18054+
18055+ SPIN_LOCK_IRQSAVE(&pcd->lock, flags);
18056+
18057+ if(ep->iso_req != req) {
18058+ return -EINVAL;
18059+ }
18060+
18061+ req->status = -ECONNRESET;
18062+
18063+ SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
18064+
18065+
18066+ ep->iso_req = 0;
18067+
18068+ return 0;
18069+}
18070+
18071+/**
18072+ * This function is used for perodical data exchnage between PCD and gadget drivers.
18073+ * for Isochronous EPs
18074+ *
18075+ * - Every time a sync period completes this function is called to
18076+ * perform data exchange between PCD and gadget
18077+ */
18078+void dwc_otg_iso_buffer_done(dwc_otg_pcd_ep_t *ep, dwc_otg_pcd_iso_request_t *req)
18079+{
18080+ int i;
18081+ struct usb_gadget_iso_packet_descriptor *iso_packet;
18082+ dwc_ep_t *dwc_ep;
18083+
18084+ dwc_ep = &ep->dwc_ep;
18085+
18086+ if(ep->iso_req->status == -ECONNRESET) {
18087+ DWC_PRINT("Device has already disconnected\n");
18088+ /*Device has been disconnected*/
18089+ return;
18090+ }
18091+
18092+ if(dwc_ep->proc_buf_num != 0) {
18093+ iso_packet = ep->iso_req->iso_packet_desc0;
18094+ }
18095+
18096+ else {
18097+ iso_packet = ep->iso_req->iso_packet_desc1;
18098+ }
18099+
18100+ /* Fill in ISOC packets descriptors & pass to gadget driver*/
18101+
18102+ for(i = 0; i < dwc_ep->pkt_cnt; ++i) {
18103+ iso_packet[i].status = dwc_ep->pkt_info[i].status;
18104+ iso_packet[i].offset = dwc_ep->pkt_info[i].offset;
18105+ iso_packet[i].actual_length = dwc_ep->pkt_info[i].length;
18106+ dwc_ep->pkt_info[i].status = 0;
18107+ dwc_ep->pkt_info[i].offset = 0;
18108+ dwc_ep->pkt_info[i].length = 0;
18109+ }
18110+
18111+ /* Call callback function to process data buffer */
18112+ ep->iso_req->status = 0;/* success */
18113+
18114+ SPIN_UNLOCK(&ep->pcd->lock);
18115+ ep->iso_req->process_buffer(&ep->ep, ep->iso_req);
18116+ SPIN_LOCK(&ep->pcd->lock);
18117+}
18118+
18119+
18120+static struct usb_iso_request *dwc_otg_pcd_alloc_iso_request(struct usb_ep *ep,int packets,
18121+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
18122+ int gfp_flags
18123+#else
18124+ gfp_t gfp_flags
18125+#endif
18126+)
18127+{
18128+ struct usb_iso_request *pReq = NULL;
18129+ uint32_t req_size;
18130+
18131+
18132+ req_size = sizeof(struct usb_iso_request);
18133+ req_size += (2 * packets * (sizeof(struct usb_gadget_iso_packet_descriptor)));
18134+
18135+
18136+ pReq = kmalloc(req_size, gfp_flags);
18137+ if (!pReq) {
18138+ DWC_WARN("%s, can't allocate Iso Request\n", __func__);
18139+ return 0;
18140+ }
18141+ pReq->iso_packet_desc0 = (void*) (pReq + 1);
18142+
18143+ pReq->iso_packet_desc1 = pReq->iso_packet_desc0 + packets;
18144+
18145+ return pReq;
18146+}
18147+
18148+static void dwc_otg_pcd_free_iso_request(struct usb_ep *ep, struct usb_iso_request *req)
18149+{
18150+ kfree(req);
18151+}
18152+
18153+static struct usb_isoc_ep_ops dwc_otg_pcd_ep_ops =
18154+{
18155+ .ep_ops =
18156+ {
18157+ .enable = dwc_otg_pcd_ep_enable,
18158+ .disable = dwc_otg_pcd_ep_disable,
18159+
18160+ .alloc_request = dwc_otg_pcd_alloc_request,
18161+ .free_request = dwc_otg_pcd_free_request,
18162+
18163+ //.alloc_buffer = dwc_otg_pcd_alloc_buffer,
18164+ //.free_buffer = dwc_otg_pcd_free_buffer,
18165+
18166+ .queue = dwc_otg_pcd_ep_queue,
18167+ .dequeue = dwc_otg_pcd_ep_dequeue,
18168+
18169+ .set_halt = dwc_otg_pcd_ep_set_halt,
18170+ .fifo_status = 0,
18171+ .fifo_flush = 0,
18172+ },
18173+ .iso_ep_start = dwc_otg_pcd_iso_ep_start,
18174+ .iso_ep_stop = dwc_otg_pcd_iso_ep_stop,
18175+ .alloc_iso_request = dwc_otg_pcd_alloc_iso_request,
18176+ .free_iso_request = dwc_otg_pcd_free_iso_request,
18177+};
18178+
18179+#else
18180+
18181+
18182+static struct usb_ep_ops dwc_otg_pcd_ep_ops =
18183+{
18184+ .enable = dwc_otg_pcd_ep_enable,
18185+ .disable = dwc_otg_pcd_ep_disable,
18186+
18187+ .alloc_request = dwc_otg_pcd_alloc_request,
18188+ .free_request = dwc_otg_pcd_free_request,
18189+
18190+// .alloc_buffer = dwc_otg_pcd_alloc_buffer,
18191+// .free_buffer = dwc_otg_pcd_free_buffer,
18192+
18193+ .queue = dwc_otg_pcd_ep_queue,
18194+ .dequeue = dwc_otg_pcd_ep_dequeue,
18195+
18196+ .set_halt = dwc_otg_pcd_ep_set_halt,
18197+ .fifo_status = 0,
18198+ .fifo_flush = 0,
18199+
18200+
18201+};
18202+
18203+#endif /* DWC_EN_ISOC */
18204+/* Gadget Operations */
18205+/**
18206+ * The following gadget operations will be implemented in the DWC_otg
18207+ * PCD. Functions in the API that are not described below are not
18208+ * implemented.
18209+ *
18210+ * The Gadget API provides wrapper functions for each of the function
18211+ * pointers defined in usb_gadget_ops. The Gadget Driver calls the
18212+ * wrapper function, which then calls the underlying PCD function. The
18213+ * following sections are named according to the wrapper functions
18214+ * (except for ioctl, which doesn't have a wrapper function). Within
18215+ * each section, the corresponding DWC_otg PCD function name is
18216+ * specified.
18217+ *
18218+ */
18219+
18220+/**
18221+ *Gets the USB Frame number of the last SOF.
18222+ */
18223+static int dwc_otg_pcd_get_frame(struct usb_gadget *gadget)
18224+{
18225+ dwc_otg_pcd_t *pcd;
18226+
18227+ DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, gadget);
18228+
18229+ if (gadget == 0) {
18230+ return -ENODEV;
18231+ }
18232+ else {
18233+ pcd = container_of(gadget, dwc_otg_pcd_t, gadget);
18234+ dwc_otg_get_frame_number(GET_CORE_IF(pcd));
18235+ }
18236+
18237+ return 0;
18238+}
18239+
18240+void dwc_otg_pcd_initiate_srp(dwc_otg_pcd_t *pcd)
18241+{
18242+ uint32_t *addr = (uint32_t *)&(GET_CORE_IF(pcd)->core_global_regs->gotgctl);
18243+ gotgctl_data_t mem;
18244+ gotgctl_data_t val;
18245+
18246+ val.d32 = dwc_read_reg32(addr);
18247+ if (val.b.sesreq) {
18248+ DWC_ERROR("Session Request Already active!\n");
18249+ return;
18250+ }
18251+
18252+ DWC_NOTICE("Session Request Initated\n");
18253+ mem.d32 = dwc_read_reg32(addr);
18254+ mem.b.sesreq = 1;
18255+ dwc_write_reg32(addr, mem.d32);
18256+
18257+ /* Start the SRP timer */
18258+ dwc_otg_pcd_start_srp_timer(pcd);
18259+ return;
18260+}
18261+
18262+void dwc_otg_pcd_remote_wakeup(dwc_otg_pcd_t *pcd, int set)
18263+{
18264+ dctl_data_t dctl = {.d32=0};
18265+ volatile uint32_t *addr = &(GET_CORE_IF(pcd)->dev_if->dev_global_regs->dctl);
18266+
18267+ if (dwc_otg_is_device_mode(GET_CORE_IF(pcd))) {
18268+ if (pcd->remote_wakeup_enable) {
18269+ if (set) {
18270+ dctl.b.rmtwkupsig = 1;
18271+ dwc_modify_reg32(addr, 0, dctl.d32);
18272+ DWC_DEBUGPL(DBG_PCD, "Set Remote Wakeup\n");
18273+ mdelay(1);
18274+ dwc_modify_reg32(addr, dctl.d32, 0);
18275+ DWC_DEBUGPL(DBG_PCD, "Clear Remote Wakeup\n");
18276+ }
18277+ else {
18278+ }
18279+ }
18280+ else {
18281+ DWC_DEBUGPL(DBG_PCD, "Remote Wakeup is disabled\n");
18282+ }
18283+ }
18284+ return;
18285+}
18286+
18287+/**
18288+ * Initiates Session Request Protocol (SRP) to wakeup the host if no
18289+ * session is in progress. If a session is already in progress, but
18290+ * the device is suspended, remote wakeup signaling is started.
18291+ *
18292+ */
18293+static int dwc_otg_pcd_wakeup(struct usb_gadget *gadget)
18294+{
18295+ unsigned long flags;
18296+ dwc_otg_pcd_t *pcd;
18297+ dsts_data_t dsts;
18298+ gotgctl_data_t gotgctl;
18299+
18300+ DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, gadget);
18301+
18302+ if (gadget == 0) {
18303+ return -ENODEV;
18304+ }
18305+ else {
18306+ pcd = container_of(gadget, dwc_otg_pcd_t, gadget);
18307+ }
18308+ SPIN_LOCK_IRQSAVE(&pcd->lock, flags);
18309+
18310+ /*
18311+ * This function starts the Protocol if no session is in progress. If
18312+ * a session is already in progress, but the device is suspended,
18313+ * remote wakeup signaling is started.
18314+ */
18315+
18316+ /* Check if valid session */
18317+ gotgctl.d32 = dwc_read_reg32(&(GET_CORE_IF(pcd)->core_global_regs->gotgctl));
18318+ if (gotgctl.b.bsesvld) {
18319+ /* Check if suspend state */
18320+ dsts.d32 = dwc_read_reg32(&(GET_CORE_IF(pcd)->dev_if->dev_global_regs->dsts));
18321+ if (dsts.b.suspsts) {
18322+ dwc_otg_pcd_remote_wakeup(pcd, 1);
18323+ }
18324+ }
18325+ else {
18326+ dwc_otg_pcd_initiate_srp(pcd);
18327+ }
18328+
18329+ SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
18330+ return 0;
18331+}
18332+
18333+static const struct usb_gadget_ops dwc_otg_pcd_ops =
18334+{
18335+ .get_frame = dwc_otg_pcd_get_frame,
18336+ .wakeup = dwc_otg_pcd_wakeup,
18337+ // current versions must always be self-powered
18338+};
18339+
18340+/**
18341+ * This function updates the otg values in the gadget structure.
18342+ */
18343+void dwc_otg_pcd_update_otg(dwc_otg_pcd_t *pcd, const unsigned reset)
18344+{
18345+
18346+ if (!pcd->gadget.is_otg)
18347+ return;
18348+
18349+ if (reset) {
18350+ pcd->b_hnp_enable = 0;
18351+ pcd->a_hnp_support = 0;
18352+ pcd->a_alt_hnp_support = 0;
18353+ }
18354+
18355+ pcd->gadget.b_hnp_enable = pcd->b_hnp_enable;
18356+ pcd->gadget.a_hnp_support = pcd->a_hnp_support;
18357+ pcd->gadget.a_alt_hnp_support = pcd->a_alt_hnp_support;
18358+}
18359+
18360+/**
18361+ * This function is the top level PCD interrupt handler.
18362+ */
18363+static irqreturn_t dwc_otg_pcd_irq(int irq, void *dev
18364+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
18365+ , struct pt_regs *r
18366+#endif
18367+ )
18368+{
18369+ dwc_otg_pcd_t *pcd = dev;
18370+ int32_t retval = IRQ_NONE;
18371+
18372+ retval = dwc_otg_pcd_handle_intr(pcd);
18373+ return IRQ_RETVAL(retval);
18374+}
18375+
18376+/**
18377+ * PCD Callback function for initializing the PCD when switching to
18378+ * device mode.
18379+ *
18380+ * @param p void pointer to the <code>dwc_otg_pcd_t</code>
18381+ */
18382+static int32_t dwc_otg_pcd_start_cb(void *p)
18383+{
18384+ dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *)p;
18385+
18386+ /*
18387+ * Initialized the Core for Device mode.
18388+ */
18389+ if (dwc_otg_is_device_mode(GET_CORE_IF(pcd))) {
18390+ dwc_otg_core_dev_init(GET_CORE_IF(pcd));
18391+ }
18392+ return 1;
18393+}
18394+
18395+/**
18396+ * PCD Callback function for stopping the PCD when switching to Host
18397+ * mode.
18398+ *
18399+ * @param p void pointer to the <code>dwc_otg_pcd_t</code>
18400+ */
18401+static int32_t dwc_otg_pcd_stop_cb(void *p)
18402+{
18403+ dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *)p;
18404+ extern void dwc_otg_pcd_stop(dwc_otg_pcd_t *_pcd);
18405+
18406+ dwc_otg_pcd_stop(pcd);
18407+ return 1;
18408+}
18409+
18410+
18411+/**
18412+ * PCD Callback function for notifying the PCD when resuming from
18413+ * suspend.
18414+ *
18415+ * @param p void pointer to the <code>dwc_otg_pcd_t</code>
18416+ */
18417+static int32_t dwc_otg_pcd_suspend_cb(void *p)
18418+{
18419+ dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *)p;
18420+
18421+ if (pcd->driver && pcd->driver->resume) {
18422+ SPIN_UNLOCK(&pcd->lock);
18423+ pcd->driver->suspend(&pcd->gadget);
18424+ SPIN_LOCK(&pcd->lock);
18425+ }
18426+
18427+ return 1;
18428+}
18429+
18430+
18431+/**
18432+ * PCD Callback function for notifying the PCD when resuming from
18433+ * suspend.
18434+ *
18435+ * @param p void pointer to the <code>dwc_otg_pcd_t</code>
18436+ */
18437+static int32_t dwc_otg_pcd_resume_cb(void *p)
18438+{
18439+ dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *)p;
18440+
18441+ if (pcd->driver && pcd->driver->resume) {
18442+ SPIN_UNLOCK(&pcd->lock);
18443+ pcd->driver->resume(&pcd->gadget);
18444+ SPIN_LOCK(&pcd->lock);
18445+ }
18446+
18447+ /* Stop the SRP timeout timer. */
18448+ if ((GET_CORE_IF(pcd)->core_params->phy_type != DWC_PHY_TYPE_PARAM_FS) ||
18449+ (!GET_CORE_IF(pcd)->core_params->i2c_enable)) {
18450+ if (GET_CORE_IF(pcd)->srp_timer_started) {
18451+ GET_CORE_IF(pcd)->srp_timer_started = 0;
18452+ del_timer(&pcd->srp_timer);
18453+ }
18454+ }
18455+ return 1;
18456+}
18457+
18458+
18459+/**
18460+ * PCD Callback structure for handling mode switching.
18461+ */
18462+static dwc_otg_cil_callbacks_t pcd_callbacks =
18463+{
18464+ .start = dwc_otg_pcd_start_cb,
18465+ .stop = dwc_otg_pcd_stop_cb,
18466+ .suspend = dwc_otg_pcd_suspend_cb,
18467+ .resume_wakeup = dwc_otg_pcd_resume_cb,
18468+ .p = 0, /* Set at registration */
18469+};
18470+
18471+/**
18472+ * This function is called when the SRP timer expires. The SRP should
18473+ * complete within 6 seconds.
18474+ */
18475+static void srp_timeout(unsigned long ptr)
18476+{
18477+ gotgctl_data_t gotgctl;
18478+ dwc_otg_core_if_t *core_if = (dwc_otg_core_if_t *)ptr;
18479+ volatile uint32_t *addr = &core_if->core_global_regs->gotgctl;
18480+
18481+ gotgctl.d32 = dwc_read_reg32(addr);
18482+
18483+ core_if->srp_timer_started = 0;
18484+
18485+ if ((core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS) &&
18486+ (core_if->core_params->i2c_enable)) {
18487+ DWC_PRINT("SRP Timeout\n");
18488+
18489+ if ((core_if->srp_success) &&
18490+ (gotgctl.b.bsesvld)) {
18491+ if (core_if->pcd_cb && core_if->pcd_cb->resume_wakeup) {
18492+ core_if->pcd_cb->resume_wakeup(core_if->pcd_cb->p);
18493+ }
18494+
18495+ /* Clear Session Request */
18496+ gotgctl.d32 = 0;
18497+ gotgctl.b.sesreq = 1;
18498+ dwc_modify_reg32(&core_if->core_global_regs->gotgctl,
18499+ gotgctl.d32, 0);
18500+
18501+ core_if->srp_success = 0;
18502+ }
18503+ else {
18504+ DWC_ERROR("Device not connected/responding\n");
18505+ gotgctl.b.sesreq = 0;
18506+ dwc_write_reg32(addr, gotgctl.d32);
18507+ }
18508+ }
18509+ else if (gotgctl.b.sesreq) {
18510+ DWC_PRINT("SRP Timeout\n");
18511+
18512+ DWC_ERROR("Device not connected/responding\n");
18513+ gotgctl.b.sesreq = 0;
18514+ dwc_write_reg32(addr, gotgctl.d32);
18515+ }
18516+ else {
18517+ DWC_PRINT(" SRP GOTGCTL=%0x\n", gotgctl.d32);
18518+ }
18519+}
18520+
18521+/**
18522+ * Start the SRP timer to detect when the SRP does not complete within
18523+ * 6 seconds.
18524+ *
18525+ * @param pcd the pcd structure.
18526+ */
18527+void dwc_otg_pcd_start_srp_timer(dwc_otg_pcd_t *pcd)
18528+{
18529+ struct timer_list *srp_timer = &pcd->srp_timer;
18530+ GET_CORE_IF(pcd)->srp_timer_started = 1;
18531+ init_timer(srp_timer);
18532+ srp_timer->function = srp_timeout;
18533+ srp_timer->data = (unsigned long)GET_CORE_IF(pcd);
18534+ srp_timer->expires = jiffies + (HZ*6);
18535+ add_timer(srp_timer);
18536+}
18537+
18538+/**
18539+ * Tasklet
18540+ *
18541+ */
18542+extern void start_next_request(dwc_otg_pcd_ep_t *ep);
18543+
18544+static void start_xfer_tasklet_func (unsigned long data)
18545+{
18546+ dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t*)data;
18547+ dwc_otg_core_if_t *core_if = pcd->otg_dev->core_if;
18548+
18549+ int i;
18550+ depctl_data_t diepctl;
18551+
18552+ DWC_DEBUGPL(DBG_PCDV, "Start xfer tasklet\n");
18553+
18554+ diepctl.d32 = dwc_read_reg32(&core_if->dev_if->in_ep_regs[0]->diepctl);
18555+
18556+ if (pcd->ep0.queue_sof) {
18557+ pcd->ep0.queue_sof = 0;
18558+ start_next_request (&pcd->ep0);
18559+ // break;
18560+ }
18561+
18562+ for (i=0; i<core_if->dev_if->num_in_eps; i++)
18563+ {
18564+ depctl_data_t diepctl;
18565+ diepctl.d32 = dwc_read_reg32(&core_if->dev_if->in_ep_regs[i]->diepctl);
18566+
18567+ if (pcd->in_ep[i].queue_sof) {
18568+ pcd->in_ep[i].queue_sof = 0;
18569+ start_next_request (&pcd->in_ep[i]);
18570+ // break;
18571+ }
18572+ }
18573+
18574+ return;
18575+}
18576+
18577+
18578+
18579+
18580+
18581+
18582+
18583+static struct tasklet_struct start_xfer_tasklet = {
18584+ .next = NULL,
18585+ .state = 0,
18586+ .count = ATOMIC_INIT(0),
18587+ .func = start_xfer_tasklet_func,
18588+ .data = 0,
18589+};
18590+/**
18591+ * This function initialized the pcd Dp structures to there default
18592+ * state.
18593+ *
18594+ * @param pcd the pcd structure.
18595+ */
18596+void dwc_otg_pcd_reinit(dwc_otg_pcd_t *pcd)
18597+{
18598+ static const char * names[] =
18599+ {
18600+
18601+ "ep0",
18602+ "ep1in",
18603+ "ep2in",
18604+ "ep3in",
18605+ "ep4in",
18606+ "ep5in",
18607+ "ep6in",
18608+ "ep7in",
18609+ "ep8in",
18610+ "ep9in",
18611+ "ep10in",
18612+ "ep11in",
18613+ "ep12in",
18614+ "ep13in",
18615+ "ep14in",
18616+ "ep15in",
18617+ "ep1out",
18618+ "ep2out",
18619+ "ep3out",
18620+ "ep4out",
18621+ "ep5out",
18622+ "ep6out",
18623+ "ep7out",
18624+ "ep8out",
18625+ "ep9out",
18626+ "ep10out",
18627+ "ep11out",
18628+ "ep12out",
18629+ "ep13out",
18630+ "ep14out",
18631+ "ep15out"
18632+
18633+ };
18634+
18635+ int i;
18636+ int in_ep_cntr, out_ep_cntr;
18637+ uint32_t hwcfg1;
18638+ uint32_t num_in_eps = (GET_CORE_IF(pcd))->dev_if->num_in_eps;
18639+ uint32_t num_out_eps = (GET_CORE_IF(pcd))->dev_if->num_out_eps;
18640+ dwc_otg_pcd_ep_t *ep;
18641+
18642+ DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, pcd);
18643+
18644+ INIT_LIST_HEAD (&pcd->gadget.ep_list);
18645+ pcd->gadget.ep0 = &pcd->ep0.ep;
18646+ pcd->gadget.speed = USB_SPEED_UNKNOWN;
18647+
18648+ INIT_LIST_HEAD (&pcd->gadget.ep0->ep_list);
18649+
18650+ /**
18651+ * Initialize the EP0 structure.
18652+ */
18653+ ep = &pcd->ep0;
18654+
18655+ /* Init EP structure */
18656+ ep->desc = 0;
18657+ ep->pcd = pcd;
18658+ ep->stopped = 1;
18659+
18660+ /* Init DWC ep structure */
18661+ ep->dwc_ep.num = 0;
18662+ ep->dwc_ep.active = 0;
18663+ ep->dwc_ep.tx_fifo_num = 0;
18664+ /* Control until ep is actvated */
18665+ ep->dwc_ep.type = DWC_OTG_EP_TYPE_CONTROL;
18666+ ep->dwc_ep.maxpacket = MAX_PACKET_SIZE;
18667+ ep->dwc_ep.dma_addr = 0;
18668+ ep->dwc_ep.start_xfer_buff = 0;
18669+ ep->dwc_ep.xfer_buff = 0;
18670+ ep->dwc_ep.xfer_len = 0;
18671+ ep->dwc_ep.xfer_count = 0;
18672+ ep->dwc_ep.sent_zlp = 0;
18673+ ep->dwc_ep.total_len = 0;
18674+ ep->queue_sof = 0;
18675+ ep->dwc_ep.desc_addr = 0;
18676+ ep->dwc_ep.dma_desc_addr = 0;
18677+
18678+ ep->dwc_ep.aligned_buf=NULL;
18679+ ep->dwc_ep.aligned_buf_size=0;
18680+ ep->dwc_ep.aligned_dma_addr=0;
18681+
18682+
18683+ /* Init the usb_ep structure. */
18684+ ep->ep.name = names[0];
18685+ ep->ep.ops = (struct usb_ep_ops*)&dwc_otg_pcd_ep_ops;
18686+
18687+ /**
18688+ * @todo NGS: What should the max packet size be set to
18689+ * here? Before EP type is set?
18690+ */
18691+ ep->ep.maxpacket = MAX_PACKET_SIZE;
18692+
18693+ list_add_tail (&ep->ep.ep_list, &pcd->gadget.ep_list);
18694+
18695+ INIT_LIST_HEAD (&ep->queue);
18696+ /**
18697+ * Initialize the EP structures.
18698+ */
18699+ in_ep_cntr = 0;
18700+ hwcfg1 = (GET_CORE_IF(pcd))->hwcfg1.d32 >> 3;
18701+
18702+ for (i = 1; in_ep_cntr < num_in_eps; i++)
18703+ {
18704+ if((hwcfg1 & 0x1) == 0) {
18705+ dwc_otg_pcd_ep_t *ep = &pcd->in_ep[in_ep_cntr];
18706+ in_ep_cntr ++;
18707+
18708+ /* Init EP structure */
18709+ ep->desc = 0;
18710+ ep->pcd = pcd;
18711+ ep->stopped = 1;
18712+
18713+ /* Init DWC ep structure */
18714+ ep->dwc_ep.is_in = 1;
18715+ ep->dwc_ep.num = i;
18716+ ep->dwc_ep.active = 0;
18717+ ep->dwc_ep.tx_fifo_num = 0;
18718+
18719+ /* Control until ep is actvated */
18720+ ep->dwc_ep.type = DWC_OTG_EP_TYPE_CONTROL;
18721+ ep->dwc_ep.maxpacket = MAX_PACKET_SIZE;
18722+ ep->dwc_ep.dma_addr = 0;
18723+ ep->dwc_ep.start_xfer_buff = 0;
18724+ ep->dwc_ep.xfer_buff = 0;
18725+ ep->dwc_ep.xfer_len = 0;
18726+ ep->dwc_ep.xfer_count = 0;
18727+ ep->dwc_ep.sent_zlp = 0;
18728+ ep->dwc_ep.total_len = 0;
18729+ ep->queue_sof = 0;
18730+ ep->dwc_ep.desc_addr = 0;
18731+ ep->dwc_ep.dma_desc_addr = 0;
18732+
18733+ /* Init the usb_ep structure. */
18734+ ep->ep.name = names[i];
18735+ ep->ep.ops = (struct usb_ep_ops*)&dwc_otg_pcd_ep_ops;
18736+
18737+ /**
18738+ * @todo NGS: What should the max packet size be set to
18739+ * here? Before EP type is set?
18740+ */
18741+ ep->ep.maxpacket = MAX_PACKET_SIZE;
18742+
18743+ //add only even number ep as in
18744+ if((i%2)==1)
18745+ list_add_tail (&ep->ep.ep_list, &pcd->gadget.ep_list);
18746+
18747+ INIT_LIST_HEAD (&ep->queue);
18748+ }
18749+ hwcfg1 >>= 2;
18750+ }
18751+
18752+ out_ep_cntr = 0;
18753+ hwcfg1 = (GET_CORE_IF(pcd))->hwcfg1.d32 >> 2;
18754+
18755+ for (i = 1; out_ep_cntr < num_out_eps; i++)
18756+ {
18757+ if((hwcfg1 & 0x1) == 0) {
18758+ dwc_otg_pcd_ep_t *ep = &pcd->out_ep[out_ep_cntr];
18759+ out_ep_cntr++;
18760+
18761+ /* Init EP structure */
18762+ ep->desc = 0;
18763+ ep->pcd = pcd;
18764+ ep->stopped = 1;
18765+
18766+ /* Init DWC ep structure */
18767+ ep->dwc_ep.is_in = 0;
18768+ ep->dwc_ep.num = i;
18769+ ep->dwc_ep.active = 0;
18770+ ep->dwc_ep.tx_fifo_num = 0;
18771+ /* Control until ep is actvated */
18772+ ep->dwc_ep.type = DWC_OTG_EP_TYPE_CONTROL;
18773+ ep->dwc_ep.maxpacket = MAX_PACKET_SIZE;
18774+ ep->dwc_ep.dma_addr = 0;
18775+ ep->dwc_ep.start_xfer_buff = 0;
18776+ ep->dwc_ep.xfer_buff = 0;
18777+ ep->dwc_ep.xfer_len = 0;
18778+ ep->dwc_ep.xfer_count = 0;
18779+ ep->dwc_ep.sent_zlp = 0;
18780+ ep->dwc_ep.total_len = 0;
18781+ ep->queue_sof = 0;
18782+
18783+ /* Init the usb_ep structure. */
18784+ ep->ep.name = names[15 + i];
18785+ ep->ep.ops = (struct usb_ep_ops*)&dwc_otg_pcd_ep_ops;
18786+ /**
18787+ * @todo NGS: What should the max packet size be set to
18788+ * here? Before EP type is set?
18789+ */
18790+ ep->ep.maxpacket = MAX_PACKET_SIZE;
18791+
18792+ //add only odd number ep as out
18793+ if((i%2)==0)
18794+ list_add_tail (&ep->ep.ep_list, &pcd->gadget.ep_list);
18795+
18796+ INIT_LIST_HEAD (&ep->queue);
18797+ }
18798+ hwcfg1 >>= 2;
18799+ }
18800+
18801+ /* remove ep0 from the list. There is a ep0 pointer.*/
18802+ list_del_init (&pcd->ep0.ep.ep_list);
18803+
18804+ pcd->ep0state = EP0_DISCONNECT;
18805+ pcd->ep0.ep.maxpacket = MAX_EP0_SIZE;
18806+ pcd->ep0.dwc_ep.maxpacket = MAX_EP0_SIZE;
18807+ pcd->ep0.dwc_ep.type = DWC_OTG_EP_TYPE_CONTROL;
18808+}
18809+
18810+/**
18811+ * This function releases the Gadget device.
18812+ * required by device_unregister().
18813+ *
18814+ * @todo Should this do something? Should it free the PCD?
18815+ */
18816+static void dwc_otg_pcd_gadget_release(struct device *dev)
18817+{
18818+ DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, dev);
18819+}
18820+
18821+
18822+
18823+/**
18824+ * This function initialized the PCD portion of the driver.
18825+ *
18826+ */
18827+u8 dev_id[]="gadget";
18828+int dwc_otg_pcd_init(struct lm_device *lmdev)
18829+{
18830+ static char pcd_name[] = "dwc_otg_pcd";
18831+ dwc_otg_pcd_t *pcd;
18832+ dwc_otg_core_if_t* core_if;
18833+ dwc_otg_dev_if_t* dev_if;
18834+ dwc_otg_device_t *otg_dev = lm_get_drvdata(lmdev);
18835+ int retval = 0;
18836+
18837+
18838+ DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n",__func__, lmdev);
18839+ /*
18840+ * Allocate PCD structure
18841+ */
18842+ pcd = kmalloc(sizeof(dwc_otg_pcd_t), GFP_KERNEL);
18843+
18844+ if (pcd == 0) {
18845+ return -ENOMEM;
18846+ }
18847+
18848+ memset(pcd, 0, sizeof(dwc_otg_pcd_t));
18849+ spin_lock_init(&pcd->lock);
18850+
18851+ otg_dev->pcd = pcd;
18852+ s_pcd = pcd;
18853+ pcd->gadget.name = pcd_name;
18854+
18855+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)
18856+ strcpy(pcd->gadget.dev.bus_id, "gadget");
18857+#else
18858+ pcd->gadget.dev.init_name = dev_id;
18859+#endif
18860+ pcd->otg_dev = lm_get_drvdata(lmdev);
18861+
18862+ pcd->gadget.dev.parent = &lmdev->dev;
18863+ pcd->gadget.dev.release = dwc_otg_pcd_gadget_release;
18864+ pcd->gadget.ops = &dwc_otg_pcd_ops;
18865+
18866+ core_if = GET_CORE_IF(pcd);
18867+ dev_if = core_if->dev_if;
18868+
18869+ if(core_if->hwcfg4.b.ded_fifo_en) {
18870+ DWC_PRINT("Dedicated Tx FIFOs mode\n");
18871+ }
18872+ else {
18873+ DWC_PRINT("Shared Tx FIFO mode\n");
18874+ }
18875+
18876+ /* If the module is set to FS or if the PHY_TYPE is FS then the gadget
18877+ * should not report as dual-speed capable. replace the following line
18878+ * with the block of code below it once the software is debugged for
18879+ * this. If is_dualspeed = 0 then the gadget driver should not report
18880+ * a device qualifier descriptor when queried. */
18881+ if ((GET_CORE_IF(pcd)->core_params->speed == DWC_SPEED_PARAM_FULL) ||
18882+ ((GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type == 2) &&
18883+ (GET_CORE_IF(pcd)->hwcfg2.b.fs_phy_type == 1) &&
18884+ (GET_CORE_IF(pcd)->core_params->ulpi_fs_ls))) {
18885+ pcd->gadget.is_dualspeed = 0;
18886+ }
18887+ else {
18888+ pcd->gadget.is_dualspeed = 1;
18889+ }
18890+
18891+ if ((otg_dev->core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE) ||
18892+ (otg_dev->core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST) ||
18893+ (otg_dev->core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE) ||
18894+ (otg_dev->core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)) {
18895+ pcd->gadget.is_otg = 0;
18896+ }
18897+ else {
18898+ pcd->gadget.is_otg = 1;
18899+ }
18900+
18901+
18902+ pcd->driver = 0;
18903+ /* Register the gadget device */
18904+printk("%s: 1\n",__func__);
18905+ retval = device_register(&pcd->gadget.dev);
18906+ if (retval != 0) {
18907+ kfree (pcd);
18908+printk("%s: 2\n",__func__);
18909+ return retval;
18910+ }
18911+
18912+
18913+ /*
18914+ * Initialized the Core for Device mode.
18915+ */
18916+ if (dwc_otg_is_device_mode(core_if)) {
18917+ dwc_otg_core_dev_init(core_if);
18918+ }
18919+
18920+ /*
18921+ * Initialize EP structures
18922+ */
18923+ dwc_otg_pcd_reinit(pcd);
18924+
18925+ /*
18926+ * Register the PCD Callbacks.
18927+ */
18928+ dwc_otg_cil_register_pcd_callbacks(otg_dev->core_if, &pcd_callbacks,
18929+ pcd);
18930+ /*
18931+ * Setup interupt handler
18932+ */
18933+ DWC_DEBUGPL(DBG_ANY, "registering handler for irq%d\n", lmdev->irq);
18934+ retval = request_irq(lmdev->irq, dwc_otg_pcd_irq,
18935+ IRQF_SHARED, pcd->gadget.name, pcd);
18936+ if (retval != 0) {
18937+ DWC_ERROR("request of irq%d failed\n", lmdev->irq);
18938+ device_unregister(&pcd->gadget.dev);
18939+ kfree (pcd);
18940+ return -EBUSY;
18941+ }
18942+
18943+ /*
18944+ * Initialize the DMA buffer for SETUP packets
18945+ */
18946+ if (GET_CORE_IF(pcd)->dma_enable) {
18947+ pcd->setup_pkt = dma_alloc_coherent (NULL, sizeof (*pcd->setup_pkt) * 5, &pcd->setup_pkt_dma_handle, 0);
18948+ if (pcd->setup_pkt == 0) {
18949+ free_irq(lmdev->irq, pcd);
18950+ device_unregister(&pcd->gadget.dev);
18951+ kfree (pcd);
18952+ return -ENOMEM;
18953+ }
18954+
18955+ pcd->status_buf = dma_alloc_coherent (NULL, sizeof (uint16_t), &pcd->status_buf_dma_handle, 0);
18956+ if (pcd->status_buf == 0) {
18957+ dma_free_coherent(NULL, sizeof(*pcd->setup_pkt), pcd->setup_pkt, pcd->setup_pkt_dma_handle);
18958+ free_irq(lmdev->irq, pcd);
18959+ device_unregister(&pcd->gadget.dev);
18960+ kfree (pcd);
18961+ return -ENOMEM;
18962+ }
18963+
18964+ if (GET_CORE_IF(pcd)->dma_desc_enable) {
18965+ dev_if->setup_desc_addr[0] = dwc_otg_ep_alloc_desc_chain(&dev_if->dma_setup_desc_addr[0], 1);
18966+ dev_if->setup_desc_addr[1] = dwc_otg_ep_alloc_desc_chain(&dev_if->dma_setup_desc_addr[1], 1);
18967+ dev_if->in_desc_addr = dwc_otg_ep_alloc_desc_chain(&dev_if->dma_in_desc_addr, 1);
18968+ dev_if->out_desc_addr = dwc_otg_ep_alloc_desc_chain(&dev_if->dma_out_desc_addr, 1);
18969+
18970+ if(dev_if->setup_desc_addr[0] == 0
18971+ || dev_if->setup_desc_addr[1] == 0
18972+ || dev_if->in_desc_addr == 0
18973+ || dev_if->out_desc_addr == 0 ) {
18974+
18975+ if(dev_if->out_desc_addr)
18976+ dwc_otg_ep_free_desc_chain(dev_if->out_desc_addr, dev_if->dma_out_desc_addr, 1);
18977+ if(dev_if->in_desc_addr)
18978+ dwc_otg_ep_free_desc_chain(dev_if->in_desc_addr, dev_if->dma_in_desc_addr, 1);
18979+ if(dev_if->setup_desc_addr[1])
18980+ dwc_otg_ep_free_desc_chain(dev_if->setup_desc_addr[1], dev_if->dma_setup_desc_addr[1], 1);
18981+ if(dev_if->setup_desc_addr[0])
18982+ dwc_otg_ep_free_desc_chain(dev_if->setup_desc_addr[0], dev_if->dma_setup_desc_addr[0], 1);
18983+
18984+
18985+ dma_free_coherent(NULL, sizeof(*pcd->status_buf), pcd->status_buf, pcd->setup_pkt_dma_handle);
18986+ dma_free_coherent(NULL, sizeof(*pcd->setup_pkt), pcd->setup_pkt, pcd->setup_pkt_dma_handle);
18987+
18988+ free_irq(lmdev->irq, pcd);
18989+ device_unregister(&pcd->gadget.dev);
18990+ kfree (pcd);
18991+
18992+ return -ENOMEM;
18993+ }
18994+ }
18995+ }
18996+ else {
18997+ pcd->setup_pkt = kmalloc (sizeof (*pcd->setup_pkt) * 5, GFP_KERNEL);
18998+ if (pcd->setup_pkt == 0) {
18999+ free_irq(lmdev->irq, pcd);
19000+ device_unregister(&pcd->gadget.dev);
19001+ kfree (pcd);
19002+ return -ENOMEM;
19003+ }
19004+
19005+ pcd->status_buf = kmalloc (sizeof (uint16_t), GFP_KERNEL);
19006+ if (pcd->status_buf == 0) {
19007+ kfree(pcd->setup_pkt);
19008+ free_irq(lmdev->irq, pcd);
19009+ device_unregister(&pcd->gadget.dev);
19010+ kfree (pcd);
19011+ return -ENOMEM;
19012+ }
19013+ }
19014+
19015+
19016+ /* Initialize tasklet */
19017+ start_xfer_tasklet.data = (unsigned long)pcd;
19018+ pcd->start_xfer_tasklet = &start_xfer_tasklet;
19019+
19020+ return 0;
19021+}
19022+
19023+/**
19024+ * Cleanup the PCD.
19025+ */
19026+void dwc_otg_pcd_remove(struct lm_device *lmdev)
19027+{
19028+ dwc_otg_device_t *otg_dev = lm_get_drvdata(lmdev);
19029+ dwc_otg_pcd_t *pcd = otg_dev->pcd;
19030+ dwc_otg_dev_if_t* dev_if = GET_CORE_IF(pcd)->dev_if;
19031+
19032+ DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, lmdev);
19033+
19034+ /*
19035+ * Free the IRQ
19036+ */
19037+ free_irq(lmdev->irq, pcd);
19038+
19039+ /* start with the driver above us */
19040+ if (pcd->driver) {
19041+ /* should have been done already by driver model core */
19042+ DWC_WARN("driver '%s' is still registered\n",
19043+ pcd->driver->driver.name);
19044+ usb_gadget_unregister_driver(pcd->driver);
19045+ }
19046+ device_unregister(&pcd->gadget.dev);
19047+
19048+ if (GET_CORE_IF(pcd)->dma_enable) {
19049+ dma_free_coherent (NULL, sizeof (*pcd->setup_pkt) * 5, pcd->setup_pkt, pcd->setup_pkt_dma_handle);
19050+ dma_free_coherent (NULL, sizeof (uint16_t), pcd->status_buf, pcd->status_buf_dma_handle);
19051+ if (GET_CORE_IF(pcd)->dma_desc_enable) {
19052+ dwc_otg_ep_free_desc_chain(dev_if->setup_desc_addr[0], dev_if->dma_setup_desc_addr[0], 1);
19053+ dwc_otg_ep_free_desc_chain(dev_if->setup_desc_addr[1], dev_if->dma_setup_desc_addr[1], 1);
19054+ dwc_otg_ep_free_desc_chain(dev_if->in_desc_addr, dev_if->dma_in_desc_addr, 1);
19055+ dwc_otg_ep_free_desc_chain(dev_if->out_desc_addr, dev_if->dma_out_desc_addr, 1);
19056+ }
19057+ }
19058+ else {
19059+ kfree (pcd->setup_pkt);
19060+ kfree (pcd->status_buf);
19061+ }
19062+
19063+ kfree(pcd);
19064+ otg_dev->pcd = 0;
19065+}
19066+
19067+/**
19068+ * This function registers a gadget driver with the PCD.
19069+ *
19070+ * When a driver is successfully registered, it will receive control
19071+ * requests including set_configuration(), which enables non-control
19072+ * requests. then usb traffic follows until a disconnect is reported.
19073+ * then a host may connect again, or the driver might get unbound.
19074+ *
19075+ * @param driver The driver being registered
19076+ */
19077+int usb_gadget_register_driver(struct usb_gadget_driver *driver)
19078+{
19079+ int retval;
19080+
19081+ DWC_DEBUGPL(DBG_PCD, "registering gadget driver '%s'\n", driver->driver.name);
19082+
19083+ if (!driver || driver->speed == USB_SPEED_UNKNOWN ||
19084+ !driver->bind ||
19085+ !driver->unbind ||
19086+ !driver->disconnect ||
19087+ !driver->setup) {
19088+ DWC_DEBUGPL(DBG_PCDV,"EINVAL\n");
19089+ return -EINVAL;
19090+ }
19091+ if (s_pcd == 0) {
19092+ DWC_DEBUGPL(DBG_PCDV,"ENODEV\n");
19093+ return -ENODEV;
19094+ }
19095+ if (s_pcd->driver != 0) {
19096+ DWC_DEBUGPL(DBG_PCDV,"EBUSY (%p)\n", s_pcd->driver);
19097+ return -EBUSY;
19098+ }
19099+
19100+ /* hook up the driver */
19101+ s_pcd->driver = driver;
19102+ s_pcd->gadget.dev.driver = &driver->driver;
19103+
19104+ DWC_DEBUGPL(DBG_PCD, "bind to driver %s\n", driver->driver.name);
19105+ retval = driver->bind(&s_pcd->gadget);
19106+ if (retval) {
19107+ DWC_ERROR("bind to driver %s --> error %d\n",
19108+ driver->driver.name, retval);
19109+ s_pcd->driver = 0;
19110+ s_pcd->gadget.dev.driver = 0;
19111+ return retval;
19112+ }
19113+ DWC_DEBUGPL(DBG_ANY, "registered gadget driver '%s'\n",
19114+ driver->driver.name);
19115+ return 0;
19116+}
19117+
19118+EXPORT_SYMBOL(usb_gadget_register_driver);
19119+
19120+/**
19121+ * This function unregisters a gadget driver
19122+ *
19123+ * @param driver The driver being unregistered
19124+ */
19125+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
19126+{
19127+ //DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, _driver);
19128+
19129+ if (s_pcd == 0) {
19130+ DWC_DEBUGPL(DBG_ANY, "%s Return(%d): s_pcd==0\n", __func__,
19131+ -ENODEV);
19132+ return -ENODEV;
19133+ }
19134+ if (driver == 0 || driver != s_pcd->driver) {
19135+ DWC_DEBUGPL(DBG_ANY, "%s Return(%d): driver?\n", __func__,
19136+ -EINVAL);
19137+ return -EINVAL;
19138+ }
19139+
19140+ driver->unbind(&s_pcd->gadget);
19141+ s_pcd->driver = 0;
19142+
19143+ DWC_DEBUGPL(DBG_ANY, "unregistered driver '%s'\n",
19144+ driver->driver.name);
19145+ return 0;
19146+}
19147+EXPORT_SYMBOL(usb_gadget_unregister_driver);
19148+
19149+#endif /* DWC_HOST_ONLY */
19150--- /dev/null
19151+++ b/drivers/usb/host/otg/dwc_otg_pcd.h
19152@@ -0,0 +1,297 @@
19153+/* ==========================================================================
19154+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_pcd.h $
19155+ * $Revision: #36 $
19156+ * $Date: 2008/09/26 $
19157+ * $Change: 1103515 $
19158+ *
19159+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
19160+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
19161+ * otherwise expressly agreed to in writing between Synopsys and you.
19162+ *
19163+ * The Software IS NOT an item of Licensed Software or Licensed Product under
19164+ * any End User Software License Agreement or Agreement for Licensed Product
19165+ * with Synopsys or any supplement thereto. You are permitted to use and
19166+ * redistribute this Software in source and binary forms, with or without
19167+ * modification, provided that redistributions of source code must retain this
19168+ * notice. You may not view, use, disclose, copy or distribute this file or
19169+ * any information contained herein except pursuant to this license grant from
19170+ * Synopsys. If you do not agree with this notice, including the disclaimer
19171+ * below, then you are not authorized to use the Software.
19172+ *
19173+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
19174+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19175+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19176+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
19177+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19178+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19179+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
19180+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
19181+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
19182+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
19183+ * DAMAGE.
19184+ * ========================================================================== */
19185+#ifndef DWC_HOST_ONLY
19186+#if !defined(__DWC_PCD_H__)
19187+#define __DWC_PCD_H__
19188+
19189+#include <linux/types.h>
19190+#include <linux/list.h>
19191+#include <linux/errno.h>
19192+#include <linux/device.h>
19193+
19194+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
19195+# include <linux/usb/ch9.h>
19196+# include <linux/usb/gadget.h>
19197+#else
19198+# include <linux/usb_ch9.h>
19199+# include <linux/usb_gadget.h>
19200+#endif
19201+
19202+#include <linux/interrupt.h>
19203+#include <linux/dma-mapping.h>
19204+
19205+struct lm_device;
19206+struct dwc_otg_device;
19207+
19208+#include "dwc_otg_cil.h"
19209+
19210+/**
19211+ * @file
19212+ *
19213+ * This file contains the structures, constants, and interfaces for
19214+ * the Perpherial Contoller Driver (PCD).
19215+ *
19216+ * The Peripheral Controller Driver (PCD) for Linux will implement the
19217+ * Gadget API, so that the existing Gadget drivers can be used. For
19218+ * the Mass Storage Function driver the File-backed USB Storage Gadget
19219+ * (FBS) driver will be used. The FBS driver supports the
19220+ * Control-Bulk (CB), Control-Bulk-Interrupt (CBI), and Bulk-Only
19221+ * transports.
19222+ *
19223+ */
19224+
19225+/** Invalid DMA Address */
19226+#define DMA_ADDR_INVALID (~(dma_addr_t)0)
19227+/** Maxpacket size for EP0 */
19228+#define MAX_EP0_SIZE 64
19229+/** Maxpacket size for any EP */
19230+#define MAX_PACKET_SIZE 1024
19231+
19232+/** Max Transfer size for any EP */
19233+#define MAX_TRANSFER_SIZE 65535
19234+
19235+/** Max DMA Descriptor count for any EP */
19236+#define MAX_DMA_DESC_CNT 64
19237+
19238+/**
19239+ * Get the pointer to the core_if from the pcd pointer.
19240+ */
19241+#define GET_CORE_IF( _pcd ) (_pcd->otg_dev->core_if)
19242+
19243+/**
19244+ * States of EP0.
19245+ */
19246+typedef enum ep0_state
19247+{
19248+ EP0_DISCONNECT, /* no host */
19249+ EP0_IDLE,
19250+ EP0_IN_DATA_PHASE,
19251+ EP0_OUT_DATA_PHASE,
19252+ EP0_IN_STATUS_PHASE,
19253+ EP0_OUT_STATUS_PHASE,
19254+ EP0_STALL,
19255+} ep0state_e;
19256+
19257+/** Fordward declaration.*/
19258+struct dwc_otg_pcd;
19259+
19260+/** DWC_otg iso request structure.
19261+ *
19262+ */
19263+typedef struct usb_iso_request dwc_otg_pcd_iso_request_t;
19264+
19265+/** PCD EP structure.
19266+ * This structure describes an EP, there is an array of EPs in the PCD
19267+ * structure.
19268+ */
19269+typedef struct dwc_otg_pcd_ep
19270+{
19271+ /** USB EP data */
19272+ struct usb_ep ep;
19273+ /** USB EP Descriptor */
19274+ const struct usb_endpoint_descriptor *desc;
19275+
19276+ /** queue of dwc_otg_pcd_requests. */
19277+ struct list_head queue;
19278+ unsigned stopped : 1;
19279+ unsigned disabling : 1;
19280+ unsigned dma : 1;
19281+ unsigned queue_sof : 1;
19282+
19283+#ifdef DWC_EN_ISOC
19284+ /** DWC_otg Isochronous Transfer */
19285+ struct usb_iso_request* iso_req;
19286+#endif //DWC_EN_ISOC
19287+
19288+ /** DWC_otg ep data. */
19289+ dwc_ep_t dwc_ep;
19290+
19291+ /** Pointer to PCD */
19292+ struct dwc_otg_pcd *pcd;
19293+}dwc_otg_pcd_ep_t;
19294+
19295+
19296+
19297+/** DWC_otg PCD Structure.
19298+ * This structure encapsulates the data for the dwc_otg PCD.
19299+ */
19300+typedef struct dwc_otg_pcd
19301+{
19302+ /** USB gadget */
19303+ struct usb_gadget gadget;
19304+ /** USB gadget driver pointer*/
19305+ struct usb_gadget_driver *driver;
19306+ /** The DWC otg device pointer. */
19307+ struct dwc_otg_device *otg_dev;
19308+
19309+ /** State of EP0 */
19310+ ep0state_e ep0state;
19311+ /** EP0 Request is pending */
19312+ unsigned ep0_pending : 1;
19313+ /** Indicates when SET CONFIGURATION Request is in process */
19314+ unsigned request_config : 1;
19315+ /** The state of the Remote Wakeup Enable. */
19316+ unsigned remote_wakeup_enable : 1;
19317+ /** The state of the B-Device HNP Enable. */
19318+ unsigned b_hnp_enable : 1;
19319+ /** The state of A-Device HNP Support. */
19320+ unsigned a_hnp_support : 1;
19321+ /** The state of the A-Device Alt HNP support. */
19322+ unsigned a_alt_hnp_support : 1;
19323+ /** Count of pending Requests */
19324+ unsigned request_pending;
19325+
19326+ /** SETUP packet for EP0
19327+ * This structure is allocated as a DMA buffer on PCD initialization
19328+ * with enough space for up to 3 setup packets.
19329+ */
19330+ union
19331+ {
19332+ struct usb_ctrlrequest req;
19333+ uint32_t d32[2];
19334+ } *setup_pkt;
19335+
19336+ dma_addr_t setup_pkt_dma_handle;
19337+
19338+ /** 2-byte dma buffer used to return status from GET_STATUS */
19339+ uint16_t *status_buf;
19340+ dma_addr_t status_buf_dma_handle;
19341+
19342+ /** EP0 */
19343+ dwc_otg_pcd_ep_t ep0;
19344+
19345+ /** Array of IN EPs. */
19346+ dwc_otg_pcd_ep_t in_ep[ MAX_EPS_CHANNELS - 1];
19347+ /** Array of OUT EPs. */
19348+ dwc_otg_pcd_ep_t out_ep[ MAX_EPS_CHANNELS - 1];
19349+ /** number of valid EPs in the above array. */
19350+// unsigned num_eps : 4;
19351+ spinlock_t lock;
19352+ /** Timer for SRP. If it expires before SRP is successful
19353+ * clear the SRP. */
19354+ struct timer_list srp_timer;
19355+
19356+ /** Tasklet to defer starting of TEST mode transmissions until
19357+ * Status Phase has been completed.
19358+ */
19359+ struct tasklet_struct test_mode_tasklet;
19360+
19361+ /** Tasklet to delay starting of xfer in DMA mode */
19362+ struct tasklet_struct *start_xfer_tasklet;
19363+
19364+ /** The test mode to enter when the tasklet is executed. */
19365+ unsigned test_mode;
19366+
19367+} dwc_otg_pcd_t;
19368+
19369+
19370+/** DWC_otg request structure.
19371+ * This structure is a list of requests.
19372+ */
19373+typedef struct
19374+{
19375+ struct usb_request req; /**< USB Request. */
19376+ struct list_head queue; /**< queue of these requests. */
19377+} dwc_otg_pcd_request_t;
19378+
19379+
19380+extern int dwc_otg_pcd_init(struct lm_device *lmdev);
19381+
19382+//extern void dwc_otg_pcd_remove( struct dwc_otg_device *_otg_dev );
19383+extern void dwc_otg_pcd_remove( struct lm_device *lmdev );
19384+extern int32_t dwc_otg_pcd_handle_intr( dwc_otg_pcd_t *pcd );
19385+extern void dwc_otg_pcd_start_srp_timer(dwc_otg_pcd_t *pcd );
19386+
19387+extern void dwc_otg_pcd_initiate_srp(dwc_otg_pcd_t *pcd);
19388+extern void dwc_otg_pcd_remote_wakeup(dwc_otg_pcd_t *pcd, int set);
19389+
19390+extern void dwc_otg_iso_buffer_done(dwc_otg_pcd_ep_t *ep, dwc_otg_pcd_iso_request_t *req);
19391+extern void dwc_otg_request_done(dwc_otg_pcd_ep_t *_ep, dwc_otg_pcd_request_t *req,
19392+ int status);
19393+extern void dwc_otg_request_nuke(dwc_otg_pcd_ep_t *_ep);
19394+extern void dwc_otg_pcd_update_otg(dwc_otg_pcd_t *_pcd,
19395+ const unsigned reset);
19396+#ifndef VERBOSE
19397+#define VERIFY_PCD_DMA_ADDR(_addr_) BUG_ON(((_addr_)==DMA_ADDR_INVALID)||\
19398+ ((_addr_)==0)||\
19399+ ((_addr_)&0x3))
19400+#else
19401+#define VERIFY_PCD_DMA_ADDR(_addr_) {\
19402+ if(((_addr_)==DMA_ADDR_INVALID)||\
19403+ ((_addr_)==0)||\
19404+ ((_addr_)&0x3)) {\
19405+ printk("%s: Invalid DMA address "#_addr_"(%.8x)\n",__func__,_addr_);\
19406+ BUG();\
19407+ }\
19408+ }
19409+#endif
19410+
19411+
19412+static inline void ep_check_and_patch_dma_addr(dwc_otg_pcd_ep_t *ep){
19413+//void ep_check_and_patch_dma_addr(dwc_otg_pcd_ep_t *ep){
19414+ dwc_ep_t *dwc_ep=&ep->dwc_ep;
19415+
19416+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);
19417+ if (/*(core_if->dma_enable)&&*/(dwc_ep->dma_addr==DMA_ADDR_INVALID)) {
19418+ if((((u32)dwc_ep->xfer_buff)&0x3)==0){
19419+ dwc_ep->dma_addr=dma_map_single(NULL,(void *)(dwc_ep->start_xfer_buff),(dwc_ep->total_len), DMA_TO_DEVICE);
19420+DWC_DEBUGPL(DBG_PCDV," got dma_addr=%.8x\n",dwc_ep->dma_addr);
19421+ }else{
19422+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);
19423+ if(dwc_ep->aligned_buf_size<dwc_ep->total_len){
19424+ if(dwc_ep->aligned_buf){
19425+//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);
19426+ //dma_free_coherent(NULL,dwc_ep->aligned_buf_size,dwc_ep->aligned_buf,dwc_ep->aligned_dma_addr);
19427+ kfree(dwc_ep->aligned_buf);
19428+ }
19429+ dwc_ep->aligned_buf_size=((1<<20)>(dwc_ep->total_len<<1))?(dwc_ep->total_len<<1):(1<<20);
19430+ //dwc_ep->aligned_buf = dma_alloc_coherent (NULL, dwc_ep->aligned_buf_size, &dwc_ep->aligned_dma_addr, GFP_KERNEL|GFP_DMA);
19431+ dwc_ep->aligned_buf=kmalloc(dwc_ep->aligned_buf_size,GFP_KERNEL|GFP_DMA|GFP_ATOMIC);
19432+ dwc_ep->aligned_dma_addr=dma_map_single(NULL,(void *)(dwc_ep->aligned_buf),(dwc_ep->aligned_buf_size),DMA_FROM_DEVICE);
19433+ if(!dwc_ep->aligned_buf){
19434+ DWC_ERROR("Cannot alloc required buffer!!\n");
19435+ BUG();
19436+ }
19437+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);
19438+ }
19439+ dwc_ep->dma_addr=dwc_ep->aligned_dma_addr;
19440+ if(dwc_ep->is_in) {
19441+ memcpy(dwc_ep->aligned_buf,dwc_ep->xfer_buff,dwc_ep->total_len);
19442+ dma_sync_single_for_device(NULL,dwc_ep->dma_addr,dwc_ep->total_len,DMA_TO_DEVICE);
19443+ }
19444+ }
19445+ }
19446+}
19447+
19448+#endif
19449+#endif /* DWC_HOST_ONLY */
19450--- /dev/null
19451+++ b/drivers/usb/host/otg/dwc_otg_pcd_intr.c
19452@@ -0,0 +1,3708 @@
19453+/* ==========================================================================
19454+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_pcd_intr.c $
19455+ * $Revision: #83 $
19456+ * $Date: 2008/10/14 $
19457+ * $Change: 1115682 $
19458+ *
19459+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
19460+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
19461+ * otherwise expressly agreed to in writing between Synopsys and you.
19462+ *
19463+ * The Software IS NOT an item of Licensed Software or Licensed Product under
19464+ * any End User Software License Agreement or Agreement for Licensed Product
19465+ * with Synopsys or any supplement thereto. You are permitted to use and
19466+ * redistribute this Software in source and binary forms, with or without
19467+ * modification, provided that redistributions of source code must retain this
19468+ * notice. You may not view, use, disclose, copy or distribute this file or
19469+ * any information contained herein except pursuant to this license grant from
19470+ * Synopsys. If you do not agree with this notice, including the disclaimer
19471+ * below, then you are not authorized to use the Software.
19472+ *
19473+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
19474+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19475+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19476+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
19477+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19478+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19479+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
19480+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
19481+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
19482+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
19483+ * DAMAGE.
19484+ * ========================================================================== */
19485+#ifndef DWC_HOST_ONLY
19486+#include <linux/interrupt.h>
19487+#include <linux/dma-mapping.h>
19488+#include <linux/version.h>
19489+#include <linux/pci.h>
19490+
19491+#include "dwc_otg_driver.h"
19492+#include "dwc_otg_pcd.h"
19493+
19494+
19495+#define DEBUG_EP0
19496+
19497+
19498+/* request functions defined in "dwc_otg_pcd.c" */
19499+
19500+/** @file
19501+ * This file contains the implementation of the PCD Interrupt handlers.
19502+ *
19503+ * The PCD handles the device interrupts. Many conditions can cause a
19504+ * device interrupt. When an interrupt occurs, the device interrupt
19505+ * service routine determines the cause of the interrupt and
19506+ * dispatches handling to the appropriate function. These interrupt
19507+ * handling functions are described below.
19508+ * All interrupt registers are processed from LSB to MSB.
19509+ */
19510+
19511+
19512+/**
19513+ * This function prints the ep0 state for debug purposes.
19514+ */
19515+static inline void print_ep0_state(dwc_otg_pcd_t *pcd)
19516+{
19517+#ifdef DEBUG
19518+ char str[40];
19519+
19520+ switch (pcd->ep0state) {
19521+ case EP0_DISCONNECT:
19522+ strcpy(str, "EP0_DISCONNECT");
19523+ break;
19524+ case EP0_IDLE:
19525+ strcpy(str, "EP0_IDLE");
19526+ break;
19527+ case EP0_IN_DATA_PHASE:
19528+ strcpy(str, "EP0_IN_DATA_PHASE");
19529+ break;
19530+ case EP0_OUT_DATA_PHASE:
19531+ strcpy(str, "EP0_OUT_DATA_PHASE");
19532+ break;
19533+ case EP0_IN_STATUS_PHASE:
19534+ strcpy(str,"EP0_IN_STATUS_PHASE");
19535+ break;
19536+ case EP0_OUT_STATUS_PHASE:
19537+ strcpy(str,"EP0_OUT_STATUS_PHASE");
19538+ break;
19539+ case EP0_STALL:
19540+ strcpy(str,"EP0_STALL");
19541+ break;
19542+ default:
19543+ strcpy(str,"EP0_INVALID");
19544+ }
19545+
19546+ DWC_DEBUGPL(DBG_ANY, "%s(%d)\n", str, pcd->ep0state);
19547+#endif
19548+}
19549+
19550+/**
19551+ * This function returns pointer to in ep struct with number ep_num
19552+ */
19553+static inline dwc_otg_pcd_ep_t* get_in_ep(dwc_otg_pcd_t *pcd, uint32_t ep_num)
19554+{
19555+ int i;
19556+ int num_in_eps = GET_CORE_IF(pcd)->dev_if->num_in_eps;
19557+ if(ep_num == 0) {
19558+ return &pcd->ep0;
19559+ }
19560+ else {
19561+ for(i = 0; i < num_in_eps; ++i)
19562+ {
19563+ if(pcd->in_ep[i].dwc_ep.num == ep_num)
19564+ return &pcd->in_ep[i];
19565+ }
19566+ return 0;
19567+ }
19568+}
19569+/**
19570+ * This function returns pointer to out ep struct with number ep_num
19571+ */
19572+static inline dwc_otg_pcd_ep_t* get_out_ep(dwc_otg_pcd_t *pcd, uint32_t ep_num)
19573+{
19574+ int i;
19575+ int num_out_eps = GET_CORE_IF(pcd)->dev_if->num_out_eps;
19576+ if(ep_num == 0) {
19577+ return &pcd->ep0;
19578+ }
19579+ else {
19580+ for(i = 0; i < num_out_eps; ++i)
19581+ {
19582+ if(pcd->out_ep[i].dwc_ep.num == ep_num)
19583+ return &pcd->out_ep[i];
19584+ }
19585+ return 0;
19586+ }
19587+}
19588+/**
19589+ * This functions gets a pointer to an EP from the wIndex address
19590+ * value of the control request.
19591+ */
19592+static dwc_otg_pcd_ep_t *get_ep_by_addr (dwc_otg_pcd_t *pcd, u16 wIndex)
19593+{
19594+ dwc_otg_pcd_ep_t *ep;
19595+
19596+ if ((wIndex & USB_ENDPOINT_NUMBER_MASK) == 0)
19597+ return &pcd->ep0;
19598+ list_for_each_entry(ep, &pcd->gadget.ep_list, ep.ep_list)
19599+ {
19600+ u8 bEndpointAddress;
19601+
19602+ if (!ep->desc)
19603+ continue;
19604+
19605+ bEndpointAddress = ep->desc->bEndpointAddress;
19606+ if((wIndex & (USB_DIR_IN | USB_ENDPOINT_NUMBER_MASK))
19607+ == (bEndpointAddress & (USB_DIR_IN | USB_ENDPOINT_NUMBER_MASK)))
19608+ return ep;
19609+ }
19610+ return NULL;
19611+}
19612+
19613+/**
19614+ * This function checks the EP request queue, if the queue is not
19615+ * empty the next request is started.
19616+ */
19617+void start_next_request(dwc_otg_pcd_ep_t *ep)
19618+{
19619+ dwc_otg_pcd_request_t *req = 0;
19620+ uint32_t max_transfer = GET_CORE_IF(ep->pcd)->core_params->max_transfer_size;
19621+ if (!list_empty(&ep->queue)) {
19622+ req = list_entry(ep->queue.next,
19623+ dwc_otg_pcd_request_t, queue);
19624+
19625+ /* Setup and start the Transfer */
19626+ ep->dwc_ep.dma_addr = req->req.dma;
19627+ ep->dwc_ep.start_xfer_buff = req->req.buf;
19628+ ep->dwc_ep.xfer_buff = req->req.buf;
19629+ ep->dwc_ep.sent_zlp = 0;
19630+ ep->dwc_ep.total_len = req->req.length;
19631+ ep->dwc_ep.xfer_len = 0;
19632+ ep->dwc_ep.xfer_count = 0;
19633+
19634+ if(max_transfer > MAX_TRANSFER_SIZE) {
19635+ ep->dwc_ep.maxxfer = max_transfer - (max_transfer % ep->dwc_ep.maxpacket);
19636+ } else {
19637+ ep->dwc_ep.maxxfer = max_transfer;
19638+ }
19639+
19640+ if(req->req.zero) {
19641+ if((ep->dwc_ep.total_len % ep->dwc_ep.maxpacket == 0)
19642+ && (ep->dwc_ep.total_len != 0)) {
19643+ ep->dwc_ep.sent_zlp = 1;
19644+ }
19645+
19646+ }
19647+ ep_check_and_patch_dma_addr(ep);
19648+ dwc_otg_ep_start_transfer(GET_CORE_IF(ep->pcd), &ep->dwc_ep);
19649+ }
19650+}
19651+
19652+/**
19653+ * This function handles the SOF Interrupts. At this time the SOF
19654+ * Interrupt is disabled.
19655+ */
19656+int32_t dwc_otg_pcd_handle_sof_intr(dwc_otg_pcd_t *pcd)
19657+{
19658+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
19659+
19660+ gintsts_data_t gintsts;
19661+
19662+ DWC_DEBUGPL(DBG_PCD, "SOF\n");
19663+
19664+ /* Clear interrupt */
19665+ gintsts.d32 = 0;
19666+ gintsts.b.sofintr = 1;
19667+ dwc_write_reg32 (&core_if->core_global_regs->gintsts, gintsts.d32);
19668+
19669+ return 1;
19670+}
19671+
19672+
19673+/**
19674+ * This function handles the Rx Status Queue Level Interrupt, which
19675+ * indicates that there is a least one packet in the Rx FIFO. The
19676+ * packets are moved from the FIFO to memory, where they will be
19677+ * processed when the Endpoint Interrupt Register indicates Transfer
19678+ * Complete or SETUP Phase Done.
19679+ *
19680+ * Repeat the following until the Rx Status Queue is empty:
19681+ * -# Read the Receive Status Pop Register (GRXSTSP) to get Packet
19682+ * info
19683+ * -# If Receive FIFO is empty then skip to step Clear the interrupt
19684+ * and exit
19685+ * -# If SETUP Packet call dwc_otg_read_setup_packet to copy the
19686+ * SETUP data to the buffer
19687+ * -# If OUT Data Packet call dwc_otg_read_packet to copy the data
19688+ * to the destination buffer
19689+ */
19690+int32_t dwc_otg_pcd_handle_rx_status_q_level_intr(dwc_otg_pcd_t *pcd)
19691+{
19692+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
19693+ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
19694+ gintmsk_data_t gintmask = {.d32=0};
19695+ device_grxsts_data_t status;
19696+ dwc_otg_pcd_ep_t *ep;
19697+ gintsts_data_t gintsts;
19698+#ifdef DEBUG
19699+ static char *dpid_str[] ={ "D0", "D2", "D1", "MDATA" };
19700+#endif
19701+
19702+ //DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, _pcd);
19703+ /* Disable the Rx Status Queue Level interrupt */
19704+ gintmask.b.rxstsqlvl= 1;
19705+ dwc_modify_reg32(&global_regs->gintmsk, gintmask.d32, 0);
19706+
19707+ /* Get the Status from the top of the FIFO */
19708+ status.d32 = dwc_read_reg32(&global_regs->grxstsp);
19709+
19710+ DWC_DEBUGPL(DBG_PCD, "EP:%d BCnt:%d DPID:%s "
19711+ "pktsts:%x Frame:%d(0x%0x)\n",
19712+ status.b.epnum, status.b.bcnt,
19713+ dpid_str[status.b.dpid],
19714+ status.b.pktsts, status.b.fn, status.b.fn);
19715+ /* Get pointer to EP structure */
19716+ ep = get_out_ep(pcd, status.b.epnum);
19717+
19718+ switch (status.b.pktsts) {
19719+ case DWC_DSTS_GOUT_NAK:
19720+ DWC_DEBUGPL(DBG_PCDV, "Global OUT NAK\n");
19721+ break;
19722+ case DWC_STS_DATA_UPDT:
19723+ DWC_DEBUGPL(DBG_PCDV, "OUT Data Packet\n");
19724+ if (status.b.bcnt && ep->dwc_ep.xfer_buff) {
19725+ /** @todo NGS Check for buffer overflow? */
19726+ dwc_otg_read_packet(core_if,
19727+ ep->dwc_ep.xfer_buff,
19728+ status.b.bcnt);
19729+ ep->dwc_ep.xfer_count += status.b.bcnt;
19730+ ep->dwc_ep.xfer_buff += status.b.bcnt;
19731+ }
19732+ break;
19733+ case DWC_STS_XFER_COMP:
19734+ DWC_DEBUGPL(DBG_PCDV, "OUT Complete\n");
19735+ break;
19736+ case DWC_DSTS_SETUP_COMP:
19737+#ifdef DEBUG_EP0
19738+ DWC_DEBUGPL(DBG_PCDV, "Setup Complete\n");
19739+#endif
19740+ break;
19741+case DWC_DSTS_SETUP_UPDT:
19742+ dwc_otg_read_setup_packet(core_if, pcd->setup_pkt->d32);
19743+#ifdef DEBUG_EP0
19744+ DWC_DEBUGPL(DBG_PCD,
19745+ "SETUP PKT: %02x.%02x v%04x i%04x l%04x\n",
19746+ pcd->setup_pkt->req.bRequestType,
19747+ pcd->setup_pkt->req.bRequest,
19748+ pcd->setup_pkt->req.wValue,
19749+ pcd->setup_pkt->req.wIndex,
19750+ pcd->setup_pkt->req.wLength);
19751+#endif
19752+ ep->dwc_ep.xfer_count += status.b.bcnt;
19753+ break;
19754+ default:
19755+ DWC_DEBUGPL(DBG_PCDV, "Invalid Packet Status (0x%0x)\n",
19756+ status.b.pktsts);
19757+ break;
19758+ }
19759+
19760+ /* Enable the Rx Status Queue Level interrupt */
19761+ dwc_modify_reg32(&global_regs->gintmsk, 0, gintmask.d32);
19762+ /* Clear interrupt */
19763+ gintsts.d32 = 0;
19764+ gintsts.b.rxstsqlvl = 1;
19765+ dwc_write_reg32 (&global_regs->gintsts, gintsts.d32);
19766+
19767+ //DWC_DEBUGPL(DBG_PCDV, "EXIT: %s\n", __func__);
19768+ return 1;
19769+}
19770+/**
19771+ * This function examines the Device IN Token Learning Queue to
19772+ * determine the EP number of the last IN token received. This
19773+ * implementation is for the Mass Storage device where there are only
19774+ * 2 IN EPs (Control-IN and BULK-IN).
19775+ *
19776+ * The EP numbers for the first six IN Tokens are in DTKNQR1 and there
19777+ * are 8 EP Numbers in each of the other possible DTKNQ Registers.
19778+ *
19779+ * @param core_if Programming view of DWC_otg controller.
19780+ *
19781+ */
19782+static inline int get_ep_of_last_in_token(dwc_otg_core_if_t *core_if)
19783+{
19784+ dwc_otg_device_global_regs_t *dev_global_regs =
19785+ core_if->dev_if->dev_global_regs;
19786+ const uint32_t TOKEN_Q_DEPTH = core_if->hwcfg2.b.dev_token_q_depth;
19787+ /* Number of Token Queue Registers */
19788+ const int DTKNQ_REG_CNT = (TOKEN_Q_DEPTH + 7) / 8;
19789+ dtknq1_data_t dtknqr1;
19790+ uint32_t in_tkn_epnums[4];
19791+ int ndx = 0;
19792+ int i = 0;
19793+ volatile uint32_t *addr = &dev_global_regs->dtknqr1;
19794+ int epnum = 0;
19795+
19796+ //DWC_DEBUGPL(DBG_PCD,"dev_token_q_depth=%d\n",TOKEN_Q_DEPTH);
19797+
19798+
19799+ /* Read the DTKNQ Registers */
19800+ for (i = 0; i < DTKNQ_REG_CNT; i++)
19801+ {
19802+ in_tkn_epnums[ i ] = dwc_read_reg32(addr);
19803+ DWC_DEBUGPL(DBG_PCDV, "DTKNQR%d=0x%08x\n", i+1,
19804+ in_tkn_epnums[i]);
19805+ if (addr == &dev_global_regs->dvbusdis) {
19806+ addr = &dev_global_regs->dtknqr3_dthrctl;
19807+ }
19808+ else {
19809+ ++addr;
19810+ }
19811+
19812+ }
19813+
19814+ /* Copy the DTKNQR1 data to the bit field. */
19815+ dtknqr1.d32 = in_tkn_epnums[0];
19816+ /* Get the EP numbers */
19817+ in_tkn_epnums[0] = dtknqr1.b.epnums0_5;
19818+ ndx = dtknqr1.b.intknwptr - 1;
19819+
19820+ //DWC_DEBUGPL(DBG_PCDV,"ndx=%d\n",ndx);
19821+ if (ndx == -1) {
19822+ /** @todo Find a simpler way to calculate the max
19823+ * queue position.*/
19824+ int cnt = TOKEN_Q_DEPTH;
19825+ if (TOKEN_Q_DEPTH <= 6) {
19826+ cnt = TOKEN_Q_DEPTH - 1;
19827+ }
19828+ else if (TOKEN_Q_DEPTH <= 14) {
19829+ cnt = TOKEN_Q_DEPTH - 7;
19830+ }
19831+ else if (TOKEN_Q_DEPTH <= 22) {
19832+ cnt = TOKEN_Q_DEPTH - 15;
19833+ }
19834+ else {
19835+ cnt = TOKEN_Q_DEPTH - 23;
19836+ }
19837+ epnum = (in_tkn_epnums[ DTKNQ_REG_CNT - 1 ] >> (cnt * 4)) & 0xF;
19838+ }
19839+ else {
19840+ if (ndx <= 5) {
19841+ epnum = (in_tkn_epnums[0] >> (ndx * 4)) & 0xF;
19842+ }
19843+ else if (ndx <= 13) {
19844+ ndx -= 6;
19845+ epnum = (in_tkn_epnums[1] >> (ndx * 4)) & 0xF;
19846+ }
19847+ else if (ndx <= 21) {
19848+ ndx -= 14;
19849+ epnum = (in_tkn_epnums[2] >> (ndx * 4)) & 0xF;
19850+ }
19851+ else if (ndx <= 29) {
19852+ ndx -= 22;
19853+ epnum = (in_tkn_epnums[3] >> (ndx * 4)) & 0xF;
19854+ }
19855+ }
19856+ //DWC_DEBUGPL(DBG_PCD,"epnum=%d\n",epnum);
19857+ return epnum;
19858+}
19859+
19860+/**
19861+ * This interrupt occurs when the non-periodic Tx FIFO is half-empty.
19862+ * The active request is checked for the next packet to be loaded into
19863+ * the non-periodic Tx FIFO.
19864+ */
19865+int32_t dwc_otg_pcd_handle_np_tx_fifo_empty_intr(dwc_otg_pcd_t *pcd)
19866+{
19867+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
19868+ dwc_otg_core_global_regs_t *global_regs =
19869+ core_if->core_global_regs;
19870+ dwc_otg_dev_in_ep_regs_t *ep_regs;
19871+ gnptxsts_data_t txstatus = {.d32 = 0};
19872+ gintsts_data_t gintsts;
19873+
19874+ int epnum = 0;
19875+ dwc_otg_pcd_ep_t *ep = 0;
19876+ uint32_t len = 0;
19877+ int dwords;
19878+
19879+ /* Get the epnum from the IN Token Learning Queue. */
19880+ epnum = get_ep_of_last_in_token(core_if);
19881+ ep = get_in_ep(pcd, epnum);
19882+
19883+ DWC_DEBUGPL(DBG_PCD, "NP TxFifo Empty: %s(%d) \n", ep->ep.name, epnum);
19884+ ep_regs = core_if->dev_if->in_ep_regs[epnum];
19885+
19886+ len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
19887+ if (len > ep->dwc_ep.maxpacket) {
19888+ len = ep->dwc_ep.maxpacket;
19889+ }
19890+ dwords = (len + 3)/4;
19891+
19892+
19893+ /* While there is space in the queue and space in the FIFO and
19894+ * More data to tranfer, Write packets to the Tx FIFO */
19895+ txstatus.d32 = dwc_read_reg32(&global_regs->gnptxsts);
19896+ DWC_DEBUGPL(DBG_PCDV, "b4 GNPTXSTS=0x%08x\n",txstatus.d32);
19897+
19898+ while (txstatus.b.nptxqspcavail > 0 &&
19899+ txstatus.b.nptxfspcavail > dwords &&
19900+ ep->dwc_ep.xfer_count < ep->dwc_ep.xfer_len) {
19901+ /* Write the FIFO */
19902+ dwc_otg_ep_write_packet(core_if, &ep->dwc_ep, 0);
19903+ len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
19904+
19905+ if (len > ep->dwc_ep.maxpacket) {
19906+ len = ep->dwc_ep.maxpacket;
19907+ }
19908+
19909+ dwords = (len + 3)/4;
19910+ txstatus.d32 = dwc_read_reg32(&global_regs->gnptxsts);
19911+ DWC_DEBUGPL(DBG_PCDV,"GNPTXSTS=0x%08x\n",txstatus.d32);
19912+ }
19913+
19914+ DWC_DEBUGPL(DBG_PCDV, "GNPTXSTS=0x%08x\n",
19915+ dwc_read_reg32(&global_regs->gnptxsts));
19916+
19917+ /* Clear interrupt */
19918+ gintsts.d32 = 0;
19919+ gintsts.b.nptxfempty = 1;
19920+ dwc_write_reg32 (&global_regs->gintsts, gintsts.d32);
19921+
19922+ return 1;
19923+}
19924+
19925+/**
19926+ * This function is called when dedicated Tx FIFO Empty interrupt occurs.
19927+ * The active request is checked for the next packet to be loaded into
19928+ * apropriate Tx FIFO.
19929+ */
19930+static int32_t write_empty_tx_fifo(dwc_otg_pcd_t *pcd, uint32_t epnum)
19931+{
19932+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
19933+ dwc_otg_dev_if_t* dev_if = core_if->dev_if;
19934+ dwc_otg_dev_in_ep_regs_t *ep_regs;
19935+ dtxfsts_data_t txstatus = {.d32 = 0};
19936+ dwc_otg_pcd_ep_t *ep = 0;
19937+ uint32_t len = 0;
19938+ int dwords;
19939+
19940+ ep = get_in_ep(pcd, epnum);
19941+
19942+ DWC_DEBUGPL(DBG_PCD, "Dedicated TxFifo Empty: %s(%d) \n", ep->ep.name, epnum);
19943+
19944+ ep_regs = core_if->dev_if->in_ep_regs[epnum];
19945+
19946+ len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
19947+
19948+ if (len > ep->dwc_ep.maxpacket) {
19949+ len = ep->dwc_ep.maxpacket;
19950+ }
19951+
19952+ dwords = (len + 3)/4;
19953+
19954+ /* While there is space in the queue and space in the FIFO and
19955+ * More data to tranfer, Write packets to the Tx FIFO */
19956+ txstatus.d32 = dwc_read_reg32(&dev_if->in_ep_regs[epnum]->dtxfsts);
19957+ DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n",epnum,txstatus.d32);
19958+
19959+ while (txstatus.b.txfspcavail > dwords &&
19960+ ep->dwc_ep.xfer_count < ep->dwc_ep.xfer_len &&
19961+ ep->dwc_ep.xfer_len != 0) {
19962+ /* Write the FIFO */
19963+ dwc_otg_ep_write_packet(core_if, &ep->dwc_ep, 0);
19964+
19965+ len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
19966+ if (len > ep->dwc_ep.maxpacket) {
19967+ len = ep->dwc_ep.maxpacket;
19968+ }
19969+
19970+ dwords = (len + 3)/4;
19971+ txstatus.d32 = dwc_read_reg32(&dev_if->in_ep_regs[epnum]->dtxfsts);
19972+ DWC_DEBUGPL(DBG_PCDV,"dtxfsts[%d]=0x%08x\n", epnum, txstatus.d32);
19973+ }
19974+
19975+ DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n",epnum,dwc_read_reg32(&dev_if->in_ep_regs[epnum]->dtxfsts));
19976+
19977+ return 1;
19978+}
19979+
19980+
19981+/**
19982+ * This function is called when the Device is disconnected. It stops
19983+ * any active requests and informs the Gadget driver of the
19984+ * disconnect.
19985+ */
19986+void dwc_otg_pcd_stop(dwc_otg_pcd_t *pcd)
19987+{
19988+ int i, num_in_eps, num_out_eps;
19989+ dwc_otg_pcd_ep_t *ep;
19990+
19991+ gintmsk_data_t intr_mask = {.d32 = 0};
19992+
19993+ num_in_eps = GET_CORE_IF(pcd)->dev_if->num_in_eps;
19994+ num_out_eps = GET_CORE_IF(pcd)->dev_if->num_out_eps;
19995+
19996+ DWC_DEBUGPL(DBG_PCDV, "%s() \n", __func__);
19997+ /* don't disconnect drivers more than once */
19998+ if (pcd->ep0state == EP0_DISCONNECT) {
19999+ DWC_DEBUGPL(DBG_ANY, "%s() Already Disconnected\n", __func__);
20000+ return;
20001+ }
20002+ pcd->ep0state = EP0_DISCONNECT;
20003+
20004+ /* Reset the OTG state. */
20005+ dwc_otg_pcd_update_otg(pcd, 1);
20006+
20007+ /* Disable the NP Tx Fifo Empty Interrupt. */
20008+ intr_mask.b.nptxfempty = 1;
20009+ dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
20010+ intr_mask.d32, 0);
20011+
20012+ /* Flush the FIFOs */
20013+ /**@todo NGS Flush Periodic FIFOs */
20014+ dwc_otg_flush_tx_fifo(GET_CORE_IF(pcd), 0x10);
20015+ dwc_otg_flush_rx_fifo(GET_CORE_IF(pcd));
20016+
20017+ /* prevent new request submissions, kill any outstanding requests */
20018+ ep = &pcd->ep0;
20019+ dwc_otg_request_nuke(ep);
20020+ /* prevent new request submissions, kill any outstanding requests */
20021+ for (i = 0; i < num_in_eps; i++)
20022+ {
20023+ dwc_otg_pcd_ep_t *ep = &pcd->in_ep[i];
20024+ dwc_otg_request_nuke(ep);
20025+ }
20026+ /* prevent new request submissions, kill any outstanding requests */
20027+ for (i = 0; i < num_out_eps; i++)
20028+ {
20029+ dwc_otg_pcd_ep_t *ep = &pcd->out_ep[i];
20030+ dwc_otg_request_nuke(ep);
20031+ }
20032+
20033+ /* report disconnect; the driver is already quiesced */
20034+ if (pcd->driver && pcd->driver->disconnect) {
20035+ SPIN_UNLOCK(&pcd->lock);
20036+ pcd->driver->disconnect(&pcd->gadget);
20037+ SPIN_LOCK(&pcd->lock);
20038+ }
20039+}
20040+
20041+/**
20042+ * This interrupt indicates that ...
20043+ */
20044+int32_t dwc_otg_pcd_handle_i2c_intr(dwc_otg_pcd_t *pcd)
20045+{
20046+ gintmsk_data_t intr_mask = { .d32 = 0};
20047+ gintsts_data_t gintsts;
20048+
20049+ DWC_PRINT("INTERRUPT Handler not implemented for %s\n", "i2cintr");
20050+ intr_mask.b.i2cintr = 1;
20051+ dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
20052+ intr_mask.d32, 0);
20053+
20054+ /* Clear interrupt */
20055+ gintsts.d32 = 0;
20056+ gintsts.b.i2cintr = 1;
20057+ dwc_write_reg32 (&GET_CORE_IF(pcd)->core_global_regs->gintsts,
20058+ gintsts.d32);
20059+ return 1;
20060+}
20061+
20062+
20063+/**
20064+ * This interrupt indicates that ...
20065+ */
20066+int32_t dwc_otg_pcd_handle_early_suspend_intr(dwc_otg_pcd_t *pcd)
20067+{
20068+ gintsts_data_t gintsts;
20069+#if defined(VERBOSE)
20070+ DWC_PRINT("Early Suspend Detected\n");
20071+#endif
20072+ /* Clear interrupt */
20073+ gintsts.d32 = 0;
20074+ gintsts.b.erlysuspend = 1;
20075+ dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
20076+ gintsts.d32);
20077+ return 1;
20078+}
20079+
20080+/**
20081+ * This function configures EPO to receive SETUP packets.
20082+ *
20083+ * @todo NGS: Update the comments from the HW FS.
20084+ *
20085+ * -# Program the following fields in the endpoint specific registers
20086+ * for Control OUT EP 0, in order to receive a setup packet
20087+ * - DOEPTSIZ0.Packet Count = 3 (To receive up to 3 back to back
20088+ * setup packets)
20089+ * - DOEPTSIZE0.Transfer Size = 24 Bytes (To receive up to 3 back
20090+ * to back setup packets)
20091+ * - In DMA mode, DOEPDMA0 Register with a memory address to
20092+ * store any setup packets received
20093+ *
20094+ * @param core_if Programming view of DWC_otg controller.
20095+ * @param pcd Programming view of the PCD.
20096+ */
20097+static inline void ep0_out_start(dwc_otg_core_if_t *core_if, dwc_otg_pcd_t *pcd)
20098+{
20099+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
20100+ deptsiz0_data_t doeptsize0 = { .d32 = 0};
20101+ dwc_otg_dma_desc_t* dma_desc;
20102+ depctl_data_t doepctl = { .d32 = 0 };
20103+
20104+#ifdef VERBOSE
20105+ DWC_DEBUGPL(DBG_PCDV,"%s() doepctl0=%0x\n", __func__,
20106+ dwc_read_reg32(&dev_if->out_ep_regs[0]->doepctl));
20107+#endif
20108+
20109+ doeptsize0.b.supcnt = 3;
20110+ doeptsize0.b.pktcnt = 1;
20111+ doeptsize0.b.xfersize = 8*3;
20112+
20113+
20114+ if (core_if->dma_enable) {
20115+ if (!core_if->dma_desc_enable) {
20116+ /** put here as for Hermes mode deptisz register should not be written */
20117+ dwc_write_reg32(&dev_if->out_ep_regs[0]->doeptsiz,
20118+ doeptsize0.d32);
20119+
20120+ /** @todo dma needs to handle multiple setup packets (up to 3) */
20121+ VERIFY_PCD_DMA_ADDR(pcd->setup_pkt_dma_handle);
20122+
20123+ dwc_write_reg32(&dev_if->out_ep_regs[0]->doepdma,
20124+ pcd->setup_pkt_dma_handle);
20125+ } else {
20126+ dev_if->setup_desc_index = (dev_if->setup_desc_index + 1) & 1;
20127+ dma_desc = dev_if->setup_desc_addr[dev_if->setup_desc_index];
20128+
20129+ /** DMA Descriptor Setup */
20130+ dma_desc->status.b.bs = BS_HOST_BUSY;
20131+ dma_desc->status.b.l = 1;
20132+ dma_desc->status.b.ioc = 1;
20133+ dma_desc->status.b.bytes = pcd->ep0.dwc_ep.maxpacket;
20134+ dma_desc->buf = pcd->setup_pkt_dma_handle;
20135+ dma_desc->status.b.bs = BS_HOST_READY;
20136+
20137+ /** DOEPDMA0 Register write */
20138+ VERIFY_PCD_DMA_ADDR(dev_if->dma_setup_desc_addr[dev_if->setup_desc_index]);
20139+ dwc_write_reg32(&dev_if->out_ep_regs[0]->doepdma, dev_if->dma_setup_desc_addr[dev_if->setup_desc_index]);
20140+ }
20141+
20142+ } else {
20143+ /** put here as for Hermes mode deptisz register should not be written */
20144+ dwc_write_reg32(&dev_if->out_ep_regs[0]->doeptsiz,
20145+ doeptsize0.d32);
20146+ }
20147+
20148+ /** DOEPCTL0 Register write */
20149+ doepctl.b.epena = 1;
20150+ doepctl.b.cnak = 1;
20151+ dwc_write_reg32(&dev_if->out_ep_regs[0]->doepctl, doepctl.d32);
20152+
20153+#ifdef VERBOSE
20154+ DWC_DEBUGPL(DBG_PCDV,"doepctl0=%0x\n",
20155+ dwc_read_reg32(&dev_if->out_ep_regs[0]->doepctl));
20156+ DWC_DEBUGPL(DBG_PCDV,"diepctl0=%0x\n",
20157+ dwc_read_reg32(&dev_if->in_ep_regs[0]->diepctl));
20158+#endif
20159+}
20160+
20161+
20162+/**
20163+ * This interrupt occurs when a USB Reset is detected. When the USB
20164+ * Reset Interrupt occurs the device state is set to DEFAULT and the
20165+ * EP0 state is set to IDLE.
20166+ * -# Set the NAK bit for all OUT endpoints (DOEPCTLn.SNAK = 1)
20167+ * -# Unmask the following interrupt bits
20168+ * - DAINTMSK.INEP0 = 1 (Control 0 IN endpoint)
20169+ * - DAINTMSK.OUTEP0 = 1 (Control 0 OUT endpoint)
20170+ * - DOEPMSK.SETUP = 1
20171+ * - DOEPMSK.XferCompl = 1
20172+ * - DIEPMSK.XferCompl = 1
20173+ * - DIEPMSK.TimeOut = 1
20174+ * -# Program the following fields in the endpoint specific registers
20175+ * for Control OUT EP 0, in order to receive a setup packet
20176+ * - DOEPTSIZ0.Packet Count = 3 (To receive up to 3 back to back
20177+ * setup packets)
20178+ * - DOEPTSIZE0.Transfer Size = 24 Bytes (To receive up to 3 back
20179+ * to back setup packets)
20180+ * - In DMA mode, DOEPDMA0 Register with a memory address to
20181+ * store any setup packets received
20182+ * At this point, all the required initialization, except for enabling
20183+ * the control 0 OUT endpoint is done, for receiving SETUP packets.
20184+ */
20185+int32_t dwc_otg_pcd_handle_usb_reset_intr(dwc_otg_pcd_t * pcd)
20186+{
20187+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
20188+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
20189+ depctl_data_t doepctl = { .d32 = 0};
20190+
20191+ daint_data_t daintmsk = { .d32 = 0};
20192+ doepmsk_data_t doepmsk = { .d32 = 0};
20193+ diepmsk_data_t diepmsk = { .d32 = 0};
20194+
20195+ dcfg_data_t dcfg = { .d32=0 };
20196+ grstctl_t resetctl = { .d32=0 };
20197+ dctl_data_t dctl = {.d32=0};
20198+ int i = 0;
20199+ gintsts_data_t gintsts;
20200+
20201+ DWC_PRINT("USB RESET\n");
20202+#ifdef DWC_EN_ISOC
20203+ for(i = 1;i < 16; ++i)
20204+ {
20205+ dwc_otg_pcd_ep_t *ep;
20206+ dwc_ep_t *dwc_ep;
20207+ ep = get_in_ep(pcd,i);
20208+ if(ep != 0){
20209+ dwc_ep = &ep->dwc_ep;
20210+ dwc_ep->next_frame = 0xffffffff;
20211+ }
20212+ }
20213+#endif /* DWC_EN_ISOC */
20214+
20215+ /* reset the HNP settings */
20216+ dwc_otg_pcd_update_otg(pcd, 1);
20217+
20218+ /* Clear the Remote Wakeup Signalling */
20219+ dctl.b.rmtwkupsig = 1;
20220+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->dctl,
20221+ dctl.d32, 0);
20222+
20223+ /* Set NAK for all OUT EPs */
20224+ doepctl.b.snak = 1;
20225+ for (i=0; i <= dev_if->num_out_eps; i++)
20226+ {
20227+ dwc_write_reg32(&dev_if->out_ep_regs[i]->doepctl,
20228+ doepctl.d32);
20229+ }
20230+
20231+ /* Flush the NP Tx FIFO */
20232+ dwc_otg_flush_tx_fifo(core_if, 0x10);
20233+ /* Flush the Learning Queue */
20234+ resetctl.b.intknqflsh = 1;
20235+ dwc_write_reg32(&core_if->core_global_regs->grstctl, resetctl.d32);
20236+
20237+ if(core_if->multiproc_int_enable) {
20238+ daintmsk.b.inep0 = 1;
20239+ daintmsk.b.outep0 = 1;
20240+ dwc_write_reg32(&dev_if->dev_global_regs->deachintmsk, daintmsk.d32);
20241+
20242+ doepmsk.b.setup = 1;
20243+ doepmsk.b.xfercompl = 1;
20244+ doepmsk.b.ahberr = 1;
20245+ doepmsk.b.epdisabled = 1;
20246+
20247+ if(core_if->dma_desc_enable) {
20248+ doepmsk.b.stsphsercvd = 1;
20249+ doepmsk.b.bna = 1;
20250+ }
20251+/*
20252+ doepmsk.b.babble = 1;
20253+ doepmsk.b.nyet = 1;
20254+
20255+ if(core_if->dma_enable) {
20256+ doepmsk.b.nak = 1;
20257+ }
20258+*/
20259+ dwc_write_reg32(&dev_if->dev_global_regs->doepeachintmsk[0], doepmsk.d32);
20260+
20261+ diepmsk.b.xfercompl = 1;
20262+ diepmsk.b.timeout = 1;
20263+ diepmsk.b.epdisabled = 1;
20264+ diepmsk.b.ahberr = 1;
20265+ diepmsk.b.intknepmis = 1;
20266+
20267+ if(core_if->dma_desc_enable) {
20268+ diepmsk.b.bna = 1;
20269+ }
20270+/*
20271+ if(core_if->dma_enable) {
20272+ diepmsk.b.nak = 1;
20273+ }
20274+*/
20275+ dwc_write_reg32(&dev_if->dev_global_regs->diepeachintmsk[0], diepmsk.d32);
20276+ } else{
20277+ daintmsk.b.inep0 = 1;
20278+ daintmsk.b.outep0 = 1;
20279+ dwc_write_reg32(&dev_if->dev_global_regs->daintmsk, daintmsk.d32);
20280+
20281+ doepmsk.b.setup = 1;
20282+ doepmsk.b.xfercompl = 1;
20283+ doepmsk.b.ahberr = 1;
20284+ doepmsk.b.epdisabled = 1;
20285+
20286+ if(core_if->dma_desc_enable) {
20287+ doepmsk.b.stsphsercvd = 1;
20288+ doepmsk.b.bna = 1;
20289+ }
20290+/*
20291+ doepmsk.b.babble = 1;
20292+ doepmsk.b.nyet = 1;
20293+ doepmsk.b.nak = 1;
20294+*/
20295+ dwc_write_reg32(&dev_if->dev_global_regs->doepmsk, doepmsk.d32);
20296+
20297+ diepmsk.b.xfercompl = 1;
20298+ diepmsk.b.timeout = 1;
20299+ diepmsk.b.epdisabled = 1;
20300+ diepmsk.b.ahberr = 1;
20301+ diepmsk.b.intknepmis = 1;
20302+
20303+ if(core_if->dma_desc_enable) {
20304+ diepmsk.b.bna = 1;
20305+ }
20306+
20307+// diepmsk.b.nak = 1;
20308+
20309+ dwc_write_reg32(&dev_if->dev_global_regs->diepmsk, diepmsk.d32);
20310+ }
20311+
20312+ /* Reset Device Address */
20313+ dcfg.d32 = dwc_read_reg32(&dev_if->dev_global_regs->dcfg);
20314+ dcfg.b.devaddr = 0;
20315+ dwc_write_reg32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
20316+
20317+ /* setup EP0 to receive SETUP packets */
20318+ ep0_out_start(core_if, pcd);
20319+
20320+ /* Clear interrupt */
20321+ gintsts.d32 = 0;
20322+ gintsts.b.usbreset = 1;
20323+ dwc_write_reg32 (&core_if->core_global_regs->gintsts, gintsts.d32);
20324+
20325+ return 1;
20326+}
20327+
20328+/**
20329+ * Get the device speed from the device status register and convert it
20330+ * to USB speed constant.
20331+ *
20332+ * @param core_if Programming view of DWC_otg controller.
20333+ */
20334+static int get_device_speed(dwc_otg_core_if_t *core_if)
20335+{
20336+ dsts_data_t dsts;
20337+ enum usb_device_speed speed = USB_SPEED_UNKNOWN;
20338+ dsts.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts);
20339+
20340+ switch (dsts.b.enumspd) {
20341+ case DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
20342+ speed = USB_SPEED_HIGH;
20343+ break;
20344+ case DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
20345+ case DWC_DSTS_ENUMSPD_FS_PHY_48MHZ:
20346+ speed = USB_SPEED_FULL;
20347+ break;
20348+
20349+ case DWC_DSTS_ENUMSPD_LS_PHY_6MHZ:
20350+ speed = USB_SPEED_LOW;
20351+ break;
20352+ }
20353+
20354+ return speed;
20355+}
20356+
20357+/**
20358+ * Read the device status register and set the device speed in the
20359+ * data structure.
20360+ * Set up EP0 to receive SETUP packets by calling dwc_ep0_activate.
20361+ */
20362+int32_t dwc_otg_pcd_handle_enum_done_intr(dwc_otg_pcd_t *pcd)
20363+{
20364+ dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
20365+ gintsts_data_t gintsts;
20366+ gusbcfg_data_t gusbcfg;
20367+ dwc_otg_core_global_regs_t *global_regs =
20368+ GET_CORE_IF(pcd)->core_global_regs;
20369+ uint8_t utmi16b, utmi8b;
20370+// DWC_DEBUGPL(DBG_PCD, "SPEED ENUM\n");
20371+ DWC_PRINT("SPEED ENUM\n");
20372+
20373+ if (GET_CORE_IF(pcd)->snpsid >= 0x4F54260A) {
20374+ utmi16b = 6;
20375+ utmi8b = 9;
20376+ } else {
20377+ utmi16b = 4;
20378+ utmi8b = 8;
20379+ }
20380+ dwc_otg_ep0_activate(GET_CORE_IF(pcd), &ep0->dwc_ep);
20381+
20382+#ifdef DEBUG_EP0
20383+ print_ep0_state(pcd);
20384+#endif
20385+
20386+ if (pcd->ep0state == EP0_DISCONNECT) {
20387+ pcd->ep0state = EP0_IDLE;
20388+ }
20389+ else if (pcd->ep0state == EP0_STALL) {
20390+ pcd->ep0state = EP0_IDLE;
20391+ }
20392+
20393+ pcd->ep0state = EP0_IDLE;
20394+
20395+ ep0->stopped = 0;
20396+
20397+ pcd->gadget.speed = get_device_speed(GET_CORE_IF(pcd));
20398+
20399+ /* Set USB turnaround time based on device speed and PHY interface. */
20400+ gusbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
20401+ if (pcd->gadget.speed == USB_SPEED_HIGH) {
20402+ if (GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type == DWC_HWCFG2_HS_PHY_TYPE_ULPI) {
20403+ /* ULPI interface */
20404+ gusbcfg.b.usbtrdtim = 9;
20405+ }
20406+ if (GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type == DWC_HWCFG2_HS_PHY_TYPE_UTMI) {
20407+ /* UTMI+ interface */
20408+ if (GET_CORE_IF(pcd)->hwcfg4.b.utmi_phy_data_width == 0) {
20409+ gusbcfg.b.usbtrdtim = utmi8b;
20410+ }
20411+ else if (GET_CORE_IF(pcd)->hwcfg4.b.utmi_phy_data_width == 1) {
20412+ gusbcfg.b.usbtrdtim = utmi16b;
20413+ }
20414+ else if (GET_CORE_IF(pcd)->core_params->phy_utmi_width == 8) {
20415+ gusbcfg.b.usbtrdtim = utmi8b;
20416+ }
20417+ else {
20418+ gusbcfg.b.usbtrdtim = utmi16b;
20419+ }
20420+ }
20421+ if (GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type == DWC_HWCFG2_HS_PHY_TYPE_UTMI_ULPI) {
20422+ /* UTMI+ OR ULPI interface */
20423+ if (gusbcfg.b.ulpi_utmi_sel == 1) {
20424+ /* ULPI interface */
20425+ gusbcfg.b.usbtrdtim = 9;
20426+ }
20427+ else {
20428+ /* UTMI+ interface */
20429+ if (GET_CORE_IF(pcd)->core_params->phy_utmi_width == 16) {
20430+ gusbcfg.b.usbtrdtim = utmi16b;
20431+ }
20432+ else {
20433+ gusbcfg.b.usbtrdtim = utmi8b;
20434+ }
20435+ }
20436+ }
20437+ }
20438+ else {
20439+ /* Full or low speed */
20440+ gusbcfg.b.usbtrdtim = 9;
20441+ }
20442+ dwc_write_reg32(&global_regs->gusbcfg, gusbcfg.d32);
20443+
20444+ /* Clear interrupt */
20445+ gintsts.d32 = 0;
20446+ gintsts.b.enumdone = 1;
20447+ dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
20448+ gintsts.d32);
20449+ return 1;
20450+}
20451+
20452+/**
20453+ * This interrupt indicates that the ISO OUT Packet was dropped due to
20454+ * Rx FIFO full or Rx Status Queue Full. If this interrupt occurs
20455+ * read all the data from the Rx FIFO.
20456+ */
20457+int32_t dwc_otg_pcd_handle_isoc_out_packet_dropped_intr(dwc_otg_pcd_t *pcd)
20458+{
20459+ gintmsk_data_t intr_mask = { .d32 = 0};
20460+ gintsts_data_t gintsts;
20461+
20462+ DWC_PRINT("INTERRUPT Handler not implemented for %s\n",
20463+ "ISOC Out Dropped");
20464+
20465+ intr_mask.b.isooutdrop = 1;
20466+ dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
20467+ intr_mask.d32, 0);
20468+
20469+ /* Clear interrupt */
20470+
20471+ gintsts.d32 = 0;
20472+ gintsts.b.isooutdrop = 1;
20473+ dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
20474+ gintsts.d32);
20475+
20476+ return 1;
20477+}
20478+
20479+/**
20480+ * This interrupt indicates the end of the portion of the micro-frame
20481+ * for periodic transactions. If there is a periodic transaction for
20482+ * the next frame, load the packets into the EP periodic Tx FIFO.
20483+ */
20484+int32_t dwc_otg_pcd_handle_end_periodic_frame_intr(dwc_otg_pcd_t *pcd)
20485+{
20486+ gintmsk_data_t intr_mask = { .d32 = 0};
20487+ gintsts_data_t gintsts;
20488+ DWC_PRINT("INTERRUPT Handler not implemented for %s\n", "EOP");
20489+
20490+ intr_mask.b.eopframe = 1;
20491+ dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
20492+ intr_mask.d32, 0);
20493+
20494+ /* Clear interrupt */
20495+ gintsts.d32 = 0;
20496+ gintsts.b.eopframe = 1;
20497+ dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts, gintsts.d32);
20498+
20499+ return 1;
20500+}
20501+
20502+/**
20503+ * This interrupt indicates that EP of the packet on the top of the
20504+ * non-periodic Tx FIFO does not match EP of the IN Token received.
20505+ *
20506+ * The "Device IN Token Queue" Registers are read to determine the
20507+ * order the IN Tokens have been received. The non-periodic Tx FIFO
20508+ * is flushed, so it can be reloaded in the order seen in the IN Token
20509+ * Queue.
20510+ */
20511+int32_t dwc_otg_pcd_handle_ep_mismatch_intr(dwc_otg_core_if_t *core_if)
20512+{
20513+ gintsts_data_t gintsts;
20514+ DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, core_if);
20515+
20516+ /* Clear interrupt */
20517+ gintsts.d32 = 0;
20518+ gintsts.b.epmismatch = 1;
20519+ dwc_write_reg32 (&core_if->core_global_regs->gintsts, gintsts.d32);
20520+
20521+ return 1;
20522+}
20523+
20524+/**
20525+ * This funcion stalls EP0.
20526+ */
20527+static inline void ep0_do_stall(dwc_otg_pcd_t *pcd, const int err_val)
20528+{
20529+ dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
20530+ struct usb_ctrlrequest *ctrl = &pcd->setup_pkt->req;
20531+ DWC_WARN("req %02x.%02x protocol STALL; err %d\n",
20532+ ctrl->bRequestType, ctrl->bRequest, err_val);
20533+
20534+ ep0->dwc_ep.is_in = 1;
20535+ dwc_otg_ep_set_stall(pcd->otg_dev->core_if, &ep0->dwc_ep);
20536+ pcd->ep0.stopped = 1;
20537+ pcd->ep0state = EP0_IDLE;
20538+ ep0_out_start(GET_CORE_IF(pcd), pcd);
20539+}
20540+
20541+/**
20542+ * This functions delegates the setup command to the gadget driver.
20543+ */
20544+static inline void do_gadget_setup(dwc_otg_pcd_t *pcd,
20545+ struct usb_ctrlrequest * ctrl)
20546+{
20547+ int ret = 0;
20548+ if (pcd->driver && pcd->driver->setup) {
20549+ SPIN_UNLOCK(&pcd->lock);
20550+ ret = pcd->driver->setup(&pcd->gadget, ctrl);
20551+ SPIN_LOCK(&pcd->lock);
20552+ if (ret < 0) {
20553+ ep0_do_stall(pcd, ret);
20554+ }
20555+
20556+ /** @todo This is a g_file_storage gadget driver specific
20557+ * workaround: a DELAYED_STATUS result from the fsg_setup
20558+ * routine will result in the gadget queueing a EP0 IN status
20559+ * phase for a two-stage control transfer. Exactly the same as
20560+ * a SET_CONFIGURATION/SET_INTERFACE except that this is a class
20561+ * specific request. Need a generic way to know when the gadget
20562+ * driver will queue the status phase. Can we assume when we
20563+ * call the gadget driver setup() function that it will always
20564+ * queue and require the following flag? Need to look into
20565+ * this.
20566+ */
20567+
20568+ if (ret == 256 + 999) {
20569+ pcd->request_config = 1;
20570+ }
20571+ }
20572+}
20573+
20574+/**
20575+ * This function starts the Zero-Length Packet for the IN status phase
20576+ * of a 2 stage control transfer.
20577+ */
20578+static inline void do_setup_in_status_phase(dwc_otg_pcd_t *pcd)
20579+{
20580+ dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
20581+ if (pcd->ep0state == EP0_STALL) {
20582+ return;
20583+ }
20584+
20585+ pcd->ep0state = EP0_IN_STATUS_PHASE;
20586+
20587+ /* Prepare for more SETUP Packets */
20588+ DWC_DEBUGPL(DBG_PCD, "EP0 IN ZLP\n");
20589+ ep0->dwc_ep.xfer_len = 0;
20590+ ep0->dwc_ep.xfer_count = 0;
20591+ ep0->dwc_ep.is_in = 1;
20592+ ep0->dwc_ep.dma_addr = pcd->setup_pkt_dma_handle;
20593+ dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
20594+
20595+ /* Prepare for more SETUP Packets */
20596+// if(GET_CORE_IF(pcd)->dma_enable == 0) ep0_out_start(GET_CORE_IF(pcd), pcd);
20597+}
20598+
20599+/**
20600+ * This function starts the Zero-Length Packet for the OUT status phase
20601+ * of a 2 stage control transfer.
20602+ */
20603+static inline void do_setup_out_status_phase(dwc_otg_pcd_t *pcd)
20604+{
20605+ dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
20606+ if (pcd->ep0state == EP0_STALL) {
20607+ DWC_DEBUGPL(DBG_PCD, "EP0 STALLED\n");
20608+ return;
20609+ }
20610+ pcd->ep0state = EP0_OUT_STATUS_PHASE;
20611+
20612+ DWC_DEBUGPL(DBG_PCD, "EP0 OUT ZLP\n");
20613+ ep0->dwc_ep.xfer_len = 0;
20614+ ep0->dwc_ep.xfer_count = 0;
20615+ ep0->dwc_ep.is_in = 0;
20616+ ep0->dwc_ep.dma_addr = pcd->setup_pkt_dma_handle;
20617+ dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
20618+
20619+ /* Prepare for more SETUP Packets */
20620+ if(GET_CORE_IF(pcd)->dma_enable == 0) {
20621+ ep0_out_start(GET_CORE_IF(pcd), pcd);
20622+ }
20623+}
20624+
20625+/**
20626+ * Clear the EP halt (STALL) and if pending requests start the
20627+ * transfer.
20628+ */
20629+static inline void pcd_clear_halt(dwc_otg_pcd_t *pcd, dwc_otg_pcd_ep_t *ep)
20630+{
20631+ if(ep->dwc_ep.stall_clear_flag == 0)
20632+ dwc_otg_ep_clear_stall(GET_CORE_IF(pcd), &ep->dwc_ep);
20633+
20634+ /* Reactive the EP */
20635+ dwc_otg_ep_activate(GET_CORE_IF(pcd), &ep->dwc_ep);
20636+ if (ep->stopped) {
20637+ ep->stopped = 0;
20638+ /* If there is a request in the EP queue start it */
20639+
20640+ /** @todo FIXME: this causes an EP mismatch in DMA mode.
20641+ * epmismatch not yet implemented. */
20642+
20643+ /*
20644+ * Above fixme is solved by implmenting a tasklet to call the
20645+ * start_next_request(), outside of interrupt context at some
20646+ * time after the current time, after a clear-halt setup packet.
20647+ * Still need to implement ep mismatch in the future if a gadget
20648+ * ever uses more than one endpoint at once
20649+ */
20650+ ep->queue_sof = 1;
20651+ tasklet_schedule (pcd->start_xfer_tasklet);
20652+ }
20653+ /* Start Control Status Phase */
20654+ do_setup_in_status_phase(pcd);
20655+}
20656+
20657+/**
20658+ * This function is called when the SET_FEATURE TEST_MODE Setup packet
20659+ * is sent from the host. The Device Control register is written with
20660+ * the Test Mode bits set to the specified Test Mode. This is done as
20661+ * a tasklet so that the "Status" phase of the control transfer
20662+ * completes before transmitting the TEST packets.
20663+ *
20664+ * @todo This has not been tested since the tasklet struct was put
20665+ * into the PCD struct!
20666+ *
20667+ */
20668+static void do_test_mode(unsigned long data)
20669+{
20670+ dctl_data_t dctl;
20671+ dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *)data;
20672+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
20673+ int test_mode = pcd->test_mode;
20674+
20675+
20676+// DWC_WARN("%s() has not been tested since being rewritten!\n", __func__);
20677+
20678+ dctl.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dctl);
20679+ switch (test_mode) {
20680+ case 1: // TEST_J
20681+ dctl.b.tstctl = 1;
20682+ break;
20683+
20684+ case 2: // TEST_K
20685+ dctl.b.tstctl = 2;
20686+ break;
20687+
20688+ case 3: // TEST_SE0_NAK
20689+ dctl.b.tstctl = 3;
20690+ break;
20691+
20692+ case 4: // TEST_PACKET
20693+ dctl.b.tstctl = 4;
20694+ break;
20695+
20696+ case 5: // TEST_FORCE_ENABLE
20697+ dctl.b.tstctl = 5;
20698+ break;
20699+ }
20700+ dwc_write_reg32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32);
20701+}
20702+
20703+/**
20704+ * This function process the GET_STATUS Setup Commands.
20705+ */
20706+static inline void do_get_status(dwc_otg_pcd_t *pcd)
20707+{
20708+ struct usb_ctrlrequest ctrl = pcd->setup_pkt->req;
20709+ dwc_otg_pcd_ep_t *ep;
20710+ dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
20711+ uint16_t *status = pcd->status_buf;
20712+
20713+#ifdef DEBUG_EP0
20714+ DWC_DEBUGPL(DBG_PCD,
20715+ "GET_STATUS %02x.%02x v%04x i%04x l%04x\n",
20716+ ctrl.bRequestType, ctrl.bRequest,
20717+ ctrl.wValue, ctrl.wIndex, ctrl.wLength);
20718+#endif
20719+
20720+ switch (ctrl.bRequestType & USB_RECIP_MASK) {
20721+ case USB_RECIP_DEVICE:
20722+ *status = 0x1; /* Self powered */
20723+ *status |= pcd->remote_wakeup_enable << 1;
20724+ break;
20725+
20726+ case USB_RECIP_INTERFACE:
20727+ *status = 0;
20728+ break;
20729+
20730+ case USB_RECIP_ENDPOINT:
20731+ ep = get_ep_by_addr(pcd, ctrl.wIndex);
20732+ if (ep == 0 || ctrl.wLength > 2) {
20733+ ep0_do_stall(pcd, -EOPNOTSUPP);
20734+ return;
20735+ }
20736+ /** @todo check for EP stall */
20737+ *status = ep->stopped;
20738+ break;
20739+ }
20740+ pcd->ep0_pending = 1;
20741+ ep0->dwc_ep.start_xfer_buff = (uint8_t *)status;
20742+ ep0->dwc_ep.xfer_buff = (uint8_t *)status;
20743+ ep0->dwc_ep.dma_addr = pcd->status_buf_dma_handle;
20744+ ep0->dwc_ep.xfer_len = 2;
20745+ ep0->dwc_ep.xfer_count = 0;
20746+ ep0->dwc_ep.total_len = ep0->dwc_ep.xfer_len;
20747+ dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
20748+}
20749+/**
20750+ * This function process the SET_FEATURE Setup Commands.
20751+ */
20752+static inline void do_set_feature(dwc_otg_pcd_t *pcd)
20753+{
20754+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
20755+ dwc_otg_core_global_regs_t *global_regs =
20756+ core_if->core_global_regs;
20757+ struct usb_ctrlrequest ctrl = pcd->setup_pkt->req;
20758+ dwc_otg_pcd_ep_t *ep = 0;
20759+ int32_t otg_cap_param = core_if->core_params->otg_cap;
20760+ gotgctl_data_t gotgctl = { .d32 = 0 };
20761+
20762+ DWC_DEBUGPL(DBG_PCD, "SET_FEATURE:%02x.%02x v%04x i%04x l%04x\n",
20763+ ctrl.bRequestType, ctrl.bRequest,
20764+ ctrl.wValue, ctrl.wIndex, ctrl.wLength);
20765+ DWC_DEBUGPL(DBG_PCD,"otg_cap=%d\n", otg_cap_param);
20766+
20767+
20768+ switch (ctrl.bRequestType & USB_RECIP_MASK) {
20769+ case USB_RECIP_DEVICE:
20770+ switch (ctrl.wValue) {
20771+ case USB_DEVICE_REMOTE_WAKEUP:
20772+ pcd->remote_wakeup_enable = 1;
20773+ break;
20774+
20775+ case USB_DEVICE_TEST_MODE:
20776+ /* Setup the Test Mode tasklet to do the Test
20777+ * Packet generation after the SETUP Status
20778+ * phase has completed. */
20779+
20780+ /** @todo This has not been tested since the
20781+ * tasklet struct was put into the PCD
20782+ * struct! */
20783+ pcd->test_mode_tasklet.next = 0;
20784+ pcd->test_mode_tasklet.state = 0;
20785+ atomic_set(&pcd->test_mode_tasklet.count, 0);
20786+ pcd->test_mode_tasklet.func = do_test_mode;
20787+ pcd->test_mode_tasklet.data = (unsigned long)pcd;
20788+ pcd->test_mode = ctrl.wIndex >> 8;
20789+ tasklet_schedule(&pcd->test_mode_tasklet);
20790+ break;
20791+
20792+ case USB_DEVICE_B_HNP_ENABLE:
20793+ DWC_DEBUGPL(DBG_PCDV, "SET_FEATURE: USB_DEVICE_B_HNP_ENABLE\n");
20794+
20795+ /* dev may initiate HNP */
20796+ if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) {
20797+ pcd->b_hnp_enable = 1;
20798+ dwc_otg_pcd_update_otg(pcd, 0);
20799+ DWC_DEBUGPL(DBG_PCD, "Request B HNP\n");
20800+ /**@todo Is the gotgctl.devhnpen cleared
20801+ * by a USB Reset? */
20802+ gotgctl.b.devhnpen = 1;
20803+ gotgctl.b.hnpreq = 1;
20804+ dwc_write_reg32(&global_regs->gotgctl, gotgctl.d32);
20805+ }
20806+ else {
20807+ ep0_do_stall(pcd, -EOPNOTSUPP);
20808+ }
20809+ break;
20810+
20811+ case USB_DEVICE_A_HNP_SUPPORT:
20812+ /* RH port supports HNP */
20813+ DWC_DEBUGPL(DBG_PCDV, "SET_FEATURE: USB_DEVICE_A_HNP_SUPPORT\n");
20814+ if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) {
20815+ pcd->a_hnp_support = 1;
20816+ dwc_otg_pcd_update_otg(pcd, 0);
20817+ }
20818+ else {
20819+ ep0_do_stall(pcd, -EOPNOTSUPP);
20820+ }
20821+ break;
20822+
20823+ case USB_DEVICE_A_ALT_HNP_SUPPORT:
20824+ /* other RH port does */
20825+ DWC_DEBUGPL(DBG_PCDV, "SET_FEATURE: USB_DEVICE_A_ALT_HNP_SUPPORT\n");
20826+ if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) {
20827+ pcd->a_alt_hnp_support = 1;
20828+ dwc_otg_pcd_update_otg(pcd, 0);
20829+ }
20830+ else {
20831+ ep0_do_stall(pcd, -EOPNOTSUPP);
20832+ }
20833+ break;
20834+ }
20835+ do_setup_in_status_phase(pcd);
20836+ break;
20837+
20838+ case USB_RECIP_INTERFACE:
20839+ do_gadget_setup(pcd, &ctrl);
20840+ break;
20841+
20842+ case USB_RECIP_ENDPOINT:
20843+ if (ctrl.wValue == USB_ENDPOINT_HALT) {
20844+ ep = get_ep_by_addr(pcd, ctrl.wIndex);
20845+ if (ep == 0) {
20846+ ep0_do_stall(pcd, -EOPNOTSUPP);
20847+ return;
20848+ }
20849+ ep->stopped = 1;
20850+ dwc_otg_ep_set_stall(core_if, &ep->dwc_ep);
20851+ }
20852+ do_setup_in_status_phase(pcd);
20853+ break;
20854+ }
20855+}
20856+
20857+/**
20858+ * This function process the CLEAR_FEATURE Setup Commands.
20859+ */
20860+static inline void do_clear_feature(dwc_otg_pcd_t *pcd)
20861+{
20862+ struct usb_ctrlrequest ctrl = pcd->setup_pkt->req;
20863+ dwc_otg_pcd_ep_t *ep = 0;
20864+
20865+ DWC_DEBUGPL(DBG_PCD,
20866+ "CLEAR_FEATURE:%02x.%02x v%04x i%04x l%04x\n",
20867+ ctrl.bRequestType, ctrl.bRequest,
20868+ ctrl.wValue, ctrl.wIndex, ctrl.wLength);
20869+
20870+ switch (ctrl.bRequestType & USB_RECIP_MASK) {
20871+ case USB_RECIP_DEVICE:
20872+ switch (ctrl.wValue) {
20873+ case USB_DEVICE_REMOTE_WAKEUP:
20874+ pcd->remote_wakeup_enable = 0;
20875+ break;
20876+
20877+ case USB_DEVICE_TEST_MODE:
20878+ /** @todo Add CLEAR_FEATURE for TEST modes. */
20879+ break;
20880+ }
20881+ do_setup_in_status_phase(pcd);
20882+ break;
20883+
20884+ case USB_RECIP_ENDPOINT:
20885+ ep = get_ep_by_addr(pcd, ctrl.wIndex);
20886+ if (ep == 0) {
20887+ ep0_do_stall(pcd, -EOPNOTSUPP);
20888+ return;
20889+ }
20890+
20891+ pcd_clear_halt(pcd, ep);
20892+
20893+ break;
20894+ }
20895+}
20896+
20897+/**
20898+ * This function process the SET_ADDRESS Setup Commands.
20899+ */
20900+static inline void do_set_address(dwc_otg_pcd_t *pcd)
20901+{
20902+ dwc_otg_dev_if_t *dev_if = GET_CORE_IF(pcd)->dev_if;
20903+ struct usb_ctrlrequest ctrl = pcd->setup_pkt->req;
20904+
20905+ if (ctrl.bRequestType == USB_RECIP_DEVICE) {
20906+ dcfg_data_t dcfg = {.d32=0};
20907+
20908+#ifdef DEBUG_EP0
20909+// DWC_DEBUGPL(DBG_PCDV, "SET_ADDRESS:%d\n", ctrl.wValue);
20910+#endif
20911+ dcfg.b.devaddr = ctrl.wValue;
20912+ dwc_modify_reg32(&dev_if->dev_global_regs->dcfg, 0, dcfg.d32);
20913+ do_setup_in_status_phase(pcd);
20914+ }
20915+}
20916+
20917+/**
20918+ * This function processes SETUP commands. In Linux, the USB Command
20919+ * processing is done in two places - the first being the PCD and the
20920+ * second in the Gadget Driver (for example, the File-Backed Storage
20921+ * Gadget Driver).
20922+ *
20923+ * <table>
20924+ * <tr><td>Command </td><td>Driver </td><td>Description</td></tr>
20925+ *
20926+ * <tr><td>GET_STATUS </td><td>PCD </td><td>Command is processed as
20927+ * defined in chapter 9 of the USB 2.0 Specification chapter 9
20928+ * </td></tr>
20929+ *
20930+ * <tr><td>CLEAR_FEATURE </td><td>PCD </td><td>The Device and Endpoint
20931+ * requests are the ENDPOINT_HALT feature is procesed, all others the
20932+ * interface requests are ignored.</td></tr>
20933+ *
20934+ * <tr><td>SET_FEATURE </td><td>PCD </td><td>The Device and Endpoint
20935+ * requests are processed by the PCD. Interface requests are passed
20936+ * to the Gadget Driver.</td></tr>
20937+ *
20938+ * <tr><td>SET_ADDRESS </td><td>PCD </td><td>Program the DCFG reg,
20939+ * with device address received </td></tr>
20940+ *
20941+ * <tr><td>GET_DESCRIPTOR </td><td>Gadget Driver </td><td>Return the
20942+ * requested descriptor</td></tr>
20943+ *
20944+ * <tr><td>SET_DESCRIPTOR </td><td>Gadget Driver </td><td>Optional -
20945+ * not implemented by any of the existing Gadget Drivers.</td></tr>
20946+ *
20947+ * <tr><td>SET_CONFIGURATION </td><td>Gadget Driver </td><td>Disable
20948+ * all EPs and enable EPs for new configuration.</td></tr>
20949+ *
20950+ * <tr><td>GET_CONFIGURATION </td><td>Gadget Driver </td><td>Return
20951+ * the current configuration</td></tr>
20952+ *
20953+ * <tr><td>SET_INTERFACE </td><td>Gadget Driver </td><td>Disable all
20954+ * EPs and enable EPs for new configuration.</td></tr>
20955+ *
20956+ * <tr><td>GET_INTERFACE </td><td>Gadget Driver </td><td>Return the
20957+ * current interface.</td></tr>
20958+ *
20959+ * <tr><td>SYNC_FRAME </td><td>PCD </td><td>Display debug
20960+ * message.</td></tr>
20961+ * </table>
20962+ *
20963+ * When the SETUP Phase Done interrupt occurs, the PCD SETUP commands are
20964+ * processed by pcd_setup. Calling the Function Driver's setup function from
20965+ * pcd_setup processes the gadget SETUP commands.
20966+ */
20967+static inline void pcd_setup(dwc_otg_pcd_t *pcd)
20968+{
20969+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
20970+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
20971+ struct usb_ctrlrequest ctrl = pcd->setup_pkt->req;
20972+ dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
20973+
20974+ deptsiz0_data_t doeptsize0 = { .d32 = 0};
20975+
20976+#ifdef DEBUG_EP0
20977+ DWC_DEBUGPL(DBG_PCD, "SETUP %02x.%02x v%04x i%04x l%04x\n",
20978+ ctrl.bRequestType, ctrl.bRequest,
20979+ ctrl.wValue, ctrl.wIndex, ctrl.wLength);
20980+#endif
20981+
20982+ doeptsize0.d32 = dwc_read_reg32(&dev_if->out_ep_regs[0]->doeptsiz);
20983+
20984+ /** @todo handle > 1 setup packet , assert error for now */
20985+
20986+ if (core_if->dma_enable && core_if->dma_desc_enable == 0 && (doeptsize0.b.supcnt < 2)) {
20987+ DWC_ERROR ("\n\n----------- CANNOT handle > 1 setup packet in DMA mode\n\n");
20988+ }
20989+
20990+ /* Clean up the request queue */
20991+ dwc_otg_request_nuke(ep0);
20992+ ep0->stopped = 0;
20993+
20994+ if (ctrl.bRequestType & USB_DIR_IN) {
20995+ ep0->dwc_ep.is_in = 1;
20996+ pcd->ep0state = EP0_IN_DATA_PHASE;
20997+ }
20998+ else {
20999+ ep0->dwc_ep.is_in = 0;
21000+ pcd->ep0state = EP0_OUT_DATA_PHASE;
21001+ }
21002+
21003+ if(ctrl.wLength == 0) {
21004+ ep0->dwc_ep.is_in = 1;
21005+ pcd->ep0state = EP0_IN_STATUS_PHASE;
21006+ }
21007+
21008+ if ((ctrl.bRequestType & USB_TYPE_MASK) != USB_TYPE_STANDARD) {
21009+ /* handle non-standard (class/vendor) requests in the gadget driver */
21010+ do_gadget_setup(pcd, &ctrl);
21011+ return;
21012+ }
21013+
21014+ /** @todo NGS: Handle bad setup packet? */
21015+
21016+///////////////////////////////////////////
21017+//// --- Standard Request handling --- ////
21018+
21019+ switch (ctrl.bRequest) {
21020+ case USB_REQ_GET_STATUS:
21021+ do_get_status(pcd);
21022+ break;
21023+
21024+ case USB_REQ_CLEAR_FEATURE:
21025+ do_clear_feature(pcd);
21026+ break;
21027+
21028+ case USB_REQ_SET_FEATURE:
21029+ do_set_feature(pcd);
21030+ break;
21031+
21032+ case USB_REQ_SET_ADDRESS:
21033+ do_set_address(pcd);
21034+ break;
21035+
21036+ case USB_REQ_SET_INTERFACE:
21037+ case USB_REQ_SET_CONFIGURATION:
21038+// _pcd->request_config = 1; /* Configuration changed */
21039+ do_gadget_setup(pcd, &ctrl);
21040+ break;
21041+
21042+ case USB_REQ_SYNCH_FRAME:
21043+ do_gadget_setup(pcd, &ctrl);
21044+ break;
21045+
21046+ default:
21047+ /* Call the Gadget Driver's setup functions */
21048+ do_gadget_setup(pcd, &ctrl);
21049+ break;
21050+ }
21051+}
21052+
21053+/**
21054+ * This function completes the ep0 control transfer.
21055+ */
21056+static int32_t ep0_complete_request(dwc_otg_pcd_ep_t *ep)
21057+{
21058+ dwc_otg_core_if_t *core_if = GET_CORE_IF(ep->pcd);
21059+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
21060+ dwc_otg_dev_in_ep_regs_t *in_ep_regs =
21061+ dev_if->in_ep_regs[ep->dwc_ep.num];
21062+#ifdef DEBUG_EP0
21063+ dwc_otg_dev_out_ep_regs_t *out_ep_regs =
21064+ dev_if->out_ep_regs[ep->dwc_ep.num];
21065+#endif
21066+ deptsiz0_data_t deptsiz;
21067+ desc_sts_data_t desc_sts;
21068+ dwc_otg_pcd_request_t *req;
21069+ int is_last = 0;
21070+ dwc_otg_pcd_t *pcd = ep->pcd;
21071+
21072+ //DWC_DEBUGPL(DBG_PCDV, "%s() %s\n", __func__, _ep->ep.name);
21073+
21074+ if (pcd->ep0_pending && list_empty(&ep->queue)) {
21075+ if (ep->dwc_ep.is_in) {
21076+#ifdef DEBUG_EP0
21077+ DWC_DEBUGPL(DBG_PCDV, "Do setup OUT status phase\n");
21078+#endif
21079+ do_setup_out_status_phase(pcd);
21080+ }
21081+ else {
21082+#ifdef DEBUG_EP0
21083+ DWC_DEBUGPL(DBG_PCDV, "Do setup IN status phase\n");
21084+#endif
21085+ do_setup_in_status_phase(pcd);
21086+ }
21087+ pcd->ep0_pending = 0;
21088+ return 1;
21089+ }
21090+
21091+ if (list_empty(&ep->queue)) {
21092+ return 0;
21093+ }
21094+ req = list_entry(ep->queue.next, dwc_otg_pcd_request_t, queue);
21095+
21096+
21097+ if (pcd->ep0state == EP0_OUT_STATUS_PHASE || pcd->ep0state == EP0_IN_STATUS_PHASE) {
21098+ is_last = 1;
21099+ }
21100+ else if (ep->dwc_ep.is_in) {
21101+ deptsiz.d32 = dwc_read_reg32(&in_ep_regs->dieptsiz);
21102+ if(core_if->dma_desc_enable != 0)
21103+ desc_sts.d32 = readl(dev_if->in_desc_addr);
21104+#ifdef DEBUG_EP0
21105+ DWC_DEBUGPL(DBG_PCDV, "%s len=%d xfersize=%d pktcnt=%d\n",
21106+ ep->ep.name, ep->dwc_ep.xfer_len,
21107+ deptsiz.b.xfersize, deptsiz.b.pktcnt);
21108+#endif
21109+
21110+ if (((core_if->dma_desc_enable == 0) && (deptsiz.b.xfersize == 0)) ||
21111+ ((core_if->dma_desc_enable != 0) && (desc_sts.b.bytes == 0))) {
21112+ req->req.actual = ep->dwc_ep.xfer_count;
21113+ /* Is a Zero Len Packet needed? */
21114+ if (req->req.zero) {
21115+#ifdef DEBUG_EP0
21116+ DWC_DEBUGPL(DBG_PCD, "Setup Rx ZLP\n");
21117+#endif
21118+ req->req.zero = 0;
21119+ }
21120+ do_setup_out_status_phase(pcd);
21121+ }
21122+ }
21123+ else {
21124+ /* ep0-OUT */
21125+#ifdef DEBUG_EP0
21126+ deptsiz.d32 = dwc_read_reg32(&out_ep_regs->doeptsiz);
21127+ DWC_DEBUGPL(DBG_PCDV, "%s len=%d xsize=%d pktcnt=%d\n",
21128+ ep->ep.name, ep->dwc_ep.xfer_len,
21129+ deptsiz.b.xfersize,
21130+ deptsiz.b.pktcnt);
21131+#endif
21132+ req->req.actual = ep->dwc_ep.xfer_count;
21133+ /* Is a Zero Len Packet needed? */
21134+ if (req->req.zero) {
21135+#ifdef DEBUG_EP0
21136+ DWC_DEBUGPL(DBG_PCDV, "Setup Tx ZLP\n");
21137+#endif
21138+ req->req.zero = 0;
21139+ }
21140+ if(core_if->dma_desc_enable == 0)
21141+ do_setup_in_status_phase(pcd);
21142+ }
21143+
21144+ /* Complete the request */
21145+ if (is_last) {
21146+ dwc_otg_request_done(ep, req, 0);
21147+ ep->dwc_ep.start_xfer_buff = 0;
21148+ ep->dwc_ep.xfer_buff = 0;
21149+ ep->dwc_ep.xfer_len = 0;
21150+ return 1;
21151+ }
21152+ return 0;
21153+}
21154+
21155+inline void aligned_buf_patch_on_buf_dma_oep_completion(dwc_otg_pcd_ep_t *ep, uint32_t byte_count)
21156+{
21157+ dwc_ep_t *dwc_ep = &ep->dwc_ep;
21158+ if(byte_count && dwc_ep->aligned_buf &&
21159+ dwc_ep->dma_addr>=dwc_ep->aligned_dma_addr &&
21160+ dwc_ep->dma_addr<=(dwc_ep->aligned_dma_addr+dwc_ep->aligned_buf_size))\
21161+ {
21162+ //aligned buf used, apply complete patch
21163+ u32 offset=(dwc_ep->dma_addr-dwc_ep->aligned_dma_addr);
21164+ memcpy(dwc_ep->start_xfer_buff+offset, dwc_ep->aligned_buf+offset, byte_count);
21165+
21166+ }
21167+}
21168+
21169+/**
21170+ * This function completes the request for the EP. If there are
21171+ * additional requests for the EP in the queue they will be started.
21172+ */
21173+static void complete_ep(dwc_otg_pcd_ep_t *ep)
21174+{
21175+ dwc_otg_core_if_t *core_if = GET_CORE_IF(ep->pcd);
21176+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
21177+ dwc_otg_dev_in_ep_regs_t *in_ep_regs =
21178+ dev_if->in_ep_regs[ep->dwc_ep.num];
21179+ deptsiz_data_t deptsiz;
21180+ desc_sts_data_t desc_sts;
21181+ dwc_otg_pcd_request_t *req = 0;
21182+ dwc_otg_dma_desc_t* dma_desc;
21183+ uint32_t byte_count = 0;
21184+ int is_last = 0;
21185+ int i;
21186+
21187+ DWC_DEBUGPL(DBG_PCDV,"%s() %s-%s\n", __func__, ep->ep.name,
21188+ (ep->dwc_ep.is_in?"IN":"OUT"));
21189+
21190+ /* Get any pending requests */
21191+ if (!list_empty(&ep->queue)) {
21192+ req = list_entry(ep->queue.next, dwc_otg_pcd_request_t,
21193+ queue);
21194+ if (!req) {
21195+ printk("complete_ep 0x%p, req = NULL!\n", ep);
21196+ return;
21197+ }
21198+ }
21199+ else {
21200+ printk("complete_ep 0x%p, ep->queue empty!\n", ep);
21201+ return;
21202+ }
21203+ DWC_DEBUGPL(DBG_PCD, "Requests %d\n", ep->pcd->request_pending);
21204+
21205+ if (ep->dwc_ep.is_in) {
21206+ deptsiz.d32 = dwc_read_reg32(&in_ep_regs->dieptsiz);
21207+
21208+ if (core_if->dma_enable) {
21209+ //dma_unmap_single(NULL,ep->dwc_ep.dma_addr,ep->dwc_ep.xfer_count,DMA_NONE);
21210+ if(core_if->dma_desc_enable == 0) {
21211+ //dma_unmap_single(NULL,ep->dwc_ep.dma_addr,ep->dwc_ep.xfer_count,DMA_NONE);
21212+ if (deptsiz.b.xfersize == 0 && deptsiz.b.pktcnt == 0) {
21213+ byte_count = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
21214+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 );
21215+
21216+ ep->dwc_ep.xfer_buff += byte_count;
21217+ ep->dwc_ep.dma_addr += byte_count;
21218+ ep->dwc_ep.xfer_count += byte_count;
21219+
21220+ DWC_DEBUGPL(DBG_PCDV, "%s len=%d xfersize=%d pktcnt=%d\n",
21221+ ep->ep.name, ep->dwc_ep.xfer_len,
21222+ deptsiz.b.xfersize, deptsiz.b.pktcnt);
21223+
21224+
21225+ if(ep->dwc_ep.xfer_len < ep->dwc_ep.total_len) {
21226+ //dwc_otg_ep_start_transfer(core_if, &ep->dwc_ep);
21227+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);
21228+ } else if(ep->dwc_ep.sent_zlp) {
21229+ /*
21230+ * This fragment of code should initiate 0
21231+ * length trasfer in case if it is queued
21232+ * a trasfer with size divisible to EPs max
21233+ * packet size and with usb_request zero field
21234+ * is set, which means that after data is transfered,
21235+ * it is also should be transfered
21236+ * a 0 length packet at the end. For Slave and
21237+ * Buffer DMA modes in this case SW has
21238+ * to initiate 2 transfers one with transfer size,
21239+ * and the second with 0 size. For Desriptor
21240+ * DMA mode SW is able to initiate a transfer,
21241+ * which will handle all the packets including
21242+ * the last 0 legth.
21243+ */
21244+ ep->dwc_ep.sent_zlp = 0;
21245+ dwc_otg_ep_start_zl_transfer(core_if, &ep->dwc_ep);
21246+ } else {
21247+ is_last = 1;
21248+ }
21249+ } else {
21250+ DWC_WARN("Incomplete transfer (%s-%s [siz=%d pkt=%d])\n",
21251+ ep->ep.name, (ep->dwc_ep.is_in?"IN":"OUT"),
21252+ deptsiz.b.xfersize, deptsiz.b.pktcnt);
21253+ }
21254+ } else {
21255+
21256+ dma_desc = ep->dwc_ep.desc_addr;
21257+ byte_count = 0;
21258+ ep->dwc_ep.sent_zlp = 0;
21259+
21260+ for(i = 0; i < ep->dwc_ep.desc_cnt; ++i) {
21261+ desc_sts.d32 = readl(dma_desc);
21262+ byte_count += desc_sts.b.bytes;
21263+ dma_desc++;
21264+ }
21265+
21266+ if(byte_count == 0) {
21267+ ep->dwc_ep.xfer_count = ep->dwc_ep.total_len;
21268+ is_last = 1;
21269+ } else {
21270+ DWC_WARN("Incomplete transfer\n");
21271+ }
21272+ }
21273+ } else {
21274+ if (deptsiz.b.xfersize == 0 && deptsiz.b.pktcnt == 0) {
21275+ /* Check if the whole transfer was completed,
21276+ * if no, setup transfer for next portion of data
21277+ */
21278+ DWC_DEBUGPL(DBG_PCDV, "%s len=%d xfersize=%d pktcnt=%d\n",
21279+ ep->ep.name, ep->dwc_ep.xfer_len,
21280+ deptsiz.b.xfersize, deptsiz.b.pktcnt);
21281+ if(ep->dwc_ep.xfer_len < ep->dwc_ep.total_len) {
21282+ //dwc_otg_ep_start_transfer(core_if, &ep->dwc_ep);
21283+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 );
21284+ } else if(ep->dwc_ep.sent_zlp) {
21285+ /*
21286+ * This fragment of code should initiate 0
21287+ * length trasfer in case if it is queued
21288+ * a trasfer with size divisible to EPs max
21289+ * packet size and with usb_request zero field
21290+ * is set, which means that after data is transfered,
21291+ * it is also should be transfered
21292+ * a 0 length packet at the end. For Slave and
21293+ * Buffer DMA modes in this case SW has
21294+ * to initiate 2 transfers one with transfer size,
21295+ * and the second with 0 size. For Desriptor
21296+ * DMA mode SW is able to initiate a transfer,
21297+ * which will handle all the packets including
21298+ * the last 0 legth.
21299+ */
21300+ ep->dwc_ep.sent_zlp = 0;
21301+ dwc_otg_ep_start_zl_transfer(core_if, &ep->dwc_ep);
21302+ } else {
21303+ is_last = 1;
21304+ }
21305+ }
21306+ else {
21307+ DWC_WARN("Incomplete transfer (%s-%s [siz=%d pkt=%d])\n",
21308+ ep->ep.name, (ep->dwc_ep.is_in?"IN":"OUT"),
21309+ deptsiz.b.xfersize, deptsiz.b.pktcnt);
21310+ }
21311+ }
21312+ } else {
21313+ dwc_otg_dev_out_ep_regs_t *out_ep_regs =
21314+ dev_if->out_ep_regs[ep->dwc_ep.num];
21315+ desc_sts.d32 = 0;
21316+ if(core_if->dma_enable) {
21317+ //dma_unmap_single(NULL,ep->dwc_ep.dma_addr,ep->dwc_ep.xfer_count,DMA_FROM_DEVICE);
21318+ if(core_if->dma_desc_enable) {
21319+ DWC_WARN("\n\n%s: we need a cache invalidation here!!\n\n",__func__);
21320+ dma_desc = ep->dwc_ep.desc_addr;
21321+ byte_count = 0;
21322+ ep->dwc_ep.sent_zlp = 0;
21323+ for(i = 0; i < ep->dwc_ep.desc_cnt; ++i) {
21324+ desc_sts.d32 = readl(dma_desc);
21325+ byte_count += desc_sts.b.bytes;
21326+ dma_desc++;
21327+ }
21328+
21329+ ep->dwc_ep.xfer_count = ep->dwc_ep.total_len
21330+ - byte_count + ((4 - (ep->dwc_ep.total_len & 0x3)) & 0x3);
21331+
21332+ //todo: invalidate cache & aligned buf patch on completion
21333+ //
21334+
21335+ is_last = 1;
21336+ } else {
21337+ deptsiz.d32 = 0;
21338+ deptsiz.d32 = dwc_read_reg32(&out_ep_regs->doeptsiz);
21339+
21340+ byte_count = (ep->dwc_ep.xfer_len -
21341+ ep->dwc_ep.xfer_count - deptsiz.b.xfersize);
21342+
21343+// dma_sync_single_for_device(NULL,ep->dwc_ep.dma_addr,byte_count,DMA_FROM_DEVICE);
21344+
21345+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);
21346+ //todo: invalidate cache & aligned buf patch on completion
21347+ dma_sync_single_for_device(NULL,ep->dwc_ep.dma_addr,byte_count,DMA_FROM_DEVICE);
21348+ aligned_buf_patch_on_buf_dma_oep_completion(ep,byte_count);
21349+
21350+ ep->dwc_ep.xfer_buff += byte_count;
21351+ ep->dwc_ep.dma_addr += byte_count;
21352+ ep->dwc_ep.xfer_count += byte_count;
21353+
21354+ /* Check if the whole transfer was completed,
21355+ * if no, setup transfer for next portion of data
21356+ */
21357+ if(ep->dwc_ep.xfer_len < ep->dwc_ep.total_len) {
21358+ //dwc_otg_ep_start_transfer(core_if, &ep->dwc_ep);
21359+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);
21360+ }
21361+ else if(ep->dwc_ep.sent_zlp) {
21362+ /*
21363+ * This fragment of code should initiate 0
21364+ * length trasfer in case if it is queued
21365+ * a trasfer with size divisible to EPs max
21366+ * packet size and with usb_request zero field
21367+ * is set, which means that after data is transfered,
21368+ * it is also should be transfered
21369+ * a 0 length packet at the end. For Slave and
21370+ * Buffer DMA modes in this case SW has
21371+ * to initiate 2 transfers one with transfer size,
21372+ * and the second with 0 size. For Desriptor
21373+ * DMA mode SW is able to initiate a transfer,
21374+ * which will handle all the packets including
21375+ * the last 0 legth.
21376+ */
21377+ ep->dwc_ep.sent_zlp = 0;
21378+ dwc_otg_ep_start_zl_transfer(core_if, &ep->dwc_ep);
21379+ } else {
21380+ is_last = 1;
21381+ }
21382+ }
21383+ } else {
21384+ /* Check if the whole transfer was completed,
21385+ * if no, setup transfer for next portion of data
21386+ */
21387+ if(ep->dwc_ep.xfer_len < ep->dwc_ep.total_len) {
21388+ //dwc_otg_ep_start_transfer(core_if, &ep->dwc_ep);
21389+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 );
21390+ }
21391+ else if(ep->dwc_ep.sent_zlp) {
21392+ /*
21393+ * This fragment of code should initiate 0
21394+ * length trasfer in case if it is queued
21395+ * a trasfer with size divisible to EPs max
21396+ * packet size and with usb_request zero field
21397+ * is set, which means that after data is transfered,
21398+ * it is also should be transfered
21399+ * a 0 length packet at the end. For Slave and
21400+ * Buffer DMA modes in this case SW has
21401+ * to initiate 2 transfers one with transfer size,
21402+ * and the second with 0 size. For Desriptor
21403+ * DMA mode SW is able to initiate a transfer,
21404+ * which will handle all the packets including
21405+ * the last 0 legth.
21406+ */
21407+ ep->dwc_ep.sent_zlp = 0;
21408+ dwc_otg_ep_start_zl_transfer(core_if, &ep->dwc_ep);
21409+ } else {
21410+ is_last = 1;
21411+ }
21412+ }
21413+
21414+#ifdef DEBUG
21415+
21416+ DWC_DEBUGPL(DBG_PCDV, "addr %p, %s len=%d cnt=%d xsize=%d pktcnt=%d\n",
21417+ &out_ep_regs->doeptsiz, ep->ep.name, ep->dwc_ep.xfer_len,
21418+ ep->dwc_ep.xfer_count,
21419+ deptsiz.b.xfersize,
21420+ deptsiz.b.pktcnt);
21421+#endif
21422+ }
21423+
21424+ /* Complete the request */
21425+ if (is_last) {
21426+ req->req.actual = ep->dwc_ep.xfer_count;
21427+
21428+ dwc_otg_request_done(ep, req, 0);
21429+
21430+ ep->dwc_ep.start_xfer_buff = 0;
21431+ ep->dwc_ep.xfer_buff = 0;
21432+ ep->dwc_ep.xfer_len = 0;
21433+
21434+ /* If there is a request in the queue start it.*/
21435+ start_next_request(ep);
21436+ }
21437+}
21438+
21439+
21440+#ifdef DWC_EN_ISOC
21441+
21442+/**
21443+ * This function BNA interrupt for Isochronous EPs
21444+ *
21445+ */
21446+static void dwc_otg_pcd_handle_iso_bna(dwc_otg_pcd_ep_t *ep)
21447+{
21448+ dwc_ep_t *dwc_ep = &ep->dwc_ep;
21449+ volatile uint32_t *addr;
21450+ depctl_data_t depctl = {.d32 = 0};
21451+ dwc_otg_pcd_t *pcd = ep->pcd;
21452+ dwc_otg_dma_desc_t *dma_desc;
21453+ int i;
21454+
21455+ dma_desc = dwc_ep->iso_desc_addr + dwc_ep->desc_cnt * (dwc_ep->proc_buf_num);
21456+
21457+ if(dwc_ep->is_in) {
21458+ desc_sts_data_t sts = {.d32 = 0};
21459+ for(i = 0;i < dwc_ep->desc_cnt; ++i, ++dma_desc)
21460+ {
21461+ sts.d32 = readl(&dma_desc->status);
21462+ sts.b_iso_in.bs = BS_HOST_READY;
21463+ writel(sts.d32,&dma_desc->status);
21464+ }
21465+ }
21466+ else {
21467+ desc_sts_data_t sts = {.d32 = 0};
21468+ for(i = 0;i < dwc_ep->desc_cnt; ++i, ++dma_desc)
21469+ {
21470+ sts.d32 = readl(&dma_desc->status);
21471+ sts.b_iso_out.bs = BS_HOST_READY;
21472+ writel(sts.d32,&dma_desc->status);
21473+ }
21474+ }
21475+
21476+ if(dwc_ep->is_in == 0){
21477+ addr = &GET_CORE_IF(pcd)->dev_if->out_ep_regs[dwc_ep->num]->doepctl;
21478+ }
21479+ else{
21480+ addr = &GET_CORE_IF(pcd)->dev_if->in_ep_regs[dwc_ep->num]->diepctl;
21481+ }
21482+ depctl.b.epena = 1;
21483+ dwc_modify_reg32(addr,depctl.d32,depctl.d32);
21484+}
21485+
21486+/**
21487+ * This function sets latest iso packet information(non-PTI mode)
21488+ *
21489+ * @param core_if Programming view of DWC_otg controller.
21490+ * @param ep The EP to start the transfer on.
21491+ *
21492+ */
21493+void set_current_pkt_info(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
21494+{
21495+ deptsiz_data_t deptsiz = { .d32 = 0 };
21496+ dma_addr_t dma_addr;
21497+ uint32_t offset;
21498+
21499+ if(ep->proc_buf_num)
21500+ dma_addr = ep->dma_addr1;
21501+ else
21502+ dma_addr = ep->dma_addr0;
21503+
21504+
21505+ if(ep->is_in) {
21506+ deptsiz.d32 = dwc_read_reg32(&core_if->dev_if->in_ep_regs[ep->num]->dieptsiz);
21507+ offset = ep->data_per_frame;
21508+ } else {
21509+ deptsiz.d32 = dwc_read_reg32(&core_if->dev_if->out_ep_regs[ep->num]->doeptsiz);
21510+ offset = ep->data_per_frame + (0x4 & (0x4 - (ep->data_per_frame & 0x3)));
21511+ }
21512+
21513+ if(!deptsiz.b.xfersize) {
21514+ ep->pkt_info[ep->cur_pkt].length = ep->data_per_frame;
21515+ ep->pkt_info[ep->cur_pkt].offset = ep->cur_pkt_dma_addr - dma_addr;
21516+ ep->pkt_info[ep->cur_pkt].status = 0;
21517+ } else {
21518+ ep->pkt_info[ep->cur_pkt].length = ep->data_per_frame;
21519+ ep->pkt_info[ep->cur_pkt].offset = ep->cur_pkt_dma_addr - dma_addr;
21520+ ep->pkt_info[ep->cur_pkt].status = -ENODATA;
21521+ }
21522+ ep->cur_pkt_addr += offset;
21523+ ep->cur_pkt_dma_addr += offset;
21524+ ep->cur_pkt++;
21525+}
21526+
21527+/**
21528+ * This function sets latest iso packet information(DDMA mode)
21529+ *
21530+ * @param core_if Programming view of DWC_otg controller.
21531+ * @param dwc_ep The EP to start the transfer on.
21532+ *
21533+ */
21534+static void set_ddma_iso_pkts_info(dwc_otg_core_if_t *core_if, dwc_ep_t *dwc_ep)
21535+{
21536+ dwc_otg_dma_desc_t* dma_desc;
21537+ desc_sts_data_t sts = {.d32 = 0};
21538+ iso_pkt_info_t *iso_packet;
21539+ uint32_t data_per_desc;
21540+ uint32_t offset;
21541+ int i, j;
21542+
21543+ iso_packet = dwc_ep->pkt_info;
21544+
21545+ /** Reinit closed DMA Descriptors*/
21546+ /** ISO OUT EP */
21547+ if(dwc_ep->is_in == 0) {
21548+ dma_desc = dwc_ep->iso_desc_addr + dwc_ep->desc_cnt * dwc_ep->proc_buf_num;
21549+ offset = 0;
21550+
21551+ for(i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm; i+= dwc_ep->pkt_per_frm)
21552+ {
21553+ for(j = 0; j < dwc_ep->pkt_per_frm; ++j)
21554+ {
21555+ data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
21556+ dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
21557+ data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
21558+
21559+ sts.d32 = readl(&dma_desc->status);
21560+
21561+ /* Write status in iso_packet_decsriptor */
21562+ iso_packet->status = sts.b_iso_out.rxsts + (sts.b_iso_out.bs^BS_DMA_DONE);
21563+ if(iso_packet->status) {
21564+ iso_packet->status = -ENODATA;
21565+ }
21566+
21567+ /* Received data length */
21568+ if(!sts.b_iso_out.rxbytes){
21569+ iso_packet->length = data_per_desc - sts.b_iso_out.rxbytes;
21570+ } else {
21571+ iso_packet->length = data_per_desc - sts.b_iso_out.rxbytes +
21572+ (4 - dwc_ep->data_per_frame % 4);
21573+ }
21574+
21575+ iso_packet->offset = offset;
21576+
21577+ offset += data_per_desc;
21578+ dma_desc ++;
21579+ iso_packet ++;
21580+ }
21581+ }
21582+
21583+ for(j = 0; j < dwc_ep->pkt_per_frm - 1; ++j)
21584+ {
21585+ data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
21586+ dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
21587+ data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
21588+
21589+ sts.d32 = readl(&dma_desc->status);
21590+
21591+ /* Write status in iso_packet_decsriptor */
21592+ iso_packet->status = sts.b_iso_out.rxsts + (sts.b_iso_out.bs^BS_DMA_DONE);
21593+ if(iso_packet->status) {
21594+ iso_packet->status = -ENODATA;
21595+ }
21596+
21597+ /* Received data length */
21598+ iso_packet->length = dwc_ep->data_per_frame - sts.b_iso_out.rxbytes;
21599+
21600+ iso_packet->offset = offset;
21601+
21602+ offset += data_per_desc;
21603+ iso_packet++;
21604+ dma_desc++;
21605+ }
21606+
21607+ sts.d32 = readl(&dma_desc->status);
21608+
21609+ /* Write status in iso_packet_decsriptor */
21610+ iso_packet->status = sts.b_iso_out.rxsts + (sts.b_iso_out.bs^BS_DMA_DONE);
21611+ if(iso_packet->status) {
21612+ iso_packet->status = -ENODATA;
21613+ }
21614+ /* Received data length */
21615+ if(!sts.b_iso_out.rxbytes){
21616+ iso_packet->length = dwc_ep->data_per_frame - sts.b_iso_out.rxbytes;
21617+ } else {
21618+ iso_packet->length = dwc_ep->data_per_frame - sts.b_iso_out.rxbytes +
21619+ (4 - dwc_ep->data_per_frame % 4);
21620+ }
21621+
21622+ iso_packet->offset = offset;
21623+ }
21624+ else /** ISO IN EP */
21625+ {
21626+ dma_desc = dwc_ep->iso_desc_addr + dwc_ep->desc_cnt * dwc_ep->proc_buf_num;
21627+
21628+ for(i = 0; i < dwc_ep->desc_cnt - 1; i++)
21629+ {
21630+ sts.d32 = readl(&dma_desc->status);
21631+
21632+ /* Write status in iso packet descriptor */
21633+ iso_packet->status = sts.b_iso_in.txsts + (sts.b_iso_in.bs^BS_DMA_DONE);
21634+ if(iso_packet->status != 0) {
21635+ iso_packet->status = -ENODATA;
21636+
21637+ }
21638+ /* Bytes has been transfered */
21639+ iso_packet->length = dwc_ep->data_per_frame - sts.b_iso_in.txbytes;
21640+
21641+ dma_desc ++;
21642+ iso_packet++;
21643+ }
21644+
21645+ sts.d32 = readl(&dma_desc->status);
21646+ while(sts.b_iso_in.bs == BS_DMA_BUSY) {
21647+ sts.d32 = readl(&dma_desc->status);
21648+ }
21649+
21650+ /* Write status in iso packet descriptor ??? do be done with ERROR codes*/
21651+ iso_packet->status = sts.b_iso_in.txsts + (sts.b_iso_in.bs^BS_DMA_DONE);
21652+ if(iso_packet->status != 0) {
21653+ iso_packet->status = -ENODATA;
21654+ }
21655+
21656+ /* Bytes has been transfered */
21657+ iso_packet->length = dwc_ep->data_per_frame - sts.b_iso_in.txbytes;
21658+ }
21659+}
21660+
21661+/**
21662+ * This function reinitialize DMA Descriptors for Isochronous transfer
21663+ *
21664+ * @param core_if Programming view of DWC_otg controller.
21665+ * @param dwc_ep The EP to start the transfer on.
21666+ *
21667+ */
21668+static void reinit_ddma_iso_xfer(dwc_otg_core_if_t *core_if, dwc_ep_t *dwc_ep)
21669+{
21670+ int i, j;
21671+ dwc_otg_dma_desc_t* dma_desc;
21672+ dma_addr_t dma_ad;
21673+ volatile uint32_t *addr;
21674+ desc_sts_data_t sts = { .d32 =0 };
21675+ uint32_t data_per_desc;
21676+
21677+ if(dwc_ep->is_in == 0) {
21678+ addr = &core_if->dev_if->out_ep_regs[dwc_ep->num]->doepctl;
21679+ }
21680+ else {
21681+ addr = &core_if->dev_if->in_ep_regs[dwc_ep->num]->diepctl;
21682+ }
21683+
21684+
21685+ if(dwc_ep->proc_buf_num == 0) {
21686+ /** Buffer 0 descriptors setup */
21687+ dma_ad = dwc_ep->dma_addr0;
21688+ }
21689+ else {
21690+ /** Buffer 1 descriptors setup */
21691+ dma_ad = dwc_ep->dma_addr1;
21692+ }
21693+
21694+
21695+ /** Reinit closed DMA Descriptors*/
21696+ /** ISO OUT EP */
21697+ if(dwc_ep->is_in == 0) {
21698+ dma_desc = dwc_ep->iso_desc_addr + dwc_ep->desc_cnt * dwc_ep->proc_buf_num;
21699+
21700+ sts.b_iso_out.bs = BS_HOST_READY;
21701+ sts.b_iso_out.rxsts = 0;
21702+ sts.b_iso_out.l = 0;
21703+ sts.b_iso_out.sp = 0;
21704+ sts.b_iso_out.ioc = 0;
21705+ sts.b_iso_out.pid = 0;
21706+ sts.b_iso_out.framenum = 0;
21707+
21708+ for(i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm; i+= dwc_ep->pkt_per_frm)
21709+ {
21710+ for(j = 0; j < dwc_ep->pkt_per_frm; ++j)
21711+ {
21712+ data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
21713+ dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
21714+ data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
21715+ sts.b_iso_out.rxbytes = data_per_desc;
21716+ writel((uint32_t)dma_ad, &dma_desc->buf);
21717+ writel(sts.d32, &dma_desc->status);
21718+
21719+ //(uint32_t)dma_ad += data_per_desc;
21720+ dma_ad = (uint32_t)dma_ad + data_per_desc;
21721+ dma_desc ++;
21722+ }
21723+ }
21724+
21725+ for(j = 0; j < dwc_ep->pkt_per_frm - 1; ++j)
21726+ {
21727+
21728+ data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
21729+ dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
21730+ data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
21731+ sts.b_iso_out.rxbytes = data_per_desc;
21732+
21733+ writel((uint32_t)dma_ad, &dma_desc->buf);
21734+ writel(sts.d32, &dma_desc->status);
21735+
21736+ dma_desc++;
21737+ //(uint32_t)dma_ad += data_per_desc;
21738+ dma_ad = (uint32_t)dma_ad + data_per_desc;
21739+ }
21740+
21741+ sts.b_iso_out.ioc = 1;
21742+ sts.b_iso_out.l = dwc_ep->proc_buf_num;
21743+
21744+ data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
21745+ dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
21746+ data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
21747+ sts.b_iso_out.rxbytes = data_per_desc;
21748+
21749+ writel((uint32_t)dma_ad, &dma_desc->buf);
21750+ writel(sts.d32, &dma_desc->status);
21751+ }
21752+ else /** ISO IN EP */
21753+ {
21754+ dma_desc = dwc_ep->iso_desc_addr + dwc_ep->desc_cnt * dwc_ep->proc_buf_num;
21755+
21756+ sts.b_iso_in.bs = BS_HOST_READY;
21757+ sts.b_iso_in.txsts = 0;
21758+ sts.b_iso_in.sp = 0;
21759+ sts.b_iso_in.ioc = 0;
21760+ sts.b_iso_in.pid = dwc_ep->pkt_per_frm;
21761+ sts.b_iso_in.framenum = dwc_ep->next_frame;
21762+ sts.b_iso_in.txbytes = dwc_ep->data_per_frame;
21763+ sts.b_iso_in.l = 0;
21764+
21765+ for(i = 0; i < dwc_ep->desc_cnt - 1; i++)
21766+ {
21767+ writel((uint32_t)dma_ad, &dma_desc->buf);
21768+ writel(sts.d32, &dma_desc->status);
21769+
21770+ sts.b_iso_in.framenum += dwc_ep->bInterval;
21771+ //(uint32_t)dma_ad += dwc_ep->data_per_frame;
21772+ dma_ad = (uint32_t)dma_ad + dwc_ep->data_per_frame;
21773+ dma_desc ++;
21774+ }
21775+
21776+ sts.b_iso_in.ioc = 1;
21777+ sts.b_iso_in.l = dwc_ep->proc_buf_num;
21778+
21779+ writel((uint32_t)dma_ad, &dma_desc->buf);
21780+ writel(sts.d32, &dma_desc->status);
21781+
21782+ dwc_ep->next_frame = sts.b_iso_in.framenum + dwc_ep->bInterval * 1;
21783+ }
21784+ dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1;
21785+}
21786+
21787+
21788+/**
21789+ * This function is to handle Iso EP transfer complete interrupt
21790+ * in case Iso out packet was dropped
21791+ *
21792+ * @param core_if Programming view of DWC_otg controller.
21793+ * @param dwc_ep The EP for wihich transfer complete was asserted
21794+ *
21795+ */
21796+static uint32_t handle_iso_out_pkt_dropped(dwc_otg_core_if_t *core_if, dwc_ep_t *dwc_ep)
21797+{
21798+ uint32_t dma_addr;
21799+ uint32_t drp_pkt;
21800+ uint32_t drp_pkt_cnt;
21801+ deptsiz_data_t deptsiz = { .d32 = 0 };
21802+ depctl_data_t depctl = { .d32 = 0 };
21803+ int i;
21804+
21805+ deptsiz.d32 = dwc_read_reg32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doeptsiz);
21806+
21807+ drp_pkt = dwc_ep->pkt_cnt - deptsiz.b.pktcnt;
21808+ drp_pkt_cnt = dwc_ep->pkt_per_frm - (drp_pkt % dwc_ep->pkt_per_frm);
21809+
21810+ /* Setting dropped packets status */
21811+ for(i = 0; i < drp_pkt_cnt; ++i) {
21812+ dwc_ep->pkt_info[drp_pkt].status = -ENODATA;
21813+ drp_pkt ++;
21814+ deptsiz.b.pktcnt--;
21815+ }
21816+
21817+
21818+ if(deptsiz.b.pktcnt > 0) {
21819+ deptsiz.b.xfersize = dwc_ep->xfer_len - (dwc_ep->pkt_cnt - deptsiz.b.pktcnt) * dwc_ep->maxpacket;
21820+ } else {
21821+ deptsiz.b.xfersize = 0;
21822+ deptsiz.b.pktcnt = 0;
21823+ }
21824+
21825+ dwc_write_reg32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doeptsiz, deptsiz.d32);
21826+
21827+ if(deptsiz.b.pktcnt > 0) {
21828+ if(dwc_ep->proc_buf_num) {
21829+ dma_addr = dwc_ep->dma_addr1 + dwc_ep->xfer_len - deptsiz.b.xfersize;
21830+ } else {
21831+ dma_addr = dwc_ep->dma_addr0 + dwc_ep->xfer_len - deptsiz.b.xfersize;;
21832+ }
21833+
21834+ VERIFY_PCD_DMA_ADDR(dma_addr);
21835+ dwc_write_reg32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doepdma, dma_addr);
21836+
21837+ /** Re-enable endpoint, clear nak */
21838+ depctl.d32 = 0;
21839+ depctl.b.epena = 1;
21840+ depctl.b.cnak = 1;
21841+
21842+ dwc_modify_reg32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doepctl,
21843+ depctl.d32,depctl.d32);
21844+ return 0;
21845+ } else {
21846+ return 1;
21847+ }
21848+}
21849+
21850+/**
21851+ * This function sets iso packets information(PTI mode)
21852+ *
21853+ * @param core_if Programming view of DWC_otg controller.
21854+ * @param ep The EP to start the transfer on.
21855+ *
21856+ */
21857+static uint32_t set_iso_pkts_info(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
21858+{
21859+ int i, j;
21860+ dma_addr_t dma_ad;
21861+ iso_pkt_info_t *packet_info = ep->pkt_info;
21862+ uint32_t offset;
21863+ uint32_t frame_data;
21864+ deptsiz_data_t deptsiz;
21865+
21866+ if(ep->proc_buf_num == 0) {
21867+ /** Buffer 0 descriptors setup */
21868+ dma_ad = ep->dma_addr0;
21869+ }
21870+ else {
21871+ /** Buffer 1 descriptors setup */
21872+ dma_ad = ep->dma_addr1;
21873+ }
21874+
21875+
21876+ if(ep->is_in) {
21877+ deptsiz.d32 = dwc_read_reg32(&core_if->dev_if->in_ep_regs[ep->num]->dieptsiz);
21878+ } else {
21879+ deptsiz.d32 = dwc_read_reg32(&core_if->dev_if->out_ep_regs[ep->num]->doeptsiz);
21880+ }
21881+
21882+ if(!deptsiz.b.xfersize) {
21883+ offset = 0;
21884+ for(i = 0; i < ep->pkt_cnt; i += ep->pkt_per_frm)
21885+ {
21886+ frame_data = ep->data_per_frame;
21887+ for(j = 0; j < ep->pkt_per_frm; ++j) {
21888+
21889+ /* Packet status - is not set as initially
21890+ * it is set to 0 and if packet was sent
21891+ successfully, status field will remain 0*/
21892+
21893+
21894+ /* Bytes has been transfered */
21895+ packet_info->length = (ep->maxpacket < frame_data) ?
21896+ ep->maxpacket : frame_data;
21897+
21898+ /* Received packet offset */
21899+ packet_info->offset = offset;
21900+ offset += packet_info->length;
21901+ frame_data -= packet_info->length;
21902+
21903+ packet_info ++;
21904+ }
21905+ }
21906+ return 1;
21907+ } else {
21908+ /* This is a workaround for in case of Transfer Complete with
21909+ * PktDrpSts interrupts merging - in this case Transfer complete
21910+ * interrupt for Isoc Out Endpoint is asserted without PktDrpSts
21911+ * set and with DOEPTSIZ register non zero. Investigations showed,
21912+ * that this happens when Out packet is dropped, but because of
21913+ * interrupts merging during first interrupt handling PktDrpSts
21914+ * bit is cleared and for next merged interrupts it is not reset.
21915+ * In this case SW hadles the interrupt as if PktDrpSts bit is set.
21916+ */
21917+ if(ep->is_in) {
21918+ return 1;
21919+ } else {
21920+ return handle_iso_out_pkt_dropped(core_if, ep);
21921+ }
21922+ }
21923+}
21924+
21925+/**
21926+ * This function is to handle Iso EP transfer complete interrupt
21927+ *
21928+ * @param ep The EP for which transfer complete was asserted
21929+ *
21930+ */
21931+static void complete_iso_ep(dwc_otg_pcd_ep_t *ep)
21932+{
21933+ dwc_otg_core_if_t *core_if = GET_CORE_IF(ep->pcd);
21934+ dwc_ep_t *dwc_ep = &ep->dwc_ep;
21935+ uint8_t is_last = 0;
21936+
21937+ if(core_if->dma_enable) {
21938+ if(core_if->dma_desc_enable) {
21939+ set_ddma_iso_pkts_info(core_if, dwc_ep);
21940+ reinit_ddma_iso_xfer(core_if, dwc_ep);
21941+ is_last = 1;
21942+ } else {
21943+ if(core_if->pti_enh_enable) {
21944+ if(set_iso_pkts_info(core_if, dwc_ep)) {
21945+ dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1;
21946+ dwc_otg_iso_ep_start_buf_transfer(core_if, dwc_ep);
21947+ is_last = 1;
21948+ }
21949+ } else {
21950+ set_current_pkt_info(core_if, dwc_ep);
21951+ if(dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
21952+ is_last = 1;
21953+ dwc_ep->cur_pkt = 0;
21954+ dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1;
21955+ if(dwc_ep->proc_buf_num) {
21956+ dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff1;
21957+ dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr1;
21958+ } else {
21959+ dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff0;
21960+ dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr0;
21961+ }
21962+
21963+ }
21964+ dwc_otg_iso_ep_start_frm_transfer(core_if, dwc_ep);
21965+ }
21966+ }
21967+ } else {
21968+ set_current_pkt_info(core_if, dwc_ep);
21969+ if(dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
21970+ is_last = 1;
21971+ dwc_ep->cur_pkt = 0;
21972+ dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1;
21973+ if(dwc_ep->proc_buf_num) {
21974+ dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff1;
21975+ dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr1;
21976+ } else {
21977+ dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff0;
21978+ dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr0;
21979+ }
21980+
21981+ }
21982+ dwc_otg_iso_ep_start_frm_transfer(core_if, dwc_ep);
21983+ }
21984+ if(is_last)
21985+ dwc_otg_iso_buffer_done(ep, ep->iso_req);
21986+}
21987+
21988+#endif //DWC_EN_ISOC
21989+
21990+
21991+/**
21992+ * This function handles EP0 Control transfers.
21993+ *
21994+ * The state of the control tranfers are tracked in
21995+ * <code>ep0state</code>.
21996+ */
21997+static void handle_ep0(dwc_otg_pcd_t *pcd)
21998+{
21999+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
22000+ dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
22001+ desc_sts_data_t desc_sts;
22002+ deptsiz0_data_t deptsiz;
22003+ uint32_t byte_count;
22004+
22005+#ifdef DEBUG_EP0
22006+ DWC_DEBUGPL(DBG_PCDV, "%s()\n", __func__);
22007+ print_ep0_state(pcd);
22008+#endif
22009+
22010+ switch (pcd->ep0state) {
22011+ case EP0_DISCONNECT:
22012+ break;
22013+
22014+ case EP0_IDLE:
22015+ pcd->request_config = 0;
22016+
22017+ pcd_setup(pcd);
22018+ break;
22019+
22020+ case EP0_IN_DATA_PHASE:
22021+#ifdef DEBUG_EP0
22022+ DWC_DEBUGPL(DBG_PCD, "DATA_IN EP%d-%s: type=%d, mps=%d\n",
22023+ ep0->dwc_ep.num, (ep0->dwc_ep.is_in ?"IN":"OUT"),
22024+ ep0->dwc_ep.type, ep0->dwc_ep.maxpacket);
22025+#endif
22026+
22027+ if (core_if->dma_enable != 0) {
22028+ /*
22029+ * For EP0 we can only program 1 packet at a time so we
22030+ * need to do the make calculations after each complete.
22031+ * Call write_packet to make the calculations, as in
22032+ * slave mode, and use those values to determine if we
22033+ * can complete.
22034+ */
22035+ if(core_if->dma_desc_enable == 0) {
22036+ deptsiz.d32 = dwc_read_reg32(&core_if->dev_if->in_ep_regs[0]->dieptsiz);
22037+ byte_count = ep0->dwc_ep.xfer_len - deptsiz.b.xfersize;
22038+ }
22039+ else {
22040+ desc_sts.d32 = readl(core_if->dev_if->in_desc_addr);
22041+ byte_count = ep0->dwc_ep.xfer_len - desc_sts.b.bytes;
22042+ }
22043+
22044+ ep0->dwc_ep.xfer_count += byte_count;
22045+ ep0->dwc_ep.xfer_buff += byte_count;
22046+ ep0->dwc_ep.dma_addr += byte_count;
22047+ }
22048+ if (ep0->dwc_ep.xfer_count < ep0->dwc_ep.total_len) {
22049+ dwc_otg_ep0_continue_transfer (GET_CORE_IF(pcd), &ep0->dwc_ep);
22050+ DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");
22051+ }
22052+ else if(ep0->dwc_ep.sent_zlp) {
22053+ dwc_otg_ep0_continue_transfer (GET_CORE_IF(pcd), &ep0->dwc_ep);
22054+ ep0->dwc_ep.sent_zlp = 0;
22055+ DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");
22056+ }
22057+ else {
22058+ ep0_complete_request(ep0);
22059+ DWC_DEBUGPL(DBG_PCD, "COMPLETE TRANSFER\n");
22060+ }
22061+ break;
22062+ case EP0_OUT_DATA_PHASE:
22063+#ifdef DEBUG_EP0
22064+ DWC_DEBUGPL(DBG_PCD, "DATA_OUT EP%d-%s: type=%d, mps=%d\n",
22065+ ep0->dwc_ep.num, (ep0->dwc_ep.is_in ?"IN":"OUT"),
22066+ ep0->dwc_ep.type, ep0->dwc_ep.maxpacket);
22067+#endif
22068+ if (core_if->dma_enable != 0) {
22069+ if(core_if->dma_desc_enable == 0) {
22070+ deptsiz.d32 = dwc_read_reg32(&core_if->dev_if->out_ep_regs[0]->doeptsiz);
22071+ byte_count = ep0->dwc_ep.maxpacket - deptsiz.b.xfersize;
22072+
22073+ //todo: invalidate cache & aligned buf patch on completion
22074+ dma_sync_single_for_device(NULL,ep0->dwc_ep.dma_addr,byte_count,DMA_FROM_DEVICE);
22075+ aligned_buf_patch_on_buf_dma_oep_completion(ep0,byte_count);
22076+ }
22077+ else {
22078+ desc_sts.d32 = readl(core_if->dev_if->out_desc_addr);
22079+ byte_count = ep0->dwc_ep.maxpacket - desc_sts.b.bytes;
22080+
22081+ //todo: invalidate cache & aligned buf patch on completion
22082+ //
22083+
22084+ }
22085+ ep0->dwc_ep.xfer_count += byte_count;
22086+ ep0->dwc_ep.xfer_buff += byte_count;
22087+ ep0->dwc_ep.dma_addr += byte_count;
22088+ }
22089+ if (ep0->dwc_ep.xfer_count < ep0->dwc_ep.total_len) {
22090+ dwc_otg_ep0_continue_transfer (GET_CORE_IF(pcd), &ep0->dwc_ep);
22091+ DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");
22092+ }
22093+ else if(ep0->dwc_ep.sent_zlp) {
22094+ dwc_otg_ep0_continue_transfer (GET_CORE_IF(pcd), &ep0->dwc_ep);
22095+ ep0->dwc_ep.sent_zlp = 0;
22096+ DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");
22097+ }
22098+ else {
22099+ ep0_complete_request(ep0);
22100+ DWC_DEBUGPL(DBG_PCD, "COMPLETE TRANSFER\n");
22101+ }
22102+ break;
22103+
22104+
22105+ case EP0_IN_STATUS_PHASE:
22106+ case EP0_OUT_STATUS_PHASE:
22107+ DWC_DEBUGPL(DBG_PCD, "CASE: EP0_STATUS\n");
22108+ ep0_complete_request(ep0);
22109+ pcd->ep0state = EP0_IDLE;
22110+ ep0->stopped = 1;
22111+ ep0->dwc_ep.is_in = 0; /* OUT for next SETUP */
22112+
22113+ /* Prepare for more SETUP Packets */
22114+ if(core_if->dma_enable) {
22115+ ep0_out_start(core_if, pcd);
22116+ }
22117+ break;
22118+
22119+ case EP0_STALL:
22120+ DWC_ERROR("EP0 STALLed, should not get here pcd_setup()\n");
22121+ break;
22122+ }
22123+#ifdef DEBUG_EP0
22124+ print_ep0_state(pcd);
22125+#endif
22126+}
22127+
22128+
22129+/**
22130+ * Restart transfer
22131+ */
22132+static void restart_transfer(dwc_otg_pcd_t *pcd, const uint32_t epnum)
22133+{
22134+ dwc_otg_core_if_t *core_if;
22135+ dwc_otg_dev_if_t *dev_if;
22136+ deptsiz_data_t dieptsiz = {.d32=0};
22137+ dwc_otg_pcd_ep_t *ep;
22138+
22139+ ep = get_in_ep(pcd, epnum);
22140+
22141+#ifdef DWC_EN_ISOC
22142+ if(ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) {
22143+ return;
22144+ }
22145+#endif /* DWC_EN_ISOC */
22146+
22147+ core_if = GET_CORE_IF(pcd);
22148+ dev_if = core_if->dev_if;
22149+
22150+ dieptsiz.d32 = dwc_read_reg32(&dev_if->in_ep_regs[epnum]->dieptsiz);
22151+
22152+ DWC_DEBUGPL(DBG_PCD,"xfer_buff=%p xfer_count=%0x xfer_len=%0x"
22153+ " stopped=%d\n", ep->dwc_ep.xfer_buff,
22154+ ep->dwc_ep.xfer_count, ep->dwc_ep.xfer_len ,
22155+ ep->stopped);
22156+ /*
22157+ * If xfersize is 0 and pktcnt in not 0, resend the last packet.
22158+ */
22159+ if (dieptsiz.b.pktcnt && dieptsiz.b.xfersize == 0 &&
22160+ ep->dwc_ep.start_xfer_buff != 0) {
22161+ if (ep->dwc_ep.total_len <= ep->dwc_ep.maxpacket) {
22162+ ep->dwc_ep.xfer_count = 0;
22163+ ep->dwc_ep.xfer_buff = ep->dwc_ep.start_xfer_buff;
22164+ ep->dwc_ep.xfer_len = ep->dwc_ep.xfer_count;
22165+ }
22166+ else {
22167+ ep->dwc_ep.xfer_count -= ep->dwc_ep.maxpacket;
22168+ /* convert packet size to dwords. */
22169+ ep->dwc_ep.xfer_buff -= ep->dwc_ep.maxpacket;
22170+ ep->dwc_ep.xfer_len = ep->dwc_ep.xfer_count;
22171+ }
22172+ ep->stopped = 0;
22173+ DWC_DEBUGPL(DBG_PCD,"xfer_buff=%p xfer_count=%0x "
22174+ "xfer_len=%0x stopped=%d\n",
22175+ ep->dwc_ep.xfer_buff,
22176+ ep->dwc_ep.xfer_count, ep->dwc_ep.xfer_len ,
22177+ ep->stopped
22178+ );
22179+ if (epnum == 0) {
22180+ dwc_otg_ep0_start_transfer(core_if, &ep->dwc_ep);
22181+ }
22182+ else {
22183+ dwc_otg_ep_start_transfer(core_if, &ep->dwc_ep);
22184+ }
22185+ }
22186+}
22187+
22188+
22189+/**
22190+ * handle the IN EP disable interrupt.
22191+ */
22192+static inline void handle_in_ep_disable_intr(dwc_otg_pcd_t *pcd,
22193+ const uint32_t epnum)
22194+{
22195+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
22196+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
22197+ deptsiz_data_t dieptsiz = {.d32=0};
22198+ dctl_data_t dctl = {.d32=0};
22199+ dwc_otg_pcd_ep_t *ep;
22200+ dwc_ep_t *dwc_ep;
22201+
22202+ ep = get_in_ep(pcd, epnum);
22203+ dwc_ep = &ep->dwc_ep;
22204+
22205+ if(dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
22206+ dwc_otg_flush_tx_fifo(core_if, dwc_ep->tx_fifo_num);
22207+ return;
22208+ }
22209+
22210+ DWC_DEBUGPL(DBG_PCD,"diepctl%d=%0x\n", epnum,
22211+ dwc_read_reg32(&dev_if->in_ep_regs[epnum]->diepctl));
22212+ dieptsiz.d32 = dwc_read_reg32(&dev_if->in_ep_regs[epnum]->dieptsiz);
22213+
22214+ DWC_DEBUGPL(DBG_ANY, "pktcnt=%d size=%d\n",
22215+ dieptsiz.b.pktcnt,
22216+ dieptsiz.b.xfersize);
22217+
22218+ if (ep->stopped) {
22219+ /* Flush the Tx FIFO */
22220+ dwc_otg_flush_tx_fifo(core_if, dwc_ep->tx_fifo_num);
22221+ /* Clear the Global IN NP NAK */
22222+ dctl.d32 = 0;
22223+ dctl.b.cgnpinnak = 1;
22224+ dwc_modify_reg32(&dev_if->dev_global_regs->dctl,
22225+ dctl.d32, 0);
22226+ /* Restart the transaction */
22227+ if (dieptsiz.b.pktcnt != 0 ||
22228+ dieptsiz.b.xfersize != 0) {
22229+ restart_transfer(pcd, epnum);
22230+ }
22231+ }
22232+ else {
22233+ /* Restart the transaction */
22234+ if (dieptsiz.b.pktcnt != 0 ||
22235+ dieptsiz.b.xfersize != 0) {
22236+ restart_transfer(pcd, epnum);
22237+ }
22238+ DWC_DEBUGPL(DBG_ANY, "STOPPED!!!\n");
22239+ }
22240+}
22241+
22242+/**
22243+ * Handler for the IN EP timeout handshake interrupt.
22244+ */
22245+static inline void handle_in_ep_timeout_intr(dwc_otg_pcd_t *pcd,
22246+ const uint32_t epnum)
22247+{
22248+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
22249+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
22250+
22251+#ifdef DEBUG
22252+ deptsiz_data_t dieptsiz = {.d32=0};
22253+ uint32_t num = 0;
22254+#endif
22255+ dctl_data_t dctl = {.d32=0};
22256+ dwc_otg_pcd_ep_t *ep;
22257+
22258+ gintmsk_data_t intr_mask = {.d32 = 0};
22259+
22260+ ep = get_in_ep(pcd, epnum);
22261+
22262+ /* Disable the NP Tx Fifo Empty Interrrupt */
22263+ if (!core_if->dma_enable) {
22264+ intr_mask.b.nptxfempty = 1;
22265+ dwc_modify_reg32(&core_if->core_global_regs->gintmsk, intr_mask.d32, 0);
22266+ }
22267+ /** @todo NGS Check EP type.
22268+ * Implement for Periodic EPs */
22269+ /*
22270+ * Non-periodic EP
22271+ */
22272+ /* Enable the Global IN NAK Effective Interrupt */
22273+ intr_mask.b.ginnakeff = 1;
22274+ dwc_modify_reg32(&core_if->core_global_regs->gintmsk,
22275+ 0, intr_mask.d32);
22276+
22277+ /* Set Global IN NAK */
22278+ dctl.b.sgnpinnak = 1;
22279+ dwc_modify_reg32(&dev_if->dev_global_regs->dctl,
22280+ dctl.d32, dctl.d32);
22281+
22282+ ep->stopped = 1;
22283+
22284+#ifdef DEBUG
22285+ dieptsiz.d32 = dwc_read_reg32(&dev_if->in_ep_regs[num]->dieptsiz);
22286+ DWC_DEBUGPL(DBG_ANY, "pktcnt=%d size=%d\n",
22287+ dieptsiz.b.pktcnt,
22288+ dieptsiz.b.xfersize);
22289+#endif
22290+
22291+#ifdef DISABLE_PERIODIC_EP
22292+ /*
22293+ * Set the NAK bit for this EP to
22294+ * start the disable process.
22295+ */
22296+ diepctl.d32 = 0;
22297+ diepctl.b.snak = 1;
22298+ dwc_modify_reg32(&dev_if->in_ep_regs[num]->diepctl, diepctl.d32, diepctl.d32);
22299+ ep->disabling = 1;
22300+ ep->stopped = 1;
22301+#endif
22302+}
22303+
22304+/**
22305+ * Handler for the IN EP NAK interrupt.
22306+ */
22307+static inline int32_t handle_in_ep_nak_intr(dwc_otg_pcd_t *pcd,
22308+ const uint32_t epnum)
22309+{
22310+ /** @todo implement ISR */
22311+ dwc_otg_core_if_t* core_if;
22312+ diepmsk_data_t intr_mask = { .d32 = 0};
22313+
22314+ DWC_PRINT("INTERRUPT Handler not implemented for %s\n", "IN EP NAK");
22315+ core_if = GET_CORE_IF(pcd);
22316+ intr_mask.b.nak = 1;
22317+
22318+ if(core_if->multiproc_int_enable) {
22319+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->diepeachintmsk[epnum],
22320+ intr_mask.d32, 0);
22321+ } else {
22322+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->diepmsk,
22323+ intr_mask.d32, 0);
22324+ }
22325+
22326+ return 1;
22327+}
22328+
22329+/**
22330+ * Handler for the OUT EP Babble interrupt.
22331+ */
22332+static inline int32_t handle_out_ep_babble_intr(dwc_otg_pcd_t *pcd,
22333+ const uint32_t epnum)
22334+{
22335+ /** @todo implement ISR */
22336+ dwc_otg_core_if_t* core_if;
22337+ doepmsk_data_t intr_mask = { .d32 = 0};
22338+
22339+ DWC_PRINT("INTERRUPT Handler not implemented for %s\n", "OUT EP Babble");
22340+ core_if = GET_CORE_IF(pcd);
22341+ intr_mask.b.babble = 1;
22342+
22343+ if(core_if->multiproc_int_enable) {
22344+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->doepeachintmsk[epnum],
22345+ intr_mask.d32, 0);
22346+ } else {
22347+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->doepmsk,
22348+ intr_mask.d32, 0);
22349+ }
22350+
22351+ return 1;
22352+}
22353+
22354+/**
22355+ * Handler for the OUT EP NAK interrupt.
22356+ */
22357+static inline int32_t handle_out_ep_nak_intr(dwc_otg_pcd_t *pcd,
22358+ const uint32_t epnum)
22359+{
22360+ /** @todo implement ISR */
22361+ dwc_otg_core_if_t* core_if;
22362+ doepmsk_data_t intr_mask = { .d32 = 0};
22363+
22364+ DWC_PRINT("INTERRUPT Handler not implemented for %s\n", "OUT EP NAK");
22365+ core_if = GET_CORE_IF(pcd);
22366+ intr_mask.b.nak = 1;
22367+
22368+ if(core_if->multiproc_int_enable) {
22369+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->doepeachintmsk[epnum],
22370+ intr_mask.d32, 0);
22371+ } else {
22372+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->doepmsk,
22373+ intr_mask.d32, 0);
22374+ }
22375+
22376+ return 1;
22377+}
22378+
22379+/**
22380+ * Handler for the OUT EP NYET interrupt.
22381+ */
22382+static inline int32_t handle_out_ep_nyet_intr(dwc_otg_pcd_t *pcd,
22383+ const uint32_t epnum)
22384+{
22385+ /** @todo implement ISR */
22386+ dwc_otg_core_if_t* core_if;
22387+ doepmsk_data_t intr_mask = { .d32 = 0};
22388+
22389+ DWC_PRINT("INTERRUPT Handler not implemented for %s\n", "OUT EP NYET");
22390+ core_if = GET_CORE_IF(pcd);
22391+ intr_mask.b.nyet = 1;
22392+
22393+ if(core_if->multiproc_int_enable) {
22394+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->doepeachintmsk[epnum],
22395+ intr_mask.d32, 0);
22396+ } else {
22397+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->doepmsk,
22398+ intr_mask.d32, 0);
22399+ }
22400+
22401+ return 1;
22402+}
22403+
22404+/**
22405+ * This interrupt indicates that an IN EP has a pending Interrupt.
22406+ * The sequence for handling the IN EP interrupt is shown below:
22407+ * -# Read the Device All Endpoint Interrupt register
22408+ * -# Repeat the following for each IN EP interrupt bit set (from
22409+ * LSB to MSB).
22410+ * -# Read the Device Endpoint Interrupt (DIEPINTn) register
22411+ * -# If "Transfer Complete" call the request complete function
22412+ * -# If "Endpoint Disabled" complete the EP disable procedure.
22413+ * -# If "AHB Error Interrupt" log error
22414+ * -# If "Time-out Handshake" log error
22415+ * -# If "IN Token Received when TxFIFO Empty" write packet to Tx
22416+ * FIFO.
22417+ * -# If "IN Token EP Mismatch" (disable, this is handled by EP
22418+ * Mismatch Interrupt)
22419+ */
22420+static int32_t dwc_otg_pcd_handle_in_ep_intr(dwc_otg_pcd_t *pcd)
22421+{
22422+#define CLEAR_IN_EP_INTR(__core_if,__epnum,__intr) \
22423+do { \
22424+ diepint_data_t diepint = {.d32=0}; \
22425+ diepint.b.__intr = 1; \
22426+ dwc_write_reg32(&__core_if->dev_if->in_ep_regs[__epnum]->diepint, \
22427+ diepint.d32); \
22428+} while (0)
22429+
22430+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
22431+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
22432+ diepint_data_t diepint = {.d32=0};
22433+ dctl_data_t dctl = {.d32=0};
22434+ depctl_data_t depctl = {.d32=0};
22435+ uint32_t ep_intr;
22436+ uint32_t epnum = 0;
22437+ dwc_otg_pcd_ep_t *ep;
22438+ dwc_ep_t *dwc_ep;
22439+ gintmsk_data_t intr_mask = {.d32 = 0};
22440+
22441+
22442+
22443+ DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, pcd);
22444+
22445+ /* Read in the device interrupt bits */
22446+ ep_intr = dwc_otg_read_dev_all_in_ep_intr(core_if);
22447+
22448+ /* Service the Device IN interrupts for each endpoint */
22449+ while(ep_intr) {
22450+ if (ep_intr&0x1) {
22451+ uint32_t empty_msk;
22452+ /* Get EP pointer */
22453+ ep = get_in_ep(pcd, epnum);
22454+ dwc_ep = &ep->dwc_ep;
22455+
22456+ depctl.d32 = dwc_read_reg32(&dev_if->in_ep_regs[epnum]->diepctl);
22457+ empty_msk = dwc_read_reg32(&dev_if->dev_global_regs->dtknqr4_fifoemptymsk);
22458+
22459+ DWC_DEBUGPL(DBG_PCDV,
22460+ "IN EP INTERRUPT - %d\nepmty_msk - %8x diepctl - %8x\n",
22461+ epnum,
22462+ empty_msk,
22463+ depctl.d32);
22464+
22465+ DWC_DEBUGPL(DBG_PCD,
22466+ "EP%d-%s: type=%d, mps=%d\n",
22467+ dwc_ep->num, (dwc_ep->is_in ?"IN":"OUT"),
22468+ dwc_ep->type, dwc_ep->maxpacket);
22469+
22470+ diepint.d32 = dwc_otg_read_dev_in_ep_intr(core_if, dwc_ep);
22471+
22472+ DWC_DEBUGPL(DBG_PCDV, "EP %d Interrupt Register - 0x%x\n", epnum, diepint.d32);
22473+ /* Transfer complete */
22474+ if (diepint.b.xfercompl) {
22475+ /* Disable the NP Tx FIFO Empty
22476+ * Interrrupt */
22477+ if(core_if->en_multiple_tx_fifo == 0) {
22478+ intr_mask.b.nptxfempty = 1;
22479+ dwc_modify_reg32(&core_if->core_global_regs->gintmsk, intr_mask.d32, 0);
22480+ }
22481+ else {
22482+ /* Disable the Tx FIFO Empty Interrupt for this EP */
22483+ uint32_t fifoemptymsk = 0x1 << dwc_ep->num;
22484+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
22485+ fifoemptymsk, 0);
22486+ }
22487+ /* Clear the bit in DIEPINTn for this interrupt */
22488+ CLEAR_IN_EP_INTR(core_if,epnum,xfercompl);
22489+
22490+ /* Complete the transfer */
22491+ if (epnum == 0) {
22492+ handle_ep0(pcd);
22493+ }
22494+#ifdef DWC_EN_ISOC
22495+ else if(dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
22496+ if(!ep->stopped)
22497+ complete_iso_ep(ep);
22498+ }
22499+#endif //DWC_EN_ISOC
22500+ else {
22501+
22502+ complete_ep(ep);
22503+ }
22504+ }
22505+ /* Endpoint disable */
22506+ if (diepint.b.epdisabled) {
22507+ DWC_DEBUGPL(DBG_ANY,"EP%d IN disabled\n", epnum);
22508+ handle_in_ep_disable_intr(pcd, epnum);
22509+
22510+ /* Clear the bit in DIEPINTn for this interrupt */
22511+ CLEAR_IN_EP_INTR(core_if,epnum,epdisabled);
22512+ }
22513+ /* AHB Error */
22514+ if (diepint.b.ahberr) {
22515+ DWC_DEBUGPL(DBG_ANY,"EP%d IN AHB Error\n", epnum);
22516+ /* Clear the bit in DIEPINTn for this interrupt */
22517+ CLEAR_IN_EP_INTR(core_if,epnum,ahberr);
22518+ }
22519+ /* TimeOUT Handshake (non-ISOC IN EPs) */
22520+ if (diepint.b.timeout) {
22521+ DWC_DEBUGPL(DBG_ANY,"EP%d IN Time-out\n", epnum);
22522+ handle_in_ep_timeout_intr(pcd, epnum);
22523+
22524+ CLEAR_IN_EP_INTR(core_if,epnum,timeout);
22525+ }
22526+ /** IN Token received with TxF Empty */
22527+ if (diepint.b.intktxfemp) {
22528+ DWC_DEBUGPL(DBG_ANY,"EP%d IN TKN TxFifo Empty\n",
22529+ epnum);
22530+ if (!ep->stopped && epnum != 0) {
22531+
22532+ diepmsk_data_t diepmsk = { .d32 = 0};
22533+ diepmsk.b.intktxfemp = 1;
22534+
22535+ if(core_if->multiproc_int_enable) {
22536+ dwc_modify_reg32(&dev_if->dev_global_regs->diepeachintmsk[epnum],
22537+ diepmsk.d32, 0);
22538+ } else {
22539+ dwc_modify_reg32(&dev_if->dev_global_regs->diepmsk, diepmsk.d32, 0);
22540+ }
22541+ start_next_request(ep);
22542+ }
22543+ else if(core_if->dma_desc_enable && epnum == 0 &&
22544+ pcd->ep0state == EP0_OUT_STATUS_PHASE) {
22545+ // EP0 IN set STALL
22546+ depctl.d32 = dwc_read_reg32(&dev_if->in_ep_regs[epnum]->diepctl);
22547+
22548+ /* set the disable and stall bits */
22549+ if (depctl.b.epena) {
22550+ depctl.b.epdis = 1;
22551+ }
22552+ depctl.b.stall = 1;
22553+ dwc_write_reg32(&dev_if->in_ep_regs[epnum]->diepctl, depctl.d32);
22554+ }
22555+ CLEAR_IN_EP_INTR(core_if,epnum,intktxfemp);
22556+ }
22557+ /** IN Token Received with EP mismatch */
22558+ if (diepint.b.intknepmis) {
22559+ DWC_DEBUGPL(DBG_ANY,"EP%d IN TKN EP Mismatch\n", epnum);
22560+ CLEAR_IN_EP_INTR(core_if,epnum,intknepmis);
22561+ }
22562+ /** IN Endpoint NAK Effective */
22563+ if (diepint.b.inepnakeff) {
22564+ DWC_DEBUGPL(DBG_ANY,"EP%d IN EP NAK Effective\n", epnum);
22565+ /* Periodic EP */
22566+ if (ep->disabling) {
22567+ depctl.d32 = 0;
22568+ depctl.b.snak = 1;
22569+ depctl.b.epdis = 1;
22570+ dwc_modify_reg32(&dev_if->in_ep_regs[epnum]->diepctl, depctl.d32, depctl.d32);
22571+ }
22572+ CLEAR_IN_EP_INTR(core_if,epnum,inepnakeff);
22573+
22574+ }
22575+
22576+ /** IN EP Tx FIFO Empty Intr */
22577+ if (diepint.b.emptyintr) {
22578+ DWC_DEBUGPL(DBG_ANY,"EP%d Tx FIFO Empty Intr \n", epnum);
22579+ write_empty_tx_fifo(pcd, epnum);
22580+
22581+ CLEAR_IN_EP_INTR(core_if,epnum,emptyintr);
22582+
22583+ }
22584+
22585+ /** IN EP BNA Intr */
22586+ if (diepint.b.bna) {
22587+ CLEAR_IN_EP_INTR(core_if,epnum,bna);
22588+ if(core_if->dma_desc_enable) {
22589+#ifdef DWC_EN_ISOC
22590+ if(dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
22591+ /*
22592+ * This checking is performed to prevent first "false" BNA
22593+ * handling occuring right after reconnect
22594+ */
22595+ if(dwc_ep->next_frame != 0xffffffff)
22596+ dwc_otg_pcd_handle_iso_bna(ep);
22597+ }
22598+ else
22599+#endif //DWC_EN_ISOC
22600+ {
22601+ dctl.d32 = dwc_read_reg32(&dev_if->dev_global_regs->dctl);
22602+
22603+ /* If Global Continue on BNA is disabled - disable EP */
22604+ if(!dctl.b.gcontbna) {
22605+ depctl.d32 = 0;
22606+ depctl.b.snak = 1;
22607+ depctl.b.epdis = 1;
22608+ dwc_modify_reg32(&dev_if->in_ep_regs[epnum]->diepctl, depctl.d32, depctl.d32);
22609+ } else {
22610+ start_next_request(ep);
22611+ }
22612+ }
22613+ }
22614+ }
22615+ /* NAK Interrutp */
22616+ if (diepint.b.nak) {
22617+ DWC_DEBUGPL(DBG_ANY,"EP%d IN NAK Interrupt\n", epnum);
22618+ handle_in_ep_nak_intr(pcd, epnum);
22619+
22620+ CLEAR_IN_EP_INTR(core_if,epnum,nak);
22621+ }
22622+ }
22623+ epnum++;
22624+ ep_intr >>=1;
22625+ }
22626+
22627+ return 1;
22628+#undef CLEAR_IN_EP_INTR
22629+}
22630+
22631+/**
22632+ * This interrupt indicates that an OUT EP has a pending Interrupt.
22633+ * The sequence for handling the OUT EP interrupt is shown below:
22634+ * -# Read the Device All Endpoint Interrupt register
22635+ * -# Repeat the following for each OUT EP interrupt bit set (from
22636+ * LSB to MSB).
22637+ * -# Read the Device Endpoint Interrupt (DOEPINTn) register
22638+ * -# If "Transfer Complete" call the request complete function
22639+ * -# If "Endpoint Disabled" complete the EP disable procedure.
22640+ * -# If "AHB Error Interrupt" log error
22641+ * -# If "Setup Phase Done" process Setup Packet (See Standard USB
22642+ * Command Processing)
22643+ */
22644+static int32_t dwc_otg_pcd_handle_out_ep_intr(dwc_otg_pcd_t *pcd)
22645+{
22646+#define CLEAR_OUT_EP_INTR(__core_if,__epnum,__intr) \
22647+do { \
22648+ doepint_data_t doepint = {.d32=0}; \
22649+ doepint.b.__intr = 1; \
22650+ dwc_write_reg32(&__core_if->dev_if->out_ep_regs[__epnum]->doepint, \
22651+ doepint.d32); \
22652+} while (0)
22653+
22654+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
22655+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
22656+ uint32_t ep_intr;
22657+ doepint_data_t doepint = {.d32=0};
22658+ dctl_data_t dctl = {.d32=0};
22659+ depctl_data_t doepctl = {.d32=0};
22660+ uint32_t epnum = 0;
22661+ dwc_otg_pcd_ep_t *ep;
22662+ dwc_ep_t *dwc_ep;
22663+
22664+ DWC_DEBUGPL(DBG_PCDV, "%s()\n", __func__);
22665+
22666+ /* Read in the device interrupt bits */
22667+ ep_intr = dwc_otg_read_dev_all_out_ep_intr(core_if);
22668+
22669+ while(ep_intr) {
22670+ if (ep_intr&0x1) {
22671+ /* Get EP pointer */
22672+ ep = get_out_ep(pcd, epnum);
22673+ dwc_ep = &ep->dwc_ep;
22674+
22675+#ifdef VERBOSE
22676+ DWC_DEBUGPL(DBG_PCDV,
22677+ "EP%d-%s: type=%d, mps=%d\n",
22678+ dwc_ep->num, (dwc_ep->is_in ?"IN":"OUT"),
22679+ dwc_ep->type, dwc_ep->maxpacket);
22680+#endif
22681+ doepint.d32 = dwc_otg_read_dev_out_ep_intr(core_if, dwc_ep);
22682+
22683+ /* Transfer complete */
22684+ if (doepint.b.xfercompl) {
22685+
22686+ if (epnum == 0) {
22687+ /* Clear the bit in DOEPINTn for this interrupt */
22688+ CLEAR_OUT_EP_INTR(core_if,epnum,xfercompl);
22689+ if(core_if->dma_desc_enable == 0 || pcd->ep0state != EP0_IDLE)
22690+ handle_ep0(pcd);
22691+#ifdef DWC_EN_ISOC
22692+ } else if(dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
22693+ if (doepint.b.pktdrpsts == 0) {
22694+ /* Clear the bit in DOEPINTn for this interrupt */
22695+ CLEAR_OUT_EP_INTR(core_if,epnum,xfercompl);
22696+ complete_iso_ep(ep);
22697+ } else {
22698+
22699+ doepint_data_t doepint = {.d32=0};
22700+ doepint.b.xfercompl = 1;
22701+ doepint.b.pktdrpsts = 1;
22702+ dwc_write_reg32(&core_if->dev_if->out_ep_regs[epnum]->doepint,
22703+ doepint.d32);
22704+ if(handle_iso_out_pkt_dropped(core_if,dwc_ep)) {
22705+ complete_iso_ep(ep);
22706+ }
22707+ }
22708+#endif //DWC_EN_ISOC
22709+ } else {
22710+ /* Clear the bit in DOEPINTn for this interrupt */
22711+ CLEAR_OUT_EP_INTR(core_if,epnum,xfercompl);
22712+ complete_ep(ep);
22713+ }
22714+
22715+ }
22716+
22717+ /* Endpoint disable */
22718+ if (doepint.b.epdisabled) {
22719+
22720+ /* Clear the bit in DOEPINTn for this interrupt */
22721+ CLEAR_OUT_EP_INTR(core_if,epnum,epdisabled);
22722+ }
22723+ /* AHB Error */
22724+ if (doepint.b.ahberr) {
22725+ DWC_DEBUGPL(DBG_PCD,"EP%d OUT AHB Error\n", epnum);
22726+ DWC_DEBUGPL(DBG_PCD,"EP DMA REG %d \n", core_if->dev_if->out_ep_regs[epnum]->doepdma);
22727+ CLEAR_OUT_EP_INTR(core_if,epnum,ahberr);
22728+ }
22729+ /* Setup Phase Done (contorl EPs) */
22730+ if (doepint.b.setup) {
22731+#ifdef DEBUG_EP0
22732+ DWC_DEBUGPL(DBG_PCD,"EP%d SETUP Done\n",
22733+ epnum);
22734+#endif
22735+ CLEAR_OUT_EP_INTR(core_if,epnum,setup);
22736+
22737+ handle_ep0(pcd);
22738+ }
22739+
22740+ /** OUT EP BNA Intr */
22741+ if (doepint.b.bna) {
22742+ CLEAR_OUT_EP_INTR(core_if,epnum,bna);
22743+ if(core_if->dma_desc_enable) {
22744+#ifdef DWC_EN_ISOC
22745+ if(dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
22746+ /*
22747+ * This checking is performed to prevent first "false" BNA
22748+ * handling occuring right after reconnect
22749+ */
22750+ if(dwc_ep->next_frame != 0xffffffff)
22751+ dwc_otg_pcd_handle_iso_bna(ep);
22752+ }
22753+ else
22754+#endif //DWC_EN_ISOC
22755+ {
22756+ dctl.d32 = dwc_read_reg32(&dev_if->dev_global_regs->dctl);
22757+
22758+ /* If Global Continue on BNA is disabled - disable EP*/
22759+ if(!dctl.b.gcontbna) {
22760+ doepctl.d32 = 0;
22761+ doepctl.b.snak = 1;
22762+ doepctl.b.epdis = 1;
22763+ dwc_modify_reg32(&dev_if->out_ep_regs[epnum]->doepctl, doepctl.d32, doepctl.d32);
22764+ } else {
22765+ start_next_request(ep);
22766+ }
22767+ }
22768+ }
22769+ }
22770+ if (doepint.b.stsphsercvd) {
22771+ CLEAR_OUT_EP_INTR(core_if,epnum,stsphsercvd);
22772+ if(core_if->dma_desc_enable) {
22773+ do_setup_in_status_phase(pcd);
22774+ }
22775+ }
22776+ /* Babble Interrutp */
22777+ if (doepint.b.babble) {
22778+ DWC_DEBUGPL(DBG_ANY,"EP%d OUT Babble\n", epnum);
22779+ handle_out_ep_babble_intr(pcd, epnum);
22780+
22781+ CLEAR_OUT_EP_INTR(core_if,epnum,babble);
22782+ }
22783+ /* NAK Interrutp */
22784+ if (doepint.b.nak) {
22785+ DWC_DEBUGPL(DBG_ANY,"EP%d OUT NAK\n", epnum);
22786+ handle_out_ep_nak_intr(pcd, epnum);
22787+
22788+ CLEAR_OUT_EP_INTR(core_if,epnum,nak);
22789+ }
22790+ /* NYET Interrutp */
22791+ if (doepint.b.nyet) {
22792+ DWC_DEBUGPL(DBG_ANY,"EP%d OUT NYET\n", epnum);
22793+ handle_out_ep_nyet_intr(pcd, epnum);
22794+
22795+ CLEAR_OUT_EP_INTR(core_if,epnum,nyet);
22796+ }
22797+ }
22798+
22799+ epnum++;
22800+ ep_intr >>=1;
22801+ }
22802+
22803+ return 1;
22804+
22805+#undef CLEAR_OUT_EP_INTR
22806+}
22807+
22808+
22809+/**
22810+ * Incomplete ISO IN Transfer Interrupt.
22811+ * This interrupt indicates one of the following conditions occurred
22812+ * while transmitting an ISOC transaction.
22813+ * - Corrupted IN Token for ISOC EP.
22814+ * - Packet not complete in FIFO.
22815+ * The follow actions will be taken:
22816+ * -# Determine the EP
22817+ * -# Set incomplete flag in dwc_ep structure
22818+ * -# Disable EP; when "Endpoint Disabled" interrupt is received
22819+ * Flush FIFO
22820+ */
22821+int32_t dwc_otg_pcd_handle_incomplete_isoc_in_intr(dwc_otg_pcd_t *pcd)
22822+{
22823+ gintsts_data_t gintsts;
22824+
22825+
22826+#ifdef DWC_EN_ISOC
22827+ dwc_otg_dev_if_t *dev_if;
22828+ deptsiz_data_t deptsiz = { .d32 = 0};
22829+ depctl_data_t depctl = { .d32 = 0};
22830+ dsts_data_t dsts = { .d32 = 0};
22831+ dwc_ep_t *dwc_ep;
22832+ int i;
22833+
22834+ dev_if = GET_CORE_IF(pcd)->dev_if;
22835+
22836+ for(i = 1; i <= dev_if->num_in_eps; ++i) {
22837+ dwc_ep = &pcd->in_ep[i].dwc_ep;
22838+ if(dwc_ep->active &&
22839+ dwc_ep->type == USB_ENDPOINT_XFER_ISOC)
22840+ {
22841+ deptsiz.d32 = dwc_read_reg32(&dev_if->in_ep_regs[i]->dieptsiz);
22842+ depctl.d32 = dwc_read_reg32(&dev_if->in_ep_regs[i]->diepctl);
22843+
22844+ if(depctl.b.epdis && deptsiz.d32) {
22845+ set_current_pkt_info(GET_CORE_IF(pcd), dwc_ep);
22846+ if(dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
22847+ dwc_ep->cur_pkt = 0;
22848+ dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1;
22849+
22850+ if(dwc_ep->proc_buf_num) {
22851+ dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff1;
22852+ dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr1;
22853+ } else {
22854+ dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff0;
22855+ dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr0;
22856+ }
22857+
22858+ }
22859+
22860+ dsts.d32 = dwc_read_reg32(&GET_CORE_IF(pcd)->dev_if->dev_global_regs->dsts);
22861+ dwc_ep->next_frame = dsts.b.soffn;
22862+
22863+ dwc_otg_iso_ep_start_frm_transfer(GET_CORE_IF(pcd), dwc_ep);
22864+ }
22865+ }
22866+ }
22867+
22868+#else
22869+ gintmsk_data_t intr_mask = { .d32 = 0};
22870+ DWC_PRINT("INTERRUPT Handler not implemented for %s\n",
22871+ "IN ISOC Incomplete");
22872+
22873+ intr_mask.b.incomplisoin = 1;
22874+ dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
22875+ intr_mask.d32, 0);
22876+#endif //DWC_EN_ISOC
22877+
22878+ /* Clear interrupt */
22879+ gintsts.d32 = 0;
22880+ gintsts.b.incomplisoin = 1;
22881+ dwc_write_reg32 (&GET_CORE_IF(pcd)->core_global_regs->gintsts,
22882+ gintsts.d32);
22883+
22884+ return 1;
22885+}
22886+
22887+/**
22888+ * Incomplete ISO OUT Transfer Interrupt.
22889+ *
22890+ * This interrupt indicates that the core has dropped an ISO OUT
22891+ * packet. The following conditions can be the cause:
22892+ * - FIFO Full, the entire packet would not fit in the FIFO.
22893+ * - CRC Error
22894+ * - Corrupted Token
22895+ * The follow actions will be taken:
22896+ * -# Determine the EP
22897+ * -# Set incomplete flag in dwc_ep structure
22898+ * -# Read any data from the FIFO
22899+ * -# Disable EP. when "Endpoint Disabled" interrupt is received
22900+ * re-enable EP.
22901+ */
22902+int32_t dwc_otg_pcd_handle_incomplete_isoc_out_intr(dwc_otg_pcd_t *pcd)
22903+{
22904+ /* @todo implement ISR */
22905+ gintsts_data_t gintsts;
22906+
22907+#ifdef DWC_EN_ISOC
22908+ dwc_otg_dev_if_t *dev_if;
22909+ deptsiz_data_t deptsiz = { .d32 = 0};
22910+ depctl_data_t depctl = { .d32 = 0};
22911+ dsts_data_t dsts = { .d32 = 0};
22912+ dwc_ep_t *dwc_ep;
22913+ int i;
22914+
22915+ dev_if = GET_CORE_IF(pcd)->dev_if;
22916+
22917+ for(i = 1; i <= dev_if->num_out_eps; ++i) {
22918+ dwc_ep = &pcd->in_ep[i].dwc_ep;
22919+ if(pcd->out_ep[i].dwc_ep.active &&
22920+ pcd->out_ep[i].dwc_ep.type == USB_ENDPOINT_XFER_ISOC)
22921+ {
22922+ deptsiz.d32 = dwc_read_reg32(&dev_if->out_ep_regs[i]->doeptsiz);
22923+ depctl.d32 = dwc_read_reg32(&dev_if->out_ep_regs[i]->doepctl);
22924+
22925+ if(depctl.b.epdis && deptsiz.d32) {
22926+ set_current_pkt_info(GET_CORE_IF(pcd), &pcd->out_ep[i].dwc_ep);
22927+ if(dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
22928+ dwc_ep->cur_pkt = 0;
22929+ dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1;
22930+
22931+ if(dwc_ep->proc_buf_num) {
22932+ dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff1;
22933+ dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr1;
22934+ } else {
22935+ dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff0;
22936+ dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr0;
22937+ }
22938+
22939+ }
22940+
22941+ dsts.d32 = dwc_read_reg32(&GET_CORE_IF(pcd)->dev_if->dev_global_regs->dsts);
22942+ dwc_ep->next_frame = dsts.b.soffn;
22943+
22944+ dwc_otg_iso_ep_start_frm_transfer(GET_CORE_IF(pcd), dwc_ep);
22945+ }
22946+ }
22947+ }
22948+#else
22949+ /** @todo implement ISR */
22950+ gintmsk_data_t intr_mask = { .d32 = 0};
22951+
22952+ DWC_PRINT("INTERRUPT Handler not implemented for %s\n",
22953+ "OUT ISOC Incomplete");
22954+
22955+ intr_mask.b.incomplisoout = 1;
22956+ dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
22957+ intr_mask.d32, 0);
22958+
22959+#endif // DWC_EN_ISOC
22960+
22961+ /* Clear interrupt */
22962+ gintsts.d32 = 0;
22963+ gintsts.b.incomplisoout = 1;
22964+ dwc_write_reg32 (&GET_CORE_IF(pcd)->core_global_regs->gintsts,
22965+ gintsts.d32);
22966+
22967+ return 1;
22968+}
22969+
22970+/**
22971+ * This function handles the Global IN NAK Effective interrupt.
22972+ *
22973+ */
22974+int32_t dwc_otg_pcd_handle_in_nak_effective(dwc_otg_pcd_t *pcd)
22975+{
22976+ dwc_otg_dev_if_t *dev_if = GET_CORE_IF(pcd)->dev_if;
22977+ depctl_data_t diepctl = { .d32 = 0};
22978+ depctl_data_t diepctl_rd = { .d32 = 0};
22979+ gintmsk_data_t intr_mask = { .d32 = 0};
22980+ gintsts_data_t gintsts;
22981+ int i;
22982+
22983+ DWC_DEBUGPL(DBG_PCD, "Global IN NAK Effective\n");
22984+
22985+ /* Disable all active IN EPs */
22986+ diepctl.b.epdis = 1;
22987+ diepctl.b.snak = 1;
22988+
22989+ for (i=0; i <= dev_if->num_in_eps; i++)
22990+ {
22991+ diepctl_rd.d32 = dwc_read_reg32(&dev_if->in_ep_regs[i]->diepctl);
22992+ if (diepctl_rd.b.epena) {
22993+ dwc_write_reg32(&dev_if->in_ep_regs[i]->diepctl,
22994+ diepctl.d32);
22995+ }
22996+ }
22997+ /* Disable the Global IN NAK Effective Interrupt */
22998+ intr_mask.b.ginnakeff = 1;
22999+ dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
23000+ intr_mask.d32, 0);
23001+
23002+ /* Clear interrupt */
23003+ gintsts.d32 = 0;
23004+ gintsts.b.ginnakeff = 1;
23005+ dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
23006+ gintsts.d32);
23007+
23008+ return 1;
23009+}
23010+
23011+/**
23012+ * OUT NAK Effective.
23013+ *
23014+ */
23015+int32_t dwc_otg_pcd_handle_out_nak_effective(dwc_otg_pcd_t *pcd)
23016+{
23017+ gintmsk_data_t intr_mask = { .d32 = 0};
23018+ gintsts_data_t gintsts;
23019+
23020+ DWC_PRINT("INTERRUPT Handler not implemented for %s\n",
23021+ "Global IN NAK Effective\n");
23022+ /* Disable the Global IN NAK Effective Interrupt */
23023+ intr_mask.b.goutnakeff = 1;
23024+ dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
23025+ intr_mask.d32, 0);
23026+
23027+ /* Clear interrupt */
23028+ gintsts.d32 = 0;
23029+ gintsts.b.goutnakeff = 1;
23030+ dwc_write_reg32 (&GET_CORE_IF(pcd)->core_global_regs->gintsts,
23031+ gintsts.d32);
23032+
23033+ return 1;
23034+}
23035+
23036+
23037+/**
23038+ * PCD interrupt handler.
23039+ *
23040+ * The PCD handles the device interrupts. Many conditions can cause a
23041+ * device interrupt. When an interrupt occurs, the device interrupt
23042+ * service routine determines the cause of the interrupt and
23043+ * dispatches handling to the appropriate function. These interrupt
23044+ * handling functions are described below.
23045+ *
23046+ * All interrupt registers are processed from LSB to MSB.
23047+ *
23048+ */
23049+int32_t dwc_otg_pcd_handle_intr(dwc_otg_pcd_t *pcd)
23050+{
23051+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
23052+#ifdef VERBOSE
23053+ dwc_otg_core_global_regs_t *global_regs =
23054+ core_if->core_global_regs;
23055+#endif
23056+ gintsts_data_t gintr_status;
23057+ int32_t retval = 0;
23058+
23059+
23060+#ifdef VERBOSE
23061+ DWC_DEBUGPL(DBG_ANY, "%s() gintsts=%08x gintmsk=%08x\n",
23062+ __func__,
23063+ dwc_read_reg32(&global_regs->gintsts),
23064+ dwc_read_reg32(&global_regs->gintmsk));
23065+#endif
23066+
23067+ if (dwc_otg_is_device_mode(core_if)) {
23068+ SPIN_LOCK(&pcd->lock);
23069+#ifdef VERBOSE
23070+ DWC_DEBUGPL(DBG_PCDV, "%s() gintsts=%08x gintmsk=%08x\n",
23071+ __func__,
23072+ dwc_read_reg32(&global_regs->gintsts),
23073+ dwc_read_reg32(&global_regs->gintmsk));
23074+#endif
23075+
23076+ gintr_status.d32 = dwc_otg_read_core_intr(core_if);
23077+
23078+/*
23079+ if (!gintr_status.d32) {
23080+ SPIN_UNLOCK(&pcd->lock);
23081+ return 0;
23082+ }
23083+*/
23084+ DWC_DEBUGPL(DBG_PCDV, "%s: gintsts&gintmsk=%08x\n",
23085+ __func__, gintr_status.d32);
23086+
23087+ if (gintr_status.b.sofintr) {
23088+ retval |= dwc_otg_pcd_handle_sof_intr(pcd);
23089+ }
23090+ if (gintr_status.b.rxstsqlvl) {
23091+ retval |= dwc_otg_pcd_handle_rx_status_q_level_intr(pcd);
23092+ }
23093+ if (gintr_status.b.nptxfempty) {
23094+ retval |= dwc_otg_pcd_handle_np_tx_fifo_empty_intr(pcd);
23095+ }
23096+ if (gintr_status.b.ginnakeff) {
23097+ retval |= dwc_otg_pcd_handle_in_nak_effective(pcd);
23098+ }
23099+ if (gintr_status.b.goutnakeff) {
23100+ retval |= dwc_otg_pcd_handle_out_nak_effective(pcd);
23101+ }
23102+ if (gintr_status.b.i2cintr) {
23103+ retval |= dwc_otg_pcd_handle_i2c_intr(pcd);
23104+ }
23105+ if (gintr_status.b.erlysuspend) {
23106+ retval |= dwc_otg_pcd_handle_early_suspend_intr(pcd);
23107+ }
23108+ if (gintr_status.b.usbreset) {
23109+ retval |= dwc_otg_pcd_handle_usb_reset_intr(pcd);
23110+ }
23111+ if (gintr_status.b.enumdone) {
23112+ retval |= dwc_otg_pcd_handle_enum_done_intr(pcd);
23113+ }
23114+ if (gintr_status.b.isooutdrop) {
23115+ retval |= dwc_otg_pcd_handle_isoc_out_packet_dropped_intr(pcd);
23116+ }
23117+ if (gintr_status.b.eopframe) {
23118+ retval |= dwc_otg_pcd_handle_end_periodic_frame_intr(pcd);
23119+ }
23120+ if (gintr_status.b.epmismatch) {
23121+ retval |= dwc_otg_pcd_handle_ep_mismatch_intr(core_if);
23122+ }
23123+ if (gintr_status.b.inepint) {
23124+ if(!core_if->multiproc_int_enable) {
23125+ retval |= dwc_otg_pcd_handle_in_ep_intr(pcd);
23126+ }
23127+ }
23128+ if (gintr_status.b.outepintr) {
23129+ if(!core_if->multiproc_int_enable) {
23130+ retval |= dwc_otg_pcd_handle_out_ep_intr(pcd);
23131+ }
23132+ }
23133+ if (gintr_status.b.incomplisoin) {
23134+ retval |= dwc_otg_pcd_handle_incomplete_isoc_in_intr(pcd);
23135+ }
23136+ if (gintr_status.b.incomplisoout) {
23137+ retval |= dwc_otg_pcd_handle_incomplete_isoc_out_intr(pcd);
23138+ }
23139+
23140+ /* In MPI mode De vice Endpoints intterrupts are asserted
23141+ * without setting outepintr and inepint bits set, so these
23142+ * Interrupt handlers are called without checking these bit-fields
23143+ */
23144+ if(core_if->multiproc_int_enable) {
23145+ retval |= dwc_otg_pcd_handle_in_ep_intr(pcd);
23146+ retval |= dwc_otg_pcd_handle_out_ep_intr(pcd);
23147+ }
23148+#ifdef VERBOSE
23149+ DWC_DEBUGPL(DBG_PCDV, "%s() gintsts=%0x\n", __func__,
23150+ dwc_read_reg32(&global_regs->gintsts));
23151+#endif
23152+ SPIN_UNLOCK(&pcd->lock);
23153+ }
23154+
23155+ S3C2410X_CLEAR_EINTPEND();
23156+
23157+ return retval;
23158+}
23159+
23160+#endif /* DWC_HOST_ONLY */
23161--- /dev/null
23162+++ b/drivers/usb/host/otg/dwc_otg_plat.h
23163@@ -0,0 +1,268 @@
23164+/* ==========================================================================
23165+ * $File: //dwh/usb_iip/dev/software/otg/linux/platform/dwc_otg_plat.h $
23166+ * $Revision: #23 $
23167+ * $Date: 2008/07/15 $
23168+ * $Change: 1064915 $
23169+ *
23170+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
23171+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
23172+ * otherwise expressly agreed to in writing between Synopsys and you.
23173+ *
23174+ * The Software IS NOT an item of Licensed Software or Licensed Product under
23175+ * any End User Software License Agreement or Agreement for Licensed Product
23176+ * with Synopsys or any supplement thereto. You are permitted to use and
23177+ * redistribute this Software in source and binary forms, with or without
23178+ * modification, provided that redistributions of source code must retain this
23179+ * notice. You may not view, use, disclose, copy or distribute this file or
23180+ * any information contained herein except pursuant to this license grant from
23181+ * Synopsys. If you do not agree with this notice, including the disclaimer
23182+ * below, then you are not authorized to use the Software.
23183+ *
23184+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
23185+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23186+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23187+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
23188+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23189+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23190+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23191+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23192+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23193+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
23194+ * DAMAGE.
23195+ * ========================================================================== */
23196+
23197+#if !defined(__DWC_OTG_PLAT_H__)
23198+#define __DWC_OTG_PLAT_H__
23199+
23200+#include <linux/types.h>
23201+#include <linux/slab.h>
23202+#include <linux/list.h>
23203+#include <linux/delay.h>
23204+#include <asm/io.h>
23205+
23206+#define cns3xxx_ioremap(addr, size) ioremap(addr, size)
23207+#define cns3xxx_iounmap(addr) iounmap(addr)
23208+/* Changed all readl and writel to __raw_readl, __raw_writel */
23209+
23210+/**
23211+ * @file
23212+ *
23213+ * This file contains the Platform Specific constants, interfaces
23214+ * (functions and macros) for Linux.
23215+ *
23216+ */
23217+//#if !defined(__LINUX_ARM_ARCH__)
23218+//#error "The contents of this file is Linux specific!!!"
23219+//#endif
23220+
23221+/**
23222+ * Reads the content of a register.
23223+ *
23224+ * @param reg address of register to read.
23225+ * @return contents of the register.
23226+ *
23227+
23228+ * Usage:<br>
23229+ * <code>uint32_t dev_ctl = dwc_read_reg32(&dev_regs->dctl);</code>
23230+ */
23231+static __inline__ uint32_t dwc_read_reg32( volatile uint32_t *reg)
23232+{
23233+ return __raw_readl(reg);
23234+ // return readl(reg);
23235+};
23236+
23237+/**
23238+ * Writes a register with a 32 bit value.
23239+ *
23240+ * @param reg address of register to read.
23241+ * @param value to write to _reg.
23242+ *
23243+ * Usage:<br>
23244+ * <code>dwc_write_reg32(&dev_regs->dctl, 0); </code>
23245+ */
23246+static __inline__ void dwc_write_reg32( volatile uint32_t *reg, const uint32_t value)
23247+{
23248+ // writel( value, reg );
23249+ __raw_writel(value, reg);
23250+
23251+};
23252+
23253+/**
23254+ * This function modifies bit values in a register. Using the
23255+ * algorithm: (reg_contents & ~clear_mask) | set_mask.
23256+ *
23257+ * @param reg address of register to read.
23258+ * @param clear_mask bit mask to be cleared.
23259+ * @param set_mask bit mask to be set.
23260+ *
23261+ * Usage:<br>
23262+ * <code> // Clear the SOF Interrupt Mask bit and <br>
23263+ * // set the OTG Interrupt mask bit, leaving all others as they were.
23264+ * dwc_modify_reg32(&dev_regs->gintmsk, DWC_SOF_INT, DWC_OTG_INT);</code>
23265+ */
23266+static __inline__
23267+ void dwc_modify_reg32( volatile uint32_t *reg, const uint32_t clear_mask, const uint32_t set_mask)
23268+{
23269+ // writel( (readl(reg) & ~clear_mask) | set_mask, reg );
23270+ __raw_writel( (__raw_readl(reg) & ~clear_mask) | set_mask, reg );
23271+};
23272+
23273+
23274+/**
23275+ * Wrapper for the OS micro-second delay function.
23276+ * @param[in] usecs Microseconds of delay
23277+ */
23278+static __inline__ void UDELAY( const uint32_t usecs )
23279+{
23280+ udelay( usecs );
23281+}
23282+
23283+/**
23284+ * Wrapper for the OS milli-second delay function.
23285+ * @param[in] msecs milliseconds of delay
23286+ */
23287+static __inline__ void MDELAY( const uint32_t msecs )
23288+{
23289+ mdelay( msecs );
23290+}
23291+
23292+/**
23293+ * Wrapper for the Linux spin_lock. On the ARM (Integrator)
23294+ * spin_lock() is a nop.
23295+ *
23296+ * @param lock Pointer to the spinlock.
23297+ */
23298+static __inline__ void SPIN_LOCK( spinlock_t *lock )
23299+{
23300+ spin_lock(lock);
23301+}
23302+
23303+/**
23304+ * Wrapper for the Linux spin_unlock. On the ARM (Integrator)
23305+ * spin_lock() is a nop.
23306+ *
23307+ * @param lock Pointer to the spinlock.
23308+ */
23309+static __inline__ void SPIN_UNLOCK( spinlock_t *lock )
23310+{
23311+ spin_unlock(lock);
23312+}
23313+
23314+/**
23315+ * Wrapper (macro) for the Linux spin_lock_irqsave. On the ARM
23316+ * (Integrator) spin_lock() is a nop.
23317+ *
23318+ * @param l Pointer to the spinlock.
23319+ * @param f unsigned long for irq flags storage.
23320+ */
23321+#define SPIN_LOCK_IRQSAVE( l, f ) spin_lock_irqsave(l,f);
23322+
23323+/**
23324+ * Wrapper (macro) for the Linux spin_unlock_irqrestore. On the ARM
23325+ * (Integrator) spin_lock() is a nop.
23326+ *
23327+ * @param l Pointer to the spinlock.
23328+ * @param f unsigned long for irq flags storage.
23329+ */
23330+#define SPIN_UNLOCK_IRQRESTORE( l,f ) spin_unlock_irqrestore(l,f);
23331+
23332+/*
23333+ * Debugging support vanishes in non-debug builds.
23334+ */
23335+
23336+
23337+/**
23338+ * The Debug Level bit-mask variable.
23339+ */
23340+extern uint32_t g_dbg_lvl;
23341+/**
23342+ * Set the Debug Level variable.
23343+ */
23344+static inline uint32_t SET_DEBUG_LEVEL( const uint32_t new )
23345+{
23346+ uint32_t old = g_dbg_lvl;
23347+ g_dbg_lvl = new;
23348+ return old;
23349+}
23350+
23351+/** When debug level has the DBG_CIL bit set, display CIL Debug messages. */
23352+#define DBG_CIL (0x2)
23353+/** When debug level has the DBG_CILV bit set, display CIL Verbose debug
23354+ * messages */
23355+#define DBG_CILV (0x20)
23356+/** When debug level has the DBG_PCD bit set, display PCD (Device) debug
23357+ * messages */
23358+#define DBG_PCD (0x4)
23359+/** When debug level has the DBG_PCDV set, display PCD (Device) Verbose debug
23360+ * messages */
23361+#define DBG_PCDV (0x40)
23362+/** When debug level has the DBG_HCD bit set, display Host debug messages */
23363+#define DBG_HCD (0x8)
23364+/** When debug level has the DBG_HCDV bit set, display Verbose Host debug
23365+ * messages */
23366+#define DBG_HCDV (0x80)
23367+/** When debug level has the DBG_HCD_URB bit set, display enqueued URBs in host
23368+ * mode. */
23369+#define DBG_HCD_URB (0x800)
23370+
23371+/** When debug level has any bit set, display debug messages */
23372+#define DBG_ANY (0xFF)
23373+
23374+/** All debug messages off */
23375+#define DBG_OFF 0
23376+
23377+/** Prefix string for DWC_DEBUG print macros. */
23378+#define USB_DWC "DWC_otg: "
23379+
23380+/**
23381+ * Print a debug message when the Global debug level variable contains
23382+ * the bit defined in <code>lvl</code>.
23383+ *
23384+ * @param[in] lvl - Debug level, use one of the DBG_ constants above.
23385+ * @param[in] x - like printf
23386+ *
23387+ * Example:<p>
23388+ * <code>
23389+ * DWC_DEBUGPL( DBG_ANY, "%s(%p)\n", __func__, _reg_base_addr);
23390+ * </code>
23391+ * <br>
23392+ * results in:<br>
23393+ * <code>
23394+ * usb-DWC_otg: dwc_otg_cil_init(ca867000)
23395+ * </code>
23396+ */
23397+#ifdef DEBUG
23398+
23399+# define DWC_DEBUGPL(lvl, x...) do{ if ((lvl)&g_dbg_lvl)printk( KERN_DEBUG USB_DWC x ); }while(0)
23400+# define DWC_DEBUGP(x...) DWC_DEBUGPL(DBG_ANY, x )
23401+
23402+# define CHK_DEBUG_LEVEL(level) ((level) & g_dbg_lvl)
23403+
23404+#else
23405+
23406+# define DWC_DEBUGPL(lvl, x...) do{}while(0)
23407+# define DWC_DEBUGP(x...)
23408+
23409+# define CHK_DEBUG_LEVEL(level) (0)
23410+
23411+#endif /*DEBUG*/
23412+
23413+/**
23414+ * Print an Error message.
23415+ */
23416+#define DWC_ERROR(x...) printk( KERN_ERR USB_DWC x )
23417+/**
23418+ * Print a Warning message.
23419+ */
23420+#define DWC_WARN(x...) printk( KERN_WARNING USB_DWC x )
23421+/**
23422+ * Print a notice (normal but significant message).
23423+ */
23424+#define DWC_NOTICE(x...) printk( KERN_NOTICE USB_DWC x )
23425+/**
23426+ * Basic message printing.
23427+ */
23428+#define DWC_PRINT(x...) printk( KERN_INFO USB_DWC x )
23429+
23430+#endif
23431+
23432--- /dev/null
23433+++ b/drivers/usb/host/otg/dwc_otg_regs.h
23434@@ -0,0 +1,2075 @@
23435+/* ==========================================================================
23436+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_regs.h $
23437+ * $Revision: #72 $
23438+ * $Date: 2008/09/19 $
23439+ * $Change: 1099526 $
23440+ *
23441+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
23442+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
23443+ * otherwise expressly agreed to in writing between Synopsys and you.
23444+ *
23445+ * The Software IS NOT an item of Licensed Software or Licensed Product under
23446+ * any End User Software License Agreement or Agreement for Licensed Product
23447+ * with Synopsys or any supplement thereto. You are permitted to use and
23448+ * redistribute this Software in source and binary forms, with or without
23449+ * modification, provided that redistributions of source code must retain this
23450+ * notice. You may not view, use, disclose, copy or distribute this file or
23451+ * any information contained herein except pursuant to this license grant from
23452+ * Synopsys. If you do not agree with this notice, including the disclaimer
23453+ * below, then you are not authorized to use the Software.
23454+ *
23455+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
23456+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23457+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23458+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
23459+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23460+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23461+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23462+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23463+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23464+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
23465+ * DAMAGE.
23466+ * ========================================================================== */
23467+
23468+#ifndef __DWC_OTG_REGS_H__
23469+#define __DWC_OTG_REGS_H__
23470+
23471+/**
23472+ * @file
23473+ *
23474+ * This file contains the data structures for accessing the DWC_otg core registers.
23475+ *
23476+ * The application interfaces with the HS OTG core by reading from and
23477+ * writing to the Control and Status Register (CSR) space through the
23478+ * AHB Slave interface. These registers are 32 bits wide, and the
23479+ * addresses are 32-bit-block aligned.
23480+ * CSRs are classified as follows:
23481+ * - Core Global Registers
23482+ * - Device Mode Registers
23483+ * - Device Global Registers
23484+ * - Device Endpoint Specific Registers
23485+ * - Host Mode Registers
23486+ * - Host Global Registers
23487+ * - Host Port CSRs
23488+ * - Host Channel Specific Registers
23489+ *
23490+ * Only the Core Global registers can be accessed in both Device and
23491+ * Host modes. When the HS OTG core is operating in one mode, either
23492+ * Device or Host, the application must not access registers from the
23493+ * other mode. When the core switches from one mode to another, the
23494+ * registers in the new mode of operation must be reprogrammed as they
23495+ * would be after a power-on reset.
23496+ */
23497+
23498+/** Maximum number of Periodic FIFOs */
23499+#define MAX_PERIO_FIFOS 15
23500+/** Maximum number of Transmit FIFOs */
23501+#define MAX_TX_FIFOS 15
23502+
23503+/** Maximum number of Endpoints/HostChannels */
23504+#define MAX_EPS_CHANNELS 16
23505+
23506+/****************************************************************************/
23507+/** DWC_otg Core registers .
23508+ * The dwc_otg_core_global_regs structure defines the size
23509+ * and relative field offsets for the Core Global registers.
23510+ */
23511+typedef struct dwc_otg_core_global_regs
23512+{
23513+ /** OTG Control and Status Register. <i>Offset: 000h</i> */
23514+ volatile uint32_t gotgctl;
23515+ /** OTG Interrupt Register. <i>Offset: 004h</i> */
23516+ volatile uint32_t gotgint;
23517+ /**Core AHB Configuration Register. <i>Offset: 008h</i> */
23518+ volatile uint32_t gahbcfg;
23519+
23520+#define DWC_GLBINTRMASK 0x0001
23521+#define DWC_DMAENABLE 0x0020
23522+#define DWC_NPTXEMPTYLVL_EMPTY 0x0080
23523+#define DWC_NPTXEMPTYLVL_HALFEMPTY 0x0000
23524+#define DWC_PTXEMPTYLVL_EMPTY 0x0100
23525+#define DWC_PTXEMPTYLVL_HALFEMPTY 0x0000
23526+
23527+ /**Core USB Configuration Register. <i>Offset: 00Ch</i> */
23528+ volatile uint32_t gusbcfg;
23529+ /**Core Reset Register. <i>Offset: 010h</i> */
23530+ volatile uint32_t grstctl;
23531+ /**Core Interrupt Register. <i>Offset: 014h</i> */
23532+ volatile uint32_t gintsts;
23533+ /**Core Interrupt Mask Register. <i>Offset: 018h</i> */
23534+ volatile uint32_t gintmsk;
23535+ /**Receive Status Queue Read Register (Read Only). <i>Offset: 01Ch</i> */
23536+ volatile uint32_t grxstsr;
23537+ /**Receive Status Queue Read & POP Register (Read Only). <i>Offset: 020h</i>*/
23538+ volatile uint32_t grxstsp;
23539+ /**Receive FIFO Size Register. <i>Offset: 024h</i> */
23540+ volatile uint32_t grxfsiz;
23541+ /**Non Periodic Transmit FIFO Size Register. <i>Offset: 028h</i> */
23542+ volatile uint32_t gnptxfsiz;
23543+ /**Non Periodic Transmit FIFO/Queue Status Register (Read
23544+ * Only). <i>Offset: 02Ch</i> */
23545+ volatile uint32_t gnptxsts;
23546+ /**I2C Access Register. <i>Offset: 030h</i> */
23547+ volatile uint32_t gi2cctl;
23548+ /**PHY Vendor Control Register. <i>Offset: 034h</i> */
23549+ volatile uint32_t gpvndctl;
23550+ /**General Purpose Input/Output Register. <i>Offset: 038h</i> */
23551+ volatile uint32_t ggpio;
23552+ /**User ID Register. <i>Offset: 03Ch</i> */
23553+ volatile uint32_t guid;
23554+ /**Synopsys ID Register (Read Only). <i>Offset: 040h</i> */
23555+ volatile uint32_t gsnpsid;
23556+ /**User HW Config1 Register (Read Only). <i>Offset: 044h</i> */
23557+ volatile uint32_t ghwcfg1;
23558+ /**User HW Config2 Register (Read Only). <i>Offset: 048h</i> */
23559+ volatile uint32_t ghwcfg2;
23560+#define DWC_SLAVE_ONLY_ARCH 0
23561+#define DWC_EXT_DMA_ARCH 1
23562+#define DWC_INT_DMA_ARCH 2
23563+
23564+#define DWC_MODE_HNP_SRP_CAPABLE 0
23565+#define DWC_MODE_SRP_ONLY_CAPABLE 1
23566+#define DWC_MODE_NO_HNP_SRP_CAPABLE 2
23567+#define DWC_MODE_SRP_CAPABLE_DEVICE 3
23568+#define DWC_MODE_NO_SRP_CAPABLE_DEVICE 4
23569+#define DWC_MODE_SRP_CAPABLE_HOST 5
23570+#define DWC_MODE_NO_SRP_CAPABLE_HOST 6
23571+
23572+ /**User HW Config3 Register (Read Only). <i>Offset: 04Ch</i> */
23573+ volatile uint32_t ghwcfg3;
23574+ /**User HW Config4 Register (Read Only). <i>Offset: 050h</i>*/
23575+ volatile uint32_t ghwcfg4;
23576+ /** Reserved <i>Offset: 054h-0FFh</i> */
23577+ volatile uint32_t reserved[43];
23578+ /** Host Periodic Transmit FIFO Size Register. <i>Offset: 100h</i> */
23579+ volatile uint32_t hptxfsiz;
23580+ /** Device Periodic Transmit FIFO#n Register if dedicated fifos are disabled,
23581+ otherwise Device Transmit FIFO#n Register.
23582+ * <i>Offset: 104h + (FIFO_Number-1)*04h, 1 <= FIFO Number <= 15 (1<=n<=15).</i> */
23583+ volatile uint32_t dptxfsiz_dieptxf[15];
23584+} dwc_otg_core_global_regs_t;
23585+
23586+/**
23587+ * This union represents the bit fields of the Core OTG Control
23588+ * and Status Register (GOTGCTL). Set the bits using the bit
23589+ * fields then write the <i>d32</i> value to the register.
23590+ */
23591+typedef union gotgctl_data
23592+{
23593+ /** raw register data */
23594+ uint32_t d32;
23595+ /** register bits */
23596+ struct
23597+ {
23598+ unsigned sesreqscs : 1;
23599+ unsigned sesreq : 1;
23600+ unsigned reserved2_7 : 6;
23601+ unsigned hstnegscs : 1;
23602+ unsigned hnpreq : 1;
23603+ unsigned hstsethnpen : 1;
23604+ unsigned devhnpen : 1;
23605+ unsigned reserved12_15 : 4;
23606+ unsigned conidsts : 1;
23607+ unsigned reserved17 : 1;
23608+ unsigned asesvld : 1;
23609+ unsigned bsesvld : 1;
23610+ unsigned currmod : 1;
23611+ unsigned reserved21_31 : 11;
23612+ } b;
23613+} gotgctl_data_t;
23614+
23615+/**
23616+ * This union represents the bit fields of the Core OTG Interrupt Register
23617+ * (GOTGINT). Set/clear the bits using the bit fields then write the <i>d32</i>
23618+ * value to the register.
23619+ */
23620+typedef union gotgint_data
23621+{
23622+ /** raw register data */
23623+ uint32_t d32;
23624+ /** register bits */
23625+ struct
23626+ {
23627+ /** Current Mode */
23628+ unsigned reserved0_1 : 2;
23629+
23630+ /** Session End Detected */
23631+ unsigned sesenddet : 1;
23632+
23633+ unsigned reserved3_7 : 5;
23634+
23635+ /** Session Request Success Status Change */
23636+ unsigned sesreqsucstschng : 1;
23637+ /** Host Negotiation Success Status Change */
23638+ unsigned hstnegsucstschng : 1;
23639+
23640+ unsigned reserver10_16 : 7;
23641+
23642+ /** Host Negotiation Detected */
23643+ unsigned hstnegdet : 1;
23644+ /** A-Device Timeout Change */
23645+ unsigned adevtoutchng : 1;
23646+ /** Debounce Done */
23647+ unsigned debdone : 1;
23648+
23649+ unsigned reserved31_20 : 12;
23650+
23651+ } b;
23652+} gotgint_data_t;
23653+
23654+
23655+/**
23656+ * This union represents the bit fields of the Core AHB Configuration
23657+ * Register (GAHBCFG). Set/clear the bits using the bit fields then
23658+ * write the <i>d32</i> value to the register.
23659+ */
23660+typedef union gahbcfg_data
23661+{
23662+ /** raw register data */
23663+ uint32_t d32;
23664+ /** register bits */
23665+ struct
23666+ {
23667+ unsigned glblintrmsk : 1;
23668+#define DWC_GAHBCFG_GLBINT_ENABLE 1
23669+
23670+ unsigned hburstlen : 4;
23671+#define DWC_GAHBCFG_INT_DMA_BURST_SINGLE 0
23672+#define DWC_GAHBCFG_INT_DMA_BURST_INCR 1
23673+#define DWC_GAHBCFG_INT_DMA_BURST_INCR4 3
23674+#define DWC_GAHBCFG_INT_DMA_BURST_INCR8 5
23675+#define DWC_GAHBCFG_INT_DMA_BURST_INCR16 7
23676+
23677+ unsigned dmaenable : 1;
23678+#define DWC_GAHBCFG_DMAENABLE 1
23679+ unsigned reserved : 1;
23680+ unsigned nptxfemplvl_txfemplvl : 1;
23681+ unsigned ptxfemplvl : 1;
23682+#define DWC_GAHBCFG_TXFEMPTYLVL_EMPTY 1
23683+#define DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY 0
23684+ unsigned reserved9_31 : 23;
23685+ } b;
23686+} gahbcfg_data_t;
23687+
23688+/**
23689+ * This union represents the bit fields of the Core USB Configuration
23690+ * Register (GUSBCFG). Set the bits using the bit fields then write
23691+ * the <i>d32</i> value to the register.
23692+ */
23693+typedef union gusbcfg_data
23694+{
23695+ /** raw register data */
23696+ uint32_t d32;
23697+ /** register bits */
23698+ struct
23699+ {
23700+ unsigned toutcal : 3;
23701+ unsigned phyif : 1;
23702+ unsigned ulpi_utmi_sel : 1;
23703+ unsigned fsintf : 1;
23704+ unsigned physel : 1;
23705+ unsigned ddrsel : 1;
23706+ unsigned srpcap : 1;
23707+ unsigned hnpcap : 1;
23708+ unsigned usbtrdtim : 4;
23709+ unsigned nptxfrwnden : 1;
23710+ unsigned phylpwrclksel : 1;
23711+ unsigned otgutmifssel : 1;
23712+ unsigned ulpi_fsls : 1;
23713+ unsigned ulpi_auto_res : 1;
23714+ unsigned ulpi_clk_sus_m : 1;
23715+ unsigned ulpi_ext_vbus_drv : 1;
23716+ unsigned ulpi_int_vbus_indicator : 1;
23717+ unsigned term_sel_dl_pulse : 1;
23718+ unsigned reserved23_27 : 5;
23719+ unsigned tx_end_delay : 1;
23720+ unsigned reserved29_31 : 3;
23721+ } b;
23722+} gusbcfg_data_t;
23723+
23724+/**
23725+ * This union represents the bit fields of the Core Reset Register
23726+ * (GRSTCTL). Set/clear the bits using the bit fields then write the
23727+ * <i>d32</i> value to the register.
23728+ */
23729+typedef union grstctl_data
23730+{
23731+ /** raw register data */
23732+ uint32_t d32;
23733+ /** register bits */
23734+ struct
23735+ {
23736+ /** Core Soft Reset (CSftRst) (Device and Host)
23737+ *
23738+ * The application can flush the control logic in the
23739+ * entire core using this bit. This bit resets the
23740+ * pipelines in the AHB Clock domain as well as the
23741+ * PHY Clock domain.
23742+ *
23743+ * The state machines are reset to an IDLE state, the
23744+ * control bits in the CSRs are cleared, all the
23745+ * transmit FIFOs and the receive FIFO are flushed.
23746+ *
23747+ * The status mask bits that control the generation of
23748+ * the interrupt, are cleared, to clear the
23749+ * interrupt. The interrupt status bits are not
23750+ * cleared, so the application can get the status of
23751+ * any events that occurred in the core after it has
23752+ * set this bit.
23753+ *
23754+ * Any transactions on the AHB are terminated as soon
23755+ * as possible following the protocol. Any
23756+ * transactions on the USB are terminated immediately.
23757+ *
23758+ * The configuration settings in the CSRs are
23759+ * unchanged, so the software doesn't have to
23760+ * reprogram these registers (Device
23761+ * Configuration/Host Configuration/Core System
23762+ * Configuration/Core PHY Configuration).
23763+ *
23764+ * The application can write to this bit, any time it
23765+ * wants to reset the core. This is a self clearing
23766+ * bit and the core clears this bit after all the
23767+ * necessary logic is reset in the core, which may
23768+ * take several clocks, depending on the current state
23769+ * of the core.
23770+ */
23771+ unsigned csftrst : 1;
23772+ /** Hclk Soft Reset
23773+ *
23774+ * The application uses this bit to reset the control logic in
23775+ * the AHB clock domain. Only AHB clock domain pipelines are
23776+ * reset.
23777+ */
23778+ unsigned hsftrst : 1;
23779+ /** Host Frame Counter Reset (Host Only)<br>
23780+ *
23781+ * The application can reset the (micro)frame number
23782+ * counter inside the core, using this bit. When the
23783+ * (micro)frame counter is reset, the subsequent SOF
23784+ * sent out by the core, will have a (micro)frame
23785+ * number of 0.
23786+ */
23787+ unsigned hstfrm : 1;
23788+ /** In Token Sequence Learning Queue Flush
23789+ * (INTknQFlsh) (Device Only)
23790+ */
23791+ unsigned intknqflsh : 1;
23792+ /** RxFIFO Flush (RxFFlsh) (Device and Host)
23793+ *
23794+ * The application can flush the entire Receive FIFO
23795+ * using this bit. <p>The application must first
23796+ * ensure that the core is not in the middle of a
23797+ * transaction. <p>The application should write into
23798+ * this bit, only after making sure that neither the
23799+ * DMA engine is reading from the RxFIFO nor the MAC
23800+ * is writing the data in to the FIFO. <p>The
23801+ * application should wait until the bit is cleared
23802+ * before performing any other operations. This bit
23803+ * will takes 8 clocks (slowest of PHY or AHB clock)
23804+ * to clear.
23805+ */
23806+ unsigned rxfflsh : 1;
23807+ /** TxFIFO Flush (TxFFlsh) (Device and Host).
23808+ *
23809+ * This bit is used to selectively flush a single or
23810+ * all transmit FIFOs. The application must first
23811+ * ensure that the core is not in the middle of a
23812+ * transaction. <p>The application should write into
23813+ * this bit, only after making sure that neither the
23814+ * DMA engine is writing into the TxFIFO nor the MAC
23815+ * is reading the data out of the FIFO. <p>The
23816+ * application should wait until the core clears this
23817+ * bit, before performing any operations. This bit
23818+ * will takes 8 clocks (slowest of PHY or AHB clock)
23819+ * to clear.
23820+ */
23821+ unsigned txfflsh : 1;
23822+
23823+ /** TxFIFO Number (TxFNum) (Device and Host).
23824+ *
23825+ * This is the FIFO number which needs to be flushed,
23826+ * using the TxFIFO Flush bit. This field should not
23827+ * be changed until the TxFIFO Flush bit is cleared by
23828+ * the core.
23829+ * - 0x0 : Non Periodic TxFIFO Flush
23830+ * - 0x1 : Periodic TxFIFO #1 Flush in device mode
23831+ * or Periodic TxFIFO in host mode
23832+ * - 0x2 : Periodic TxFIFO #2 Flush in device mode.
23833+ * - ...
23834+ * - 0xF : Periodic TxFIFO #15 Flush in device mode
23835+ * - 0x10: Flush all the Transmit NonPeriodic and
23836+ * Transmit Periodic FIFOs in the core
23837+ */
23838+ unsigned txfnum : 5;
23839+ /** Reserved */
23840+ unsigned reserved11_29 : 19;
23841+ /** DMA Request Signal. Indicated DMA request is in
23842+ * probress. Used for debug purpose. */
23843+ unsigned dmareq : 1;
23844+ /** AHB Master Idle. Indicates the AHB Master State
23845+ * Machine is in IDLE condition. */
23846+ unsigned ahbidle : 1;
23847+ } b;
23848+} grstctl_t;
23849+
23850+
23851+/**
23852+ * This union represents the bit fields of the Core Interrupt Mask
23853+ * Register (GINTMSK). Set/clear the bits using the bit fields then
23854+ * write the <i>d32</i> value to the register.
23855+ */
23856+typedef union gintmsk_data
23857+{
23858+ /** raw register data */
23859+ uint32_t d32;
23860+ /** register bits */
23861+ struct
23862+ {
23863+ unsigned reserved0 : 1;
23864+ unsigned modemismatch : 1;
23865+ unsigned otgintr : 1;
23866+ unsigned sofintr : 1;
23867+ unsigned rxstsqlvl : 1;
23868+ unsigned nptxfempty : 1;
23869+ unsigned ginnakeff : 1;
23870+ unsigned goutnakeff : 1;
23871+ unsigned reserved8 : 1;
23872+ unsigned i2cintr : 1;
23873+ unsigned erlysuspend : 1;
23874+ unsigned usbsuspend : 1;
23875+ unsigned usbreset : 1;
23876+ unsigned enumdone : 1;
23877+ unsigned isooutdrop : 1;
23878+ unsigned eopframe : 1;
23879+ unsigned reserved16 : 1;
23880+ unsigned epmismatch : 1;
23881+ unsigned inepintr : 1;
23882+ unsigned outepintr : 1;
23883+ unsigned incomplisoin : 1;
23884+ unsigned incomplisoout : 1;
23885+ unsigned reserved22_23 : 2;
23886+ unsigned portintr : 1;
23887+ unsigned hcintr : 1;
23888+ unsigned ptxfempty : 1;
23889+ unsigned reserved27 : 1;
23890+ unsigned conidstschng : 1;
23891+ unsigned disconnect : 1;
23892+ unsigned sessreqintr : 1;
23893+ unsigned wkupintr : 1;
23894+ } b;
23895+} gintmsk_data_t;
23896+/**
23897+ * This union represents the bit fields of the Core Interrupt Register
23898+ * (GINTSTS). Set/clear the bits using the bit fields then write the
23899+ * <i>d32</i> value to the register.
23900+ */
23901+typedef union gintsts_data
23902+{
23903+ /** raw register data */
23904+ uint32_t d32;
23905+#define DWC_SOF_INTR_MASK 0x0008
23906+ /** register bits */
23907+ struct
23908+ {
23909+#define DWC_HOST_MODE 1
23910+ unsigned curmode : 1;
23911+ unsigned modemismatch : 1;
23912+ unsigned otgintr : 1;
23913+ unsigned sofintr : 1;
23914+ unsigned rxstsqlvl : 1;
23915+ unsigned nptxfempty : 1;
23916+ unsigned ginnakeff : 1;
23917+ unsigned goutnakeff : 1;
23918+ unsigned reserved8 : 1;
23919+ unsigned i2cintr : 1;
23920+ unsigned erlysuspend : 1;
23921+ unsigned usbsuspend : 1;
23922+ unsigned usbreset : 1;
23923+ unsigned enumdone : 1;
23924+ unsigned isooutdrop : 1;
23925+ unsigned eopframe : 1;
23926+ unsigned intokenrx : 1;
23927+ unsigned epmismatch : 1;
23928+ unsigned inepint: 1;
23929+ unsigned outepintr : 1;
23930+ unsigned incomplisoin : 1;
23931+ unsigned incomplisoout : 1;
23932+ unsigned reserved22_23 : 2;
23933+ unsigned portintr : 1;
23934+ unsigned hcintr : 1;
23935+ unsigned ptxfempty : 1;
23936+ unsigned reserved27 : 1;
23937+ unsigned conidstschng : 1;
23938+ unsigned disconnect : 1;
23939+ unsigned sessreqintr : 1;
23940+ unsigned wkupintr : 1;
23941+ } b;
23942+} gintsts_data_t;
23943+
23944+
23945+/**
23946+ * This union represents the bit fields in the Device Receive Status Read and
23947+ * Pop Registers (GRXSTSR, GRXSTSP) Read the register into the <i>d32</i>
23948+ * element then read out the bits using the <i>b</i>it elements.
23949+ */
23950+typedef union device_grxsts_data
23951+{
23952+ /** raw register data */
23953+ uint32_t d32;
23954+ /** register bits */
23955+ struct
23956+ {
23957+ unsigned epnum : 4;
23958+ unsigned bcnt : 11;
23959+ unsigned dpid : 2;
23960+
23961+#define DWC_STS_DATA_UPDT 0x2 // OUT Data Packet
23962+#define DWC_STS_XFER_COMP 0x3 // OUT Data Transfer Complete
23963+
23964+#define DWC_DSTS_GOUT_NAK 0x1 // Global OUT NAK
23965+#define DWC_DSTS_SETUP_COMP 0x4 // Setup Phase Complete
23966+#define DWC_DSTS_SETUP_UPDT 0x6 // SETUP Packet
23967+ unsigned pktsts : 4;
23968+ unsigned fn : 4;
23969+ unsigned reserved : 7;
23970+ } b;
23971+} device_grxsts_data_t;
23972+
23973+/**
23974+ * This union represents the bit fields in the Host Receive Status Read and
23975+ * Pop Registers (GRXSTSR, GRXSTSP) Read the register into the <i>d32</i>
23976+ * element then read out the bits using the <i>b</i>it elements.
23977+ */
23978+typedef union host_grxsts_data
23979+{
23980+ /** raw register data */
23981+ uint32_t d32;
23982+ /** register bits */
23983+ struct
23984+ {
23985+ unsigned chnum : 4;
23986+ unsigned bcnt : 11;
23987+ unsigned dpid : 2;
23988+
23989+ unsigned pktsts : 4;
23990+#define DWC_GRXSTS_PKTSTS_IN 0x2
23991+#define DWC_GRXSTS_PKTSTS_IN_XFER_COMP 0x3
23992+#define DWC_GRXSTS_PKTSTS_DATA_TOGGLE_ERR 0x5
23993+#define DWC_GRXSTS_PKTSTS_CH_HALTED 0x7
23994+
23995+ unsigned reserved : 11;
23996+ } b;
23997+} host_grxsts_data_t;
23998+
23999+/**
24000+ * This union represents the bit fields in the FIFO Size Registers (HPTXFSIZ,
24001+ * GNPTXFSIZ, DPTXFSIZn, DIEPTXFn). Read the register into the <i>d32</i> element then
24002+ * read out the bits using the <i>b</i>it elements.
24003+ */
24004+typedef union fifosize_data
24005+{
24006+ /** raw register data */
24007+ uint32_t d32;
24008+ /** register bits */
24009+ struct
24010+ {
24011+ unsigned startaddr : 16;
24012+ unsigned depth : 16;
24013+ } b;
24014+} fifosize_data_t;
24015+
24016+/**
24017+ * This union represents the bit fields in the Non-Periodic Transmit
24018+ * FIFO/Queue Status Register (GNPTXSTS). Read the register into the
24019+ * <i>d32</i> element then read out the bits using the <i>b</i>it
24020+ * elements.
24021+ */
24022+typedef union gnptxsts_data
24023+{
24024+ /** raw register data */
24025+ uint32_t d32;
24026+ /** register bits */
24027+ struct
24028+ {
24029+ unsigned nptxfspcavail : 16;
24030+ unsigned nptxqspcavail : 8;
24031+ /** Top of the Non-Periodic Transmit Request Queue
24032+ * - bit 24 - Terminate (Last entry for the selected
24033+ * channel/EP)
24034+ * - bits 26:25 - Token Type
24035+ * - 2'b00 - IN/OUT
24036+ * - 2'b01 - Zero Length OUT
24037+ * - 2'b10 - PING/Complete Split
24038+ * - 2'b11 - Channel Halt
24039+ * - bits 30:27 - Channel/EP Number
24040+ */
24041+ unsigned nptxqtop_terminate : 1;
24042+ unsigned nptxqtop_token : 2;
24043+ unsigned nptxqtop_chnep : 4;
24044+ unsigned reserved : 1;
24045+ } b;
24046+} gnptxsts_data_t;
24047+
24048+/**
24049+ * This union represents the bit fields in the Transmit
24050+ * FIFO Status Register (DTXFSTS). Read the register into the
24051+ * <i>d32</i> element then read out the bits using the <i>b</i>it
24052+ * elements.
24053+ */
24054+typedef union dtxfsts_data
24055+{
24056+ /** raw register data */
24057+ uint32_t d32;
24058+ /** register bits */
24059+ struct
24060+ {
24061+ unsigned txfspcavail : 16;
24062+ unsigned reserved : 16;
24063+ } b;
24064+} dtxfsts_data_t;
24065+
24066+/**
24067+ * This union represents the bit fields in the I2C Control Register
24068+ * (I2CCTL). Read the register into the <i>d32</i> element then read out the
24069+ * bits using the <i>b</i>it elements.
24070+ */
24071+typedef union gi2cctl_data
24072+{
24073+ /** raw register data */
24074+ uint32_t d32;
24075+ /** register bits */
24076+ struct
24077+ {
24078+ unsigned rwdata : 8;
24079+ unsigned regaddr : 8;
24080+ unsigned addr : 7;
24081+ unsigned i2cen : 1;
24082+ unsigned ack : 1;
24083+ unsigned i2csuspctl : 1;
24084+ unsigned i2cdevaddr : 2;
24085+ unsigned reserved : 2;
24086+ unsigned rw : 1;
24087+ unsigned bsydne : 1;
24088+ } b;
24089+} gi2cctl_data_t;
24090+
24091+/**
24092+ * This union represents the bit fields in the User HW Config1
24093+ * Register. Read the register into the <i>d32</i> element then read
24094+ * out the bits using the <i>b</i>it elements.
24095+ */
24096+typedef union hwcfg1_data
24097+{
24098+ /** raw register data */
24099+ uint32_t d32;
24100+ /** register bits */
24101+ struct
24102+ {
24103+ unsigned ep_dir0 : 2;
24104+ unsigned ep_dir1 : 2;
24105+ unsigned ep_dir2 : 2;
24106+ unsigned ep_dir3 : 2;
24107+ unsigned ep_dir4 : 2;
24108+ unsigned ep_dir5 : 2;
24109+ unsigned ep_dir6 : 2;
24110+ unsigned ep_dir7 : 2;
24111+ unsigned ep_dir8 : 2;
24112+ unsigned ep_dir9 : 2;
24113+ unsigned ep_dir10 : 2;
24114+ unsigned ep_dir11 : 2;
24115+ unsigned ep_dir12 : 2;
24116+ unsigned ep_dir13 : 2;
24117+ unsigned ep_dir14 : 2;
24118+ unsigned ep_dir15 : 2;
24119+ } b;
24120+} hwcfg1_data_t;
24121+
24122+/**
24123+ * This union represents the bit fields in the User HW Config2
24124+ * Register. Read the register into the <i>d32</i> element then read
24125+ * out the bits using the <i>b</i>it elements.
24126+ */
24127+typedef union hwcfg2_data
24128+{
24129+ /** raw register data */
24130+ uint32_t d32;
24131+ /** register bits */
24132+ struct
24133+ {
24134+ /* GHWCFG2 */
24135+ unsigned op_mode : 3;
24136+#define DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG 0
24137+#define DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG 1
24138+#define DWC_HWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE_OTG 2
24139+#define DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE 3
24140+#define DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE 4
24141+#define DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST 5
24142+#define DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST 6
24143+
24144+ unsigned architecture : 2;
24145+ unsigned point2point : 1;
24146+ unsigned hs_phy_type : 2;
24147+#define DWC_HWCFG2_HS_PHY_TYPE_NOT_SUPPORTED 0
24148+#define DWC_HWCFG2_HS_PHY_TYPE_UTMI 1
24149+#define DWC_HWCFG2_HS_PHY_TYPE_ULPI 2
24150+#define DWC_HWCFG2_HS_PHY_TYPE_UTMI_ULPI 3
24151+
24152+ unsigned fs_phy_type : 2;
24153+ unsigned num_dev_ep : 4;
24154+ unsigned num_host_chan : 4;
24155+ unsigned perio_ep_supported : 1;
24156+ unsigned dynamic_fifo : 1;
24157+ unsigned multi_proc_int : 1;
24158+ unsigned reserved21 : 1;
24159+ unsigned nonperio_tx_q_depth : 2;
24160+ unsigned host_perio_tx_q_depth : 2;
24161+ unsigned dev_token_q_depth : 5;
24162+ unsigned reserved31 : 1;
24163+ } b;
24164+} hwcfg2_data_t;
24165+
24166+/**
24167+ * This union represents the bit fields in the User HW Config3
24168+ * Register. Read the register into the <i>d32</i> element then read
24169+ * out the bits using the <i>b</i>it elements.
24170+ */
24171+typedef union hwcfg3_data
24172+{
24173+ /** raw register data */
24174+ uint32_t d32;
24175+ /** register bits */
24176+ struct
24177+ {
24178+ /* GHWCFG3 */
24179+ unsigned xfer_size_cntr_width : 4;
24180+ unsigned packet_size_cntr_width : 3;
24181+ unsigned otg_func : 1;
24182+ unsigned i2c : 1;
24183+ unsigned vendor_ctrl_if : 1;
24184+ unsigned optional_features : 1;
24185+ unsigned synch_reset_type : 1;
24186+ unsigned ahb_phy_clock_synch : 1;
24187+ unsigned reserved15_13 : 3;
24188+ unsigned dfifo_depth : 16;
24189+ } b;
24190+} hwcfg3_data_t;
24191+
24192+/**
24193+ * This union represents the bit fields in the User HW Config4
24194+ * Register. Read the register into the <i>d32</i> element then read
24195+ * out the bits using the <i>b</i>it elements.
24196+ */
24197+typedef union hwcfg4_data
24198+{
24199+ /** raw register data */
24200+ uint32_t d32;
24201+ /** register bits */
24202+ struct
24203+ {
24204+ unsigned num_dev_perio_in_ep : 4;
24205+ unsigned power_optimiz : 1;
24206+ unsigned min_ahb_freq : 9;
24207+ unsigned utmi_phy_data_width : 2;
24208+ unsigned num_dev_mode_ctrl_ep : 4;
24209+ unsigned iddig_filt_en : 1;
24210+ unsigned vbus_valid_filt_en : 1;
24211+ unsigned a_valid_filt_en : 1;
24212+ unsigned b_valid_filt_en : 1;
24213+ unsigned session_end_filt_en : 1;
24214+ unsigned ded_fifo_en : 1;
24215+ unsigned num_in_eps : 4;
24216+ unsigned desc_dma : 1;
24217+ unsigned desc_dma_dyn : 1;
24218+ } b;
24219+} hwcfg4_data_t;
24220+
24221+////////////////////////////////////////////
24222+// Device Registers
24223+/**
24224+ * Device Global Registers. <i>Offsets 800h-BFFh</i>
24225+ *
24226+ * The following structures define the size and relative field offsets
24227+ * for the Device Mode Registers.
24228+ *
24229+ * <i>These registers are visible only in Device mode and must not be
24230+ * accessed in Host mode, as the results are unknown.</i>
24231+ */
24232+typedef struct dwc_otg_dev_global_regs
24233+{
24234+ /** Device Configuration Register. <i>Offset 800h</i> */
24235+ volatile uint32_t dcfg;
24236+ /** Device Control Register. <i>Offset: 804h</i> */
24237+ volatile uint32_t dctl;
24238+ /** Device Status Register (Read Only). <i>Offset: 808h</i> */
24239+ volatile uint32_t dsts;
24240+ /** Reserved. <i>Offset: 80Ch</i> */
24241+ uint32_t unused;
24242+ /** Device IN Endpoint Common Interrupt Mask
24243+ * Register. <i>Offset: 810h</i> */
24244+ volatile uint32_t diepmsk;
24245+ /** Device OUT Endpoint Common Interrupt Mask
24246+ * Register. <i>Offset: 814h</i> */
24247+ volatile uint32_t doepmsk;
24248+ /** Device All Endpoints Interrupt Register. <i>Offset: 818h</i> */
24249+ volatile uint32_t daint;
24250+ /** Device All Endpoints Interrupt Mask Register. <i>Offset:
24251+ * 81Ch</i> */
24252+ volatile uint32_t daintmsk;
24253+ /** Device IN Token Queue Read Register-1 (Read Only).
24254+ * <i>Offset: 820h</i> */
24255+ volatile uint32_t dtknqr1;
24256+ /** Device IN Token Queue Read Register-2 (Read Only).
24257+ * <i>Offset: 824h</i> */
24258+ volatile uint32_t dtknqr2;
24259+ /** Device VBUS discharge Register. <i>Offset: 828h</i> */
24260+ volatile uint32_t dvbusdis;
24261+ /** Device VBUS Pulse Register. <i>Offset: 82Ch</i> */
24262+ volatile uint32_t dvbuspulse;
24263+ /** Device IN Token Queue Read Register-3 (Read Only). /
24264+ * Device Thresholding control register (Read/Write)
24265+ * <i>Offset: 830h</i> */
24266+ volatile uint32_t dtknqr3_dthrctl;
24267+ /** Device IN Token Queue Read Register-4 (Read Only). /
24268+ * Device IN EPs empty Inr. Mask Register (Read/Write)
24269+ * <i>Offset: 834h</i> */
24270+ volatile uint32_t dtknqr4_fifoemptymsk;
24271+ /** Device Each Endpoint Interrupt Register (Read Only). /
24272+ * <i>Offset: 838h</i> */
24273+ volatile uint32_t deachint;
24274+ /** Device Each Endpoint Interrupt mask Register (Read/Write). /
24275+ * <i>Offset: 83Ch</i> */
24276+ volatile uint32_t deachintmsk;
24277+ /** Device Each In Endpoint Interrupt mask Register (Read/Write). /
24278+ * <i>Offset: 840h</i> */
24279+ volatile uint32_t diepeachintmsk[MAX_EPS_CHANNELS];
24280+ /** Device Each Out Endpoint Interrupt mask Register (Read/Write). /
24281+ * <i>Offset: 880h</i> */
24282+ volatile uint32_t doepeachintmsk[MAX_EPS_CHANNELS];
24283+} dwc_otg_device_global_regs_t;
24284+
24285+/**
24286+ * This union represents the bit fields in the Device Configuration
24287+ * Register. Read the register into the <i>d32</i> member then
24288+ * set/clear the bits using the <i>b</i>it elements. Write the
24289+ * <i>d32</i> member to the dcfg register.
24290+ */
24291+typedef union dcfg_data
24292+{
24293+ /** raw register data */
24294+ uint32_t d32;
24295+ /** register bits */
24296+ struct
24297+ {
24298+ /** Device Speed */
24299+ unsigned devspd : 2;
24300+ /** Non Zero Length Status OUT Handshake */
24301+ unsigned nzstsouthshk : 1;
24302+#define DWC_DCFG_SEND_STALL 1
24303+
24304+ unsigned reserved3 : 1;
24305+ /** Device Addresses */
24306+ unsigned devaddr : 7;
24307+ /** Periodic Frame Interval */
24308+ unsigned perfrint : 2;
24309+#define DWC_DCFG_FRAME_INTERVAL_80 0
24310+#define DWC_DCFG_FRAME_INTERVAL_85 1
24311+#define DWC_DCFG_FRAME_INTERVAL_90 2
24312+#define DWC_DCFG_FRAME_INTERVAL_95 3
24313+
24314+ unsigned reserved13_17 : 5;
24315+ /** In Endpoint Mis-match count */
24316+ unsigned epmscnt : 5;
24317+ /** Enable Descriptor DMA in Device mode */
24318+ unsigned descdma : 1;
24319+ } b;
24320+} dcfg_data_t;
24321+
24322+/**
24323+ * This union represents the bit fields in the Device Control
24324+ * Register. Read the register into the <i>d32</i> member then
24325+ * set/clear the bits using the <i>b</i>it elements.
24326+ */
24327+typedef union dctl_data
24328+{
24329+ /** raw register data */
24330+ uint32_t d32;
24331+ /** register bits */
24332+ struct
24333+ {
24334+ /** Remote Wakeup */
24335+ unsigned rmtwkupsig : 1;
24336+ /** Soft Disconnect */
24337+ unsigned sftdiscon : 1;
24338+ /** Global Non-Periodic IN NAK Status */
24339+ unsigned gnpinnaksts : 1;
24340+ /** Global OUT NAK Status */
24341+ unsigned goutnaksts : 1;
24342+ /** Test Control */
24343+ unsigned tstctl : 3;
24344+ /** Set Global Non-Periodic IN NAK */
24345+ unsigned sgnpinnak : 1;
24346+ /** Clear Global Non-Periodic IN NAK */
24347+ unsigned cgnpinnak : 1;
24348+ /** Set Global OUT NAK */
24349+ unsigned sgoutnak : 1;
24350+ /** Clear Global OUT NAK */
24351+ unsigned cgoutnak : 1;
24352+
24353+ /** Power-On Programming Done */
24354+ unsigned pwronprgdone : 1;
24355+ /** Global Continue on BNA */
24356+ unsigned gcontbna : 1;
24357+ /** Global Multi Count */
24358+ unsigned gmc : 2;
24359+ /** Ignore Frame Number for ISOC EPs */
24360+ unsigned ifrmnum : 1;
24361+ /** NAK on Babble */
24362+ unsigned nakonbble : 1;
24363+
24364+ unsigned reserved16_31 : 16;
24365+ } b;
24366+} dctl_data_t;
24367+
24368+/**
24369+ * This union represents the bit fields in the Device Status
24370+ * Register. Read the register into the <i>d32</i> member then
24371+ * set/clear the bits using the <i>b</i>it elements.
24372+ */
24373+typedef union dsts_data
24374+{
24375+ /** raw register data */
24376+ uint32_t d32;
24377+ /** register bits */
24378+ struct
24379+ {
24380+ /** Suspend Status */
24381+ unsigned suspsts : 1;
24382+ /** Enumerated Speed */
24383+ unsigned enumspd : 2;
24384+#define DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ 0
24385+#define DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ 1
24386+#define DWC_DSTS_ENUMSPD_LS_PHY_6MHZ 2
24387+#define DWC_DSTS_ENUMSPD_FS_PHY_48MHZ 3
24388+ /** Erratic Error */
24389+ unsigned errticerr : 1;
24390+ unsigned reserved4_7: 4;
24391+ /** Frame or Microframe Number of the received SOF */
24392+ unsigned soffn : 14;
24393+ unsigned reserved22_31 : 10;
24394+ } b;
24395+} dsts_data_t;
24396+
24397+
24398+/**
24399+ * This union represents the bit fields in the Device IN EP Interrupt
24400+ * Register and the Device IN EP Common Mask Register.
24401+ *
24402+ * - Read the register into the <i>d32</i> member then set/clear the
24403+ * bits using the <i>b</i>it elements.
24404+ */
24405+typedef union diepint_data
24406+{
24407+ /** raw register data */
24408+ uint32_t d32;
24409+ /** register bits */
24410+ struct
24411+ {
24412+ /** Transfer complete mask */
24413+ unsigned xfercompl : 1;
24414+ /** Endpoint disable mask */
24415+ unsigned epdisabled : 1;
24416+ /** AHB Error mask */
24417+ unsigned ahberr : 1;
24418+ /** TimeOUT Handshake mask (non-ISOC EPs) */
24419+ unsigned timeout : 1;
24420+ /** IN Token received with TxF Empty mask */
24421+ unsigned intktxfemp : 1;
24422+ /** IN Token Received with EP mismatch mask */
24423+ unsigned intknepmis : 1;
24424+ /** IN Endpoint HAK Effective mask */
24425+ unsigned inepnakeff : 1;
24426+ /** IN Endpoint HAK Effective mask */
24427+ unsigned emptyintr : 1;
24428+
24429+ unsigned txfifoundrn : 1;
24430+
24431+ /** BNA Interrupt mask */
24432+ unsigned bna : 1;
24433+
24434+ unsigned reserved10_12 : 3;
24435+ /** BNA Interrupt mask */
24436+ unsigned nak : 1;
24437+
24438+ unsigned reserved14_31 : 18;
24439+ } b;
24440+} diepint_data_t;
24441+
24442+/**
24443+ * This union represents the bit fields in the Device IN EP
24444+ * Common/Dedicated Interrupt Mask Register.
24445+ */
24446+typedef union diepint_data diepmsk_data_t;
24447+
24448+/**
24449+ * This union represents the bit fields in the Device OUT EP Interrupt
24450+ * Registerand Device OUT EP Common Interrupt Mask Register.
24451+ *
24452+ * - Read the register into the <i>d32</i> member then set/clear the
24453+ * bits using the <i>b</i>it elements.
24454+ */
24455+typedef union doepint_data
24456+{
24457+ /** raw register data */
24458+ uint32_t d32;
24459+ /** register bits */
24460+ struct
24461+ {
24462+ /** Transfer complete */
24463+ unsigned xfercompl : 1;
24464+ /** Endpoint disable */
24465+ unsigned epdisabled : 1;
24466+ /** AHB Error */
24467+ unsigned ahberr : 1;
24468+ /** Setup Phase Done (contorl EPs) */
24469+ unsigned setup : 1;
24470+ /** OUT Token Received when Endpoint Disabled */
24471+ unsigned outtknepdis : 1;
24472+
24473+ unsigned stsphsercvd : 1;
24474+ /** Back-to-Back SETUP Packets Received */
24475+ unsigned back2backsetup : 1;
24476+
24477+ unsigned reserved7 : 1;
24478+ /** OUT packet Error */
24479+ unsigned outpkterr : 1;
24480+ /** BNA Interrupt */
24481+ unsigned bna : 1;
24482+
24483+ unsigned reserved10 : 1;
24484+ /** Packet Drop Status */
24485+ unsigned pktdrpsts : 1;
24486+ /** Babble Interrupt */
24487+ unsigned babble : 1;
24488+ /** NAK Interrupt */
24489+ unsigned nak : 1;
24490+ /** NYET Interrupt */
24491+ unsigned nyet : 1;
24492+
24493+ unsigned reserved15_31 : 17;
24494+ } b;
24495+} doepint_data_t;
24496+
24497+/**
24498+ * This union represents the bit fields in the Device OUT EP
24499+ * Common/Dedicated Interrupt Mask Register.
24500+ */
24501+typedef union doepint_data doepmsk_data_t;
24502+
24503+/**
24504+ * This union represents the bit fields in the Device All EP Interrupt
24505+ * and Mask Registers.
24506+ * - Read the register into the <i>d32</i> member then set/clear the
24507+ * bits using the <i>b</i>it elements.
24508+ */
24509+typedef union daint_data
24510+{
24511+ /** raw register data */
24512+ uint32_t d32;
24513+ /** register bits */
24514+ struct
24515+ {
24516+ /** IN Endpoint bits */
24517+ unsigned in : 16;
24518+ /** OUT Endpoint bits */
24519+ unsigned out : 16;
24520+ } ep;
24521+ struct
24522+ {
24523+ /** IN Endpoint bits */
24524+ unsigned inep0 : 1;
24525+ unsigned inep1 : 1;
24526+ unsigned inep2 : 1;
24527+ unsigned inep3 : 1;
24528+ unsigned inep4 : 1;
24529+ unsigned inep5 : 1;
24530+ unsigned inep6 : 1;
24531+ unsigned inep7 : 1;
24532+ unsigned inep8 : 1;
24533+ unsigned inep9 : 1;
24534+ unsigned inep10 : 1;
24535+ unsigned inep11 : 1;
24536+ unsigned inep12 : 1;
24537+ unsigned inep13 : 1;
24538+ unsigned inep14 : 1;
24539+ unsigned inep15 : 1;
24540+ /** OUT Endpoint bits */
24541+ unsigned outep0 : 1;
24542+ unsigned outep1 : 1;
24543+ unsigned outep2 : 1;
24544+ unsigned outep3 : 1;
24545+ unsigned outep4 : 1;
24546+ unsigned outep5 : 1;
24547+ unsigned outep6 : 1;
24548+ unsigned outep7 : 1;
24549+ unsigned outep8 : 1;
24550+ unsigned outep9 : 1;
24551+ unsigned outep10 : 1;
24552+ unsigned outep11 : 1;
24553+ unsigned outep12 : 1;
24554+ unsigned outep13 : 1;
24555+ unsigned outep14 : 1;
24556+ unsigned outep15 : 1;
24557+ } b;
24558+} daint_data_t;
24559+
24560+/**
24561+ * This union represents the bit fields in the Device IN Token Queue
24562+ * Read Registers.
24563+ * - Read the register into the <i>d32</i> member.
24564+ * - READ-ONLY Register
24565+ */
24566+typedef union dtknq1_data
24567+{
24568+ /** raw register data */
24569+ uint32_t d32;
24570+ /** register bits */
24571+ struct
24572+ {
24573+ /** In Token Queue Write Pointer */
24574+ unsigned intknwptr : 5;
24575+ /** Reserved */
24576+ unsigned reserved05_06 : 2;
24577+ /** write pointer has wrapped. */
24578+ unsigned wrap_bit : 1;
24579+ /** EP Numbers of IN Tokens 0 ... 4 */
24580+ unsigned epnums0_5 : 24;
24581+ }b;
24582+} dtknq1_data_t;
24583+
24584+/**
24585+ * This union represents Threshold control Register
24586+ * - Read and write the register into the <i>d32</i> member.
24587+ * - READ-WRITABLE Register
24588+ */
24589+typedef union dthrctl_data
24590+{
24591+ /** raw register data */
24592+ uint32_t d32;
24593+ /** register bits */
24594+ struct
24595+ {
24596+ /** non ISO Tx Thr. Enable */
24597+ unsigned non_iso_thr_en : 1;
24598+ /** ISO Tx Thr. Enable */
24599+ unsigned iso_thr_en : 1;
24600+ /** Tx Thr. Length */
24601+ unsigned tx_thr_len : 9;
24602+ /** Reserved */
24603+ unsigned reserved11_15 : 5;
24604+ /** Rx Thr. Enable */
24605+ unsigned rx_thr_en : 1;
24606+ /** Rx Thr. Length */
24607+ unsigned rx_thr_len : 9;
24608+ /** Reserved */
24609+ unsigned reserved26_31 : 6;
24610+ }b;
24611+} dthrctl_data_t;
24612+
24613+
24614+/**
24615+ * Device Logical IN Endpoint-Specific Registers. <i>Offsets
24616+ * 900h-AFCh</i>
24617+ *
24618+ * There will be one set of endpoint registers per logical endpoint
24619+ * implemented.
24620+ *
24621+ * <i>These registers are visible only in Device mode and must not be
24622+ * accessed in Host mode, as the results are unknown.</i>
24623+ */
24624+typedef struct dwc_otg_dev_in_ep_regs
24625+{
24626+ /** Device IN Endpoint Control Register. <i>Offset:900h +
24627+ * (ep_num * 20h) + 00h</i> */
24628+ volatile uint32_t diepctl;
24629+ /** Reserved. <i>Offset:900h + (ep_num * 20h) + 04h</i> */
24630+ uint32_t reserved04;
24631+ /** Device IN Endpoint Interrupt Register. <i>Offset:900h +
24632+ * (ep_num * 20h) + 08h</i> */
24633+ volatile uint32_t diepint;
24634+ /** Reserved. <i>Offset:900h + (ep_num * 20h) + 0Ch</i> */
24635+ uint32_t reserved0C;
24636+ /** Device IN Endpoint Transfer Size
24637+ * Register. <i>Offset:900h + (ep_num * 20h) + 10h</i> */
24638+ volatile uint32_t dieptsiz;
24639+ /** Device IN Endpoint DMA Address Register. <i>Offset:900h +
24640+ * (ep_num * 20h) + 14h</i> */
24641+ volatile uint32_t diepdma;
24642+ /** Device IN Endpoint Transmit FIFO Status Register. <i>Offset:900h +
24643+ * (ep_num * 20h) + 18h</i> */
24644+ volatile uint32_t dtxfsts;
24645+ /** Device IN Endpoint DMA Buffer Register. <i>Offset:900h +
24646+ * (ep_num * 20h) + 1Ch</i> */
24647+ volatile uint32_t diepdmab;
24648+} dwc_otg_dev_in_ep_regs_t;
24649+
24650+/**
24651+ * Device Logical OUT Endpoint-Specific Registers. <i>Offsets:
24652+ * B00h-CFCh</i>
24653+ *
24654+ * There will be one set of endpoint registers per logical endpoint
24655+ * implemented.
24656+ *
24657+ * <i>These registers are visible only in Device mode and must not be
24658+ * accessed in Host mode, as the results are unknown.</i>
24659+ */
24660+typedef struct dwc_otg_dev_out_ep_regs
24661+{
24662+ /** Device OUT Endpoint Control Register. <i>Offset:B00h +
24663+ * (ep_num * 20h) + 00h</i> */
24664+ volatile uint32_t doepctl;
24665+ /** Device OUT Endpoint Frame number Register. <i>Offset:
24666+ * B00h + (ep_num * 20h) + 04h</i> */
24667+ volatile uint32_t doepfn;
24668+ /** Device OUT Endpoint Interrupt Register. <i>Offset:B00h +
24669+ * (ep_num * 20h) + 08h</i> */
24670+ volatile uint32_t doepint;
24671+ /** Reserved. <i>Offset:B00h + (ep_num * 20h) + 0Ch</i> */
24672+ uint32_t reserved0C;
24673+ /** Device OUT Endpoint Transfer Size Register. <i>Offset:
24674+ * B00h + (ep_num * 20h) + 10h</i> */
24675+ volatile uint32_t doeptsiz;
24676+ /** Device OUT Endpoint DMA Address Register. <i>Offset:B00h
24677+ * + (ep_num * 20h) + 14h</i> */
24678+ volatile uint32_t doepdma;
24679+ /** Reserved. <i>Offset:B00h + * (ep_num * 20h) + 1Ch</i> */
24680+ uint32_t unused;
24681+ /** Device OUT Endpoint DMA Buffer Register. <i>Offset:B00h
24682+ * + (ep_num * 20h) + 1Ch</i> */
24683+ uint32_t doepdmab;
24684+} dwc_otg_dev_out_ep_regs_t;
24685+
24686+/**
24687+ * This union represents the bit fields in the Device EP Control
24688+ * Register. Read the register into the <i>d32</i> member then
24689+ * set/clear the bits using the <i>b</i>it elements.
24690+ */
24691+typedef union depctl_data
24692+{
24693+ /** raw register data */
24694+ uint32_t d32;
24695+ /** register bits */
24696+ struct
24697+ {
24698+ /** Maximum Packet Size
24699+ * IN/OUT EPn
24700+ * IN/OUT EP0 - 2 bits
24701+ * 2'b00: 64 Bytes
24702+ * 2'b01: 32
24703+ * 2'b10: 16
24704+ * 2'b11: 8 */
24705+ unsigned mps : 11;
24706+#define DWC_DEP0CTL_MPS_64 0
24707+#define DWC_DEP0CTL_MPS_32 1
24708+#define DWC_DEP0CTL_MPS_16 2
24709+#define DWC_DEP0CTL_MPS_8 3
24710+
24711+ /** Next Endpoint
24712+ * IN EPn/IN EP0
24713+ * OUT EPn/OUT EP0 - reserved */
24714+ unsigned nextep : 4;
24715+
24716+ /** USB Active Endpoint */
24717+ unsigned usbactep : 1;
24718+
24719+ /** Endpoint DPID (INTR/Bulk IN and OUT endpoints)
24720+ * This field contains the PID of the packet going to
24721+ * be received or transmitted on this endpoint. The
24722+ * application should program the PID of the first
24723+ * packet going to be received or transmitted on this
24724+ * endpoint , after the endpoint is
24725+ * activated. Application use the SetD1PID and
24726+ * SetD0PID fields of this register to program either
24727+ * D0 or D1 PID.
24728+ *
24729+ * The encoding for this field is
24730+ * - 0: D0
24731+ * - 1: D1
24732+ */
24733+ unsigned dpid : 1;
24734+
24735+ /** NAK Status */
24736+ unsigned naksts : 1;
24737+
24738+ /** Endpoint Type
24739+ * 2'b00: Control
24740+ * 2'b01: Isochronous
24741+ * 2'b10: Bulk
24742+ * 2'b11: Interrupt */
24743+ unsigned eptype : 2;
24744+
24745+ /** Snoop Mode
24746+ * OUT EPn/OUT EP0
24747+ * IN EPn/IN EP0 - reserved */
24748+ unsigned snp : 1;
24749+
24750+ /** Stall Handshake */
24751+ unsigned stall : 1;
24752+
24753+ /** Tx Fifo Number
24754+ * IN EPn/IN EP0
24755+ * OUT EPn/OUT EP0 - reserved */
24756+ unsigned txfnum : 4;
24757+
24758+ /** Clear NAK */
24759+ unsigned cnak : 1;
24760+ /** Set NAK */
24761+ unsigned snak : 1;
24762+ /** Set DATA0 PID (INTR/Bulk IN and OUT endpoints)
24763+ * Writing to this field sets the Endpoint DPID (DPID)
24764+ * field in this register to DATA0. Set Even
24765+ * (micro)frame (SetEvenFr) (ISO IN and OUT Endpoints)
24766+ * Writing to this field sets the Even/Odd
24767+ * (micro)frame (EO_FrNum) field to even (micro)
24768+ * frame.
24769+ */
24770+ unsigned setd0pid : 1;
24771+ /** Set DATA1 PID (INTR/Bulk IN and OUT endpoints)
24772+ * Writing to this field sets the Endpoint DPID (DPID)
24773+ * field in this register to DATA1 Set Odd
24774+ * (micro)frame (SetOddFr) (ISO IN and OUT Endpoints)
24775+ * Writing to this field sets the Even/Odd
24776+ * (micro)frame (EO_FrNum) field to odd (micro) frame.
24777+ */
24778+ unsigned setd1pid : 1;
24779+
24780+ /** Endpoint Disable */
24781+ unsigned epdis : 1;
24782+ /** Endpoint Enable */
24783+ unsigned epena : 1;
24784+ } b;
24785+} depctl_data_t;
24786+
24787+/**
24788+ * This union represents the bit fields in the Device EP Transfer
24789+ * Size Register. Read the register into the <i>d32</i> member then
24790+ * set/clear the bits using the <i>b</i>it elements.
24791+ */
24792+typedef union deptsiz_data
24793+{
24794+ /** raw register data */
24795+ uint32_t d32;
24796+ /** register bits */
24797+ struct {
24798+ /** Transfer size */
24799+ unsigned xfersize : 19;
24800+ /** Packet Count */
24801+ unsigned pktcnt : 10;
24802+ /** Multi Count - Periodic IN endpoints */
24803+ unsigned mc : 2;
24804+ unsigned reserved : 1;
24805+ } b;
24806+} deptsiz_data_t;
24807+
24808+/**
24809+ * This union represents the bit fields in the Device EP 0 Transfer
24810+ * Size Register. Read the register into the <i>d32</i> member then
24811+ * set/clear the bits using the <i>b</i>it elements.
24812+ */
24813+typedef union deptsiz0_data
24814+{
24815+ /** raw register data */
24816+ uint32_t d32;
24817+ /** register bits */
24818+ struct {
24819+ /** Transfer size */
24820+ unsigned xfersize : 7;
24821+ /** Reserved */
24822+ unsigned reserved7_18 : 12;
24823+ /** Packet Count */
24824+ unsigned pktcnt : 1;
24825+ /** Reserved */
24826+ unsigned reserved20_28 : 9;
24827+ /**Setup Packet Count (DOEPTSIZ0 Only) */
24828+ unsigned supcnt : 2;
24829+ unsigned reserved31;
24830+ } b;
24831+} deptsiz0_data_t;
24832+
24833+
24834+/////////////////////////////////////////////////
24835+// DMA Descriptor Specific Structures
24836+//
24837+
24838+/** Buffer status definitions */
24839+
24840+#define BS_HOST_READY 0x0
24841+#define BS_DMA_BUSY 0x1
24842+#define BS_DMA_DONE 0x2
24843+#define BS_HOST_BUSY 0x3
24844+
24845+/** Receive/Transmit status definitions */
24846+
24847+#define RTS_SUCCESS 0x0
24848+#define RTS_BUFFLUSH 0x1
24849+#define RTS_RESERVED 0x2
24850+#define RTS_BUFERR 0x3
24851+
24852+
24853+/**
24854+ * This union represents the bit fields in the DMA Descriptor
24855+ * status quadlet. Read the quadlet into the <i>d32</i> member then
24856+ * set/clear the bits using the <i>b</i>it, <i>b_iso_out</i> and
24857+ * <i>b_iso_in</i> elements.
24858+ */
24859+typedef union desc_sts_data
24860+{
24861+ /** raw register data */
24862+ uint32_t d32;
24863+ /** quadlet bits */
24864+ struct {
24865+ /** Received number of bytes */
24866+ unsigned bytes : 16;
24867+
24868+ unsigned reserved16_22 : 7;
24869+ /** Multiple Transfer - only for OUT EPs */
24870+ unsigned mtrf : 1;
24871+ /** Setup Packet received - only for OUT EPs */
24872+ unsigned sr : 1;
24873+ /** Interrupt On Complete */
24874+ unsigned ioc : 1;
24875+ /** Short Packet */
24876+ unsigned sp : 1;
24877+ /** Last */
24878+ unsigned l : 1;
24879+ /** Receive Status */
24880+ unsigned sts : 2;
24881+ /** Buffer Status */
24882+ unsigned bs : 2;
24883+ } b;
24884+
24885+#ifdef DWC_EN_ISOC
24886+ /** iso out quadlet bits */
24887+ struct {
24888+ /** Received number of bytes */
24889+ unsigned rxbytes : 11;
24890+
24891+ unsigned reserved11 : 1;
24892+ /** Frame Number */
24893+ unsigned framenum : 11;
24894+ /** Received ISO Data PID */
24895+ unsigned pid : 2;
24896+ /** Interrupt On Complete */
24897+ unsigned ioc : 1;
24898+ /** Short Packet */
24899+ unsigned sp : 1;
24900+ /** Last */
24901+ unsigned l : 1;
24902+ /** Receive Status */
24903+ unsigned rxsts : 2;
24904+ /** Buffer Status */
24905+ unsigned bs : 2;
24906+ } b_iso_out;
24907+
24908+ /** iso in quadlet bits */
24909+ struct {
24910+ /** Transmited number of bytes */
24911+ unsigned txbytes : 12;
24912+ /** Frame Number */
24913+ unsigned framenum : 11;
24914+ /** Transmited ISO Data PID */
24915+ unsigned pid : 2;
24916+ /** Interrupt On Complete */
24917+ unsigned ioc : 1;
24918+ /** Short Packet */
24919+ unsigned sp : 1;
24920+ /** Last */
24921+ unsigned l : 1;
24922+ /** Transmit Status */
24923+ unsigned txsts : 2;
24924+ /** Buffer Status */
24925+ unsigned bs : 2;
24926+ } b_iso_in;
24927+#endif //DWC_EN_ISOC
24928+} desc_sts_data_t;
24929+
24930+/**
24931+ * DMA Descriptor structure
24932+ *
24933+ * DMA Descriptor structure contains two quadlets:
24934+ * Status quadlet and Data buffer pointer.
24935+ */
24936+typedef struct dwc_otg_dma_desc
24937+{
24938+ /** DMA Descriptor status quadlet */
24939+ desc_sts_data_t status;
24940+ /** DMA Descriptor data buffer pointer */
24941+ dma_addr_t buf;
24942+} dwc_otg_dma_desc_t;
24943+
24944+/**
24945+ * The dwc_otg_dev_if structure contains information needed to manage
24946+ * the DWC_otg controller acting in device mode. It represents the
24947+ * programming view of the device-specific aspects of the controller.
24948+ */
24949+typedef struct dwc_otg_dev_if
24950+{
24951+ /** Pointer to device Global registers.
24952+ * Device Global Registers starting at offset 800h
24953+ */
24954+ dwc_otg_device_global_regs_t *dev_global_regs;
24955+#define DWC_DEV_GLOBAL_REG_OFFSET 0x800
24956+
24957+ /**
24958+ * Device Logical IN Endpoint-Specific Registers 900h-AFCh
24959+ */
24960+ dwc_otg_dev_in_ep_regs_t *in_ep_regs[MAX_EPS_CHANNELS];
24961+#define DWC_DEV_IN_EP_REG_OFFSET 0x900
24962+#define DWC_EP_REG_OFFSET 0x20
24963+
24964+ /** Device Logical OUT Endpoint-Specific Registers B00h-CFCh */
24965+ dwc_otg_dev_out_ep_regs_t *out_ep_regs[MAX_EPS_CHANNELS];
24966+#define DWC_DEV_OUT_EP_REG_OFFSET 0xB00
24967+
24968+ /* Device configuration information*/
24969+ uint8_t speed; /**< Device Speed 0: Unknown, 1: LS, 2:FS, 3: HS */
24970+ uint8_t num_in_eps; /**< Number # of Tx EP range: 0-15 exept ep0 */
24971+ uint8_t num_out_eps; /**< Number # of Rx EP range: 0-15 exept ep 0*/
24972+
24973+ /** Size of periodic FIFOs (Bytes) */
24974+ uint16_t perio_tx_fifo_size[MAX_PERIO_FIFOS];
24975+
24976+ /** Size of Tx FIFOs (Bytes) */
24977+ uint16_t tx_fifo_size[MAX_TX_FIFOS];
24978+
24979+ /** Thresholding enable flags and length varaiables **/
24980+ uint16_t rx_thr_en;
24981+ uint16_t iso_tx_thr_en;
24982+ uint16_t non_iso_tx_thr_en;
24983+
24984+ uint16_t rx_thr_length;
24985+ uint16_t tx_thr_length;
24986+
24987+ /**
24988+ * Pointers to the DMA Descriptors for EP0 Control
24989+ * transfers (virtual and physical)
24990+ */
24991+
24992+ /** 2 descriptors for SETUP packets */
24993+ uint32_t dma_setup_desc_addr[2];
24994+ dwc_otg_dma_desc_t* setup_desc_addr[2];
24995+
24996+ /** Pointer to Descriptor with latest SETUP packet */
24997+ dwc_otg_dma_desc_t* psetup;
24998+
24999+ /** Index of current SETUP handler descriptor */
25000+ uint32_t setup_desc_index;
25001+
25002+ /** Descriptor for Data In or Status In phases */
25003+ uint32_t dma_in_desc_addr;
25004+ dwc_otg_dma_desc_t* in_desc_addr;;
25005+
25006+ /** Descriptor for Data Out or Status Out phases */
25007+ uint32_t dma_out_desc_addr;
25008+ dwc_otg_dma_desc_t* out_desc_addr;
25009+
25010+} dwc_otg_dev_if_t;
25011+
25012+
25013+
25014+
25015+/////////////////////////////////////////////////
25016+// Host Mode Register Structures
25017+//
25018+/**
25019+ * The Host Global Registers structure defines the size and relative
25020+ * field offsets for the Host Mode Global Registers. Host Global
25021+ * Registers offsets 400h-7FFh.
25022+*/
25023+typedef struct dwc_otg_host_global_regs
25024+{
25025+ /** Host Configuration Register. <i>Offset: 400h</i> */
25026+ volatile uint32_t hcfg;
25027+ /** Host Frame Interval Register. <i>Offset: 404h</i> */
25028+ volatile uint32_t hfir;
25029+ /** Host Frame Number / Frame Remaining Register. <i>Offset: 408h</i> */
25030+ volatile uint32_t hfnum;
25031+ /** Reserved. <i>Offset: 40Ch</i> */
25032+ uint32_t reserved40C;
25033+ /** Host Periodic Transmit FIFO/ Queue Status Register. <i>Offset: 410h</i> */
25034+ volatile uint32_t hptxsts;
25035+ /** Host All Channels Interrupt Register. <i>Offset: 414h</i> */
25036+ volatile uint32_t haint;
25037+ /** Host All Channels Interrupt Mask Register. <i>Offset: 418h</i> */
25038+ volatile uint32_t haintmsk;
25039+} dwc_otg_host_global_regs_t;
25040+
25041+/**
25042+ * This union represents the bit fields in the Host Configuration Register.
25043+ * Read the register into the <i>d32</i> member then set/clear the bits using
25044+ * the <i>b</i>it elements. Write the <i>d32</i> member to the hcfg register.
25045+ */
25046+typedef union hcfg_data
25047+{
25048+ /** raw register data */
25049+ uint32_t d32;
25050+
25051+ /** register bits */
25052+ struct
25053+ {
25054+ /** FS/LS Phy Clock Select */
25055+ unsigned fslspclksel : 2;
25056+#define DWC_HCFG_30_60_MHZ 0
25057+#define DWC_HCFG_48_MHZ 1
25058+#define DWC_HCFG_6_MHZ 2
25059+
25060+ /** FS/LS Only Support */
25061+ unsigned fslssupp : 1;
25062+ } b;
25063+} hcfg_data_t;
25064+
25065+/**
25066+ * This union represents the bit fields in the Host Frame Remaing/Number
25067+ * Register.
25068+ */
25069+typedef union hfir_data
25070+{
25071+ /** raw register data */
25072+ uint32_t d32;
25073+
25074+ /** register bits */
25075+ struct
25076+ {
25077+ unsigned frint : 16;
25078+ unsigned reserved : 16;
25079+ } b;
25080+} hfir_data_t;
25081+
25082+/**
25083+ * This union represents the bit fields in the Host Frame Remaing/Number
25084+ * Register.
25085+ */
25086+typedef union hfnum_data
25087+{
25088+ /** raw register data */
25089+ uint32_t d32;
25090+
25091+ /** register bits */
25092+ struct
25093+ {
25094+ unsigned frnum : 16;
25095+#define DWC_HFNUM_MAX_FRNUM 0x3FFF
25096+ unsigned frrem : 16;
25097+ } b;
25098+} hfnum_data_t;
25099+
25100+typedef union hptxsts_data
25101+{
25102+ /** raw register data */
25103+ uint32_t d32;
25104+
25105+ /** register bits */
25106+ struct
25107+ {
25108+ unsigned ptxfspcavail : 16;
25109+ unsigned ptxqspcavail : 8;
25110+ /** Top of the Periodic Transmit Request Queue
25111+ * - bit 24 - Terminate (last entry for the selected channel)
25112+ * - bits 26:25 - Token Type
25113+ * - 2'b00 - Zero length
25114+ * - 2'b01 - Ping
25115+ * - 2'b10 - Disable
25116+ * - bits 30:27 - Channel Number
25117+ * - bit 31 - Odd/even microframe
25118+ */
25119+ unsigned ptxqtop_terminate : 1;
25120+ unsigned ptxqtop_token : 2;
25121+ unsigned ptxqtop_chnum : 4;
25122+ unsigned ptxqtop_odd : 1;
25123+ } b;
25124+} hptxsts_data_t;
25125+
25126+/**
25127+ * This union represents the bit fields in the Host Port Control and Status
25128+ * Register. Read the register into the <i>d32</i> member then set/clear the
25129+ * bits using the <i>b</i>it elements. Write the <i>d32</i> member to the
25130+ * hprt0 register.
25131+ */
25132+typedef union hprt0_data
25133+{
25134+ /** raw register data */
25135+ uint32_t d32;
25136+ /** register bits */
25137+ struct
25138+ {
25139+ unsigned prtconnsts : 1;
25140+ unsigned prtconndet : 1;
25141+ unsigned prtena : 1;
25142+ unsigned prtenchng : 1;
25143+ unsigned prtovrcurract : 1;
25144+ unsigned prtovrcurrchng : 1;
25145+ unsigned prtres : 1;
25146+ unsigned prtsusp : 1;
25147+ unsigned prtrst : 1;
25148+ unsigned reserved9 : 1;
25149+ unsigned prtlnsts : 2;
25150+ unsigned prtpwr : 1;
25151+ unsigned prttstctl : 4;
25152+ unsigned prtspd : 2;
25153+#define DWC_HPRT0_PRTSPD_HIGH_SPEED 0
25154+#define DWC_HPRT0_PRTSPD_FULL_SPEED 1
25155+#define DWC_HPRT0_PRTSPD_LOW_SPEED 2
25156+ unsigned reserved19_31 : 13;
25157+ } b;
25158+} hprt0_data_t;
25159+
25160+/**
25161+ * This union represents the bit fields in the Host All Interrupt
25162+ * Register.
25163+ */
25164+typedef union haint_data
25165+{
25166+ /** raw register data */
25167+ uint32_t d32;
25168+ /** register bits */
25169+ struct
25170+ {
25171+ unsigned ch0 : 1;
25172+ unsigned ch1 : 1;
25173+ unsigned ch2 : 1;
25174+ unsigned ch3 : 1;
25175+ unsigned ch4 : 1;
25176+ unsigned ch5 : 1;
25177+ unsigned ch6 : 1;
25178+ unsigned ch7 : 1;
25179+ unsigned ch8 : 1;
25180+ unsigned ch9 : 1;
25181+ unsigned ch10 : 1;
25182+ unsigned ch11 : 1;
25183+ unsigned ch12 : 1;
25184+ unsigned ch13 : 1;
25185+ unsigned ch14 : 1;
25186+ unsigned ch15 : 1;
25187+ unsigned reserved : 16;
25188+ } b;
25189+
25190+ struct
25191+ {
25192+ unsigned chint : 16;
25193+ unsigned reserved : 16;
25194+ } b2;
25195+} haint_data_t;
25196+
25197+/**
25198+ * This union represents the bit fields in the Host All Interrupt
25199+ * Register.
25200+ */
25201+typedef union haintmsk_data
25202+{
25203+ /** raw register data */
25204+ uint32_t d32;
25205+ /** register bits */
25206+ struct
25207+ {
25208+ unsigned ch0 : 1;
25209+ unsigned ch1 : 1;
25210+ unsigned ch2 : 1;
25211+ unsigned ch3 : 1;
25212+ unsigned ch4 : 1;
25213+ unsigned ch5 : 1;
25214+ unsigned ch6 : 1;
25215+ unsigned ch7 : 1;
25216+ unsigned ch8 : 1;
25217+ unsigned ch9 : 1;
25218+ unsigned ch10 : 1;
25219+ unsigned ch11 : 1;
25220+ unsigned ch12 : 1;
25221+ unsigned ch13 : 1;
25222+ unsigned ch14 : 1;
25223+ unsigned ch15 : 1;
25224+ unsigned reserved : 16;
25225+ } b;
25226+
25227+ struct
25228+ {
25229+ unsigned chint : 16;
25230+ unsigned reserved : 16;
25231+ } b2;
25232+} haintmsk_data_t;
25233+
25234+/**
25235+ * Host Channel Specific Registers. <i>500h-5FCh</i>
25236+ */
25237+typedef struct dwc_otg_hc_regs
25238+{
25239+ /** Host Channel 0 Characteristic Register. <i>Offset: 500h + (chan_num * 20h) + 00h</i> */
25240+ volatile uint32_t hcchar;
25241+ /** Host Channel 0 Split Control Register. <i>Offset: 500h + (chan_num * 20h) + 04h</i> */
25242+ volatile uint32_t hcsplt;
25243+ /** Host Channel 0 Interrupt Register. <i>Offset: 500h + (chan_num * 20h) + 08h</i> */
25244+ volatile uint32_t hcint;
25245+ /** Host Channel 0 Interrupt Mask Register. <i>Offset: 500h + (chan_num * 20h) + 0Ch</i> */
25246+ volatile uint32_t hcintmsk;
25247+ /** Host Channel 0 Transfer Size Register. <i>Offset: 500h + (chan_num * 20h) + 10h</i> */
25248+ volatile uint32_t hctsiz;
25249+ /** Host Channel 0 DMA Address Register. <i>Offset: 500h + (chan_num * 20h) + 14h</i> */
25250+ volatile uint32_t hcdma;
25251+ /** Reserved. <i>Offset: 500h + (chan_num * 20h) + 18h - 500h + (chan_num * 20h) + 1Ch</i> */
25252+ uint32_t reserved[2];
25253+} dwc_otg_hc_regs_t;
25254+
25255+/**
25256+ * This union represents the bit fields in the Host Channel Characteristics
25257+ * Register. Read the register into the <i>d32</i> member then set/clear the
25258+ * bits using the <i>b</i>it elements. Write the <i>d32</i> member to the
25259+ * hcchar register.
25260+ */
25261+typedef union hcchar_data
25262+{
25263+ /** raw register data */
25264+ uint32_t d32;
25265+
25266+ /** register bits */
25267+ struct
25268+ {
25269+ /** Maximum packet size in bytes */
25270+ unsigned mps : 11;
25271+
25272+ /** Endpoint number */
25273+ unsigned epnum : 4;
25274+
25275+ /** 0: OUT, 1: IN */
25276+ unsigned epdir : 1;
25277+
25278+ unsigned reserved : 1;
25279+
25280+ /** 0: Full/high speed device, 1: Low speed device */
25281+ unsigned lspddev : 1;
25282+
25283+ /** 0: Control, 1: Isoc, 2: Bulk, 3: Intr */
25284+ unsigned eptype : 2;
25285+
25286+ /** Packets per frame for periodic transfers. 0 is reserved. */
25287+ unsigned multicnt : 2;
25288+
25289+ /** Device address */
25290+ unsigned devaddr : 7;
25291+
25292+ /**
25293+ * Frame to transmit periodic transaction.
25294+ * 0: even, 1: odd
25295+ */
25296+ unsigned oddfrm : 1;
25297+
25298+ /** Channel disable */
25299+ unsigned chdis : 1;
25300+
25301+ /** Channel enable */
25302+ unsigned chen : 1;
25303+ } b;
25304+} hcchar_data_t;
25305+
25306+typedef union hcsplt_data
25307+{
25308+ /** raw register data */
25309+ uint32_t d32;
25310+
25311+ /** register bits */
25312+ struct
25313+ {
25314+ /** Port Address */
25315+ unsigned prtaddr : 7;
25316+
25317+ /** Hub Address */
25318+ unsigned hubaddr : 7;
25319+
25320+ /** Transaction Position */
25321+ unsigned xactpos : 2;
25322+#define DWC_HCSPLIT_XACTPOS_MID 0
25323+#define DWC_HCSPLIT_XACTPOS_END 1
25324+#define DWC_HCSPLIT_XACTPOS_BEGIN 2
25325+#define DWC_HCSPLIT_XACTPOS_ALL 3
25326+
25327+ /** Do Complete Split */
25328+ unsigned compsplt : 1;
25329+
25330+ /** Reserved */
25331+ unsigned reserved : 14;
25332+
25333+ /** Split Enble */
25334+ unsigned spltena : 1;
25335+ } b;
25336+} hcsplt_data_t;
25337+
25338+
25339+/**
25340+ * This union represents the bit fields in the Host All Interrupt
25341+ * Register.
25342+ */
25343+typedef union hcint_data
25344+{
25345+ /** raw register data */
25346+ uint32_t d32;
25347+ /** register bits */
25348+ struct
25349+ {
25350+ /** Transfer Complete */
25351+ unsigned xfercomp : 1;
25352+ /** Channel Halted */
25353+ unsigned chhltd : 1;
25354+ /** AHB Error */
25355+ unsigned ahberr : 1;
25356+ /** STALL Response Received */
25357+ unsigned stall : 1;
25358+ /** NAK Response Received */
25359+ unsigned nak : 1;
25360+ /** ACK Response Received */
25361+ unsigned ack : 1;
25362+ /** NYET Response Received */
25363+ unsigned nyet : 1;
25364+ /** Transaction Err */
25365+ unsigned xacterr : 1;
25366+ /** Babble Error */
25367+ unsigned bblerr : 1;
25368+ /** Frame Overrun */
25369+ unsigned frmovrun : 1;
25370+ /** Data Toggle Error */
25371+ unsigned datatglerr : 1;
25372+ /** Reserved */
25373+ unsigned reserved : 21;
25374+ } b;
25375+} hcint_data_t;
25376+
25377+/**
25378+ * This union represents the bit fields in the Host Channel Transfer Size
25379+ * Register. Read the register into the <i>d32</i> member then set/clear the
25380+ * bits using the <i>b</i>it elements. Write the <i>d32</i> member to the
25381+ * hcchar register.
25382+ */
25383+typedef union hctsiz_data
25384+{
25385+ /** raw register data */
25386+ uint32_t d32;
25387+
25388+ /** register bits */
25389+ struct
25390+ {
25391+ /** Total transfer size in bytes */
25392+ unsigned xfersize : 19;
25393+
25394+ /** Data packets to transfer */
25395+ unsigned pktcnt : 10;
25396+
25397+ /**
25398+ * Packet ID for next data packet
25399+ * 0: DATA0
25400+ * 1: DATA2
25401+ * 2: DATA1
25402+ * 3: MDATA (non-Control), SETUP (Control)
25403+ */
25404+ unsigned pid : 2;
25405+#define DWC_HCTSIZ_DATA0 0
25406+#define DWC_HCTSIZ_DATA1 2
25407+#define DWC_HCTSIZ_DATA2 1
25408+#define DWC_HCTSIZ_MDATA 3
25409+#define DWC_HCTSIZ_SETUP 3
25410+
25411+ /** Do PING protocol when 1 */
25412+ unsigned dopng : 1;
25413+ } b;
25414+} hctsiz_data_t;
25415+
25416+/**
25417+ * This union represents the bit fields in the Host Channel Interrupt Mask
25418+ * Register. Read the register into the <i>d32</i> member then set/clear the
25419+ * bits using the <i>b</i>it elements. Write the <i>d32</i> member to the
25420+ * hcintmsk register.
25421+ */
25422+typedef union hcintmsk_data
25423+{
25424+ /** raw register data */
25425+ uint32_t d32;
25426+
25427+ /** register bits */
25428+ struct
25429+ {
25430+ unsigned xfercompl : 1;
25431+ unsigned chhltd : 1;
25432+ unsigned ahberr : 1;
25433+ unsigned stall : 1;
25434+ unsigned nak : 1;
25435+ unsigned ack : 1;
25436+ unsigned nyet : 1;
25437+ unsigned xacterr : 1;
25438+ unsigned bblerr : 1;
25439+ unsigned frmovrun : 1;
25440+ unsigned datatglerr : 1;
25441+ unsigned reserved : 21;
25442+ } b;
25443+} hcintmsk_data_t;
25444+
25445+/** OTG Host Interface Structure.
25446+ *
25447+ * The OTG Host Interface Structure structure contains information
25448+ * needed to manage the DWC_otg controller acting in host mode. It
25449+ * represents the programming view of the host-specific aspects of the
25450+ * controller.
25451+ */
25452+typedef struct dwc_otg_host_if
25453+{
25454+ /** Host Global Registers starting at offset 400h.*/
25455+ dwc_otg_host_global_regs_t *host_global_regs;
25456+#define DWC_OTG_HOST_GLOBAL_REG_OFFSET 0x400
25457+
25458+ /** Host Port 0 Control and Status Register */
25459+ volatile uint32_t *hprt0;
25460+#define DWC_OTG_HOST_PORT_REGS_OFFSET 0x440
25461+
25462+
25463+ /** Host Channel Specific Registers at offsets 500h-5FCh. */
25464+ dwc_otg_hc_regs_t *hc_regs[MAX_EPS_CHANNELS];
25465+#define DWC_OTG_HOST_CHAN_REGS_OFFSET 0x500
25466+#define DWC_OTG_CHAN_REGS_OFFSET 0x20
25467+
25468+
25469+ /* Host configuration information */
25470+ /** Number of Host Channels (range: 1-16) */
25471+ uint8_t num_host_channels;
25472+ /** Periodic EPs supported (0: no, 1: yes) */
25473+ uint8_t perio_eps_supported;
25474+ /** Periodic Tx FIFO Size (Only 1 host periodic Tx FIFO) */
25475+ uint16_t perio_tx_fifo_size;
25476+
25477+} dwc_otg_host_if_t;
25478+
25479+
25480+/**
25481+ * This union represents the bit fields in the Power and Clock Gating Control
25482+ * Register. Read the register into the <i>d32</i> member then set/clear the
25483+ * bits using the <i>b</i>it elements.
25484+ */
25485+typedef union pcgcctl_data
25486+{
25487+ /** raw register data */
25488+ uint32_t d32;
25489+
25490+ /** register bits */
25491+ struct
25492+ {
25493+ /** Stop Pclk */
25494+ unsigned stoppclk : 1;
25495+ /** Gate Hclk */
25496+ unsigned gatehclk : 1;
25497+ /** Power Clamp */
25498+ unsigned pwrclmp : 1;
25499+ /** Reset Power Down Modules */
25500+ unsigned rstpdwnmodule : 1;
25501+ /** PHY Suspended */
25502+ unsigned physuspended : 1;
25503+
25504+ unsigned reserved : 27;
25505+ } b;
25506+} pcgcctl_data_t;
25507+
25508+
25509+#endif
25510--- /dev/null
25511+++ b/drivers/usb/host/otg/Makefile
25512@@ -0,0 +1,52 @@
25513+#
25514+# Makefile for DWC_otg Highspeed USB controller driver
25515+#
25516+
25517+ifneq ($(KERNELRELEASE),)
25518+EXTRA_CFLAGS += -DDEBUG
25519+
25520+# Use one of the following flags to compile the software in host-only or
25521+# device-only mode.
25522+#CPPFLAGS += -DDWC_HOST_ONLY
25523+#CPPFLAGS += -DDWC_DEVICE_ONLY
25524+
25525+EXTRA_CFLAGS += -Dlinux -DDWC_HS_ELECT_TST
25526+#EXTRA_CFLAGS += -DDWC_EN_ISOC
25527+
25528+ifneq ($(CONFIG_USB_CNS3XXX_OTG_HCD_ONLY),)
25529+EXTRA_CFLAGS += -DDWC_HOST_ONLY
25530+endif
25531+
25532+ifneq ($(CONFIG_USB_CNS3XXX_OTG_PCD_ONLY),)
25533+EXTRA_CFLAGS += -DDWC_DEVICE_ONLY
25534+endif
25535+
25536+obj-$(CONFIG_USB_CNS3XXX_OTG) := dwc_otg.o
25537+#obj-$(CONFIG_USB_GADGET_CNS3XXX_OTG) := dwc_otg.o
25538+
25539+dwc_otg-objs := dwc_otg_driver.o dwc_otg_attr.o
25540+dwc_otg-objs += dwc_otg_cil.o dwc_otg_cil_intr.o
25541+dwc_otg-objs += dwc_otg_pcd.o dwc_otg_pcd_intr.o
25542+dwc_otg-objs += dwc_otg_hcd.o dwc_otg_hcd_intr.o dwc_otg_hcd_queue.o
25543+
25544+else
25545+
25546+PWD := $(shell pwd)
25547+
25548+# Command paths
25549+CTAGS := $(CTAGS)
25550+DOXYGEN := $(DOXYGEN)
25551+
25552+default:
25553+ $(MAKE) -C$(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules
25554+
25555+docs: $(wildcard *.[hc]) doc/doxygen.cfg
25556+ $(DOXYGEN) doc/doxygen.cfg
25557+
25558+tags: $(wildcard *.[hc])
25559+ $(CTAGS) -e $(wildcard *.[hc]) $(wildcard linux/*.[hc]) $(wildcard $(KDIR)/include/linux/usb*.h)
25560+
25561+endif
25562+
25563+clean:
25564+ rm -rf *.o *.ko .*cmd *.mod.c .tmp_versions
25565--- a/drivers/usb/Kconfig
25566+++ b/drivers/usb/Kconfig
25567@@ -39,6 +39,7 @@ config USB_ARCH_HAS_OHCI
25568     default y if ARCH_AT91
25569     default y if ARCH_PNX4008 && I2C
25570     default y if MFD_TC6393XB
25571+ default y if ARCH_CNS3XXX
25572     # PPC:
25573     default y if STB03xxx
25574     default y if PPC_MPC52xx
25575@@ -58,6 +59,7 @@ config USB_ARCH_HAS_EHCI
25576     default y if PPC_83xx
25577     default y if SOC_AU1200
25578     default y if ARCH_IXP4XX
25579+ default y if ARCH_CNS3XXX
25580     default PCI
25581 
25582 # ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface.
25583--- a/drivers/usb/Makefile
25584+++ b/drivers/usb/Makefile
25585@@ -20,6 +20,8 @@ obj-$(CONFIG_USB_U132_HCD) += host/
25586 obj-$(CONFIG_USB_R8A66597_HCD) += host/
25587 obj-$(CONFIG_USB_HWA_HCD) += host/
25588 obj-$(CONFIG_USB_ISP1760_HCD) += host/
25589+obj-$(CONFIG_USB_CNS3XXX_OTG) += host/
25590+obj-$(CONFIG_USB_GADGET_CNS3XXX_OTG) += host/
25591 
25592 obj-$(CONFIG_USB_C67X00_HCD) += c67x00/
25593 
25594--- a/drivers/usb/storage/protocol.c
25595+++ b/drivers/usb/storage/protocol.c
25596@@ -182,9 +182,10 @@ unsigned int usb_stor_access_xfer_buf(un
25597                     PAGE_SIZE - poff);
25598             unsigned char *ptr = kmap(page);
25599 
25600- if (dir == TO_XFER_BUF)
25601+ if (dir == TO_XFER_BUF) {
25602                 memcpy(ptr + poff, buffer + cnt, plen);
25603- else
25604+ flush_dcache_page(page);
25605+ } else
25606                 memcpy(buffer + cnt, ptr + poff, plen);
25607             kunmap(page);
25608 
25609--- a/include/linux/usb.h
25610+++ b/include/linux/usb.h
25611@@ -1201,8 +1201,14 @@ struct urb {
25612     unsigned int pipe; /* (in) pipe information */
25613     int status; /* (return) non-ISO status */
25614     unsigned int transfer_flags; /* (in) URB_SHORT_NOT_OK | ...*/
25615+
25616     void *transfer_buffer; /* (in) associated data buffer */
25617     dma_addr_t transfer_dma; /* (in) dma addr for transfer_buffer */
25618+
25619+ void * aligned_transfer_buffer; /* (in) associated data buffer */
25620+ dma_addr_t aligned_transfer_dma; /* (in) dma addr for transfer_buffer */
25621+ u32 aligned_transfer_buffer_length; /* (in) data buffer length */
25622+
25623     struct usb_sg_request *sg; /* (in) scatter gather buffer list */
25624     int num_sgs; /* (in) number of entries in the sg list */
25625     u32 transfer_buffer_length; /* (in) data buffer length */
25626

Archive Download this file



interactive