Merge branch 'develop-3.10-next' of ssh://10.10.10.29/rk/kernel into develop-3.10...
[firefly-linux-kernel-4.4.55.git] / drivers / usb / dwc_otg_310 / dwc_otg_hcd.c
1 /* ==========================================================================
2  * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd.c $
3  * $Revision: #106 $
4  * $Date: 2012/12/21 $
5  * $Change: 2131568 $
6  *
7  * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
8  * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
9  * otherwise expressly agreed to in writing between Synopsys and you.
10  *
11  * The Software IS NOT an item of Licensed Software or Licensed Product under
12  * any End User Software License Agreement or Agreement for Licensed Product
13  * with Synopsys or any supplement thereto. You are permitted to use and
14  * redistribute this Software in source and binary forms, with or without
15  * modification, provided that redistributions of source code must retain this
16  * notice. You may not view, use, disclose, copy or distribute this file or
17  * any information contained herein except pursuant to this license grant from
18  * Synopsys. If you do not agree with this notice, including the disclaimer
19  * below, then you are not authorized to use the Software.
20  *
21  * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
25  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31  * DAMAGE.
32  * ========================================================================== */
33 #ifndef DWC_DEVICE_ONLY
34
35 /** @file
36  * This file implements HCD Core. All code in this file is portable and doesn't
37  * use any OS specific functions.
38  * Interface provided by HCD Core is defined in <code><hcd_if.h></code>
39  * header file.
40  */
41
42 #include "dwc_otg_hcd.h"
43 #include "dwc_otg_regs.h"
44 #include "usbdev_rk.h"
45 #include "dwc_otg_driver.h"
46 #include <linux/usb.h>
47 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
48 #include <../drivers/usb/core/hcd.h>
49 #else
50 #include <linux/usb/hcd.h>
51 #endif
52
53 dwc_otg_hcd_t *dwc_otg_hcd_alloc_hcd(void)
54 {
55         return DWC_ALLOC(sizeof(dwc_otg_hcd_t));
56 }
57
58 /**
59  * Connection timeout function.  An OTG host is required to display a
60  * message if the device does not connect within 10 seconds.
61  */
62 void dwc_otg_hcd_connect_timeout(void *ptr)
63 {
64         dwc_otg_hcd_t *hcd;
65         DWC_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, ptr);
66         DWC_PRINTF("Connect Timeout\n");
67         __DWC_ERROR("Device Not Connected/Responding\n");
68         /** Remove buspower after 10s */
69         hcd = ptr;
70         if (hcd->core_if->otg_ver)
71                 dwc_otg_set_prtpower(hcd->core_if, 0);
72 }
73
74 #ifdef DEBUG
75 static void dump_channel_info(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh)
76 {
77         if (qh->channel != NULL) {
78                 dwc_hc_t *hc = qh->channel;
79                 dwc_list_link_t *item;
80                 dwc_otg_qh_t *qh_item;
81                 int num_channels = hcd->core_if->core_params->host_channels;
82                 int i;
83
84                 dwc_otg_hc_regs_t *hc_regs;
85                 hcchar_data_t hcchar;
86                 hcsplt_data_t hcsplt;
87                 hctsiz_data_t hctsiz;
88                 uint32_t hcdma;
89
90                 hc_regs = hcd->core_if->host_if->hc_regs[hc->hc_num];
91                 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
92                 hcsplt.d32 = DWC_READ_REG32(&hc_regs->hcsplt);
93                 hctsiz.d32 = DWC_READ_REG32(&hc_regs->hctsiz);
94                 hcdma = DWC_READ_REG32(&hc_regs->hcdma);
95
96                 DWC_PRINTF("  Assigned to channel %p:\n", hc);
97                 DWC_PRINTF("    hcchar 0x%08x, hcsplt 0x%08x\n", hcchar.d32,
98                            hcsplt.d32);
99                 DWC_PRINTF("    hctsiz 0x%08x, hcdma 0x%08x\n", hctsiz.d32,
100                            hcdma);
101                 DWC_PRINTF("    dev_addr: %d, ep_num: %d, ep_is_in: %d\n",
102                            hc->dev_addr, hc->ep_num, hc->ep_is_in);
103                 DWC_PRINTF("    ep_type: %d\n", hc->ep_type);
104                 DWC_PRINTF("    max_packet: %d\n", hc->max_packet);
105                 DWC_PRINTF("    data_pid_start: %d\n", hc->data_pid_start);
106                 DWC_PRINTF("    xfer_started: %d\n", hc->xfer_started);
107                 DWC_PRINTF("    halt_status: %d\n", hc->halt_status);
108                 DWC_PRINTF("    xfer_buff: %p\n", hc->xfer_buff);
109                 DWC_PRINTF("    xfer_len: %d\n", hc->xfer_len);
110                 DWC_PRINTF("    qh: %p\n", hc->qh);
111                 DWC_PRINTF("  NP inactive sched:\n");
112                 DWC_LIST_FOREACH(item, &hcd->non_periodic_sched_inactive) {
113                         qh_item =
114                             DWC_LIST_ENTRY(item, dwc_otg_qh_t, qh_list_entry);
115                         DWC_PRINTF("    %p\n", qh_item);
116                 }
117                 DWC_PRINTF("  NP active sched:\n");
118                 DWC_LIST_FOREACH(item, &hcd->non_periodic_sched_active) {
119                         qh_item =
120                             DWC_LIST_ENTRY(item, dwc_otg_qh_t, qh_list_entry);
121                         DWC_PRINTF("    %p\n", qh_item);
122                 }
123                 DWC_PRINTF("  Channels: \n");
124                 for (i = 0; i < num_channels; i++) {
125                         dwc_hc_t *hc = hcd->hc_ptr_array[i];
126                         DWC_PRINTF("    %2d: %p\n", i, hc);
127                 }
128         }
129 }
130 #endif /* DEBUG */
131
132 /**
133  * Work queue function for starting the HCD when A-Cable is connected.
134  * The hcd_start() must be called in a process context.
135  */
136 static void hcd_start_func(void *_vp)
137 {
138         dwc_otg_hcd_t *hcd = (dwc_otg_hcd_t *) _vp;
139
140         DWC_DEBUGPL(DBG_HCDV, "%s() %p\n", __func__, hcd);
141         if (hcd) {
142                 hcd->fops->start(hcd);
143         }
144 }
145
146 static void del_xfer_timers(dwc_otg_hcd_t *hcd)
147 {
148 #ifdef DEBUG
149         int i;
150         int num_channels = hcd->core_if->core_params->host_channels;
151         for (i = 0; i < num_channels; i++) {
152                 DWC_TIMER_CANCEL(hcd->core_if->hc_xfer_timer[i]);
153         }
154 #endif
155 }
156
157 static void del_timers(dwc_otg_hcd_t *hcd)
158 {
159         del_xfer_timers(hcd);
160         DWC_TIMER_CANCEL(hcd->conn_timer);
161 }
162
163 /**
164  * Processes all the URBs in a single list of QHs. Completes them with
165  * -ETIMEDOUT and frees the QTD.
166  */
167 static void kill_urbs_in_qh_list(dwc_otg_hcd_t *hcd, dwc_list_link_t *qh_list)
168 {
169         dwc_list_link_t *qh_item;
170         dwc_otg_qh_t *qh;
171         dwc_otg_qtd_t *qtd, *qtd_tmp;
172
173         DWC_LIST_FOREACH(qh_item, qh_list) {
174                 qh = DWC_LIST_ENTRY(qh_item, dwc_otg_qh_t, qh_list_entry);
175                 DWC_CIRCLEQ_FOREACH_SAFE(qtd, qtd_tmp,
176                                          &qh->qtd_list, qtd_list_entry) {
177                         qtd = DWC_CIRCLEQ_FIRST(&qh->qtd_list);
178                         if (qtd->urb != NULL) {
179                                 hcd->fops->complete(hcd, qtd->urb->priv,
180                                                     qtd->urb, -DWC_E_SHUTDOWN);
181                                 dwc_otg_hcd_qtd_remove_and_free(hcd, qtd, qh);
182                         }
183
184                 }
185         }
186 }
187
188 /**
189  * Responds with an error status of ETIMEDOUT to all URBs in the non-periodic
190  * and periodic schedules. The QTD associated with each URB is removed from
191  * the schedule and freed. This function may be called when a disconnect is
192  * detected or when the HCD is being stopped.
193  */
194 static void kill_all_urbs(dwc_otg_hcd_t *hcd)
195 {
196         kill_urbs_in_qh_list(hcd, &hcd->non_periodic_sched_inactive);
197         kill_urbs_in_qh_list(hcd, &hcd->non_periodic_sched_active);
198         kill_urbs_in_qh_list(hcd, &hcd->periodic_sched_inactive);
199         kill_urbs_in_qh_list(hcd, &hcd->periodic_sched_ready);
200         kill_urbs_in_qh_list(hcd, &hcd->periodic_sched_assigned);
201         kill_urbs_in_qh_list(hcd, &hcd->periodic_sched_queued);
202 }
203
204 /**
205  * Start the connection timer.  An OTG host is required to display a
206  * message if the device does not connect within 10 seconds.  The
207  * timer is deleted if a port connect interrupt occurs before the
208  * timer expires.
209  */
210 static void dwc_otg_hcd_start_connect_timer(dwc_otg_hcd_t *hcd)
211 {
212         DWC_TIMER_SCHEDULE(hcd->conn_timer, 10000 /* 10 secs */);
213 }
214
215 /**
216  * HCD Callback function for disconnect of the HCD.
217  *
218  * @param p void pointer to the <code>struct usb_hcd</code>
219  */
220 static int32_t dwc_otg_hcd_session_start_cb(void *p)
221 {
222         dwc_otg_hcd_t *dwc_otg_hcd;
223         DWC_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, p);
224         dwc_otg_hcd = p;
225         dwc_otg_hcd_start_connect_timer(dwc_otg_hcd);
226         return 1;
227 }
228
229 /**
230  * HCD Callback function for starting the HCD when A-Cable is
231  * connected.
232  *
233  * @param p void pointer to the <code>struct usb_hcd</code>
234  */
235 static int32_t dwc_otg_hcd_start_cb(void *p)
236 {
237         dwc_otg_hcd_t *dwc_otg_hcd = p;
238         dwc_otg_core_if_t *core_if;
239         hprt0_data_t hprt0;
240         uint32_t timeout = 50;
241
242         core_if = dwc_otg_hcd->core_if;
243
244         if (core_if->op_state == B_HOST) {
245                 /*
246                  * Reset the port.  During a HNP mode switch the reset
247                  * needs to occur within 1ms and have a duration of at
248                  * least 50ms.
249                  */
250                 hprt0.d32 = dwc_otg_read_hprt0(core_if);
251                 hprt0.b.prtrst = 1;
252                 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
253                 if (core_if->otg_ver) {
254                         dwc_mdelay(60);
255                         hprt0.d32 = dwc_otg_read_hprt0(core_if);
256                         hprt0.b.prtrst = 0;
257                         DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
258                 }
259         }
260         /**@todo vahrama: Check the timeout value for OTG 2.0 */
261         if (core_if->otg_ver)
262                 timeout = 25;
263         DWC_WORKQ_SCHEDULE_DELAYED(core_if->wq_otg,
264                                    hcd_start_func, dwc_otg_hcd, timeout,
265                                    "start hcd");
266
267         return 1;
268 }
269
270 /**
271  * HCD Callback function for disconnect of the HCD.
272  *
273  * @param p void pointer to the <code>struct usb_hcd</code>
274  */
275 static int32_t dwc_otg_hcd_disconnect_cb(void *p)
276 {
277         gintsts_data_t intr;
278         dwc_otg_hcd_t *dwc_otg_hcd = p;
279         hprt0_data_t hprt0;
280
281         dwc_otg_hcd->non_periodic_qh_ptr = &dwc_otg_hcd->non_periodic_sched_active;
282         dwc_otg_hcd->non_periodic_channels = 0;
283         dwc_otg_hcd->periodic_channels = 0;
284
285         hprt0.d32 = DWC_READ_REG32(dwc_otg_hcd->core_if->host_if->hprt0);
286         /* In some case, we don't disconnect a usb device, but
287          * disconnect intr was triggered, so check hprt0 here. */
288         if ((!hprt0.b.prtenchng)
289             && (!hprt0.b.prtconndet)
290             && hprt0.b.prtconnsts) {
291                 DWC_PRINTF("%s: hprt0 = 0x%08x\n", __func__, hprt0.d32);
292                 return 1;
293         }
294         /*
295          * Set status flags for the hub driver.
296          */
297         dwc_otg_hcd->flags.b.port_connect_status_change = 1;
298         dwc_otg_hcd->flags.b.port_connect_status = 0;
299
300         /*
301          * Shutdown any transfers in process by clearing the Tx FIFO Empty
302          * interrupt mask and status bits and disabling subsequent host
303          * channel interrupts.
304          */
305         intr.d32 = 0;
306         intr.b.nptxfempty = 1;
307         intr.b.ptxfempty = 1;
308         intr.b.hcintr = 1;
309         DWC_MODIFY_REG32(&dwc_otg_hcd->core_if->core_global_regs->gintmsk,
310                          intr.d32, 0);
311         DWC_MODIFY_REG32(&dwc_otg_hcd->core_if->core_global_regs->gintsts,
312                          intr.d32, 0);
313
314         /*
315          * Turn off the vbus power only if the core has transitioned to device
316          * mode. If still in host mode, need to keep power on to detect a
317          * reconnection.
318          */
319         if (dwc_otg_is_device_mode(dwc_otg_hcd->core_if)) {
320                 if (dwc_otg_hcd->core_if->op_state != A_SUSPEND) {
321                         hprt0_data_t hprt0 = {.d32 = 0 };
322                         DWC_PRINTF("Disconnect: PortPower off\n");
323                         hprt0.b.prtpwr = 0;
324                         DWC_WRITE_REG32(dwc_otg_hcd->core_if->host_if->hprt0,
325                                         hprt0.d32);
326                 }
327                 /** Delete timers if become device */
328                 del_timers(dwc_otg_hcd);
329                 dwc_otg_disable_host_interrupts(dwc_otg_hcd->core_if);
330                 goto out;
331         }
332
333         /* Respond with an error status to all URBs in the schedule. */
334         kill_all_urbs(dwc_otg_hcd);
335
336         if (dwc_otg_is_host_mode(dwc_otg_hcd->core_if)) {
337                 /* Clean up any host channels that were in use. */
338                 int num_channels;
339                 int i;
340                 dwc_hc_t *channel;
341                 dwc_otg_hc_regs_t *hc_regs;
342                 hcchar_data_t hcchar;
343
344                 DWC_PRINTF("Disconnect cb-Host\n");
345                 if (dwc_otg_hcd->core_if->otg_ver == 1)
346                         del_xfer_timers(dwc_otg_hcd);
347                 else
348                         del_timers(dwc_otg_hcd);
349
350                 num_channels = dwc_otg_hcd->core_if->core_params->host_channels;
351
352                 if (!dwc_otg_hcd->core_if->dma_enable) {
353                         /* Flush out any channel requests in slave mode. */
354                         for (i = 0; i < num_channels; i++) {
355                                 channel = dwc_otg_hcd->hc_ptr_array[i];
356                                 if (DWC_CIRCLEQ_EMPTY_ENTRY
357                                     (channel, hc_list_entry)) {
358                                         hc_regs =
359                                             dwc_otg_hcd->core_if->host_if->
360                                             hc_regs[i];
361                                         hcchar.d32 =
362                                             DWC_READ_REG32(&hc_regs->hcchar);
363                                         if (hcchar.b.chen) {
364                                                 hcchar.b.chen = 0;
365                                                 hcchar.b.chdis = 1;
366                                                 hcchar.b.epdir = 0;
367                                                 DWC_WRITE_REG32
368                                                     (&hc_regs->hcchar,
369                                                      hcchar.d32);
370                                         }
371                                 }
372                         }
373                 }
374
375                 for (i = 0; i < num_channels; i++) {
376                         channel = dwc_otg_hcd->hc_ptr_array[i];
377                         if (DWC_CIRCLEQ_EMPTY_ENTRY(channel, hc_list_entry)) {
378                                 hc_regs =
379                                     dwc_otg_hcd->core_if->host_if->hc_regs[i];
380                                 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
381                                 if (hcchar.b.chen) {
382                                         /* Halt the channel. */
383                                         hcchar.b.chdis = 1;
384                                         DWC_WRITE_REG32(&hc_regs->hcchar,
385                                                         hcchar.d32);
386                                 }
387
388                                 dwc_otg_hc_cleanup(dwc_otg_hcd->core_if,
389                                                    channel);
390                                 DWC_CIRCLEQ_INSERT_TAIL
391                                     (&dwc_otg_hcd->free_hc_list, channel,
392                                      hc_list_entry);
393                                 /*
394                                  * Added for Descriptor DMA to prevent channel double cleanup
395                                  * in release_channel_ddma(). Which called from ep_disable
396                                  * when device disconnect.
397                                  */
398                                 channel->qh = NULL;
399                         }
400                 }
401         }
402
403 out:
404         if (dwc_otg_hcd->fops->disconnect) {
405                 dwc_otg_hcd->fops->disconnect(dwc_otg_hcd);
406         }
407
408         return 1;
409 }
410
411 /**
412  * HCD Callback function for stopping the HCD.
413  *
414  * @param p void pointer to the <code>struct usb_hcd</code>
415  */
416 static int32_t dwc_otg_hcd_stop_cb(void *p)
417 {
418         dwc_otg_hcd_t *dwc_otg_hcd = p;
419
420         DWC_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, p);
421         dwc_otg_hcd_stop(dwc_otg_hcd);
422         return 1;
423 }
424
425 #ifdef CONFIG_USB_DWC_OTG_LPM
426 /**
427  * HCD Callback function for sleep of HCD.
428  *
429  * @param p void pointer to the <code>struct usb_hcd</code>
430  */
431 static int dwc_otg_hcd_sleep_cb(void *p)
432 {
433         dwc_otg_hcd_t *hcd = p;
434
435         dwc_otg_hcd_free_hc_from_lpm(hcd);
436
437         return 0;
438 }
439 #endif
440
441 /**
442  * HCD Callback function for Remote Wakeup.
443  *
444  * @param p void pointer to the <code>struct usb_hcd</code>
445  */
446 extern inline struct usb_hcd *dwc_otg_hcd_to_hcd(dwc_otg_hcd_t *dwc_otg_hcd);
447 static int dwc_otg_hcd_rem_wakeup_cb(void *p)
448 {
449         dwc_otg_hcd_t *dwc_otg_hcd = p;
450         struct usb_hcd *hcd = dwc_otg_hcd_to_hcd(dwc_otg_hcd);
451
452         if (dwc_otg_hcd->core_if->lx_state == DWC_OTG_L2) {
453                 dwc_otg_hcd->flags.b.port_suspend_change = 1;
454                 usb_hcd_resume_root_hub(hcd);
455         }
456 #ifdef CONFIG_USB_DWC_OTG_LPM
457         else {
458                 dwc_otg_hcd->flags.b.port_l1_change = 1;
459         }
460 #endif
461         return 0;
462 }
463
464 /**
465  * Halts the DWC_otg host mode operations in a clean manner. USB transfers are
466  * stopped.
467  */
468 void dwc_otg_hcd_stop(dwc_otg_hcd_t *hcd)
469 {
470         hprt0_data_t hprt0 = {.d32 = 0 };
471         struct dwc_otg_platform_data *pldata;
472         pldata = hcd->core_if->otg_dev->pldata;
473
474         DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD STOP\n");
475
476         /*
477          * The root hub should be disconnected before this function is called.
478          * The disconnect will clear the QTD lists (via ..._hcd_urb_dequeue)
479          * and the QH lists (via ..._hcd_endpoint_disable).
480          */
481
482         /* Turn off all host-specific interrupts. */
483         dwc_otg_disable_host_interrupts(hcd->core_if);
484
485         /* Turn off the vbus power */
486         DWC_PRINTF("PortPower off\n");
487         hprt0.b.prtpwr = 0;
488         DWC_WRITE_REG32(hcd->core_if->host_if->hprt0, hprt0.d32);
489
490         if (pldata->power_enable)
491                 pldata->power_enable(0);
492
493         dwc_mdelay(1);
494 }
495
496 int dwc_otg_hcd_urb_enqueue(dwc_otg_hcd_t *hcd,
497                             dwc_otg_hcd_urb_t *dwc_otg_urb, void **ep_handle,
498                             int atomic_alloc)
499 {
500         dwc_irqflags_t flags;
501         int retval = 0;
502         dwc_otg_qtd_t *qtd;
503         gintmsk_data_t intr_mask = {.d32 = 0 };
504
505         if (!hcd->flags.b.port_connect_status) {
506                 /* No longer connected. */
507                 DWC_DEBUG("Not connected\n");
508                 return -DWC_E_NO_DEVICE;
509         }
510
511         qtd = dwc_otg_hcd_qtd_create(dwc_otg_urb, atomic_alloc);
512         if (qtd == NULL) {
513                 DWC_ERROR("DWC OTG HCD URB Enqueue failed creating QTD\n");
514                 return -DWC_E_NO_MEMORY;
515         }
516         DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags);
517         retval =
518             dwc_otg_hcd_qtd_add(qtd, hcd, (dwc_otg_qh_t **) ep_handle, 1);
519
520         if (retval < 0) {
521                 DWC_ERROR("DWC OTG HCD URB Enqueue failed adding QTD. "
522                           "Error status %d\n", retval);
523                 dwc_otg_hcd_qtd_free(qtd);
524         }
525         intr_mask.d32 =
526             DWC_READ_REG32(&hcd->core_if->core_global_regs->gintmsk);
527         if (!intr_mask.b.sofintr && retval == 0) {
528                 dwc_otg_transaction_type_e tr_type;
529                 if ((qtd->qh->ep_type == UE_BULK)
530                     && !(qtd->urb->flags & URB_GIVEBACK_ASAP)) {
531                         /* Do not schedule SG transactions until qtd has URB_GIVEBACK_ASAP set */
532                         retval = 0;
533                         goto out;
534                 }
535                 tr_type = dwc_otg_hcd_select_transactions(hcd);
536                 if (tr_type != DWC_OTG_TRANSACTION_NONE) {
537                         dwc_otg_hcd_queue_transactions(hcd, tr_type);
538                 }
539         }
540 out:
541         DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags);
542         return retval;
543 }
544
545 int dwc_otg_hcd_urb_dequeue(dwc_otg_hcd_t *hcd,
546                             dwc_otg_hcd_urb_t *dwc_otg_urb)
547 {
548         dwc_otg_qh_t *qh;
549         dwc_otg_qtd_t *urb_qtd;
550
551         urb_qtd = dwc_otg_urb->qtd;
552         if (((uint32_t) urb_qtd & 0xf0000000) == 0) {
553                 DWC_PRINTF("%s error: urb_qtd is %p dwc_otg_urb %p!!!\n",
554                            __func__, urb_qtd, dwc_otg_urb);
555                 return 0;
556         }
557         qh = urb_qtd->qh;
558 #ifdef DEBUG
559         if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
560                 if (urb_qtd->in_process) {
561                         dump_channel_info(hcd, qh);
562                 }
563         }
564 #endif
565         if (urb_qtd->in_process && qh->channel) {
566                 /* The QTD is in process (it has been assigned to a channel). */
567                 if (hcd->flags.b.port_connect_status) {
568                         /*
569                          * If still connected (i.e. in host mode), halt the
570                          * channel so it can be used for other transfers. If
571                          * no longer connected, the host registers can't be
572                          * written to halt the channel since the core is in
573                          * device mode.
574                          */
575                         dwc_otg_hc_halt(hcd->core_if, qh->channel,
576                                         DWC_OTG_HC_XFER_URB_DEQUEUE);
577                 }
578         }
579
580         /*
581          * Free the QTD and clean up the associated QH. Leave the QH in the
582          * schedule if it has any remaining QTDs.
583          */
584
585         if (!hcd->core_if->dma_desc_enable) {
586                 uint8_t b = urb_qtd->in_process;
587                 dwc_otg_hcd_qtd_remove_and_free(hcd, urb_qtd, qh);
588                 if (b) {
589                         dwc_otg_hcd_qh_deactivate(hcd, qh, 0);
590                         qh->channel = NULL;
591                 } else if (DWC_CIRCLEQ_EMPTY(&qh->qtd_list)) {
592                         dwc_otg_hcd_qh_remove(hcd, qh);
593                 }
594         } else {
595                 dwc_otg_hcd_qtd_remove_and_free(hcd, urb_qtd, qh);
596         }
597         return 0;
598 }
599
600 int dwc_otg_hcd_endpoint_disable(dwc_otg_hcd_t *hcd, void *ep_handle,
601                                  int retry)
602 {
603         dwc_otg_qh_t *qh = (dwc_otg_qh_t *) ep_handle;
604         int retval = 0;
605         dwc_irqflags_t flags;
606
607         if (retry < 0) {
608                 retval = -DWC_E_INVALID;
609                 goto done;
610         }
611
612         if (!qh) {
613                 retval = -DWC_E_INVALID;
614                 goto done;
615         }
616
617         DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags);
618
619         while (!DWC_CIRCLEQ_EMPTY(&qh->qtd_list) && retry) {
620                 DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags);
621                 retry--;
622                 dwc_msleep(5);
623                 DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags);
624         }
625
626         dwc_otg_hcd_qh_remove(hcd, qh);
627
628         DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags);
629         /*
630          * Split dwc_otg_hcd_qh_remove_and_free() into qh_remove
631          * and qh_free to prevent stack dump on DWC_DMA_FREE() with
632          * irq_disabled (spinlock_irqsave) in dwc_otg_hcd_desc_list_free()
633          * and dwc_otg_hcd_frame_list_alloc().
634          */
635         dwc_otg_hcd_qh_free(hcd, qh);
636
637 done:
638         return retval;
639 }
640
641 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
642 int dwc_otg_hcd_endpoint_reset(dwc_otg_hcd_t *hcd, void *ep_handle)
643 {
644         int retval = 0;
645         dwc_otg_qh_t *qh = (dwc_otg_qh_t *) ep_handle;
646         if (!qh)
647                 return -DWC_E_INVALID;
648
649         qh->data_toggle = DWC_OTG_HC_PID_DATA0;
650         return retval;
651 }
652 #endif
653
654 /**
655  * HCD Callback structure for handling mode switching.
656  */
657 static dwc_otg_cil_callbacks_t hcd_cil_callbacks = {
658         .start = dwc_otg_hcd_start_cb,
659         .stop = dwc_otg_hcd_stop_cb,
660         .disconnect = dwc_otg_hcd_disconnect_cb,
661         .session_start = dwc_otg_hcd_session_start_cb,
662         .resume_wakeup = dwc_otg_hcd_rem_wakeup_cb,
663 #ifdef CONFIG_USB_DWC_OTG_LPM
664         .sleep = dwc_otg_hcd_sleep_cb,
665 #endif
666         .p = 0,
667 };
668
669 /**
670  * Reset tasklet function
671  */
672 static void reset_tasklet_func(void *data)
673 {
674         dwc_otg_hcd_t *dwc_otg_hcd = (dwc_otg_hcd_t *) data;
675         dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
676         hprt0_data_t hprt0;
677
678         DWC_DEBUGPL(DBG_HCDV, "USB RESET tasklet called\n");
679
680         hprt0.d32 = dwc_otg_read_hprt0(core_if);
681         hprt0.b.prtrst = 1;
682         DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
683         dwc_mdelay(60);
684
685         hprt0.b.prtrst = 0;
686         DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
687         dwc_otg_hcd->flags.b.port_reset_change = 1;
688 }
689
690 static void qh_list_free(dwc_otg_hcd_t *hcd, dwc_list_link_t *qh_list)
691 {
692         dwc_list_link_t *item;
693         dwc_otg_qh_t *qh;
694         dwc_irqflags_t flags;
695
696         if (!qh_list->next) {
697                 /* The list hasn't been initialized yet. */
698                 return;
699         }
700         /*
701          * Hold spinlock here. Not needed in that case if bellow
702          * function is being called from ISR
703          */
704         DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags);
705         /* Ensure there are no QTDs or URBs left. */
706         kill_urbs_in_qh_list(hcd, qh_list);
707         DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags);
708
709         DWC_LIST_FOREACH(item, qh_list) {
710                 qh = DWC_LIST_ENTRY(item, dwc_otg_qh_t, qh_list_entry);
711                 dwc_otg_hcd_qh_remove_and_free(hcd, qh);
712         }
713 }
714
715 /**
716  * Exit from Hibernation if Host did not detect SRP from connected SRP capable
717  * Device during SRP time by host power up.
718  */
719 void dwc_otg_hcd_power_up(void *ptr)
720 {
721         gpwrdn_data_t gpwrdn = {.d32 = 0 };
722         dwc_otg_core_if_t *core_if = (dwc_otg_core_if_t *) ptr;
723
724         DWC_PRINTF("%s called\n", __FUNCTION__);
725
726         if (!core_if->hibernation_suspend) {
727                 DWC_PRINTF("Already exited from Hibernation\n");
728                 return;
729         }
730
731         /* Switch on the voltage to the core */
732         gpwrdn.b.pwrdnswtch = 1;
733         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
734         dwc_udelay(10);
735
736         /* Reset the core */
737         gpwrdn.d32 = 0;
738         gpwrdn.b.pwrdnrstn = 1;
739         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
740         dwc_udelay(10);
741
742         /* Disable power clamps */
743         gpwrdn.d32 = 0;
744         gpwrdn.b.pwrdnclmp = 1;
745         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
746
747         /* Remove reset the core signal */
748         gpwrdn.d32 = 0;
749         gpwrdn.b.pwrdnrstn = 1;
750         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
751         dwc_udelay(10);
752
753         /* Disable PMU interrupt */
754         gpwrdn.d32 = 0;
755         gpwrdn.b.pmuintsel = 1;
756         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
757
758         core_if->hibernation_suspend = 0;
759
760         /* Disable PMU */
761         gpwrdn.d32 = 0;
762         gpwrdn.b.pmuactv = 1;
763         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
764         dwc_udelay(10);
765
766         /* Enable VBUS */
767         gpwrdn.d32 = 0;
768         gpwrdn.b.dis_vbus = 1;
769         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
770
771         core_if->op_state = A_HOST;
772         dwc_otg_core_init(core_if);
773         dwc_otg_enable_global_interrupts(core_if);
774         cil_hcd_start(core_if);
775 }
776
777 /**
778  * Frees secondary storage associated with the dwc_otg_hcd structure contained
779  * in the struct usb_hcd field.
780  */
781 static void dwc_otg_hcd_free(dwc_otg_hcd_t *dwc_otg_hcd)
782 {
783         int i;
784
785         DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD FREE\n");
786
787         del_timers(dwc_otg_hcd);
788
789         /* Free memory for QH/QTD lists */
790         qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->non_periodic_sched_inactive);
791         qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->non_periodic_sched_active);
792         qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_inactive);
793         qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_ready);
794         qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_assigned);
795         qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_queued);
796
797         /* Free memory for the host channels. */
798         for (i = 0; i < MAX_EPS_CHANNELS; i++) {
799                 dwc_hc_t *hc = dwc_otg_hcd->hc_ptr_array[i];
800
801 #ifdef DEBUG
802                 if (dwc_otg_hcd->core_if->hc_xfer_timer[i]) {
803                         DWC_TIMER_FREE(dwc_otg_hcd->core_if->hc_xfer_timer[i]);
804                 }
805 #endif
806                 if (hc != NULL) {
807                         DWC_DEBUGPL(DBG_HCDV, "HCD Free channel #%i, hc=%p\n",
808                                     i, hc);
809                         DWC_FREE(hc);
810                 }
811         }
812
813         if (dwc_otg_hcd->core_if->dma_enable) {
814                 if (dwc_otg_hcd->status_buf_dma) {
815                         DWC_DMA_FREE(DWC_OTG_HCD_STATUS_BUF_SIZE,
816                                      dwc_otg_hcd->status_buf,
817                                      dwc_otg_hcd->status_buf_dma);
818                 }
819         } else if (dwc_otg_hcd->status_buf != NULL) {
820                 DWC_FREE(dwc_otg_hcd->status_buf);
821         }
822         DWC_SPINLOCK_FREE(dwc_otg_hcd->lock);
823         /* Set core_if's lock pointer to NULL */
824         dwc_otg_hcd->core_if->lock = NULL;
825
826         DWC_TIMER_FREE(dwc_otg_hcd->conn_timer);
827         DWC_TASK_FREE(dwc_otg_hcd->reset_tasklet);
828
829 #ifdef DWC_DEV_SRPCAP
830         if (dwc_otg_hcd->core_if->power_down == 2 &&
831             dwc_otg_hcd->core_if->pwron_timer) {
832                 DWC_TIMER_FREE(dwc_otg_hcd->core_if->pwron_timer);
833         }
834 #endif
835         DWC_FREE(dwc_otg_hcd);
836 }
837
838 int dwc_otg_hcd_init(dwc_otg_hcd_t *hcd, dwc_otg_core_if_t *core_if)
839 {
840         int retval = 0;
841         int num_channels;
842         int i;
843         dwc_hc_t *channel;
844
845         hcd->lock = DWC_SPINLOCK_ALLOC();
846         if (!hcd->lock) {
847                 DWC_ERROR("Could not allocate lock for pcd");
848                 DWC_FREE(hcd);
849                 retval = -DWC_E_NO_MEMORY;
850                 goto out;
851         }
852         hcd->core_if = core_if;
853
854         /* Register the HCD CIL Callbacks */
855         dwc_otg_cil_register_hcd_callbacks(hcd->core_if,
856                                            &hcd_cil_callbacks, hcd);
857
858         /* Initialize the non-periodic schedule. */
859         DWC_LIST_INIT(&hcd->non_periodic_sched_inactive);
860         DWC_LIST_INIT(&hcd->non_periodic_sched_active);
861
862         /* Initialize the periodic schedule. */
863         DWC_LIST_INIT(&hcd->periodic_sched_inactive);
864         DWC_LIST_INIT(&hcd->periodic_sched_ready);
865         DWC_LIST_INIT(&hcd->periodic_sched_assigned);
866         DWC_LIST_INIT(&hcd->periodic_sched_queued);
867
868         /*
869          * Create a host channel descriptor for each host channel implemented
870          * in the controller. Initialize the channel descriptor array.
871          */
872         DWC_CIRCLEQ_INIT(&hcd->free_hc_list);
873         num_channels = hcd->core_if->core_params->host_channels;
874         DWC_MEMSET(hcd->hc_ptr_array, 0, sizeof(hcd->hc_ptr_array));
875         for (i = 0; i < num_channels; i++) {
876                 channel = DWC_ALLOC(sizeof(dwc_hc_t));
877                 if (channel == NULL) {
878                         retval = -DWC_E_NO_MEMORY;
879                         DWC_ERROR("%s: host channel allocation failed\n",
880                                   __func__);
881                         dwc_otg_hcd_free(hcd);
882                         goto out;
883                 }
884                 channel->hc_num = i;
885                 hcd->hc_ptr_array[i] = channel;
886 #ifdef DEBUG
887                 hcd->core_if->hc_xfer_timer[i] =
888                     DWC_TIMER_ALLOC("hc timer", hc_xfer_timeout,
889                                     &hcd->core_if->hc_xfer_info[i]);
890 #endif
891                 DWC_DEBUGPL(DBG_HCDV, "HCD Added channel #%d, hc=%p\n", i,
892                             channel);
893         }
894
895         /* Initialize the Connection timeout timer. */
896         hcd->conn_timer = DWC_TIMER_ALLOC("Connection timer",
897                                           dwc_otg_hcd_connect_timeout, hcd);
898
899         /* Initialize reset tasklet. */
900         hcd->reset_tasklet =
901             DWC_TASK_ALLOC("reset_tasklet", reset_tasklet_func, hcd);
902 #ifdef DWC_DEV_SRPCAP
903         if (hcd->core_if->power_down == 2) {
904                 /* Initialize Power on timer for Host power up in case hibernation */
905                 hcd->core_if->pwron_timer = DWC_TIMER_ALLOC("PWRON TIMER",
906                                                             dwc_otg_hcd_power_up,
907                                                             core_if);
908         }
909 #endif
910
911         /*
912          * Allocate space for storing data on status transactions. Normally no
913          * data is sent, but this space acts as a bit bucket. This must be
914          * done after usb_add_hcd since that function allocates the DMA buffer
915          * pool.
916          */
917         if (hcd->core_if->dma_enable) {
918                 hcd->status_buf =
919                     DWC_DMA_ALLOC_ATOMIC(DWC_OTG_HCD_STATUS_BUF_SIZE,
920                                          &hcd->status_buf_dma);
921         } else {
922                 hcd->status_buf = DWC_ALLOC(DWC_OTG_HCD_STATUS_BUF_SIZE);
923         }
924         if (!hcd->status_buf) {
925                 retval = -DWC_E_NO_MEMORY;
926                 DWC_ERROR("%s: status_buf allocation failed\n", __func__);
927                 dwc_otg_hcd_free(hcd);
928                 goto out;
929         }
930
931         hcd->otg_port = 1;
932         hcd->frame_list = NULL;
933         hcd->frame_list_dma = 0;
934         hcd->periodic_qh_count = 0;
935 out:
936         return retval;
937 }
938
939 void dwc_otg_hcd_remove(dwc_otg_hcd_t *hcd)
940 {
941         /* Turn off all host-specific interrupts. */
942         dwc_otg_disable_host_interrupts(hcd->core_if);
943
944         dwc_otg_hcd_free(hcd);
945 }
946
947 /**
948  * Initializes dynamic portions of the DWC_otg HCD state.
949  */
950 static void dwc_otg_hcd_reinit(dwc_otg_hcd_t *hcd)
951 {
952         int num_channels;
953         int i;
954         dwc_hc_t *channel;
955         dwc_hc_t *channel_tmp;
956
957         hcd->flags.d32 = 0;
958
959         hcd->non_periodic_qh_ptr = &hcd->non_periodic_sched_active;
960         hcd->non_periodic_channels = 0;
961         hcd->periodic_channels = 0;
962
963         /*
964          * Put all channels in the free channel list and clean up channel
965          * states.
966          */
967         DWC_CIRCLEQ_FOREACH_SAFE(channel, channel_tmp,
968                                  &hcd->free_hc_list, hc_list_entry) {
969                 DWC_CIRCLEQ_REMOVE(&hcd->free_hc_list, channel, hc_list_entry);
970         }
971
972         num_channels = hcd->core_if->core_params->host_channels;
973         for (i = 0; i < num_channels; i++) {
974                 channel = hcd->hc_ptr_array[i];
975                 DWC_CIRCLEQ_INSERT_TAIL(&hcd->free_hc_list, channel,
976                                         hc_list_entry);
977                 dwc_otg_hc_cleanup(hcd->core_if, channel);
978         }
979
980         /* Initialize the DWC core for host mode operation. */
981         dwc_otg_core_host_init(hcd->core_if);
982
983         /* Set core_if's lock pointer to the hcd->lock */
984         hcd->core_if->lock = hcd->lock;
985 }
986
987 /**
988  * Assigns transactions from a QTD to a free host channel and initializes the
989  * host channel to perform the transactions. The host channel is removed from
990  * the free list.
991  *
992  * @param hcd The HCD state structure.
993  * @param qh Transactions from the first QTD for this QH are selected and
994  * assigned to a free host channel.
995  */
996 static int assign_and_init_hc(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh)
997 {
998         dwc_hc_t *hc;
999         dwc_otg_qtd_t *qtd;
1000         dwc_otg_hcd_urb_t *urb;
1001         void *ptr = NULL;
1002         int retval = 0;
1003
1004         DWC_DEBUGPL(DBG_HCDV, "%s(%p,%p)\n", __func__, hcd, qh);
1005
1006         hc = DWC_CIRCLEQ_FIRST(&hcd->free_hc_list);
1007
1008         /* Remove the host channel from the free list. */
1009         DWC_CIRCLEQ_REMOVE_INIT(&hcd->free_hc_list, hc, hc_list_entry);
1010
1011         qtd = DWC_CIRCLEQ_FIRST(&qh->qtd_list);
1012
1013         urb = qtd->urb;
1014         if (urb == NULL) {
1015                 printk("%s : urb is NULL\n", __func__);
1016                 retval = -EINVAL;
1017                 return retval;
1018         }
1019
1020         qh->channel = hc;
1021
1022         qtd->in_process = 1;
1023
1024         /*
1025          * Use usb_pipedevice to determine device address. This address is
1026          * 0 before the SET_ADDRESS command and the correct address afterward.
1027          */
1028         hc->dev_addr = dwc_otg_hcd_get_dev_addr(&urb->pipe_info);
1029         hc->ep_num = dwc_otg_hcd_get_ep_num(&urb->pipe_info);
1030         hc->speed = qh->dev_speed;
1031         hc->max_packet = dwc_max_packet(qh->maxp);
1032
1033         hc->xfer_started = 0;
1034         hc->halt_status = DWC_OTG_HC_XFER_NO_HALT_STATUS;
1035         hc->error_state = (qtd->error_count > 0);
1036         hc->halt_on_queue = 0;
1037         hc->halt_pending = 0;
1038         hc->requests = 0;
1039
1040         /*
1041          * The following values may be modified in the transfer type section
1042          * below. The xfer_len value may be reduced when the transfer is
1043          * started to accommodate the max widths of the XferSize and PktCnt
1044          * fields in the HCTSIZn register.
1045          */
1046
1047         hc->ep_is_in = (dwc_otg_hcd_is_pipe_in(&urb->pipe_info) != 0);
1048         if (hc->ep_is_in)
1049                 hc->do_ping = 0;
1050         else
1051                 hc->do_ping = qh->ping_state;
1052
1053         hc->data_pid_start = qh->data_toggle;
1054         hc->multi_count = 1;
1055
1056         if (hcd->core_if->dma_enable) {
1057                 hc->xfer_buff = (uint8_t *) urb->dma + urb->actual_length;
1058
1059                 /* For non-dword aligned case */
1060                 if (((unsigned long)hc->xfer_buff & 0x3)
1061                     && !hcd->core_if->dma_desc_enable) {
1062                         ptr = (uint8_t *) urb->buf + urb->actual_length;
1063                 }
1064         } else {
1065                 hc->xfer_buff = (uint8_t *) urb->buf + urb->actual_length;
1066         }
1067         hc->xfer_len = urb->length - urb->actual_length;
1068         hc->xfer_count = 0;
1069
1070         /*
1071          * Set the split attributes
1072          */
1073         hc->do_split = 0;
1074         if (qh->do_split) {
1075                 uint32_t hub_addr, port_addr;
1076                 hc->do_split = 1;
1077                 hc->xact_pos = qtd->isoc_split_pos;
1078                 hc->complete_split = qtd->complete_split;
1079                 hcd->fops->hub_info(hcd, urb->priv, &hub_addr, &port_addr);
1080                 hc->hub_addr = (uint8_t) hub_addr;
1081                 hc->port_addr = (uint8_t) port_addr;
1082         }
1083
1084         switch (dwc_otg_hcd_get_pipe_type(&urb->pipe_info)) {
1085         case UE_CONTROL:
1086                 hc->ep_type = DWC_OTG_EP_TYPE_CONTROL;
1087                 switch (qtd->control_phase) {
1088                 case DWC_OTG_CONTROL_SETUP:
1089                         DWC_DEBUGPL(DBG_HCDV, "  Control setup transaction\n");
1090                         hc->do_ping = 0;
1091                         hc->ep_is_in = 0;
1092                         hc->data_pid_start = DWC_OTG_HC_PID_SETUP;
1093                         if (hcd->core_if->dma_enable)
1094                                 hc->xfer_buff = (uint8_t *) urb->setup_dma;
1095                         else
1096                                 hc->xfer_buff = (uint8_t *) urb->setup_packet;
1097
1098                         hc->xfer_len = 8;
1099                         ptr = NULL;
1100                         break;
1101                 case DWC_OTG_CONTROL_DATA:
1102                         DWC_DEBUGPL(DBG_HCDV, "  Control data transaction\n");
1103                         hc->data_pid_start = qtd->data_toggle;
1104                         break;
1105                 case DWC_OTG_CONTROL_STATUS:
1106                         /*
1107                          * Direction is opposite of data direction or IN if no
1108                          * data.
1109                          */
1110                         DWC_DEBUGPL(DBG_HCDV, "  Control status transaction\n");
1111                         if (urb->length == 0) {
1112                                 hc->ep_is_in = 1;
1113                         } else {
1114                                 hc->ep_is_in =
1115                                     dwc_otg_hcd_is_pipe_out(&urb->pipe_info);
1116                         }
1117                         if (hc->ep_is_in)
1118                                 hc->do_ping = 0;
1119
1120                         hc->data_pid_start = DWC_OTG_HC_PID_DATA1;
1121
1122                         hc->xfer_len = 0;
1123                         if (hcd->core_if->dma_enable)
1124                                 hc->xfer_buff = (uint8_t *) hcd->status_buf_dma;
1125                         else
1126                                 hc->xfer_buff = (uint8_t *) hcd->status_buf;
1127
1128                         ptr = NULL;
1129                         break;
1130                 }
1131                 break;
1132         case UE_BULK:
1133                 hc->ep_type = DWC_OTG_EP_TYPE_BULK;
1134                 break;
1135         case UE_INTERRUPT:
1136                 hc->ep_type = DWC_OTG_EP_TYPE_INTR;
1137                 break;
1138         case UE_ISOCHRONOUS:
1139                 {
1140                         struct dwc_otg_hcd_iso_packet_desc *frame_desc;
1141
1142                         hc->ep_type = DWC_OTG_EP_TYPE_ISOC;
1143
1144                         if (hcd->core_if->dma_desc_enable)
1145                                 break;
1146
1147                         frame_desc = &urb->iso_descs[qtd->isoc_frame_index];
1148
1149                         frame_desc->status = 0;
1150
1151                         if (hcd->core_if->dma_enable) {
1152                                 hc->xfer_buff = (uint8_t *) urb->dma;
1153                         } else {
1154                                 hc->xfer_buff = (uint8_t *) urb->buf;
1155                         }
1156                         hc->xfer_buff +=
1157                             frame_desc->offset + qtd->isoc_split_offset;
1158                         hc->xfer_len =
1159                             frame_desc->length - qtd->isoc_split_offset;
1160
1161                         /* For non-dword aligned buffers */
1162                         if (((unsigned long)hc->xfer_buff & 0x3)
1163                             && hcd->core_if->dma_enable) {
1164                                 ptr =
1165                                     (uint8_t *) urb->buf + frame_desc->offset +
1166                                     qtd->isoc_split_offset;
1167                         } else
1168                                 ptr = NULL;
1169
1170                         if (hc->xact_pos == DWC_HCSPLIT_XACTPOS_ALL) {
1171                                 if (hc->xfer_len <= 188) {
1172                                         hc->xact_pos = DWC_HCSPLIT_XACTPOS_ALL;
1173                                 } else {
1174                                         hc->xact_pos =
1175                                             DWC_HCSPLIT_XACTPOS_BEGIN;
1176                                 }
1177                         }
1178                 }
1179                 break;
1180         }
1181         /* non DWORD-aligned buffer case */
1182         if (ptr) {
1183                 uint32_t buf_size;
1184                 if (hc->ep_type != DWC_OTG_EP_TYPE_ISOC) {
1185                         buf_size = hcd->core_if->core_params->max_transfer_size;
1186                 } else {
1187                         buf_size = 4096;
1188                 }
1189                 if (!qh->dw_align_buf) {
1190                         qh->dw_align_buf = DWC_DMA_ALLOC_ATOMIC(buf_size,
1191                                                                 &qh->
1192                                                                 dw_align_buf_dma);
1193                         if (!qh->dw_align_buf) {
1194                                 DWC_ERROR
1195                                     ("%s: Failed to allocate memory to handle "
1196                                      "non-dword aligned buffer case\n",
1197                                      __func__);
1198                                 return retval;
1199                         }
1200                 }
1201                 if (!hc->ep_is_in) {
1202                         dwc_memcpy(qh->dw_align_buf, ptr, hc->xfer_len);
1203                 }
1204                 hc->align_buff = qh->dw_align_buf_dma;
1205         } else {
1206                 hc->align_buff = 0;
1207         }
1208
1209         if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
1210             hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
1211                 /*
1212                  * This value may be modified when the transfer is started to
1213                  * reflect the actual transfer length.
1214                  */
1215                 hc->multi_count = dwc_hb_mult(qh->maxp);
1216         }
1217
1218         if (hcd->core_if->dma_desc_enable)
1219                 hc->desc_list_addr = qh->desc_list_dma;
1220
1221         dwc_otg_hc_init(hcd->core_if, hc);
1222         hc->qh = qh;
1223         return retval;
1224 }
1225
1226 /**
1227  * This function selects transactions from the HCD transfer schedule and
1228  * assigns them to available host channels. It is called from HCD interrupt
1229  * handler functions.
1230  *
1231  * @param hcd The HCD state structure.
1232  *
1233  * @return The types of new transactions that were assigned to host channels.
1234  */
1235 dwc_otg_transaction_type_e dwc_otg_hcd_select_transactions(dwc_otg_hcd_t *hcd)
1236 {
1237         dwc_list_link_t *qh_ptr;
1238         dwc_otg_qh_t *qh;
1239         int num_channels;
1240         dwc_otg_transaction_type_e ret_val = DWC_OTG_TRANSACTION_NONE;
1241         int err;
1242
1243 #ifdef DEBUG_SOF
1244         DWC_DEBUGPL(DBG_HCD, "  Select Transactions\n");
1245 #endif
1246
1247         /* Process entries in the periodic ready list. */
1248         qh_ptr = DWC_LIST_FIRST(&hcd->periodic_sched_ready);
1249
1250         while (qh_ptr != &hcd->periodic_sched_ready &&
1251                !DWC_CIRCLEQ_EMPTY(&hcd->free_hc_list)) {
1252
1253                 qh = DWC_LIST_ENTRY(qh_ptr, dwc_otg_qh_t, qh_list_entry);
1254                 assign_and_init_hc(hcd, qh);
1255
1256                 /*
1257                  * Move the QH from the periodic ready schedule to the
1258                  * periodic assigned schedule.
1259                  */
1260                 qh_ptr = DWC_LIST_NEXT(qh_ptr);
1261                 DWC_LIST_MOVE_HEAD(&hcd->periodic_sched_assigned,
1262                                    &qh->qh_list_entry);
1263
1264                 ret_val = DWC_OTG_TRANSACTION_PERIODIC;
1265         }
1266
1267         /*
1268          * Process entries in the inactive portion of the non-periodic
1269          * schedule. Some free host channels may not be used if they are
1270          * reserved for periodic transfers.
1271          */
1272         qh_ptr = hcd->non_periodic_sched_inactive.next;
1273         num_channels = hcd->core_if->core_params->host_channels;
1274         while (qh_ptr != &hcd->non_periodic_sched_inactive &&
1275                (hcd->non_periodic_channels <
1276                 num_channels - hcd->periodic_channels) &&
1277                !DWC_CIRCLEQ_EMPTY(&hcd->free_hc_list)) {
1278
1279                 qh = DWC_LIST_ENTRY(qh_ptr, dwc_otg_qh_t, qh_list_entry);
1280
1281                 err = assign_and_init_hc(hcd, qh);
1282
1283                 /*
1284                  * Move the QH from the non-periodic inactive schedule to the
1285                  * non-periodic active schedule.
1286                  */
1287                 qh_ptr = DWC_LIST_NEXT(qh_ptr);
1288                 if (err != 0)
1289                         continue;
1290                 DWC_LIST_MOVE_HEAD(&hcd->non_periodic_sched_active,
1291                                    &qh->qh_list_entry);
1292
1293                 if (ret_val == DWC_OTG_TRANSACTION_NONE) {
1294                         ret_val = DWC_OTG_TRANSACTION_NON_PERIODIC;
1295                 } else {
1296                         ret_val = DWC_OTG_TRANSACTION_ALL;
1297                 }
1298
1299                 hcd->non_periodic_channels++;
1300         }
1301
1302         return ret_val;
1303 }
1304
1305 /**
1306  * Attempts to queue a single transaction request for a host channel
1307  * associated with either a periodic or non-periodic transfer. This function
1308  * assumes that there is space available in the appropriate request queue. For
1309  * an OUT transfer or SETUP transaction in Slave mode, it checks whether space
1310  * is available in the appropriate Tx FIFO.
1311  *
1312  * @param hcd The HCD state structure.
1313  * @param hc Host channel descriptor associated with either a periodic or
1314  * non-periodic transfer.
1315  * @param fifo_dwords_avail Number of DWORDs available in the periodic Tx
1316  * FIFO for periodic transfers or the non-periodic Tx FIFO for non-periodic
1317  * transfers.
1318  *
1319  * @return 1 if a request is queued and more requests may be needed to
1320  * complete the transfer, 0 if no more requests are required for this
1321  * transfer, -1 if there is insufficient space in the Tx FIFO.
1322  */
1323 static int queue_transaction(dwc_otg_hcd_t *hcd,
1324                              dwc_hc_t *hc, uint16_t fifo_dwords_avail)
1325 {
1326         int retval;
1327
1328         if (hcd->core_if->dma_enable) {
1329                 if (hcd->core_if->dma_desc_enable) {
1330                         if (!hc->xfer_started
1331                             || (hc->ep_type == DWC_OTG_EP_TYPE_ISOC)) {
1332                                 dwc_otg_hcd_start_xfer_ddma(hcd, hc->qh);
1333                                 hc->qh->ping_state = 0;
1334                         }
1335                 } else if (!hc->xfer_started) {
1336                         dwc_otg_hc_start_transfer(hcd->core_if, hc);
1337                         hc->qh->ping_state = 0;
1338                 }
1339                 retval = 0;
1340         } else if (hc->halt_pending) {
1341                 /* Don't queue a request if the channel has been halted. */
1342                 retval = 0;
1343         } else if (hc->halt_on_queue) {
1344                 dwc_otg_hc_halt(hcd->core_if, hc, hc->halt_status);
1345                 retval = 0;
1346         } else if (hc->do_ping) {
1347                 if (!hc->xfer_started) {
1348                         dwc_otg_hc_start_transfer(hcd->core_if, hc);
1349                 }
1350                 retval = 0;
1351         } else if (!hc->ep_is_in || hc->data_pid_start == DWC_OTG_HC_PID_SETUP) {
1352                 if ((fifo_dwords_avail * 4) >= hc->max_packet) {
1353                         if (!hc->xfer_started) {
1354                                 dwc_otg_hc_start_transfer(hcd->core_if, hc);
1355                                 retval = 1;
1356                         } else {
1357                                 retval =
1358                                     dwc_otg_hc_continue_transfer(hcd->core_if,
1359                                                                  hc);
1360                         }
1361                 } else {
1362                         retval = -1;
1363                 }
1364         } else {
1365                 if (!hc->xfer_started) {
1366                         dwc_otg_hc_start_transfer(hcd->core_if, hc);
1367                         retval = 1;
1368                 } else {
1369                         retval = dwc_otg_hc_continue_transfer(hcd->core_if, hc);
1370                 }
1371         }
1372
1373         return retval;
1374 }
1375
1376 /**
1377  * Processes periodic channels for the next frame and queues transactions for
1378  * these channels to the DWC_otg controller. After queueing transactions, the
1379  * Periodic Tx FIFO Empty interrupt is enabled if there are more transactions
1380  * to queue as Periodic Tx FIFO or request queue space becomes available.
1381  * Otherwise, the Periodic Tx FIFO Empty interrupt is disabled.
1382  */
1383 static void process_periodic_channels(dwc_otg_hcd_t *hcd)
1384 {
1385         hptxsts_data_t tx_status;
1386         dwc_list_link_t *qh_ptr;
1387         dwc_otg_qh_t *qh;
1388         int status;
1389         int no_queue_space = 0;
1390         int no_fifo_space = 0;
1391
1392         dwc_otg_host_global_regs_t *host_regs;
1393         host_regs = hcd->core_if->host_if->host_global_regs;
1394
1395         DWC_DEBUGPL(DBG_HCDV, "Queue periodic transactions\n");
1396 #ifdef DEBUG
1397         tx_status.d32 = DWC_READ_REG32(&host_regs->hptxsts);
1398         DWC_DEBUGPL(DBG_HCDV,
1399                     "  P Tx Req Queue Space Avail (before queue): %d\n",
1400                     tx_status.b.ptxqspcavail);
1401         DWC_DEBUGPL(DBG_HCDV, "  P Tx FIFO Space Avail (before queue): %d\n",
1402                     tx_status.b.ptxfspcavail);
1403 #endif
1404
1405         qh_ptr = hcd->periodic_sched_assigned.next;
1406         while (qh_ptr != &hcd->periodic_sched_assigned) {
1407                 tx_status.d32 = DWC_READ_REG32(&host_regs->hptxsts);
1408                 if (tx_status.b.ptxqspcavail == 0) {
1409                         no_queue_space = 1;
1410                         break;
1411                 }
1412
1413                 qh = DWC_LIST_ENTRY(qh_ptr, dwc_otg_qh_t, qh_list_entry);
1414
1415                 /*
1416                  * Set a flag if we're queuing high-bandwidth in slave mode.
1417                  * The flag prevents any halts to get into the request queue in
1418                  * the middle of multiple high-bandwidth packets getting queued.
1419                  */
1420                 if (!hcd->core_if->dma_enable && qh->channel->multi_count > 1) {
1421                         hcd->core_if->queuing_high_bandwidth = 1;
1422                 }
1423                 status =
1424                     queue_transaction(hcd, qh->channel,
1425                                       tx_status.b.ptxfspcavail);
1426                 if (status < 0) {
1427                         no_fifo_space = 1;
1428                         break;
1429                 }
1430
1431                 /*
1432                  * In Slave mode, stay on the current transfer until there is
1433                  * nothing more to do or the high-bandwidth request count is
1434                  * reached. In DMA mode, only need to queue one request. The
1435                  * controller automatically handles multiple packets for
1436                  * high-bandwidth transfers.
1437                  */
1438                 if (hcd->core_if->dma_enable || status == 0 ||
1439                     qh->channel->requests == qh->channel->multi_count) {
1440                         qh_ptr = qh_ptr->next;
1441                         /*
1442                          * Move the QH from the periodic assigned schedule to
1443                          * the periodic queued schedule.
1444                          */
1445                         DWC_LIST_MOVE_HEAD(&hcd->periodic_sched_queued,
1446                                            &qh->qh_list_entry);
1447
1448                         /* done queuing high bandwidth */
1449                         hcd->core_if->queuing_high_bandwidth = 0;
1450                 }
1451         }
1452
1453         if (!hcd->core_if->dma_enable) {
1454                 dwc_otg_core_global_regs_t *global_regs;
1455                 gintmsk_data_t intr_mask = {.d32 = 0 };
1456
1457                 global_regs = hcd->core_if->core_global_regs;
1458                 intr_mask.b.ptxfempty = 1;
1459 #ifdef DEBUG
1460                 tx_status.d32 = DWC_READ_REG32(&host_regs->hptxsts);
1461                 DWC_DEBUGPL(DBG_HCDV,
1462                             "  P Tx Req Queue Space Avail (after queue): %d\n",
1463                             tx_status.b.ptxqspcavail);
1464                 DWC_DEBUGPL(DBG_HCDV,
1465                             "  P Tx FIFO Space Avail (after queue): %d\n",
1466                             tx_status.b.ptxfspcavail);
1467 #endif
1468                 if (!DWC_LIST_EMPTY(&hcd->periodic_sched_assigned) ||
1469                     no_queue_space || no_fifo_space) {
1470                         /*
1471                          * May need to queue more transactions as the request
1472                          * queue or Tx FIFO empties. Enable the periodic Tx
1473                          * FIFO empty interrupt. (Always use the half-empty
1474                          * level to ensure that new requests are loaded as
1475                          * soon as possible.)
1476                          */
1477                         DWC_MODIFY_REG32(&global_regs->gintmsk, 0,
1478                                          intr_mask.d32);
1479                 } else {
1480                         /*
1481                          * Disable the Tx FIFO empty interrupt since there are
1482                          * no more transactions that need to be queued right
1483                          * now. This function is called from interrupt
1484                          * handlers to queue more transactions as transfer
1485                          * states change.
1486                          */
1487                         DWC_MODIFY_REG32(&global_regs->gintmsk, intr_mask.d32,
1488                                          0);
1489                 }
1490         }
1491 }
1492
1493 /**
1494  * Processes active non-periodic channels and queues transactions for these
1495  * channels to the DWC_otg controller. After queueing transactions, the NP Tx
1496  * FIFO Empty interrupt is enabled if there are more transactions to queue as
1497  * NP Tx FIFO or request queue space becomes available. Otherwise, the NP Tx
1498  * FIFO Empty interrupt is disabled.
1499  */
1500 static void process_non_periodic_channels(dwc_otg_hcd_t *hcd)
1501 {
1502         gnptxsts_data_t tx_status;
1503         dwc_list_link_t *orig_qh_ptr;
1504         dwc_otg_qh_t *qh;
1505         int status;
1506         int no_queue_space = 0;
1507         int no_fifo_space = 0;
1508         int more_to_do = 0;
1509
1510         dwc_otg_core_global_regs_t *global_regs =
1511             hcd->core_if->core_global_regs;
1512
1513         DWC_DEBUGPL(DBG_HCDV, "Queue non-periodic transactions\n");
1514 #ifdef DEBUG
1515         tx_status.d32 = DWC_READ_REG32(&global_regs->gnptxsts);
1516         DWC_DEBUGPL(DBG_HCDV,
1517                     "  NP Tx Req Queue Space Avail (before queue): %d\n",
1518                     tx_status.b.nptxqspcavail);
1519         DWC_DEBUGPL(DBG_HCDV, "  NP Tx FIFO Space Avail (before queue): %d\n",
1520                     tx_status.b.nptxfspcavail);
1521 #endif
1522         /*
1523          * Keep track of the starting point. Skip over the start-of-list
1524          * entry.
1525          */
1526         if (hcd->non_periodic_qh_ptr == &hcd->non_periodic_sched_active) {
1527                 hcd->non_periodic_qh_ptr = hcd->non_periodic_qh_ptr->next;
1528         }
1529         orig_qh_ptr = hcd->non_periodic_qh_ptr;
1530
1531         /*
1532          * Process once through the active list or until no more space is
1533          * available in the request queue or the Tx FIFO.
1534          */
1535         do {
1536                 tx_status.d32 = DWC_READ_REG32(&global_regs->gnptxsts);
1537                 if (!hcd->core_if->dma_enable && tx_status.b.nptxqspcavail == 0) {
1538                         no_queue_space = 1;
1539                         break;
1540                 }
1541
1542                 qh = DWC_LIST_ENTRY(hcd->non_periodic_qh_ptr, dwc_otg_qh_t,
1543                                     qh_list_entry);
1544                 status =
1545                     queue_transaction(hcd, qh->channel,
1546                                       tx_status.b.nptxfspcavail);
1547
1548                 if (status > 0) {
1549                         more_to_do = 1;
1550                 } else if (status < 0) {
1551                         no_fifo_space = 1;
1552                         break;
1553                 }
1554
1555                 /* Advance to next QH, skipping start-of-list entry. */
1556                 hcd->non_periodic_qh_ptr = hcd->non_periodic_qh_ptr->next;
1557                 if (hcd->non_periodic_qh_ptr == &hcd->non_periodic_sched_active) {
1558                         hcd->non_periodic_qh_ptr =
1559                             hcd->non_periodic_qh_ptr->next;
1560                 }
1561
1562         } while (hcd->non_periodic_qh_ptr != orig_qh_ptr);
1563
1564         if (!hcd->core_if->dma_enable) {
1565                 gintmsk_data_t intr_mask = {.d32 = 0 };
1566                 intr_mask.b.nptxfempty = 1;
1567
1568 #ifdef DEBUG
1569                 tx_status.d32 = DWC_READ_REG32(&global_regs->gnptxsts);
1570                 DWC_DEBUGPL(DBG_HCDV,
1571                             "  NP Tx Req Queue Space Avail (after queue): %d\n",
1572                             tx_status.b.nptxqspcavail);
1573                 DWC_DEBUGPL(DBG_HCDV,
1574                             "  NP Tx FIFO Space Avail (after queue): %d\n",
1575                             tx_status.b.nptxfspcavail);
1576 #endif
1577                 if (more_to_do || no_queue_space || no_fifo_space) {
1578                         /*
1579                          * May need to queue more transactions as the request
1580                          * queue or Tx FIFO empties. Enable the non-periodic
1581                          * Tx FIFO empty interrupt. (Always use the half-empty
1582                          * level to ensure that new requests are loaded as
1583                          * soon as possible.)
1584                          */
1585                         DWC_MODIFY_REG32(&global_regs->gintmsk, 0,
1586                                          intr_mask.d32);
1587                 } else {
1588                         /*
1589                          * Disable the Tx FIFO empty interrupt since there are
1590                          * no more transactions that need to be queued right
1591                          * now. This function is called from interrupt
1592                          * handlers to queue more transactions as transfer
1593                          * states change.
1594                          */
1595                         DWC_MODIFY_REG32(&global_regs->gintmsk, intr_mask.d32,
1596                                          0);
1597                 }
1598         }
1599 }
1600
1601 /**
1602  * This function processes the currently active host channels and queues
1603  * transactions for these channels to the DWC_otg controller. It is called
1604  * from HCD interrupt handler functions.
1605  *
1606  * @param hcd The HCD state structure.
1607  * @param tr_type The type(s) of transactions to queue (non-periodic,
1608  * periodic, or both).
1609  */
1610 void dwc_otg_hcd_queue_transactions(dwc_otg_hcd_t *hcd,
1611                                     dwc_otg_transaction_type_e tr_type)
1612 {
1613 #ifdef DEBUG_SOF
1614         DWC_DEBUGPL(DBG_HCD, "Queue Transactions\n");
1615 #endif
1616         /* Process host channels associated with periodic transfers. */
1617         if ((tr_type == DWC_OTG_TRANSACTION_PERIODIC ||
1618              tr_type == DWC_OTG_TRANSACTION_ALL) &&
1619             !DWC_LIST_EMPTY(&hcd->periodic_sched_assigned)) {
1620
1621                 process_periodic_channels(hcd);
1622         }
1623
1624         /* Process host channels associated with non-periodic transfers. */
1625         if (tr_type == DWC_OTG_TRANSACTION_NON_PERIODIC ||
1626             tr_type == DWC_OTG_TRANSACTION_ALL) {
1627                 if (!DWC_LIST_EMPTY(&hcd->non_periodic_sched_active)) {
1628                         process_non_periodic_channels(hcd);
1629                 } else {
1630                         /*
1631                          * Ensure NP Tx FIFO empty interrupt is disabled when
1632                          * there are no non-periodic transfers to process.
1633                          */
1634                         gintmsk_data_t gintmsk = {.d32 = 0 };
1635                         gintmsk.b.nptxfempty = 1;
1636                         DWC_MODIFY_REG32(&hcd->core_if->core_global_regs->
1637                                          gintmsk, gintmsk.d32, 0);
1638                 }
1639         }
1640 }
1641
1642 #ifdef DWC_HS_ELECT_TST
1643 /*
1644  * Quick and dirty hack to implement the HS Electrical Test
1645  * SINGLE_STEP_GET_DEVICE_DESCRIPTOR feature.
1646  *
1647  * This code was copied from our userspace app "hset". It sends a
1648  * Get Device Descriptor control sequence in two parts, first the
1649  * Setup packet by itself, followed some time later by the In and
1650  * Ack packets. Rather than trying to figure out how to add this
1651  * functionality to the normal driver code, we just hijack the
1652  * hardware, using these two function to drive the hardware
1653  * directly.
1654  */
1655
1656 static dwc_otg_core_global_regs_t *global_regs;
1657 static dwc_otg_host_global_regs_t *hc_global_regs;
1658 static dwc_otg_hc_regs_t *hc_regs;
1659 static uint32_t *data_fifo;
1660
1661 static void do_setup(void)
1662 {
1663         gintsts_data_t gintsts;
1664         hctsiz_data_t hctsiz;
1665         hcchar_data_t hcchar;
1666         haint_data_t haint;
1667         hcint_data_t hcint;
1668
1669         /* Enable HAINTs */
1670         DWC_WRITE_REG32(&hc_global_regs->haintmsk, 0x0001);
1671
1672         /* Enable HCINTs */
1673         DWC_WRITE_REG32(&hc_regs->hcintmsk, 0x04a3);
1674
1675         /* Read GINTSTS */
1676         gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
1677
1678         /* Read HAINT */
1679         haint.d32 = DWC_READ_REG32(&hc_global_regs->haint);
1680
1681         /* Read HCINT */
1682         hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
1683
1684         /* Read HCCHAR */
1685         hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
1686
1687         /* Clear HCINT */
1688         DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32);
1689
1690         /* Clear HAINT */
1691         DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32);
1692
1693         /* Clear GINTSTS */
1694         DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
1695
1696         /* Read GINTSTS */
1697         gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
1698
1699         /*
1700          * Send Setup packet (Get Device Descriptor)
1701          */
1702
1703         /* Make sure channel is disabled */
1704         hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
1705         if (hcchar.b.chen) {
1706                 hcchar.b.chdis = 1;
1707                 /* hcchar.b.chen = 1; */
1708                 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
1709                 /* sleep(1); */
1710                 dwc_mdelay(1000);
1711
1712                 /* Read GINTSTS */
1713                 gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
1714
1715                 /* Read HAINT */
1716                 haint.d32 = DWC_READ_REG32(&hc_global_regs->haint);
1717
1718                 /* Read HCINT */
1719                 hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
1720
1721                 /* Read HCCHAR */
1722                 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
1723
1724                 /* Clear HCINT */
1725                 DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32);
1726
1727                 /* Clear HAINT */
1728                 DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32);
1729
1730                 /* Clear GINTSTS */
1731                 DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
1732
1733                 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
1734         }
1735
1736         /* Set HCTSIZ */
1737         hctsiz.d32 = 0;
1738         hctsiz.b.xfersize = 8;
1739         hctsiz.b.pktcnt = 1;
1740         hctsiz.b.pid = DWC_OTG_HC_PID_SETUP;
1741         DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32);
1742
1743         /* Set HCCHAR */
1744         hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
1745         hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;
1746         hcchar.b.epdir = 0;
1747         hcchar.b.epnum = 0;
1748         hcchar.b.mps = 8;
1749         hcchar.b.chen = 1;
1750         DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
1751
1752         /* Fill FIFO with Setup data for Get Device Descriptor */
1753         data_fifo = (uint32_t *) ((char *)global_regs + 0x1000);
1754         DWC_WRITE_REG32(data_fifo++, 0x01000680);
1755         DWC_WRITE_REG32(data_fifo++, 0x00080000);
1756
1757         gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
1758
1759         /* Wait for host channel interrupt */
1760         do {
1761                 gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
1762         } while (gintsts.b.hcintr == 0);
1763
1764         /* Disable HCINTs */
1765         DWC_WRITE_REG32(&hc_regs->hcintmsk, 0x0000);
1766
1767         /* Disable HAINTs */
1768         DWC_WRITE_REG32(&hc_global_regs->haintmsk, 0x0000);
1769
1770         /* Read HAINT */
1771         haint.d32 = DWC_READ_REG32(&hc_global_regs->haint);
1772
1773         /* Read HCINT */
1774         hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
1775
1776         /* Read HCCHAR */
1777         hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
1778
1779         /* Clear HCINT */
1780         DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32);
1781
1782         /* Clear HAINT */
1783         DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32);
1784
1785         /* Clear GINTSTS */
1786         DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
1787
1788         /* Read GINTSTS */
1789         gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
1790 }
1791
1792 static void do_in_ack(void)
1793 {
1794         gintsts_data_t gintsts;
1795         hctsiz_data_t hctsiz;
1796         hcchar_data_t hcchar;
1797         haint_data_t haint;
1798         hcint_data_t hcint;
1799         host_grxsts_data_t grxsts;
1800
1801         /* Enable HAINTs */
1802         DWC_WRITE_REG32(&hc_global_regs->haintmsk, 0x0001);
1803
1804         /* Enable HCINTs */
1805         DWC_WRITE_REG32(&hc_regs->hcintmsk, 0x04a3);
1806
1807         /* Read GINTSTS */
1808         gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
1809
1810         /* Read HAINT */
1811         haint.d32 = DWC_READ_REG32(&hc_global_regs->haint);
1812
1813         /* Read HCINT */
1814         hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
1815
1816         /* Read HCCHAR */
1817         hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
1818
1819         /* Clear HCINT */
1820         DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32);
1821
1822         /* Clear HAINT */
1823         DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32);
1824
1825         /* Clear GINTSTS */
1826         DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
1827
1828         /* Read GINTSTS */
1829         gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
1830
1831         /*
1832          * Receive Control In packet
1833          */
1834
1835         /* Make sure channel is disabled */
1836         hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
1837         if (hcchar.b.chen) {
1838                 hcchar.b.chdis = 1;
1839                 hcchar.b.chen = 1;
1840                 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
1841                 /* sleep(1); */
1842                 dwc_mdelay(1000);
1843
1844                 /* Read GINTSTS */
1845                 gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
1846
1847                 /* Read HAINT */
1848                 haint.d32 = DWC_READ_REG32(&hc_global_regs->haint);
1849
1850                 /* Read HCINT */
1851                 hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
1852
1853                 /* Read HCCHAR */
1854                 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
1855
1856                 /* Clear HCINT */
1857                 DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32);
1858
1859                 /* Clear HAINT */
1860                 DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32);
1861
1862                 /* Clear GINTSTS */
1863                 DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
1864
1865                 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
1866         }
1867
1868         /* Set HCTSIZ */
1869         hctsiz.d32 = 0;
1870         hctsiz.b.xfersize = 8;
1871         hctsiz.b.pktcnt = 1;
1872         hctsiz.b.pid = DWC_OTG_HC_PID_DATA1;
1873         DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32);
1874
1875         /* Set HCCHAR */
1876         hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
1877         hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;
1878         hcchar.b.epdir = 1;
1879         hcchar.b.epnum = 0;
1880         hcchar.b.mps = 8;
1881         hcchar.b.chen = 1;
1882         DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
1883
1884         gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
1885
1886         /* Wait for receive status queue interrupt */
1887         do {
1888                 gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
1889         } while (gintsts.b.rxstsqlvl == 0);
1890
1891         /* Read RXSTS */
1892         grxsts.d32 = DWC_READ_REG32(&global_regs->grxstsp);
1893
1894         /* Clear RXSTSQLVL in GINTSTS */
1895         gintsts.d32 = 0;
1896         gintsts.b.rxstsqlvl = 1;
1897         DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
1898
1899         switch (grxsts.b.pktsts) {
1900         case DWC_GRXSTS_PKTSTS_IN:
1901                 /* Read the data into the host buffer */
1902                 if (grxsts.b.bcnt > 0) {
1903                         int i;
1904                         int word_count = (grxsts.b.bcnt + 3) / 4;
1905
1906                         data_fifo = (uint32_t *) ((char *)global_regs + 0x1000);
1907
1908                         for (i = 0; i < word_count; i++) {
1909                                 (void)DWC_READ_REG32(data_fifo++);
1910                         }
1911                 }
1912                 break;
1913
1914         default:
1915                 break;
1916         }
1917
1918         gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
1919
1920         /* Wait for receive status queue interrupt */
1921         do {
1922                 gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
1923         } while (gintsts.b.rxstsqlvl == 0);
1924
1925         /* Read RXSTS */
1926         grxsts.d32 = DWC_READ_REG32(&global_regs->grxstsp);
1927
1928         /* Clear RXSTSQLVL in GINTSTS */
1929         gintsts.d32 = 0;
1930         gintsts.b.rxstsqlvl = 1;
1931         DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
1932
1933         switch (grxsts.b.pktsts) {
1934         case DWC_GRXSTS_PKTSTS_IN_XFER_COMP:
1935                 break;
1936
1937         default:
1938                 break;
1939         }
1940
1941         gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
1942
1943         /* Wait for host channel interrupt */
1944         do {
1945                 gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
1946         } while (gintsts.b.hcintr == 0);
1947
1948         /* Read HAINT */
1949         haint.d32 = DWC_READ_REG32(&hc_global_regs->haint);
1950
1951         /* Read HCINT */
1952         hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
1953
1954         /* Read HCCHAR */
1955         hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
1956
1957         /* Clear HCINT */
1958         DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32);
1959
1960         /* Clear HAINT */
1961         DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32);
1962
1963         /* Clear GINTSTS */
1964         DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
1965
1966         /* Read GINTSTS */
1967         gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
1968
1969         /* usleep(100000); */
1970         /* mdelay(100); */
1971         dwc_mdelay(1);
1972
1973         /*
1974          * Send handshake packet
1975          */
1976
1977         /* Read HAINT */
1978         haint.d32 = DWC_READ_REG32(&hc_global_regs->haint);
1979
1980         /* Read HCINT */
1981         hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
1982
1983         /* Read HCCHAR */
1984         hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
1985
1986         /* Clear HCINT */
1987         DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32);
1988
1989         /* Clear HAINT */
1990         DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32);
1991
1992         /* Clear GINTSTS */
1993         DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
1994
1995         /* Read GINTSTS */
1996         gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
1997
1998         /* Make sure channel is disabled */
1999         hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2000         if (hcchar.b.chen) {
2001                 hcchar.b.chdis = 1;
2002                 hcchar.b.chen = 1;
2003                 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
2004                 /* sleep(1); */
2005                 dwc_mdelay(1000);
2006
2007                 /* Read GINTSTS */
2008                 gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
2009
2010                 /* Read HAINT */
2011                 haint.d32 = DWC_READ_REG32(&hc_global_regs->haint);
2012
2013                 /* Read HCINT */
2014                 hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
2015
2016                 /* Read HCCHAR */
2017                 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2018
2019                 /* Clear HCINT */
2020                 DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32);
2021
2022                 /* Clear HAINT */
2023                 DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32);
2024
2025                 /* Clear GINTSTS */
2026                 DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
2027
2028                 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2029         }
2030
2031         /* Set HCTSIZ */
2032         hctsiz.d32 = 0;
2033         hctsiz.b.xfersize = 0;
2034         hctsiz.b.pktcnt = 1;
2035         hctsiz.b.pid = DWC_OTG_HC_PID_DATA1;
2036         DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32);
2037
2038         /* Set HCCHAR */
2039         hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2040         hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;
2041         hcchar.b.epdir = 0;
2042         hcchar.b.epnum = 0;
2043         hcchar.b.mps = 8;
2044         hcchar.b.chen = 1;
2045         DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
2046
2047         gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
2048
2049         /* Wait for host channel interrupt */
2050         do {
2051                 gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
2052         } while (gintsts.b.hcintr == 0);
2053
2054         /* Disable HCINTs */
2055         DWC_WRITE_REG32(&hc_regs->hcintmsk, 0x0000);
2056
2057         /* Disable HAINTs */
2058         DWC_WRITE_REG32(&hc_global_regs->haintmsk, 0x0000);
2059
2060         /* Read HAINT */
2061         haint.d32 = DWC_READ_REG32(&hc_global_regs->haint);
2062
2063         /* Read HCINT */
2064         hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
2065
2066         /* Read HCCHAR */
2067         hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2068
2069         /* Clear HCINT */
2070         DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32);
2071
2072         /* Clear HAINT */
2073         DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32);
2074
2075         /* Clear GINTSTS */
2076         DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
2077
2078         /* Read GINTSTS */
2079         gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
2080 }
2081 #endif
2082
2083 /** Handles hub class-specific requests. */
2084 int dwc_otg_hcd_hub_control(dwc_otg_hcd_t *dwc_otg_hcd,
2085                             uint16_t typeReq,
2086                             uint16_t wValue,
2087                             uint16_t wIndex, uint8_t *buf, uint16_t wLength)
2088 {
2089         int retval = 0;
2090
2091         dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
2092         usb_hub_descriptor_t *hub_desc;
2093         hprt0_data_t hprt0 = {.d32 = 0 };
2094
2095         uint32_t port_status;
2096
2097         switch (typeReq) {
2098         case UCR_CLEAR_HUB_FEATURE:
2099                 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2100                             "ClearHubFeature 0x%x\n", wValue);
2101                 switch (wValue) {
2102                 case UHF_C_HUB_LOCAL_POWER:
2103                 case UHF_C_HUB_OVER_CURRENT:
2104                         /* Nothing required here */
2105                         break;
2106                 default:
2107                         retval = -DWC_E_INVALID;
2108                         DWC_ERROR("DWC OTG HCD - "
2109                                   "ClearHubFeature request %xh unknown\n",
2110                                   wValue);
2111                 }
2112                 break;
2113         case UCR_CLEAR_PORT_FEATURE:
2114 #ifdef CONFIG_USB_DWC_OTG_LPM
2115                 if (wValue != UHF_PORT_L1)
2116 #endif
2117                         if (!wIndex || wIndex > 1)
2118                                 goto error;
2119
2120                 switch (wValue) {
2121                 case UHF_PORT_ENABLE:
2122                         DWC_DEBUGPL(DBG_ANY, "DWC OTG HCD HUB CONTROL - "
2123                                     "ClearPortFeature USB_PORT_FEAT_ENABLE\n");
2124                         hprt0.d32 = dwc_otg_read_hprt0(core_if);
2125                         hprt0.b.prtena = 1;
2126                         DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
2127                         break;
2128                 case UHF_PORT_SUSPEND:
2129                         DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2130                                     "ClearPortFeature USB_PORT_FEAT_SUSPEND\n");
2131
2132                         if (core_if->power_down == 2) {
2133                                 dwc_otg_host_hibernation_restore(core_if, 0, 0);
2134                         } else {
2135                                 DWC_WRITE_REG32(core_if->pcgcctl, 0);
2136                                 dwc_mdelay(5);
2137
2138                                 hprt0.d32 = dwc_otg_read_hprt0(core_if);
2139                                 hprt0.b.prtres = 1;
2140                                 DWC_WRITE_REG32(core_if->host_if->hprt0,
2141                                                 hprt0.d32);
2142                                 hprt0.b.prtsusp = 0;
2143                                 /* Clear Resume bit */
2144                                 dwc_mdelay(100);
2145                                 hprt0.b.prtres = 0;
2146                                 DWC_WRITE_REG32(core_if->host_if->hprt0,
2147                                                 hprt0.d32);
2148                         }
2149                         break;
2150 #ifdef CONFIG_USB_DWC_OTG_LPM
2151                 case UHF_PORT_L1:
2152                         {
2153                                 pcgcctl_data_t pcgcctl = {.d32 = 0 };
2154                                 glpmcfg_data_t lpmcfg = {.d32 = 0 };
2155
2156                                 lpmcfg.d32 =
2157                                     DWC_READ_REG32(&core_if->core_global_regs->
2158                                                    glpmcfg);
2159                                 lpmcfg.b.en_utmi_sleep = 0;
2160                                 lpmcfg.b.hird_thres &= (~(1 << 4));
2161                                 lpmcfg.b.prt_sleep_sts = 1;
2162                                 DWC_WRITE_REG32(&core_if->core_global_regs->
2163                                                 glpmcfg, lpmcfg.d32);
2164
2165                                 /* Clear Enbl_L1Gating bit. */
2166                                 pcgcctl.b.enbl_sleep_gating = 1;
2167                                 DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32,
2168                                                  0);
2169
2170                                 dwc_mdelay(5);
2171
2172                                 hprt0.d32 = dwc_otg_read_hprt0(core_if);
2173                                 hprt0.b.prtres = 1;
2174                                 DWC_WRITE_REG32(core_if->host_if->hprt0,
2175                                                 hprt0.d32);
2176                                 /* This bit will be cleared in wakeup interrupt handle */
2177                                 break;
2178                         }
2179 #endif
2180                 case UHF_PORT_POWER:
2181                         DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2182                                     "ClearPortFeature USB_PORT_FEAT_POWER\n");
2183                         hprt0.d32 = dwc_otg_read_hprt0(core_if);
2184                         hprt0.b.prtpwr = 0;
2185                         DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
2186                         break;
2187                 case UHF_PORT_INDICATOR:
2188                         DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2189                                     "ClearPortFeature USB_PORT_FEAT_INDICATOR\n");
2190                         /* Port inidicator not supported */
2191                         break;
2192                 case UHF_C_PORT_CONNECTION:
2193                         /* Clears drivers internal connect status change
2194                          * flag */
2195                         DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2196                                     "ClearPortFeature USB_PORT_FEAT_C_CONNECTION\n");
2197                         dwc_otg_hcd->flags.b.port_connect_status_change = 0;
2198                         break;
2199                 case UHF_C_PORT_RESET:
2200                         /* Clears the driver's internal Port Reset Change
2201                          * flag */
2202                         DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2203                                     "ClearPortFeature USB_PORT_FEAT_C_RESET\n");
2204                         dwc_otg_hcd->flags.b.port_reset_change = 0;
2205                         break;
2206                 case UHF_C_PORT_ENABLE:
2207                         /* Clears the driver's internal Port
2208                          * Enable/Disable Change flag */
2209                         DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2210                                     "ClearPortFeature USB_PORT_FEAT_C_ENABLE\n");
2211                         dwc_otg_hcd->flags.b.port_enable_change = 0;
2212                         break;
2213                 case UHF_C_PORT_SUSPEND:
2214                         /* Clears the driver's internal Port Suspend
2215                          * Change flag, which is set when resume signaling on
2216                          * the host port is complete */
2217                         DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2218                                     "ClearPortFeature USB_PORT_FEAT_C_SUSPEND\n");
2219                         dwc_otg_hcd->flags.b.port_suspend_change = 0;
2220                         break;
2221 #ifdef CONFIG_USB_DWC_OTG_LPM
2222                 case UHF_C_PORT_L1:
2223                         dwc_otg_hcd->flags.b.port_l1_change = 0;
2224                         break;
2225 #endif
2226                 case UHF_C_PORT_OVER_CURRENT:
2227                         DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2228                                     "ClearPortFeature USB_PORT_FEAT_C_OVER_CURRENT\n");
2229                         dwc_otg_hcd->flags.b.port_over_current_change = 0;
2230                         break;
2231                 default:
2232                         retval = -DWC_E_INVALID;
2233                         DWC_ERROR("DWC OTG HCD - "
2234                                   "ClearPortFeature request %xh "
2235                                   "unknown or unsupported\n", wValue);
2236                 }
2237                 break;
2238         case UCR_GET_HUB_DESCRIPTOR:
2239                 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2240                             "GetHubDescriptor\n");
2241                 hub_desc = (usb_hub_descriptor_t *) buf;
2242                 hub_desc->bDescLength = 9;
2243                 hub_desc->bDescriptorType = 0x29;
2244                 hub_desc->bNbrPorts = 1;
2245                 USETW(hub_desc->wHubCharacteristics, 0x08);
2246                 hub_desc->bPwrOn2PwrGood = 1;
2247                 hub_desc->bHubContrCurrent = 0;
2248                 hub_desc->DeviceRemovable[0] = 0;
2249                 hub_desc->DeviceRemovable[1] = 0xff;
2250                 break;
2251         case UCR_GET_HUB_STATUS:
2252                 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2253                             "GetHubStatus\n");
2254                 DWC_MEMSET(buf, 0, 4);
2255                 break;
2256         case UCR_GET_PORT_STATUS:
2257                 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2258                             "GetPortStatus wIndex = 0x%04x FLAGS=0x%08x\n",
2259                             wIndex, dwc_otg_hcd->flags.d32);
2260                 if (!wIndex || wIndex > 1)
2261                         goto error;
2262
2263                 port_status = 0;
2264
2265                 if (dwc_otg_hcd->flags.b.port_connect_status_change)
2266                         port_status |= (1 << UHF_C_PORT_CONNECTION);
2267
2268                 if (dwc_otg_hcd->flags.b.port_enable_change)
2269                         port_status |= (1 << UHF_C_PORT_ENABLE);
2270
2271                 if (dwc_otg_hcd->flags.b.port_suspend_change)
2272                         port_status |= (1 << UHF_C_PORT_SUSPEND);
2273
2274                 if (dwc_otg_hcd->flags.b.port_l1_change)
2275                         port_status |= (1 << UHF_C_PORT_L1);
2276
2277                 if (dwc_otg_hcd->flags.b.port_reset_change) {
2278                         port_status |= (1 << UHF_C_PORT_RESET);
2279                 }
2280
2281                 if (dwc_otg_hcd->flags.b.port_over_current_change) {
2282                         DWC_WARN("Overcurrent change detected\n");
2283                         port_status |= (1 << UHF_C_PORT_OVER_CURRENT);
2284                 }
2285
2286                 if (!dwc_otg_hcd->flags.b.port_connect_status) {
2287                         /*
2288                          * The port is disconnected, which means the core is
2289                          * either in device mode or it soon will be. Just
2290                          * return 0's for the remainder of the port status
2291                          * since the port register can't be read if the core
2292                          * is in device mode.
2293                          */
2294                         *((__le32 *) buf) = dwc_cpu_to_le32(&port_status);
2295                         break;
2296                 }
2297
2298                 hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
2299                 DWC_DEBUGPL(DBG_HCDV, "  HPRT0: 0x%08x\n", hprt0.d32);
2300
2301                 if (hprt0.b.prtconnsts)
2302                         port_status |= (1 << UHF_PORT_CONNECTION);
2303
2304                 if (hprt0.b.prtena)
2305                         port_status |= (1 << UHF_PORT_ENABLE);
2306
2307                 if (hprt0.b.prtsusp)
2308                         port_status |= (1 << UHF_PORT_SUSPEND);
2309
2310                 if (hprt0.b.prtovrcurract)
2311                         port_status |= (1 << UHF_PORT_OVER_CURRENT);
2312
2313                 if (hprt0.b.prtrst)
2314                         port_status |= (1 << UHF_PORT_RESET);
2315
2316                 if (hprt0.b.prtpwr)
2317                         port_status |= (1 << UHF_PORT_POWER);
2318
2319                 if (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_HIGH_SPEED)
2320                         port_status |= (1 << UHF_PORT_HIGH_SPEED);
2321                 else if (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_LOW_SPEED)
2322                         port_status |= (1 << UHF_PORT_LOW_SPEED);
2323
2324                 if (hprt0.b.prttstctl)
2325                         port_status |= (1 << UHF_PORT_TEST);
2326                 if (dwc_otg_get_lpm_portsleepstatus(dwc_otg_hcd->core_if)) {
2327                         port_status |= (1 << UHF_PORT_L1);
2328                 }
2329                 /*
2330                    For Synopsys HW emulation of Power down wkup_control asserts the
2331                    hreset_n and prst_n on suspned. This causes the HPRT0 to be zero.
2332                    We intentionally tell the software that port is in L2Suspend state.
2333                    Only for STE.
2334                  */
2335                 if ((core_if->power_down == 2)
2336                     && (core_if->hibernation_suspend == 1)) {
2337                         port_status |= (1 << UHF_PORT_SUSPEND);
2338                 }
2339                 /* USB_PORT_FEAT_INDICATOR unsupported always 0 */
2340
2341                 *((__le32 *) buf) = dwc_cpu_to_le32(&port_status);
2342
2343                 break;
2344         case UCR_SET_HUB_FEATURE:
2345                 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2346                             "SetHubFeature\n");
2347                 /* No HUB features supported */
2348                 break;
2349         case UCR_SET_PORT_FEATURE:
2350                 if (wValue != UHF_PORT_TEST && (!wIndex || wIndex > 1))
2351                         goto error;
2352
2353                 if (!dwc_otg_hcd->flags.b.port_connect_status) {
2354                         /*
2355                          * The port is disconnected, which means the core is
2356                          * either in device mode or it soon will be. Just
2357                          * return without doing anything since the port
2358                          * register can't be written if the core is in device
2359                          * mode.
2360                          */
2361                         break;
2362                 }
2363
2364                 switch (wValue) {
2365                 case UHF_PORT_SUSPEND:
2366                         DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2367                                     "SetPortFeature - USB_PORT_FEAT_SUSPEND\n");
2368                         if (dwc_otg_hcd_otg_port(dwc_otg_hcd) != wIndex) {
2369                                 goto error;
2370                         }
2371                         if (core_if->power_down == 2) {
2372                                 int timeout = 300;
2373                                 dwc_irqflags_t flags;
2374                                 pcgcctl_data_t pcgcctl = {.d32 = 0 };
2375                                 gpwrdn_data_t gpwrdn = {.d32 = 0 };
2376                                 gusbcfg_data_t gusbcfg = {.d32 = 0 };
2377 #ifdef DWC_DEV_SRPCAP
2378                                 int32_t otg_cap_param =
2379                                     core_if->core_params->otg_cap;
2380 #endif
2381                                 DWC_PRINTF
2382                                     ("Preparing for complete power-off\n");
2383
2384                                 /* Save registers before hibernation */
2385                                 dwc_otg_save_global_regs(core_if);
2386                                 dwc_otg_save_host_regs(core_if);
2387
2388                                 hprt0.d32 = dwc_otg_read_hprt0(core_if);
2389                                 hprt0.b.prtsusp = 1;
2390                                 hprt0.b.prtena = 0;
2391                                 DWC_WRITE_REG32(core_if->host_if->hprt0,
2392                                                 hprt0.d32);
2393                                 /* Spin hprt0.b.prtsusp to became 1 */
2394                                 do {
2395                                         hprt0.d32 = dwc_otg_read_hprt0(core_if);
2396                                         if (hprt0.b.prtsusp) {
2397                                                 break;
2398                                         }
2399                                         dwc_mdelay(1);
2400                                 } while (--timeout);
2401                                 if (!timeout) {
2402                                         DWC_WARN("Suspend wasn't genereted\n");
2403                                 }
2404                                 dwc_udelay(10);
2405
2406                                 /*
2407                                  * We need to disable interrupts to prevent servicing of any IRQ
2408                                  * during going to hibernation
2409                                  */
2410                                 DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &flags);
2411                                 core_if->lx_state = DWC_OTG_L2;
2412 #ifdef DWC_DEV_SRPCAP
2413                                 hprt0.d32 = dwc_otg_read_hprt0(core_if);
2414                                 hprt0.b.prtpwr = 0;
2415                                 hprt0.b.prtena = 0;
2416                                 DWC_WRITE_REG32(core_if->host_if->hprt0,
2417                                                 hprt0.d32);
2418 #endif
2419                                 gusbcfg.d32 =
2420                                     DWC_READ_REG32(&core_if->
2421                                                    core_global_regs->gusbcfg);
2422                                 if (gusbcfg.b.ulpi_utmi_sel == 1) {
2423                                         /* ULPI interface */
2424                                         /* Suspend the Phy Clock */
2425                                         pcgcctl.d32 = 0;
2426                                         pcgcctl.b.stoppclk = 1;
2427                                         DWC_MODIFY_REG32(core_if->pcgcctl, 0,
2428                                                          pcgcctl.d32);
2429                                         dwc_udelay(10);
2430                                         gpwrdn.b.pmuactv = 1;
2431                                         DWC_MODIFY_REG32
2432                                             (&core_if->core_global_regs->gpwrdn,
2433                                              0, gpwrdn.d32);
2434                                 } else {
2435                                         /* UTMI+ Interface */
2436                                         gpwrdn.b.pmuactv = 1;
2437                                         DWC_MODIFY_REG32
2438                                             (&core_if->core_global_regs->gpwrdn,
2439                                              0, gpwrdn.d32);
2440                                         dwc_udelay(10);
2441                                         pcgcctl.b.stoppclk = 1;
2442                                         DWC_MODIFY_REG32(core_if->pcgcctl, 0,
2443                                                          pcgcctl.d32);
2444                                         dwc_udelay(10);
2445                                 }
2446 #ifdef DWC_DEV_SRPCAP
2447                                 gpwrdn.d32 = 0;
2448                                 gpwrdn.b.dis_vbus = 1;
2449                                 DWC_MODIFY_REG32(&core_if->
2450                                                  core_global_regs->gpwrdn, 0,
2451                                                  gpwrdn.d32);
2452 #endif
2453                                 gpwrdn.d32 = 0;
2454                                 gpwrdn.b.pmuintsel = 1;
2455                                 DWC_MODIFY_REG32(&core_if->
2456                                                  core_global_regs->gpwrdn, 0,
2457                                                  gpwrdn.d32);
2458                                 dwc_udelay(10);
2459
2460                                 gpwrdn.d32 = 0;
2461 #ifdef DWC_DEV_SRPCAP
2462                                 gpwrdn.b.srp_det_msk = 1;
2463 #endif
2464                                 gpwrdn.b.disconn_det_msk = 1;
2465                                 gpwrdn.b.lnstchng_msk = 1;
2466                                 gpwrdn.b.sts_chngint_msk = 1;
2467                                 DWC_MODIFY_REG32(&core_if->
2468                                                  core_global_regs->gpwrdn, 0,
2469                                                  gpwrdn.d32);
2470                                 dwc_udelay(10);
2471
2472                                 /* Enable Power Down Clamp and all interrupts in GPWRDN */
2473                                 gpwrdn.d32 = 0;
2474                                 gpwrdn.b.pwrdnclmp = 1;
2475                                 DWC_MODIFY_REG32(&core_if->
2476                                                  core_global_regs->gpwrdn, 0,
2477                                                  gpwrdn.d32);
2478                                 dwc_udelay(10);
2479
2480                                 /* Switch off VDD */
2481                                 gpwrdn.d32 = 0;
2482                                 gpwrdn.b.pwrdnswtch = 1;
2483                                 DWC_MODIFY_REG32(&core_if->
2484                                                  core_global_regs->gpwrdn, 0,
2485                                                  gpwrdn.d32);
2486
2487 #ifdef DWC_DEV_SRPCAP
2488                                 if (otg_cap_param ==
2489                                     DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) {
2490                                         core_if->pwron_timer_started = 1;
2491                                         DWC_TIMER_SCHEDULE(core_if->pwron_timer,
2492                                                            6000 /* 6 secs */);
2493                                 }
2494 #endif
2495                                 /* Save gpwrdn register for further usage if stschng interrupt */
2496                                 core_if->gr_backup->gpwrdn_local =
2497                                     DWC_READ_REG32(&core_if->core_global_regs->
2498                                                    gpwrdn);
2499
2500                                 /* Set flag to indicate that we are in hibernation */
2501                                 core_if->hibernation_suspend = 1;
2502                                 DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock,
2503                                                           flags);
2504
2505                                 DWC_PRINTF("Host hibernation completed\n");
2506                                 /* Exit from case statement */
2507                                 break;
2508
2509                         }
2510                         if (dwc_otg_hcd_otg_port(dwc_otg_hcd) == wIndex &&
2511                             dwc_otg_hcd->fops->get_b_hnp_enable(dwc_otg_hcd)) {
2512                                 gotgctl_data_t gotgctl = {.d32 = 0 };
2513                                 gotgctl.b.hstsethnpen = 1;
2514                                 DWC_MODIFY_REG32(&core_if->
2515                                                  core_global_regs->gotgctl, 0,
2516                                                  gotgctl.d32);
2517                                 core_if->op_state = A_SUSPEND;
2518                         }
2519                         hprt0.d32 = dwc_otg_read_hprt0(core_if);
2520                         hprt0.b.prtsusp = 1;
2521                         DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
2522                         {
2523                                 dwc_irqflags_t flags;
2524                                 /* Update lx_state */
2525                                 DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &flags);
2526                                 core_if->lx_state = DWC_OTG_L2;
2527                                 DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock,
2528                                                           flags);
2529                         }
2530                         /* Suspend the Phy Clock */
2531                         if (core_if->otg_ver == 0) {
2532                                 pcgcctl_data_t pcgcctl = {.d32 = 0 };
2533                                 pcgcctl.b.stoppclk = 1;
2534                                 DWC_MODIFY_REG32(core_if->pcgcctl, 0,
2535                                                  pcgcctl.d32);
2536                                 dwc_udelay(10);
2537                         }
2538
2539                         /* For HNP the bus must be suspended for at least 200ms. */
2540                         if (dwc_otg_hcd->fops->get_b_hnp_enable(dwc_otg_hcd)) {
2541                                 pcgcctl_data_t pcgcctl = {.d32 = 0 };
2542                                 pcgcctl.b.stoppclk = 1;
2543                                 DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32,
2544                                                  0);
2545                                 dwc_mdelay(200);
2546                         }
2547
2548                         /** @todo - check how sw can wait for 1 sec to check asesvld??? */
2549 #if 0
2550                         if (core_if->adp_enable) {
2551                                 gotgctl_data_t gotgctl = {.d32 = 0 };
2552                                 gpwrdn_data_t gpwrdn;
2553
2554                                 while (gotgctl.b.asesvld == 1) {
2555                                         gotgctl.d32 =
2556                                             DWC_READ_REG32
2557                                             (&core_if->core_global_regs->gotgctl);
2558                                         dwc_mdelay(100);
2559                                 }
2560
2561                                 /* Enable Power Down Logic */
2562                                 gpwrdn.d32 = 0;
2563                                 gpwrdn.b.pmuactv = 1;
2564                                 DWC_MODIFY_REG32(&core_if->
2565                                                  core_global_regs->gpwrdn, 0,
2566                                                  gpwrdn.d32);
2567
2568                                 /* Unmask SRP detected interrupt from Power Down Logic */
2569                                 gpwrdn.d32 = 0;
2570                                 gpwrdn.b.srp_det_msk = 1;
2571                                 DWC_MODIFY_REG32(&core_if->
2572                                                  core_global_regs->gpwrdn, 0,
2573                                                  gpwrdn.d32);
2574
2575                                 dwc_otg_adp_probe_start(core_if);
2576                         }
2577 #endif
2578                         break;
2579                 case UHF_PORT_POWER:
2580                         DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2581                                     "SetPortFeature - USB_PORT_FEAT_POWER\n");
2582                         hprt0.d32 = dwc_otg_read_hprt0(core_if);
2583                         hprt0.b.prtpwr = 1;
2584                         DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
2585                         break;
2586                 case UHF_PORT_RESET:
2587                         if ((core_if->power_down == 2)
2588                             && (core_if->hibernation_suspend == 1)) {
2589                                 /* If we are going to exit from Hibernated
2590                                  * state via USB RESET.
2591                                  */
2592                                 dwc_otg_host_hibernation_restore(core_if, 0, 1);
2593                         } else {
2594                                 hprt0.d32 = dwc_otg_read_hprt0(core_if);
2595
2596                                 DWC_DEBUGPL(DBG_HCD,
2597                                             "DWC OTG HCD HUB CONTROL - "
2598                                             "SetPortFeature - USB_PORT_FEAT_RESET\n");
2599                                 {
2600                                         pcgcctl_data_t pcgcctl = {.d32 = 0 };
2601                                         pcgcctl.b.enbl_sleep_gating = 1;
2602                                         pcgcctl.b.stoppclk = 1;
2603                                         DWC_MODIFY_REG32(core_if->pcgcctl,
2604                                                          pcgcctl.d32, 0);
2605                                         DWC_WRITE_REG32(core_if->pcgcctl, 0);
2606                                 }
2607 #ifdef CONFIG_USB_DWC_OTG_LPM
2608                                 {
2609                                         glpmcfg_data_t lpmcfg;
2610                                         lpmcfg.d32 =
2611                                             DWC_READ_REG32(&core_if->
2612                                                            core_global_regs->
2613                                                            glpmcfg);
2614                                         if (lpmcfg.b.prt_sleep_sts) {
2615                                                 lpmcfg.b.en_utmi_sleep = 0;
2616                                                 lpmcfg.b.hird_thres &=
2617                                                     (~(1 << 4));
2618                                                 DWC_WRITE_REG32(&core_if->
2619                                                                 core_global_regs->
2620                                                                 glpmcfg,
2621                                                                 lpmcfg.d32);
2622                                                 dwc_mdelay(1);
2623                                         }
2624                                 }
2625 #endif
2626                                 hprt0.d32 = dwc_otg_read_hprt0(core_if);
2627                                 /* Clear suspend bit if resetting from suspended state. */
2628                                 hprt0.b.prtsusp = 0;
2629                                 /* When B-Host the Port reset bit is set in
2630                                  * the Start HCD Callback function, so that
2631                                  * the reset is started within 1ms of the HNP
2632                                  * success interrupt. */
2633                                 if (!dwc_otg_hcd_is_b_host(dwc_otg_hcd)) {
2634                                         hprt0.b.prtpwr = 1;
2635                                         hprt0.b.prtrst = 1;
2636                                         DWC_PRINTF
2637                                             ("Indeed it is in host mode hprt0 = %08x\n",
2638                                              hprt0.d32);
2639                                         DWC_WRITE_REG32(core_if->host_if->hprt0,
2640                                                         hprt0.d32);
2641                                 }
2642                                 /* Clear reset bit in 10ms (FS/LS) or 50ms (HS) */
2643                                 dwc_mdelay(60);
2644                                 hprt0.b.prtrst = 0;
2645                                 DWC_WRITE_REG32(core_if->host_if->hprt0,
2646                                                 hprt0.d32);
2647                                 core_if->lx_state = DWC_OTG_L0; /* Now back to the on state */
2648                         }
2649                         break;
2650 #ifdef DWC_HS_ELECT_TST
2651                 case UHF_PORT_TEST:
2652                         {
2653                                 uint32_t t;
2654                                 gintmsk_data_t gintmsk;
2655
2656                                 t = (wIndex >> 8);      /* MSB wIndex USB */
2657                                 DWC_DEBUGPL(DBG_HCD,
2658                                             "DWC OTG HCD HUB CONTROL - "
2659                                             "SetPortFeature - USB_PORT_FEAT_TEST %d\n",
2660                                             t);
2661                                 DWC_WARN("USB_PORT_FEAT_TEST %d\n", t);
2662                                 if (t < 6) {
2663                                         hprt0.d32 = dwc_otg_read_hprt0(core_if);
2664                                         hprt0.b.prttstctl = t;
2665                                         DWC_WRITE_REG32(core_if->host_if->hprt0,
2666                                                         hprt0.d32);
2667                                 } else {
2668                                         /* Setup global vars with reg addresses (quick and
2669                                          * dirty hack, should be cleaned up)
2670                                          */
2671                                         global_regs = core_if->core_global_regs;
2672                                         hc_global_regs =
2673                                             core_if->host_if->host_global_regs;
2674                                         hc_regs =
2675                                             (dwc_otg_hc_regs_t *) ((char *)
2676                                                                    global_regs +
2677                                                                    0x500);
2678                                         data_fifo =
2679                                             (uint32_t *) ((char *)global_regs +
2680                                                           0x1000);
2681
2682                                         if (t == 6) {   /* HS_HOST_PORT_SUSPEND_RESUME */
2683                                                 /* Save current interrupt mask */
2684                                                 gintmsk.d32 =
2685                                                     DWC_READ_REG32
2686                                                     (&global_regs->gintmsk);
2687
2688                                                 /* Disable all interrupts while we muck with
2689                                                  * the hardware directly
2690                                                  */
2691                                                 DWC_WRITE_REG32(&global_regs->
2692                                                                 gintmsk, 0);
2693
2694                                                 /* 15 second delay per the test spec */
2695                                                 dwc_mdelay(15000);
2696
2697                                                 /* Drive suspend on the root port */
2698                                                 hprt0.d32 =
2699                                                     dwc_otg_read_hprt0(core_if);
2700                                                 hprt0.b.prtsusp = 1;
2701                                                 hprt0.b.prtres = 0;
2702                                                 DWC_WRITE_REG32(core_if->
2703                                                                 host_if->hprt0,
2704                                                                 hprt0.d32);
2705
2706                                                 /* 15 second delay per the test spec */
2707                                                 dwc_mdelay(15000);
2708
2709                                                 /* Drive resume on the root port */
2710                                                 hprt0.d32 =
2711                                                     dwc_otg_read_hprt0(core_if);
2712                                                 hprt0.b.prtsusp = 0;
2713                                                 hprt0.b.prtres = 1;
2714                                                 DWC_WRITE_REG32(core_if->
2715                                                                 host_if->hprt0,
2716                                                                 hprt0.d32);
2717                                                 dwc_mdelay(100);
2718
2719                                                 /* Clear the resume bit */
2720                                                 hprt0.b.prtres = 0;
2721                                                 DWC_WRITE_REG32(core_if->
2722                                                                 host_if->hprt0,
2723                                                                 hprt0.d32);
2724
2725                                                 /* Restore interrupts */
2726                                                 DWC_WRITE_REG32(&global_regs->
2727                                                                 gintmsk,
2728                                                                 gintmsk.d32);
2729                                         } else if (t == 7) {    /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR setup */
2730                                                 /* Save current interrupt mask */
2731                                                 gintmsk.d32 =
2732                                                     DWC_READ_REG32
2733                                                     (&global_regs->gintmsk);
2734
2735                                                 /* Disable all interrupts while we muck with
2736                                                  * the hardware directly
2737                                                  */
2738                                                 DWC_WRITE_REG32(&global_regs->
2739                                                                 gintmsk, 0);
2740
2741                                                 /* 15 second delay per the test spec */
2742                                                 dwc_mdelay(15000);
2743
2744                                                 /* Send the Setup packet */
2745                                                 do_setup();
2746
2747                                                 /* 15 second delay so nothing else happens for awhile */
2748                                                 dwc_mdelay(15000);
2749
2750                                                 /* Restore interrupts */
2751                                                 DWC_WRITE_REG32(&global_regs->
2752                                                                 gintmsk,
2753                                                                 gintmsk.d32);
2754                                         } else if (t == 8) {    /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR execute */
2755                                                 /* Save current interrupt mask */
2756                                                 gintmsk.d32 =
2757                                                     DWC_READ_REG32
2758                                                     (&global_regs->gintmsk);
2759
2760                                                 /* Disable all interrupts while we muck with
2761                                                  * the hardware directly
2762                                                  */
2763                                                 DWC_WRITE_REG32(&global_regs->
2764                                                                 gintmsk, 0);
2765
2766                                                 /* Send the Setup packet */
2767                                                 do_setup();
2768
2769                                                 /* 15 second delay so nothing else happens for awhile */
2770                                                 dwc_mdelay(15000);
2771
2772                                                 /* Send the In and Ack packets */
2773                                                 do_in_ack();
2774
2775                                                 /* 15 second delay so nothing else happens for awhile */
2776                                                 dwc_mdelay(15000);
2777
2778                                                 /* Restore interrupts */
2779                                                 DWC_WRITE_REG32(&global_regs->
2780                                                                 gintmsk,
2781                                                                 gintmsk.d32);
2782                                         }
2783                                 }
2784                                 break;
2785                         }
2786 #endif /* DWC_HS_ELECT_TST */
2787
2788                 case UHF_PORT_INDICATOR:
2789                         DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2790                                     "SetPortFeature - USB_PORT_FEAT_INDICATOR\n");
2791                         /* Not supported */
2792                         break;
2793                 default:
2794                         retval = -DWC_E_INVALID;
2795                         DWC_ERROR("DWC OTG HCD - "
2796                                   "SetPortFeature request %xh "
2797                                   "unknown or unsupported\n", wValue);
2798                         break;
2799                 }
2800                 break;
2801 #ifdef CONFIG_USB_DWC_OTG_LPM
2802         case UCR_SET_AND_TEST_PORT_FEATURE:
2803                 if (wValue != UHF_PORT_L1) {
2804                         goto error;
2805                 }
2806                 {
2807                         int portnum, hird, devaddr, remwake;
2808                         glpmcfg_data_t lpmcfg;
2809                         uint32_t time_usecs;
2810                         gintsts_data_t gintsts;
2811                         gintmsk_data_t gintmsk;
2812
2813                         if (!dwc_otg_get_param_lpm_enable(core_if)) {
2814                                 goto error;
2815                         }
2816                         if (wValue != UHF_PORT_L1 || wLength != 1) {
2817                                 goto error;
2818                         }
2819                         /* Check if the port currently is in SLEEP state */
2820                         lpmcfg.d32 =
2821                             DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
2822                         if (lpmcfg.b.prt_sleep_sts) {
2823                                 DWC_INFO("Port is already in sleep mode\n");
2824                                 buf[0] = 0;     /* Return success */
2825                                 break;
2826                         }
2827
2828                         portnum = wIndex & 0xf;
2829                         hird = (wIndex >> 4) & 0xf;
2830                         devaddr = (wIndex >> 8) & 0x7f;
2831                         remwake = (wIndex >> 15);
2832
2833                         if (portnum != 1) {
2834                                 retval = -DWC_E_INVALID;
2835                                 DWC_WARN
2836                                     ("Wrong port number(%d) in SetandTestPortFeature request\n",
2837                                      portnum);
2838                                 break;
2839                         }
2840
2841                         DWC_PRINTF
2842                             ("SetandTestPortFeature request: portnum = %d, hird = %d, devaddr = %d, rewake = %d\n",
2843                              portnum, hird, devaddr, remwake);
2844                         /* Disable LPM interrupt */
2845                         gintmsk.d32 = 0;
2846                         gintmsk.b.lpmtranrcvd = 1;
2847                         DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk,
2848                                          gintmsk.d32, 0);
2849
2850                         if (dwc_otg_hcd_send_lpm
2851                             (dwc_otg_hcd, devaddr, hird, remwake)) {
2852                                 retval = -DWC_E_INVALID;
2853                                 break;
2854                         }
2855
2856                         time_usecs = 10 * (lpmcfg.b.retry_count + 1);
2857                         /* We will consider timeout if time_usecs microseconds pass,
2858                          * and we don't receive LPM transaction status.
2859                          * After receiving non-error responce(ACK/NYET/STALL) from device,
2860                          *  core will set lpmtranrcvd bit.
2861                          */
2862                         do {
2863                                 gintsts.d32 =
2864                                     DWC_READ_REG32(&core_if->core_global_regs->
2865                                                    gintsts);
2866                                 if (gintsts.b.lpmtranrcvd) {
2867                                         break;
2868                                 }
2869                                 dwc_udelay(1);
2870                         } while (--time_usecs);
2871                         /* lpm_int bit will be cleared in LPM interrupt handler */
2872
2873                         /* Now fill status
2874                          * 0x00 - Success
2875                          * 0x10 - NYET
2876                          * 0x11 - Timeout
2877                          */
2878                         if (!gintsts.b.lpmtranrcvd) {
2879                                 buf[0] = 0x3;   /* Completion code is Timeout */
2880                                 dwc_otg_hcd_free_hc_from_lpm(dwc_otg_hcd);
2881                         } else {
2882                                 lpmcfg.d32 =
2883                                     DWC_READ_REG32(&core_if->core_global_regs->
2884                                                    glpmcfg);
2885                                 if (lpmcfg.b.lpm_resp == 0x3) {
2886                                         /* ACK responce from the device */
2887                                         buf[0] = 0x00;  /* Success */
2888                                 } else if (lpmcfg.b.lpm_resp == 0x2) {
2889                                         /* NYET responce from the device */
2890                                         buf[0] = 0x2;
2891                                 } else {
2892                                         /* Otherwise responce with Timeout */
2893                                         buf[0] = 0x3;
2894                                 }
2895                         }
2896                         DWC_PRINTF("Device responce to LPM trans is %x\n",
2897                                    lpmcfg.b.lpm_resp);
2898                         DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, 0,
2899                                          gintmsk.d32);
2900
2901                         break;
2902                 }
2903 #endif /* CONFIG_USB_DWC_OTG_LPM */
2904         default:
2905 error:
2906                 retval = -DWC_E_INVALID;
2907                 DWC_WARN("DWC OTG HCD - "
2908                          "Unknown hub control request type or invalid typeReq: %xh wIndex: %xh wValue: %xh\n",
2909                          typeReq, wIndex, wValue);
2910                 break;
2911         }
2912
2913         return retval;
2914 }
2915
2916 #ifdef CONFIG_USB_DWC_OTG_LPM
2917 /** Returns index of host channel to perform LPM transaction. */
2918 int dwc_otg_hcd_get_hc_for_lpm_tran(dwc_otg_hcd_t *hcd, uint8_t devaddr)
2919 {
2920         dwc_otg_core_if_t *core_if = hcd->core_if;
2921         dwc_hc_t *hc;
2922         hcchar_data_t hcchar;
2923         gintmsk_data_t gintmsk = {.d32 = 0 };
2924
2925         if (DWC_CIRCLEQ_EMPTY(&hcd->free_hc_list)) {
2926                 DWC_PRINTF("No free channel to select for LPM transaction\n");
2927                 return -1;
2928         }
2929
2930         hc = DWC_CIRCLEQ_FIRST(&hcd->free_hc_list);
2931
2932         /* Mask host channel interrupts. */
2933         gintmsk.b.hcintr = 1;
2934         DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, gintmsk.d32, 0);
2935
2936         /* Fill fields that core needs for LPM transaction */
2937         hcchar.b.devaddr = devaddr;
2938         hcchar.b.epnum = 0;
2939         hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;
2940         hcchar.b.mps = 64;
2941         hcchar.b.lspddev = (hc->speed == DWC_OTG_EP_SPEED_LOW);
2942         hcchar.b.epdir = 0;     /* OUT */
2943         DWC_WRITE_REG32(&core_if->host_if->hc_regs[hc->hc_num]->hcchar,
2944                         hcchar.d32);
2945
2946         /* Remove the host channel from the free list. */
2947         DWC_CIRCLEQ_REMOVE_INIT(&hcd->free_hc_list, hc, hc_list_entry);
2948
2949         DWC_PRINTF("hcnum = %d devaddr = %d\n", hc->hc_num, devaddr);
2950
2951         return hc->hc_num;
2952 }
2953
2954 /** Release hc after performing LPM transaction */
2955 void dwc_otg_hcd_free_hc_from_lpm(dwc_otg_hcd_t *hcd)
2956 {
2957         dwc_hc_t *hc;
2958         glpmcfg_data_t lpmcfg;
2959         uint8_t hc_num;
2960
2961         lpmcfg.d32 = DWC_READ_REG32(&hcd->core_if->core_global_regs->glpmcfg);
2962         hc_num = lpmcfg.b.lpm_chan_index;
2963
2964         hc = hcd->hc_ptr_array[hc_num];
2965
2966         DWC_PRINTF("Freeing channel %d after LPM\n", hc_num);
2967         /* Return host channel to free list */
2968         DWC_CIRCLEQ_INSERT_TAIL(&hcd->free_hc_list, hc, hc_list_entry);
2969 }
2970
2971 int dwc_otg_hcd_send_lpm(dwc_otg_hcd_t *hcd, uint8_t devaddr, uint8_t hird,
2972                          uint8_t bRemoteWake)
2973 {
2974         glpmcfg_data_t lpmcfg;
2975         pcgcctl_data_t pcgcctl = {.d32 = 0 };
2976         int channel;
2977
2978         channel = dwc_otg_hcd_get_hc_for_lpm_tran(hcd, devaddr);
2979         if (channel < 0) {
2980                 return channel;
2981         }
2982
2983         pcgcctl.b.enbl_sleep_gating = 1;
2984         DWC_MODIFY_REG32(hcd->core_if->pcgcctl, 0, pcgcctl.d32);
2985
2986         /* Read LPM config register */
2987         lpmcfg.d32 = DWC_READ_REG32(&hcd->core_if->core_global_regs->glpmcfg);
2988
2989         /* Program LPM transaction fields */
2990         lpmcfg.b.rem_wkup_en = bRemoteWake;
2991         lpmcfg.b.hird = hird;
2992
2993         if (dwc_otg_get_param_besl_enable(hcd->core_if)) {
2994                 lpmcfg.b.hird_thres = 0x16;
2995                 lpmcfg.b.en_besl = 1;
2996         } else {
2997                 lpmcfg.b.hird_thres = 0x1c;
2998         }
2999
3000         lpmcfg.b.lpm_chan_index = channel;
3001         lpmcfg.b.en_utmi_sleep = 1;
3002         /* Program LPM config register */
3003         DWC_WRITE_REG32(&hcd->core_if->core_global_regs->glpmcfg, lpmcfg.d32);
3004
3005         /* Send LPM transaction */
3006         lpmcfg.b.send_lpm = 1;
3007         DWC_WRITE_REG32(&hcd->core_if->core_global_regs->glpmcfg, lpmcfg.d32);
3008
3009         return 0;
3010 }
3011
3012 #endif /* CONFIG_USB_DWC_OTG_LPM */
3013
3014 int dwc_otg_hcd_is_status_changed(dwc_otg_hcd_t *hcd, int port)
3015 {
3016         int retval;
3017
3018         if (port != 1) {
3019                 return -DWC_E_INVALID;
3020         }
3021
3022         retval = (hcd->flags.b.port_connect_status_change ||
3023                   hcd->flags.b.port_reset_change ||
3024                   hcd->flags.b.port_enable_change ||
3025                   hcd->flags.b.port_suspend_change ||
3026                   hcd->flags.b.port_over_current_change);
3027 #ifdef DEBUG
3028         if (retval) {
3029                 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB STATUS DATA:"
3030                             " Root port status changed\n");
3031                 DWC_DEBUGPL(DBG_HCDV, "  port_connect_status_change: %d\n",
3032                             hcd->flags.b.port_connect_status_change);
3033                 DWC_DEBUGPL(DBG_HCDV, "  port_reset_change: %d\n",
3034                             hcd->flags.b.port_reset_change);
3035                 DWC_DEBUGPL(DBG_HCDV, "  port_enable_change: %d\n",
3036                             hcd->flags.b.port_enable_change);
3037                 DWC_DEBUGPL(DBG_HCDV, "  port_suspend_change: %d\n",
3038                             hcd->flags.b.port_suspend_change);
3039                 DWC_DEBUGPL(DBG_HCDV, "  port_over_current_change: %d\n",
3040                             hcd->flags.b.port_over_current_change);
3041         }
3042 #endif
3043         return retval;
3044 }
3045
3046 int dwc_otg_hcd_get_frame_number(dwc_otg_hcd_t *dwc_otg_hcd)
3047 {
3048         hfnum_data_t hfnum;
3049         hfnum.d32 =
3050             DWC_READ_REG32(&dwc_otg_hcd->core_if->host_if->
3051                            host_global_regs->hfnum);
3052
3053 #ifdef DEBUG_SOF
3054         DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD GET FRAME NUMBER %d\n",
3055                     hfnum.b.frnum);
3056 #endif
3057         return hfnum.b.frnum;
3058 }
3059
3060 int dwc_otg_hcd_start(dwc_otg_hcd_t *hcd,
3061                       struct dwc_otg_hcd_function_ops *fops)
3062 {
3063         int retval = 0;
3064
3065         hcd->fops = fops;
3066         if (!dwc_otg_is_device_mode(hcd->core_if) &&
3067             (!hcd->core_if->adp_enable || hcd->core_if->adp.adp_started)) {
3068                 dwc_otg_hcd_reinit(hcd);
3069         } else {
3070                 retval = -DWC_E_NO_DEVICE;
3071         }
3072
3073         return retval;
3074 }
3075
3076 void *dwc_otg_hcd_get_priv_data(dwc_otg_hcd_t *hcd)
3077 {
3078         return hcd->priv;
3079 }
3080
3081 void dwc_otg_hcd_set_priv_data(dwc_otg_hcd_t *hcd, void *priv_data)
3082 {
3083         hcd->priv = priv_data;
3084 }
3085
3086 uint32_t dwc_otg_hcd_otg_port(dwc_otg_hcd_t *hcd)
3087 {
3088         return hcd->otg_port;
3089 }
3090
3091 uint32_t dwc_otg_hcd_is_b_host(dwc_otg_hcd_t *hcd)
3092 {
3093         uint32_t is_b_host;
3094         if (hcd->core_if->op_state == B_HOST) {
3095                 is_b_host = 1;
3096         } else {
3097                 is_b_host = 0;
3098         }
3099
3100         return is_b_host;
3101 }
3102
3103 dwc_otg_hcd_urb_t *dwc_otg_hcd_urb_alloc(dwc_otg_hcd_t *hcd,
3104                                          int iso_desc_count, int atomic_alloc)
3105 {
3106         dwc_otg_hcd_urb_t *dwc_otg_urb;
3107         uint32_t size;
3108
3109         size =
3110             sizeof(*dwc_otg_urb) +
3111             iso_desc_count * sizeof(struct dwc_otg_hcd_iso_packet_desc);
3112         if (atomic_alloc)
3113                 dwc_otg_urb = DWC_ALLOC_ATOMIC(size);
3114         else
3115                 dwc_otg_urb = DWC_ALLOC(size);
3116
3117         dwc_otg_urb->packet_count = iso_desc_count;
3118
3119         return dwc_otg_urb;
3120 }
3121
3122 void dwc_otg_hcd_urb_set_pipeinfo(dwc_otg_hcd_urb_t *dwc_otg_urb,
3123                                   uint8_t dev_addr, uint8_t ep_num,
3124                                   uint8_t ep_type, uint8_t ep_dir, uint16_t mps)
3125 {
3126         dwc_otg_hcd_fill_pipe(&dwc_otg_urb->pipe_info, dev_addr, ep_num,
3127                               ep_type, ep_dir, mps);
3128 #if 0
3129         DWC_PRINTF
3130             ("addr = %d, ep_num = %d, ep_dir = 0x%x, ep_type = 0x%x, mps = %d\n",
3131              dev_addr, ep_num, ep_dir, ep_type, mps);
3132 #endif
3133 }
3134
3135 void dwc_otg_hcd_urb_set_params(dwc_otg_hcd_urb_t *dwc_otg_urb,
3136                                 void *urb_handle, void *buf, dwc_dma_t dma,
3137                                 uint32_t buflen, void *setup_packet,
3138                                 dwc_dma_t setup_dma, uint32_t flags,
3139                                 uint16_t interval)
3140 {
3141         dwc_otg_urb->priv = urb_handle;
3142         dwc_otg_urb->buf = buf;
3143         dwc_otg_urb->dma = dma;
3144         dwc_otg_urb->length = buflen;
3145         dwc_otg_urb->setup_packet = setup_packet;
3146         dwc_otg_urb->setup_dma = setup_dma;
3147         dwc_otg_urb->flags = flags;
3148         dwc_otg_urb->interval = interval;
3149         dwc_otg_urb->status = -DWC_E_IN_PROGRESS;
3150 }
3151
3152 uint32_t dwc_otg_hcd_urb_get_status(dwc_otg_hcd_urb_t *dwc_otg_urb)
3153 {
3154         return dwc_otg_urb->status;
3155 }
3156
3157 uint32_t dwc_otg_hcd_urb_get_actual_length(dwc_otg_hcd_urb_t *dwc_otg_urb)
3158 {
3159         return dwc_otg_urb->actual_length;
3160 }
3161
3162 uint32_t dwc_otg_hcd_urb_get_error_count(dwc_otg_hcd_urb_t *dwc_otg_urb)
3163 {
3164         return dwc_otg_urb->error_count;
3165 }
3166
3167 void dwc_otg_hcd_urb_set_iso_desc_params(dwc_otg_hcd_urb_t *dwc_otg_urb,
3168                                          int desc_num, uint32_t offset,
3169                                          uint32_t length)
3170 {
3171         dwc_otg_urb->iso_descs[desc_num].offset = offset;
3172         dwc_otg_urb->iso_descs[desc_num].length = length;
3173 }
3174
3175 uint32_t dwc_otg_hcd_urb_get_iso_desc_status(dwc_otg_hcd_urb_t *dwc_otg_urb,
3176                                              int desc_num)
3177 {
3178         return dwc_otg_urb->iso_descs[desc_num].status;
3179 }
3180
3181 uint32_t dwc_otg_hcd_urb_get_iso_desc_actual_length(dwc_otg_hcd_urb_t *
3182                                                     dwc_otg_urb, int desc_num)
3183 {
3184         return dwc_otg_urb->iso_descs[desc_num].actual_length;
3185 }
3186
3187 int dwc_otg_hcd_is_bandwidth_allocated(dwc_otg_hcd_t *hcd, void *ep_handle)
3188 {
3189         int allocated = 0;
3190         dwc_otg_qh_t *qh = (dwc_otg_qh_t *) ep_handle;
3191
3192         if (qh) {
3193                 if (!DWC_LIST_EMPTY(&qh->qh_list_entry)) {
3194                         allocated = 1;
3195                 }
3196         }
3197         return allocated;
3198 }
3199
3200 int dwc_otg_hcd_is_bandwidth_freed(dwc_otg_hcd_t *hcd, void *ep_handle)
3201 {
3202         dwc_otg_qh_t *qh = (dwc_otg_qh_t *) ep_handle;
3203         int freed = 0;
3204         DWC_ASSERT(qh, "qh is not allocated\n");
3205
3206         if (DWC_LIST_EMPTY(&qh->qh_list_entry)) {
3207                 freed = 1;
3208         }
3209
3210         return freed;
3211 }
3212
3213 uint8_t dwc_otg_hcd_get_ep_bandwidth(dwc_otg_hcd_t *hcd, void *ep_handle)
3214 {
3215         dwc_otg_qh_t *qh = (dwc_otg_qh_t *) ep_handle;
3216         DWC_ASSERT(qh, "qh is not allocated\n");
3217         return qh->usecs;
3218 }
3219
3220 void dwc_otg_hcd_dump_state(dwc_otg_hcd_t *hcd)
3221 {
3222 #ifdef DEBUG
3223         int num_channels;
3224         int i;
3225         gnptxsts_data_t np_tx_status;
3226         hptxsts_data_t p_tx_status;
3227
3228         num_channels = hcd->core_if->core_params->host_channels;
3229         DWC_PRINTF("\n");
3230         DWC_PRINTF
3231             ("************************************************************\n");
3232         DWC_PRINTF("HCD State:\n");
3233         DWC_PRINTF("  Num channels: %d\n", num_channels);
3234         for (i = 0; i < num_channels; i++) {
3235                 dwc_hc_t *hc = hcd->hc_ptr_array[i];
3236                 DWC_PRINTF("  Channel %d:\n", i);
3237                 DWC_PRINTF("    dev_addr: %d, ep_num: %d, ep_is_in: %d\n",
3238                            hc->dev_addr, hc->ep_num, hc->ep_is_in);
3239                 DWC_PRINTF("    speed: %d\n", hc->speed);
3240                 DWC_PRINTF("    ep_type: %d\n", hc->ep_type);
3241                 DWC_PRINTF("    max_packet: %d\n", hc->max_packet);
3242                 DWC_PRINTF("    data_pid_start: %d\n", hc->data_pid_start);
3243                 DWC_PRINTF("    multi_count: %d\n", hc->multi_count);
3244                 DWC_PRINTF("    xfer_started: %d\n", hc->xfer_started);
3245                 DWC_PRINTF("    xfer_buff: %p\n", hc->xfer_buff);
3246                 DWC_PRINTF("    xfer_len: %d\n", hc->xfer_len);
3247                 DWC_PRINTF("    xfer_count: %d\n", hc->xfer_count);
3248                 DWC_PRINTF("    halt_on_queue: %d\n", hc->halt_on_queue);
3249                 DWC_PRINTF("    halt_pending: %d\n", hc->halt_pending);
3250                 DWC_PRINTF("    halt_status: %d\n", hc->halt_status);
3251                 DWC_PRINTF("    do_split: %d\n", hc->do_split);
3252                 DWC_PRINTF("    complete_split: %d\n", hc->complete_split);
3253                 DWC_PRINTF("    hub_addr: %d\n", hc->hub_addr);
3254                 DWC_PRINTF("    port_addr: %d\n", hc->port_addr);
3255                 DWC_PRINTF("    xact_pos: %d\n", hc->xact_pos);
3256                 DWC_PRINTF("    requests: %d\n", hc->requests);
3257                 DWC_PRINTF("    qh: %p\n", hc->qh);
3258                 if (hc->xfer_started) {
3259                         hfnum_data_t hfnum;
3260                         hcchar_data_t hcchar;
3261                         hctsiz_data_t hctsiz;
3262                         hcint_data_t hcint;
3263                         hcintmsk_data_t hcintmsk;
3264                         hfnum.d32 =
3265                             DWC_READ_REG32(&hcd->core_if->host_if->
3266                                            host_global_regs->hfnum);
3267                         hcchar.d32 =
3268                             DWC_READ_REG32(&hcd->core_if->host_if->hc_regs[i]->
3269                                            hcchar);
3270                         hctsiz.d32 =
3271                             DWC_READ_REG32(&hcd->core_if->host_if->hc_regs[i]->
3272                                            hctsiz);
3273                         hcint.d32 =
3274                             DWC_READ_REG32(&hcd->core_if->host_if->hc_regs[i]->
3275                                            hcint);
3276                         hcintmsk.d32 =
3277                             DWC_READ_REG32(&hcd->core_if->host_if->hc_regs[i]->
3278                                            hcintmsk);
3279                         DWC_PRINTF("    hfnum: 0x%08x\n", hfnum.d32);
3280                         DWC_PRINTF("    hcchar: 0x%08x\n", hcchar.d32);
3281                         DWC_PRINTF("    hctsiz: 0x%08x\n", hctsiz.d32);
3282                         DWC_PRINTF("    hcint: 0x%08x\n", hcint.d32);
3283                         DWC_PRINTF("    hcintmsk: 0x%08x\n", hcintmsk.d32);
3284                 }
3285                 if (hc->xfer_started && hc->qh) {
3286                         dwc_otg_qtd_t *qtd;
3287                         dwc_otg_hcd_urb_t *urb;
3288
3289                         DWC_CIRCLEQ_FOREACH(qtd, &hc->qh->qtd_list,
3290                                             qtd_list_entry) {
3291                                 if (!qtd->in_process)
3292                                         break;
3293
3294                                 urb = qtd->urb;
3295                                 DWC_PRINTF("    URB Info:\n");
3296                                 DWC_PRINTF("      qtd: %p, urb: %p\n", qtd,
3297                                            urb);
3298                                 if (urb) {
3299                                         DWC_PRINTF("      Dev: %d, EP: %d %s\n",
3300                                                    dwc_otg_hcd_get_dev_addr
3301                                                    (&urb->pipe_info),
3302                                                    dwc_otg_hcd_get_ep_num
3303                                                    (&urb->pipe_info),
3304                                                    dwc_otg_hcd_is_pipe_in
3305                                                    (&urb->pipe_info) ? "IN" :
3306                                                    "OUT");
3307                                         DWC_PRINTF
3308                                             ("      Max packet size: %d\n",
3309                                              dwc_otg_hcd_get_mps
3310                                              (&urb->pipe_info));
3311                                         DWC_PRINTF
3312                                             ("      transfer_buffer: %p\n",
3313                                              urb->buf);
3314                                         DWC_PRINTF("      transfer_dma: %p\n",
3315                                                    (void *)urb->dma);
3316                                         DWC_PRINTF
3317                                             ("      transfer_buffer_length: %d\n",
3318                                              urb->length);
3319                                         DWC_PRINTF("      actual_length: %d\n",
3320                                                    urb->actual_length);
3321                                 }
3322                         }
3323                 }
3324         }
3325         DWC_PRINTF("  non_periodic_channels: %d\n", hcd->non_periodic_channels);
3326         DWC_PRINTF("  periodic_channels: %d\n", hcd->periodic_channels);
3327         DWC_PRINTF("  periodic_usecs: %d\n", hcd->periodic_usecs);
3328         np_tx_status.d32 =
3329             DWC_READ_REG32(&hcd->core_if->core_global_regs->gnptxsts);
3330         DWC_PRINTF("  NP Tx Req Queue Space Avail: %d\n",
3331                    np_tx_status.b.nptxqspcavail);
3332         DWC_PRINTF("  NP Tx FIFO Space Avail: %d\n",
3333                    np_tx_status.b.nptxfspcavail);
3334         p_tx_status.d32 =
3335             DWC_READ_REG32(&hcd->core_if->host_if->host_global_regs->hptxsts);
3336         DWC_PRINTF("  P Tx Req Queue Space Avail: %d\n",
3337                    p_tx_status.b.ptxqspcavail);
3338         DWC_PRINTF("  P Tx FIFO Space Avail: %d\n", p_tx_status.b.ptxfspcavail);
3339         dwc_otg_hcd_dump_frrem(hcd);
3340         dwc_otg_dump_global_registers(hcd->core_if);
3341         dwc_otg_dump_host_registers(hcd->core_if);
3342         DWC_PRINTF
3343             ("************************************************************\n");
3344         DWC_PRINTF("\n");
3345 #endif
3346 }
3347
3348 #ifdef DEBUG
3349 void dwc_print_setup_data(uint8_t *setup)
3350 {
3351         int i;
3352         if (CHK_DEBUG_LEVEL(DBG_HCD)) {
3353                 DWC_PRINTF("Setup Data = MSB ");
3354                 for (i = 7; i >= 0; i--)
3355                         DWC_PRINTF("%02x ", setup[i]);
3356                 DWC_PRINTF("\n");
3357                 DWC_PRINTF("  bmRequestType Tranfer = %s\n",
3358                            (setup[0] & 0x80) ? "Device-to-Host" :
3359                            "Host-to-Device");
3360                 DWC_PRINTF("  bmRequestType Type = ");
3361                 switch ((setup[0] & 0x60) >> 5) {
3362                 case 0:
3363                         DWC_PRINTF("Standard\n");
3364                         break;
3365                 case 1:
3366                         DWC_PRINTF("Class\n");
3367                         break;
3368                 case 2:
3369                         DWC_PRINTF("Vendor\n");
3370                         break;
3371                 case 3:
3372                         DWC_PRINTF("Reserved\n");
3373                         break;
3374                 }
3375                 DWC_PRINTF("  bmRequestType Recipient = ");
3376                 switch (setup[0] & 0x1f) {
3377                 case 0:
3378                         DWC_PRINTF("Device\n");
3379                         break;
3380                 case 1:
3381                         DWC_PRINTF("Interface\n");
3382                         break;
3383                 case 2:
3384                         DWC_PRINTF("Endpoint\n");
3385                         break;
3386                 case 3:
3387                         DWC_PRINTF("Other\n");
3388                         break;
3389                 default:
3390                         DWC_PRINTF("Reserved\n");
3391                         break;
3392                 }
3393                 DWC_PRINTF("  bRequest = 0x%0x\n", setup[1]);
3394                 DWC_PRINTF("  wValue = 0x%0x\n", *((uint16_t *)&setup[2]));
3395                 DWC_PRINTF("  wIndex = 0x%0x\n", *((uint16_t *)&setup[4]));
3396                 DWC_PRINTF("  wLength = 0x%0x\n\n", *((uint16_t *)&setup[6]));
3397         }
3398 }
3399 #endif
3400
3401 void dwc_otg_hcd_dump_frrem(dwc_otg_hcd_t *hcd)
3402 {
3403 #if 0
3404         DWC_PRINTF("Frame remaining at SOF:\n");
3405         DWC_PRINTF("  samples %u, accum %llu, avg %llu\n",
3406                    hcd->frrem_samples, hcd->frrem_accum,
3407                    (hcd->frrem_samples > 0) ?
3408                    hcd->frrem_accum / hcd->frrem_samples : 0);
3409
3410         DWC_PRINTF("\n");
3411         DWC_PRINTF("Frame remaining at start_transfer (uframe 7):\n");
3412         DWC_PRINTF("  samples %u, accum %llu, avg %llu\n",
3413                    hcd->core_if->hfnum_7_samples,
3414                    hcd->core_if->hfnum_7_frrem_accum,
3415                    (hcd->core_if->hfnum_7_samples >
3416                     0) ? hcd->core_if->hfnum_7_frrem_accum /
3417                    hcd->core_if->hfnum_7_samples : 0);
3418         DWC_PRINTF("Frame remaining at start_transfer (uframe 0):\n");
3419         DWC_PRINTF("  samples %u, accum %llu, avg %llu\n",
3420                    hcd->core_if->hfnum_0_samples,
3421                    hcd->core_if->hfnum_0_frrem_accum,
3422                    (hcd->core_if->hfnum_0_samples >
3423                     0) ? hcd->core_if->hfnum_0_frrem_accum /
3424                    hcd->core_if->hfnum_0_samples : 0);
3425         DWC_PRINTF("Frame remaining at start_transfer (uframe 1-6):\n");
3426         DWC_PRINTF("  samples %u, accum %llu, avg %llu\n",
3427                    hcd->core_if->hfnum_other_samples,
3428                    hcd->core_if->hfnum_other_frrem_accum,
3429                    (hcd->core_if->hfnum_other_samples >
3430                     0) ? hcd->core_if->hfnum_other_frrem_accum /
3431                    hcd->core_if->hfnum_other_samples : 0);
3432
3433         DWC_PRINTF("\n");
3434         DWC_PRINTF("Frame remaining at sample point A (uframe 7):\n");
3435         DWC_PRINTF("  samples %u, accum %llu, avg %llu\n",
3436                    hcd->hfnum_7_samples_a, hcd->hfnum_7_frrem_accum_a,
3437                    (hcd->hfnum_7_samples_a > 0) ?
3438                    hcd->hfnum_7_frrem_accum_a / hcd->hfnum_7_samples_a : 0);
3439         DWC_PRINTF("Frame remaining at sample point A (uframe 0):\n");
3440         DWC_PRINTF("  samples %u, accum %llu, avg %llu\n",
3441                    hcd->hfnum_0_samples_a, hcd->hfnum_0_frrem_accum_a,
3442                    (hcd->hfnum_0_samples_a > 0) ?
3443                    hcd->hfnum_0_frrem_accum_a / hcd->hfnum_0_samples_a : 0);
3444         DWC_PRINTF("Frame remaining at sample point A (uframe 1-6):\n");
3445         DWC_PRINTF("  samples %u, accum %llu, avg %llu\n",
3446                    hcd->hfnum_other_samples_a, hcd->hfnum_other_frrem_accum_a,
3447                    (hcd->hfnum_other_samples_a > 0) ?
3448                    hcd->hfnum_other_frrem_accum_a /
3449                    hcd->hfnum_other_samples_a : 0);
3450
3451         DWC_PRINTF("\n");
3452         DWC_PRINTF("Frame remaining at sample point B (uframe 7):\n");
3453         DWC_PRINTF("  samples %u, accum %llu, avg %llu\n",
3454                    hcd->hfnum_7_samples_b, hcd->hfnum_7_frrem_accum_b,
3455                    (hcd->hfnum_7_samples_b > 0) ?
3456                    hcd->hfnum_7_frrem_accum_b / hcd->hfnum_7_samples_b : 0);
3457         DWC_PRINTF("Frame remaining at sample point B (uframe 0):\n");
3458         DWC_PRINTF("  samples %u, accum %llu, avg %llu\n",
3459                    hcd->hfnum_0_samples_b, hcd->hfnum_0_frrem_accum_b,
3460                    (hcd->hfnum_0_samples_b > 0) ?
3461                    hcd->hfnum_0_frrem_accum_b / hcd->hfnum_0_samples_b : 0);
3462         DWC_PRINTF("Frame remaining at sample point B (uframe 1-6):\n");
3463         DWC_PRINTF("  samples %u, accum %llu, avg %llu\n",
3464                    hcd->hfnum_other_samples_b, hcd->hfnum_other_frrem_accum_b,
3465                    (hcd->hfnum_other_samples_b > 0) ?
3466                    hcd->hfnum_other_frrem_accum_b /
3467                    hcd->hfnum_other_samples_b : 0);
3468 #endif
3469 }
3470
3471 #endif /* DWC_DEVICE_ONLY */