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