usb: dwc_otg_310: support vbus controlled by both gpio and pmic
[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_DEV_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_DEV_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 =
1218                                 DWC_DEV_DMA_ALLOC_ATOMIC(buf_size,
1219                                                          &qh->
1220                                                          dw_align_buf_dma);
1221                         if (!qh->dw_align_buf) {
1222                                 DWC_ERROR
1223                                     ("%s: Failed to allocate memory to handle "
1224                                      "non-dword aligned buffer case\n",
1225                                      __func__);
1226                                 return retval;
1227                         }
1228                 }
1229                 if (!hc->ep_is_in) {
1230                         dwc_memcpy(qh->dw_align_buf, ptr, hc->xfer_len);
1231                 }
1232                 hc->align_buff = qh->dw_align_buf_dma;
1233         } else {
1234                 hc->align_buff = 0;
1235         }
1236
1237         if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
1238             hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
1239                 /*
1240                  * This value may be modified when the transfer is started to
1241                  * reflect the actual transfer length.
1242                  */
1243                 hc->multi_count = dwc_hb_mult(qh->maxp);
1244         }
1245
1246         if (hcd->core_if->dma_desc_enable)
1247                 hc->desc_list_addr = qh->desc_list_dma;
1248
1249         dwc_otg_hc_init(hcd->core_if, hc);
1250         hc->qh = qh;
1251         return retval;
1252 }
1253
1254 /**
1255  * This function selects transactions from the HCD transfer schedule and
1256  * assigns them to available host channels. It is called from HCD interrupt
1257  * handler functions.
1258  *
1259  * @param hcd The HCD state structure.
1260  *
1261  * @return The types of new transactions that were assigned to host channels.
1262  */
1263 dwc_otg_transaction_type_e dwc_otg_hcd_select_transactions(dwc_otg_hcd_t *hcd)
1264 {
1265         dwc_list_link_t *qh_ptr;
1266         dwc_otg_qh_t *qh;
1267         int num_channels;
1268         dwc_otg_transaction_type_e ret_val = DWC_OTG_TRANSACTION_NONE;
1269         int err;
1270
1271 #ifdef DEBUG_SOF
1272         DWC_DEBUGPL(DBG_HCD, "  Select Transactions\n");
1273 #endif
1274
1275         /* Process entries in the periodic ready list. */
1276         qh_ptr = DWC_LIST_FIRST(&hcd->periodic_sched_ready);
1277
1278         while (qh_ptr != &hcd->periodic_sched_ready &&
1279                !DWC_CIRCLEQ_EMPTY(&hcd->free_hc_list)) {
1280
1281                 qh = DWC_LIST_ENTRY(qh_ptr, dwc_otg_qh_t, qh_list_entry);
1282                 assign_and_init_hc(hcd, qh);
1283
1284                 /*
1285                  * Move the QH from the periodic ready schedule to the
1286                  * periodic assigned schedule.
1287                  */
1288                 qh_ptr = DWC_LIST_NEXT(qh_ptr);
1289                 DWC_LIST_MOVE_HEAD(&hcd->periodic_sched_assigned,
1290                                    &qh->qh_list_entry);
1291
1292                 ret_val = DWC_OTG_TRANSACTION_PERIODIC;
1293         }
1294
1295         /*
1296          * Process entries in the inactive portion of the non-periodic
1297          * schedule. Some free host channels may not be used if they are
1298          * reserved for periodic transfers.
1299          */
1300         qh_ptr = hcd->non_periodic_sched_inactive.next;
1301         num_channels = hcd->core_if->core_params->host_channels;
1302         while (qh_ptr != &hcd->non_periodic_sched_inactive &&
1303                (hcd->non_periodic_channels <
1304                 num_channels - hcd->periodic_channels) &&
1305                !DWC_CIRCLEQ_EMPTY(&hcd->free_hc_list)) {
1306
1307                 qh = DWC_LIST_ENTRY(qh_ptr, dwc_otg_qh_t, qh_list_entry);
1308
1309                 err = assign_and_init_hc(hcd, qh);
1310
1311                 /*
1312                  * Move the QH from the non-periodic inactive schedule to the
1313                  * non-periodic active schedule.
1314                  */
1315                 qh_ptr = DWC_LIST_NEXT(qh_ptr);
1316                 if (err != 0)
1317                         continue;
1318                 DWC_LIST_MOVE_HEAD(&hcd->non_periodic_sched_active,
1319                                    &qh->qh_list_entry);
1320
1321                 if (ret_val == DWC_OTG_TRANSACTION_NONE) {
1322                         ret_val = DWC_OTG_TRANSACTION_NON_PERIODIC;
1323                 } else {
1324                         ret_val = DWC_OTG_TRANSACTION_ALL;
1325                 }
1326
1327                 hcd->non_periodic_channels++;
1328         }
1329
1330         return ret_val;
1331 }
1332
1333 /**
1334  * Attempts to queue a single transaction request for a host channel
1335  * associated with either a periodic or non-periodic transfer. This function
1336  * assumes that there is space available in the appropriate request queue. For
1337  * an OUT transfer or SETUP transaction in Slave mode, it checks whether space
1338  * is available in the appropriate Tx FIFO.
1339  *
1340  * @param hcd The HCD state structure.
1341  * @param hc Host channel descriptor associated with either a periodic or
1342  * non-periodic transfer.
1343  * @param fifo_dwords_avail Number of DWORDs available in the periodic Tx
1344  * FIFO for periodic transfers or the non-periodic Tx FIFO for non-periodic
1345  * transfers.
1346  *
1347  * @return 1 if a request is queued and more requests may be needed to
1348  * complete the transfer, 0 if no more requests are required for this
1349  * transfer, -1 if there is insufficient space in the Tx FIFO.
1350  */
1351 static int queue_transaction(dwc_otg_hcd_t *hcd,
1352                              dwc_hc_t *hc, uint16_t fifo_dwords_avail)
1353 {
1354         int retval;
1355         if (!hc || !(hc->qh))
1356                 return -ENODEV;
1357         if (hcd->core_if->dma_enable) {
1358                 if (hcd->core_if->dma_desc_enable) {
1359                         if (!hc->xfer_started
1360                             || (hc->ep_type == DWC_OTG_EP_TYPE_ISOC)) {
1361                                 dwc_otg_hcd_start_xfer_ddma(hcd, hc->qh);
1362                                 hc->qh->ping_state = 0;
1363                         }
1364                 } else if (!hc->xfer_started) {
1365                         if (!hc || !(hc->qh))
1366                                 return -ENODEV;
1367                         dwc_otg_hc_start_transfer(hcd->core_if, hc);
1368                         hc->qh->ping_state = 0;
1369                 }
1370                 retval = 0;
1371         } else if (hc->halt_pending) {
1372                 /* Don't queue a request if the channel has been halted. */
1373                 retval = 0;
1374         } else if (hc->halt_on_queue) {
1375                 dwc_otg_hc_halt(hcd->core_if, hc, hc->halt_status);
1376                 retval = 0;
1377         } else if (hc->do_ping) {
1378                 if (!hc->xfer_started) {
1379                         dwc_otg_hc_start_transfer(hcd->core_if, hc);
1380                 }
1381                 retval = 0;
1382         } else if (!hc->ep_is_in || hc->data_pid_start == DWC_OTG_HC_PID_SETUP) {
1383                 if ((fifo_dwords_avail * 4) >= hc->max_packet) {
1384                         if (!hc->xfer_started) {
1385                                 dwc_otg_hc_start_transfer(hcd->core_if, hc);
1386                                 retval = 1;
1387                         } else {
1388                                 retval =
1389                                     dwc_otg_hc_continue_transfer(hcd->core_if,
1390                                                                  hc);
1391                         }
1392                 } else {
1393                         retval = -1;
1394                 }
1395         } else {
1396                 if (!hc->xfer_started) {
1397                         dwc_otg_hc_start_transfer(hcd->core_if, hc);
1398                         retval = 1;
1399                 } else {
1400                         retval = dwc_otg_hc_continue_transfer(hcd->core_if, hc);
1401                 }
1402         }
1403
1404         return retval;
1405 }
1406
1407 /**
1408  * Processes periodic channels for the next frame and queues transactions for
1409  * these channels to the DWC_otg controller. After queueing transactions, the
1410  * Periodic Tx FIFO Empty interrupt is enabled if there are more transactions
1411  * to queue as Periodic Tx FIFO or request queue space becomes available.
1412  * Otherwise, the Periodic Tx FIFO Empty interrupt is disabled.
1413  */
1414 static void process_periodic_channels(dwc_otg_hcd_t *hcd)
1415 {
1416         hptxsts_data_t tx_status;
1417         dwc_list_link_t *qh_ptr;
1418         dwc_otg_qh_t *qh;
1419         int status;
1420         int no_queue_space = 0;
1421         int no_fifo_space = 0;
1422
1423         dwc_otg_host_global_regs_t *host_regs;
1424         host_regs = hcd->core_if->host_if->host_global_regs;
1425
1426         DWC_DEBUGPL(DBG_HCDV, "Queue periodic transactions\n");
1427 #ifdef DEBUG
1428         tx_status.d32 = DWC_READ_REG32(&host_regs->hptxsts);
1429         DWC_DEBUGPL(DBG_HCDV,
1430                     "  P Tx Req Queue Space Avail (before queue): %d\n",
1431                     tx_status.b.ptxqspcavail);
1432         DWC_DEBUGPL(DBG_HCDV, "  P Tx FIFO Space Avail (before queue): %d\n",
1433                     tx_status.b.ptxfspcavail);
1434 #endif
1435
1436         qh_ptr = hcd->periodic_sched_assigned.next;
1437         while (qh_ptr != &hcd->periodic_sched_assigned) {
1438                 tx_status.d32 = DWC_READ_REG32(&host_regs->hptxsts);
1439                 if (tx_status.b.ptxqspcavail == 0) {
1440                         no_queue_space = 1;
1441                         break;
1442                 }
1443
1444                 qh = DWC_LIST_ENTRY(qh_ptr, dwc_otg_qh_t, qh_list_entry);
1445
1446                 /*
1447                  * Set a flag if we're queuing high-bandwidth in slave mode.
1448                  * The flag prevents any halts to get into the request queue in
1449                  * the middle of multiple high-bandwidth packets getting queued.
1450                  */
1451                 if (!hcd->core_if->dma_enable && qh->channel->multi_count > 1) {
1452                         hcd->core_if->queuing_high_bandwidth = 1;
1453                 }
1454                 status =
1455                     queue_transaction(hcd, qh->channel,
1456                                       tx_status.b.ptxfspcavail);
1457                 if (status < 0) {
1458                         no_fifo_space = 1;
1459                         break;
1460                 }
1461
1462                 /*
1463                  * In Slave mode, stay on the current transfer until there is
1464                  * nothing more to do or the high-bandwidth request count is
1465                  * reached. In DMA mode, only need to queue one request. The
1466                  * controller automatically handles multiple packets for
1467                  * high-bandwidth transfers.
1468                  */
1469                 if (hcd->core_if->dma_enable || status == 0 ||
1470                     qh->channel->requests == qh->channel->multi_count) {
1471                         qh_ptr = qh_ptr->next;
1472                         /*
1473                          * Move the QH from the periodic assigned schedule to
1474                          * the periodic queued schedule.
1475                          */
1476                         DWC_LIST_MOVE_HEAD(&hcd->periodic_sched_queued,
1477                                            &qh->qh_list_entry);
1478
1479                         /* done queuing high bandwidth */
1480                         hcd->core_if->queuing_high_bandwidth = 0;
1481                 }
1482         }
1483
1484         if (!hcd->core_if->dma_enable) {
1485                 dwc_otg_core_global_regs_t *global_regs;
1486                 gintmsk_data_t intr_mask = {.d32 = 0 };
1487
1488                 global_regs = hcd->core_if->core_global_regs;
1489                 intr_mask.b.ptxfempty = 1;
1490 #ifdef DEBUG
1491                 tx_status.d32 = DWC_READ_REG32(&host_regs->hptxsts);
1492                 DWC_DEBUGPL(DBG_HCDV,
1493                             "  P Tx Req Queue Space Avail (after queue): %d\n",
1494                             tx_status.b.ptxqspcavail);
1495                 DWC_DEBUGPL(DBG_HCDV,
1496                             "  P Tx FIFO Space Avail (after queue): %d\n",
1497                             tx_status.b.ptxfspcavail);
1498 #endif
1499                 if (!DWC_LIST_EMPTY(&hcd->periodic_sched_assigned) ||
1500                     no_queue_space || no_fifo_space) {
1501                         /*
1502                          * May need to queue more transactions as the request
1503                          * queue or Tx FIFO empties. Enable the periodic Tx
1504                          * FIFO empty interrupt. (Always use the half-empty
1505                          * level to ensure that new requests are loaded as
1506                          * soon as possible.)
1507                          */
1508                         DWC_MODIFY_REG32(&global_regs->gintmsk, 0,
1509                                          intr_mask.d32);
1510                 } else {
1511                         /*
1512                          * Disable the Tx FIFO empty interrupt since there are
1513                          * no more transactions that need to be queued right
1514                          * now. This function is called from interrupt
1515                          * handlers to queue more transactions as transfer
1516                          * states change.
1517                          */
1518                         DWC_MODIFY_REG32(&global_regs->gintmsk, intr_mask.d32,
1519                                          0);
1520                 }
1521         }
1522 }
1523
1524 /**
1525  * Processes active non-periodic channels and queues transactions for these
1526  * channels to the DWC_otg controller. After queueing transactions, the NP Tx
1527  * FIFO Empty interrupt is enabled if there are more transactions to queue as
1528  * NP Tx FIFO or request queue space becomes available. Otherwise, the NP Tx
1529  * FIFO Empty interrupt is disabled.
1530  */
1531 static void process_non_periodic_channels(dwc_otg_hcd_t *hcd)
1532 {
1533         gnptxsts_data_t tx_status;
1534         dwc_list_link_t *orig_qh_ptr;
1535         dwc_otg_qh_t *qh;
1536         int status;
1537         int no_queue_space = 0;
1538         int no_fifo_space = 0;
1539         int more_to_do = 0;
1540
1541         dwc_otg_core_global_regs_t *global_regs =
1542             hcd->core_if->core_global_regs;
1543
1544         DWC_DEBUGPL(DBG_HCDV, "Queue non-periodic transactions\n");
1545 #ifdef DEBUG
1546         tx_status.d32 = DWC_READ_REG32(&global_regs->gnptxsts);
1547         DWC_DEBUGPL(DBG_HCDV,
1548                     "  NP Tx Req Queue Space Avail (before queue): %d\n",
1549                     tx_status.b.nptxqspcavail);
1550         DWC_DEBUGPL(DBG_HCDV, "  NP Tx FIFO Space Avail (before queue): %d\n",
1551                     tx_status.b.nptxfspcavail);
1552 #endif
1553         /*
1554          * Keep track of the starting point. Skip over the start-of-list
1555          * entry.
1556          */
1557         if (hcd->non_periodic_qh_ptr == &hcd->non_periodic_sched_active) {
1558                 hcd->non_periodic_qh_ptr = hcd->non_periodic_qh_ptr->next;
1559         }
1560         orig_qh_ptr = hcd->non_periodic_qh_ptr;
1561
1562         /*
1563          * Process once through the active list or until no more space is
1564          * available in the request queue or the Tx FIFO.
1565          */
1566         do {
1567                 tx_status.d32 = DWC_READ_REG32(&global_regs->gnptxsts);
1568                 if (!hcd->core_if->dma_enable && tx_status.b.nptxqspcavail == 0) {
1569                         no_queue_space = 1;
1570                         break;
1571                 }
1572
1573                 qh = DWC_LIST_ENTRY(hcd->non_periodic_qh_ptr, dwc_otg_qh_t,
1574                                     qh_list_entry);
1575                 status =
1576                     queue_transaction(hcd, qh->channel,
1577                                       tx_status.b.nptxfspcavail);
1578
1579                 if (status > 0) {
1580                         more_to_do = 1;
1581                 } else if (status < 0) {
1582                         no_fifo_space = 1;
1583                         break;
1584                 }
1585
1586                 /* Advance to next QH, skipping start-of-list entry. */
1587                 hcd->non_periodic_qh_ptr = hcd->non_periodic_qh_ptr->next;
1588                 if (hcd->non_periodic_qh_ptr == &hcd->non_periodic_sched_active) {
1589                         hcd->non_periodic_qh_ptr =
1590                             hcd->non_periodic_qh_ptr->next;
1591                 }
1592
1593         } while (hcd->non_periodic_qh_ptr != orig_qh_ptr);
1594
1595         if (!hcd->core_if->dma_enable) {
1596                 gintmsk_data_t intr_mask = {.d32 = 0 };
1597                 intr_mask.b.nptxfempty = 1;
1598
1599 #ifdef DEBUG
1600                 tx_status.d32 = DWC_READ_REG32(&global_regs->gnptxsts);
1601                 DWC_DEBUGPL(DBG_HCDV,
1602                             "  NP Tx Req Queue Space Avail (after queue): %d\n",
1603                             tx_status.b.nptxqspcavail);
1604                 DWC_DEBUGPL(DBG_HCDV,
1605                             "  NP Tx FIFO Space Avail (after queue): %d\n",
1606                             tx_status.b.nptxfspcavail);
1607 #endif
1608                 if (more_to_do || no_queue_space || no_fifo_space) {
1609                         /*
1610                          * May need to queue more transactions as the request
1611                          * queue or Tx FIFO empties. Enable the non-periodic
1612                          * Tx FIFO empty interrupt. (Always use the half-empty
1613                          * level to ensure that new requests are loaded as
1614                          * soon as possible.)
1615                          */
1616                         DWC_MODIFY_REG32(&global_regs->gintmsk, 0,
1617                                          intr_mask.d32);
1618                 } else {
1619                         /*
1620                          * Disable the Tx FIFO empty interrupt since there are
1621                          * no more transactions that need to be queued right
1622                          * now. This function is called from interrupt
1623                          * handlers to queue more transactions as transfer
1624                          * states change.
1625                          */
1626                         DWC_MODIFY_REG32(&global_regs->gintmsk, intr_mask.d32,
1627                                          0);
1628                 }
1629         }
1630 }
1631
1632 /**
1633  * This function processes the currently active host channels and queues
1634  * transactions for these channels to the DWC_otg controller. It is called
1635  * from HCD interrupt handler functions.
1636  *
1637  * @param hcd The HCD state structure.
1638  * @param tr_type The type(s) of transactions to queue (non-periodic,
1639  * periodic, or both).
1640  */
1641 void dwc_otg_hcd_queue_transactions(dwc_otg_hcd_t *hcd,
1642                                     dwc_otg_transaction_type_e tr_type)
1643 {
1644 #ifdef DEBUG_SOF
1645         DWC_DEBUGPL(DBG_HCD, "Queue Transactions\n");
1646 #endif
1647         /* Process host channels associated with periodic transfers. */
1648         if ((tr_type == DWC_OTG_TRANSACTION_PERIODIC ||
1649              tr_type == DWC_OTG_TRANSACTION_ALL) &&
1650             !DWC_LIST_EMPTY(&hcd->periodic_sched_assigned)) {
1651
1652                 process_periodic_channels(hcd);
1653         }
1654
1655         /* Process host channels associated with non-periodic transfers. */
1656         if (tr_type == DWC_OTG_TRANSACTION_NON_PERIODIC ||
1657             tr_type == DWC_OTG_TRANSACTION_ALL) {
1658                 if (!DWC_LIST_EMPTY(&hcd->non_periodic_sched_active)) {
1659                         process_non_periodic_channels(hcd);
1660                 } else {
1661                         /*
1662                          * Ensure NP Tx FIFO empty interrupt is disabled when
1663                          * there are no non-periodic transfers to process.
1664                          */
1665                         gintmsk_data_t gintmsk = {.d32 = 0 };
1666                         gintmsk.b.nptxfempty = 1;
1667                         DWC_MODIFY_REG32(&hcd->core_if->core_global_regs->
1668                                          gintmsk, gintmsk.d32, 0);
1669                 }
1670         }
1671 }
1672
1673 #ifdef DWC_HS_ELECT_TST
1674 /*
1675  * Quick and dirty hack to implement the HS Electrical Test
1676  * SINGLE_STEP_GET_DEVICE_DESCRIPTOR feature.
1677  *
1678  * This code was copied from our userspace app "hset". It sends a
1679  * Get Device Descriptor control sequence in two parts, first the
1680  * Setup packet by itself, followed some time later by the In and
1681  * Ack packets. Rather than trying to figure out how to add this
1682  * functionality to the normal driver code, we just hijack the
1683  * hardware, using these two function to drive the hardware
1684  * directly.
1685  */
1686
1687 static dwc_otg_core_global_regs_t *global_regs;
1688 static dwc_otg_host_global_regs_t *hc_global_regs;
1689 static dwc_otg_hc_regs_t *hc_regs;
1690 static uint32_t *data_fifo;
1691
1692 static void do_setup(void)
1693 {
1694         gintsts_data_t gintsts;
1695         hctsiz_data_t hctsiz;
1696         hcchar_data_t hcchar;
1697         haint_data_t haint;
1698         hcint_data_t hcint;
1699
1700         /* Enable HAINTs */
1701         DWC_WRITE_REG32(&hc_global_regs->haintmsk, 0x0001);
1702
1703         /* Enable HCINTs */
1704         DWC_WRITE_REG32(&hc_regs->hcintmsk, 0x04a3);
1705
1706         /* Read GINTSTS */
1707         gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
1708
1709         /* Read HAINT */
1710         haint.d32 = DWC_READ_REG32(&hc_global_regs->haint);
1711
1712         /* Read HCINT */
1713         hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
1714
1715         /* Read HCCHAR */
1716         hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
1717
1718         /* Clear HCINT */
1719         DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32);
1720
1721         /* Clear HAINT */
1722         DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32);
1723
1724         /* Clear GINTSTS */
1725         DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
1726
1727         /* Read GINTSTS */
1728         gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
1729
1730         /*
1731          * Send Setup packet (Get Device Descriptor)
1732          */
1733
1734         /* Make sure channel is disabled */
1735         hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
1736         if (hcchar.b.chen) {
1737                 hcchar.b.chdis = 1;
1738                 /* hcchar.b.chen = 1; */
1739                 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
1740                 /* sleep(1); */
1741                 dwc_mdelay(1000);
1742
1743                 /* Read GINTSTS */
1744                 gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
1745
1746                 /* Read HAINT */
1747                 haint.d32 = DWC_READ_REG32(&hc_global_regs->haint);
1748
1749                 /* Read HCINT */
1750                 hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
1751
1752                 /* Read HCCHAR */
1753                 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
1754
1755                 /* Clear HCINT */
1756                 DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32);
1757
1758                 /* Clear HAINT */
1759                 DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32);
1760
1761                 /* Clear GINTSTS */
1762                 DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
1763
1764                 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
1765         }
1766
1767         /* Set HCTSIZ */
1768         hctsiz.d32 = 0;
1769         hctsiz.b.xfersize = 8;
1770         hctsiz.b.pktcnt = 1;
1771         hctsiz.b.pid = DWC_OTG_HC_PID_SETUP;
1772         DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32);
1773
1774         /* Set HCCHAR */
1775         hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
1776         hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;
1777         hcchar.b.epdir = 0;
1778         hcchar.b.epnum = 0;
1779         hcchar.b.mps = 8;
1780         hcchar.b.chen = 1;
1781         DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
1782
1783         /* Fill FIFO with Setup data for Get Device Descriptor */
1784         data_fifo = (uint32_t *) ((char *)global_regs + 0x1000);
1785         DWC_WRITE_REG32(data_fifo++, 0x01000680);
1786         DWC_WRITE_REG32(data_fifo++, 0x00080000);
1787
1788         gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
1789
1790         /* Wait for host channel interrupt */
1791         do {
1792                 gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
1793         } while (gintsts.b.hcintr == 0);
1794
1795         /* Disable HCINTs */
1796         DWC_WRITE_REG32(&hc_regs->hcintmsk, 0x0000);
1797
1798         /* Disable HAINTs */
1799         DWC_WRITE_REG32(&hc_global_regs->haintmsk, 0x0000);
1800
1801         /* Read HAINT */
1802         haint.d32 = DWC_READ_REG32(&hc_global_regs->haint);
1803
1804         /* Read HCINT */
1805         hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
1806
1807         /* Read HCCHAR */
1808         hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
1809
1810         /* Clear HCINT */
1811         DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32);
1812
1813         /* Clear HAINT */
1814         DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32);
1815
1816         /* Clear GINTSTS */
1817         DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
1818
1819         /* Read GINTSTS */
1820         gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
1821 }
1822
1823 static void do_in_ack(void)
1824 {
1825         gintsts_data_t gintsts;
1826         hctsiz_data_t hctsiz;
1827         hcchar_data_t hcchar;
1828         haint_data_t haint;
1829         hcint_data_t hcint;
1830         host_grxsts_data_t grxsts;
1831
1832         /* Enable HAINTs */
1833         DWC_WRITE_REG32(&hc_global_regs->haintmsk, 0x0001);
1834
1835         /* Enable HCINTs */
1836         DWC_WRITE_REG32(&hc_regs->hcintmsk, 0x04a3);
1837
1838         /* Read GINTSTS */
1839         gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
1840
1841         /* Read HAINT */
1842         haint.d32 = DWC_READ_REG32(&hc_global_regs->haint);
1843
1844         /* Read HCINT */
1845         hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
1846
1847         /* Read HCCHAR */
1848         hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
1849
1850         /* Clear HCINT */
1851         DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32);
1852
1853         /* Clear HAINT */
1854         DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32);
1855
1856         /* Clear GINTSTS */
1857         DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
1858
1859         /* Read GINTSTS */
1860         gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
1861
1862         /*
1863          * Receive Control In packet
1864          */
1865
1866         /* Make sure channel is disabled */
1867         hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
1868         if (hcchar.b.chen) {
1869                 hcchar.b.chdis = 1;
1870                 hcchar.b.chen = 1;
1871                 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
1872                 /* sleep(1); */
1873                 dwc_mdelay(1000);
1874
1875                 /* Read GINTSTS */
1876                 gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
1877
1878                 /* Read HAINT */
1879                 haint.d32 = DWC_READ_REG32(&hc_global_regs->haint);
1880
1881                 /* Read HCINT */
1882                 hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
1883
1884                 /* Read HCCHAR */
1885                 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
1886
1887                 /* Clear HCINT */
1888                 DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32);
1889
1890                 /* Clear HAINT */
1891                 DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32);
1892
1893                 /* Clear GINTSTS */
1894                 DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
1895
1896                 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
1897         }
1898
1899         /* Set HCTSIZ */
1900         hctsiz.d32 = 0;
1901         hctsiz.b.xfersize = 8;
1902         hctsiz.b.pktcnt = 1;
1903         hctsiz.b.pid = DWC_OTG_HC_PID_DATA1;
1904         DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32);
1905
1906         /* Set HCCHAR */
1907         hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
1908         hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;
1909         hcchar.b.epdir = 1;
1910         hcchar.b.epnum = 0;
1911         hcchar.b.mps = 8;
1912         hcchar.b.chen = 1;
1913         DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
1914
1915         gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
1916
1917         /* Wait for receive status queue interrupt */
1918         do {
1919                 gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
1920         } while (gintsts.b.rxstsqlvl == 0);
1921
1922         /* Read RXSTS */
1923         grxsts.d32 = DWC_READ_REG32(&global_regs->grxstsp);
1924
1925         /* Clear RXSTSQLVL in GINTSTS */
1926         gintsts.d32 = 0;
1927         gintsts.b.rxstsqlvl = 1;
1928         DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
1929
1930         switch (grxsts.b.pktsts) {
1931         case DWC_GRXSTS_PKTSTS_IN:
1932                 /* Read the data into the host buffer */
1933                 if (grxsts.b.bcnt > 0) {
1934                         int i;
1935                         int word_count = (grxsts.b.bcnt + 3) / 4;
1936
1937                         data_fifo = (uint32_t *) ((char *)global_regs + 0x1000);
1938
1939                         for (i = 0; i < word_count; i++) {
1940                                 (void)DWC_READ_REG32(data_fifo++);
1941                         }
1942                 }
1943                 break;
1944
1945         default:
1946                 break;
1947         }
1948
1949         gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
1950
1951         /* Wait for receive status queue interrupt */
1952         do {
1953                 gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
1954         } while (gintsts.b.rxstsqlvl == 0);
1955
1956         /* Read RXSTS */
1957         grxsts.d32 = DWC_READ_REG32(&global_regs->grxstsp);
1958
1959         /* Clear RXSTSQLVL in GINTSTS */
1960         gintsts.d32 = 0;
1961         gintsts.b.rxstsqlvl = 1;
1962         DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
1963
1964         switch (grxsts.b.pktsts) {
1965         case DWC_GRXSTS_PKTSTS_IN_XFER_COMP:
1966                 break;
1967
1968         default:
1969                 break;
1970         }
1971
1972         gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
1973
1974         /* Wait for host channel interrupt */
1975         do {
1976                 gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
1977         } while (gintsts.b.hcintr == 0);
1978
1979         /* Read HAINT */
1980         haint.d32 = DWC_READ_REG32(&hc_global_regs->haint);
1981
1982         /* Read HCINT */
1983         hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
1984
1985         /* Read HCCHAR */
1986         hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
1987
1988         /* Clear HCINT */
1989         DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32);
1990
1991         /* Clear HAINT */
1992         DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32);
1993
1994         /* Clear GINTSTS */
1995         DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
1996
1997         /* Read GINTSTS */
1998         gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
1999
2000         /* usleep(100000); */
2001         /* mdelay(100); */
2002         dwc_mdelay(1);
2003
2004         /*
2005          * Send handshake packet
2006          */
2007
2008         /* Read HAINT */
2009         haint.d32 = DWC_READ_REG32(&hc_global_regs->haint);
2010
2011         /* Read HCINT */
2012         hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
2013
2014         /* Read HCCHAR */
2015         hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2016
2017         /* Clear HCINT */
2018         DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32);
2019
2020         /* Clear HAINT */
2021         DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32);
2022
2023         /* Clear GINTSTS */
2024         DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
2025
2026         /* Read GINTSTS */
2027         gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
2028
2029         /* Make sure channel is disabled */
2030         hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2031         if (hcchar.b.chen) {
2032                 hcchar.b.chdis = 1;
2033                 hcchar.b.chen = 1;
2034                 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
2035                 /* sleep(1); */
2036                 dwc_mdelay(1000);
2037
2038                 /* Read GINTSTS */
2039                 gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
2040
2041                 /* Read HAINT */
2042                 haint.d32 = DWC_READ_REG32(&hc_global_regs->haint);
2043
2044                 /* Read HCINT */
2045                 hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
2046
2047                 /* Read HCCHAR */
2048                 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2049
2050                 /* Clear HCINT */
2051                 DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32);
2052
2053                 /* Clear HAINT */
2054                 DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32);
2055
2056                 /* Clear GINTSTS */
2057                 DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
2058
2059                 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2060         }
2061
2062         /* Set HCTSIZ */
2063         hctsiz.d32 = 0;
2064         hctsiz.b.xfersize = 0;
2065         hctsiz.b.pktcnt = 1;
2066         hctsiz.b.pid = DWC_OTG_HC_PID_DATA1;
2067         DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32);
2068
2069         /* Set HCCHAR */
2070         hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2071         hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;
2072         hcchar.b.epdir = 0;
2073         hcchar.b.epnum = 0;
2074         hcchar.b.mps = 8;
2075         hcchar.b.chen = 1;
2076         DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
2077
2078         gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
2079
2080         /* Wait for host channel interrupt */
2081         do {
2082                 gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
2083         } while (gintsts.b.hcintr == 0);
2084
2085         /* Disable HCINTs */
2086         DWC_WRITE_REG32(&hc_regs->hcintmsk, 0x0000);
2087
2088         /* Disable HAINTs */
2089         DWC_WRITE_REG32(&hc_global_regs->haintmsk, 0x0000);
2090
2091         /* Read HAINT */
2092         haint.d32 = DWC_READ_REG32(&hc_global_regs->haint);
2093
2094         /* Read HCINT */
2095         hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
2096
2097         /* Read HCCHAR */
2098         hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2099
2100         /* Clear HCINT */
2101         DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32);
2102
2103         /* Clear HAINT */
2104         DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32);
2105
2106         /* Clear GINTSTS */
2107         DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
2108
2109         /* Read GINTSTS */
2110         gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
2111 }
2112 #endif
2113
2114 /** Handles hub class-specific requests. */
2115 int dwc_otg_hcd_hub_control(dwc_otg_hcd_t *dwc_otg_hcd,
2116                             uint16_t typeReq,
2117                             uint16_t wValue,
2118                             uint16_t wIndex, uint8_t *buf, uint16_t wLength)
2119 {
2120         int retval = 0;
2121
2122         dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
2123         usb_hub_descriptor_t *hub_desc;
2124         hprt0_data_t hprt0 = {.d32 = 0 };
2125
2126         uint32_t port_status;
2127
2128         switch (typeReq) {
2129         case UCR_CLEAR_HUB_FEATURE:
2130                 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2131                             "ClearHubFeature 0x%x\n", wValue);
2132                 switch (wValue) {
2133                 case UHF_C_HUB_LOCAL_POWER:
2134                 case UHF_C_HUB_OVER_CURRENT:
2135                         /* Nothing required here */
2136                         break;
2137                 default:
2138                         retval = -DWC_E_INVALID;
2139                         DWC_ERROR("DWC OTG HCD - "
2140                                   "ClearHubFeature request %xh unknown\n",
2141                                   wValue);
2142                 }
2143                 break;
2144         case UCR_CLEAR_PORT_FEATURE:
2145 #ifdef CONFIG_USB_DWC_OTG_LPM
2146                 if (wValue != UHF_PORT_L1)
2147 #endif
2148                         if (!wIndex || wIndex > 1)
2149                                 goto error;
2150
2151                 switch (wValue) {
2152                 case UHF_PORT_ENABLE:
2153                         DWC_DEBUGPL(DBG_ANY, "DWC OTG HCD HUB CONTROL - "
2154                                     "ClearPortFeature USB_PORT_FEAT_ENABLE\n");
2155                         hprt0.d32 = dwc_otg_read_hprt0(core_if);
2156                         hprt0.b.prtena = 1;
2157                         DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
2158                         break;
2159                 case UHF_PORT_SUSPEND:
2160                         DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2161                                     "ClearPortFeature USB_PORT_FEAT_SUSPEND\n");
2162
2163                         if (core_if->power_down == 2) {
2164                                 dwc_otg_host_hibernation_restore(core_if, 0, 0);
2165                         } else {
2166                                 DWC_WRITE_REG32(core_if->pcgcctl, 0);
2167                                 dwc_mdelay(5);
2168
2169                                 hprt0.d32 = dwc_otg_read_hprt0(core_if);
2170                                 hprt0.b.prtres = 1;
2171                                 DWC_WRITE_REG32(core_if->host_if->hprt0,
2172                                                 hprt0.d32);
2173                                 hprt0.b.prtsusp = 0;
2174                                 /* Clear Resume bit */
2175                                 dwc_mdelay(100);
2176                                 hprt0.b.prtres = 0;
2177                                 DWC_WRITE_REG32(core_if->host_if->hprt0,
2178                                                 hprt0.d32);
2179                         }
2180                         break;
2181 #ifdef CONFIG_USB_DWC_OTG_LPM
2182                 case UHF_PORT_L1:
2183                         {
2184                                 pcgcctl_data_t pcgcctl = {.d32 = 0 };
2185                                 glpmcfg_data_t lpmcfg = {.d32 = 0 };
2186
2187                                 lpmcfg.d32 =
2188                                     DWC_READ_REG32(&core_if->core_global_regs->
2189                                                    glpmcfg);
2190                                 lpmcfg.b.en_utmi_sleep = 0;
2191                                 lpmcfg.b.hird_thres &= (~(1 << 4));
2192                                 lpmcfg.b.prt_sleep_sts = 1;
2193                                 DWC_WRITE_REG32(&core_if->core_global_regs->
2194                                                 glpmcfg, lpmcfg.d32);
2195
2196                                 /* Clear Enbl_L1Gating bit. */
2197                                 pcgcctl.b.enbl_sleep_gating = 1;
2198                                 DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32,
2199                                                  0);
2200
2201                                 dwc_mdelay(5);
2202
2203                                 hprt0.d32 = dwc_otg_read_hprt0(core_if);
2204                                 hprt0.b.prtres = 1;
2205                                 DWC_WRITE_REG32(core_if->host_if->hprt0,
2206                                                 hprt0.d32);
2207                                 /* This bit will be cleared in wakeup interrupt handle */
2208                                 break;
2209                         }
2210 #endif
2211                 case UHF_PORT_POWER:
2212                         DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2213                                     "ClearPortFeature USB_PORT_FEAT_POWER\n");
2214                         hprt0.d32 = dwc_otg_read_hprt0(core_if);
2215                         hprt0.b.prtpwr = 0;
2216                         DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
2217                         break;
2218                 case UHF_PORT_INDICATOR:
2219                         DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2220                                     "ClearPortFeature USB_PORT_FEAT_INDICATOR\n");
2221                         /* Port inidicator not supported */
2222                         break;
2223                 case UHF_C_PORT_CONNECTION:
2224                         /* Clears drivers internal connect status change
2225                          * flag */
2226                         DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2227                                     "ClearPortFeature USB_PORT_FEAT_C_CONNECTION\n");
2228                         dwc_otg_hcd->flags.b.port_connect_status_change = 0;
2229                         break;
2230                 case UHF_C_PORT_RESET:
2231                         /* Clears the driver's internal Port Reset Change
2232                          * flag */
2233                         DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2234                                     "ClearPortFeature USB_PORT_FEAT_C_RESET\n");
2235                         dwc_otg_hcd->flags.b.port_reset_change = 0;
2236                         break;
2237                 case UHF_C_PORT_ENABLE:
2238                         /* Clears the driver's internal Port
2239                          * Enable/Disable Change flag */
2240                         DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2241                                     "ClearPortFeature USB_PORT_FEAT_C_ENABLE\n");
2242                         dwc_otg_hcd->flags.b.port_enable_change = 0;
2243                         break;
2244                 case UHF_C_PORT_SUSPEND:
2245                         /* Clears the driver's internal Port Suspend
2246                          * Change flag, which is set when resume signaling on
2247                          * the host port is complete */
2248                         DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2249                                     "ClearPortFeature USB_PORT_FEAT_C_SUSPEND\n");
2250                         dwc_otg_hcd->flags.b.port_suspend_change = 0;
2251                         break;
2252 #ifdef CONFIG_USB_DWC_OTG_LPM
2253                 case UHF_C_PORT_L1:
2254                         dwc_otg_hcd->flags.b.port_l1_change = 0;
2255                         break;
2256 #endif
2257                 case UHF_C_PORT_OVER_CURRENT:
2258                         DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2259                                     "ClearPortFeature USB_PORT_FEAT_C_OVER_CURRENT\n");
2260                         dwc_otg_hcd->flags.b.port_over_current_change = 0;
2261                         break;
2262                 default:
2263                         retval = -DWC_E_INVALID;
2264                         DWC_ERROR("DWC OTG HCD - "
2265                                   "ClearPortFeature request %xh "
2266                                   "unknown or unsupported\n", wValue);
2267                 }
2268                 break;
2269         case UCR_GET_HUB_DESCRIPTOR:
2270                 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2271                             "GetHubDescriptor\n");
2272                 hub_desc = (usb_hub_descriptor_t *) buf;
2273                 hub_desc->bDescLength = 9;
2274                 hub_desc->bDescriptorType = 0x29;
2275                 hub_desc->bNbrPorts = 1;
2276                 USETW(hub_desc->wHubCharacteristics, 0x08);
2277                 hub_desc->bPwrOn2PwrGood = 1;
2278                 hub_desc->bHubContrCurrent = 0;
2279                 hub_desc->DeviceRemovable[0] = 0;
2280                 hub_desc->DeviceRemovable[1] = 0xff;
2281                 break;
2282         case UCR_GET_HUB_STATUS:
2283                 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2284                             "GetHubStatus\n");
2285                 DWC_MEMSET(buf, 0, 4);
2286                 break;
2287         case UCR_GET_PORT_STATUS:
2288                 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2289                             "GetPortStatus wIndex = 0x%04x FLAGS=0x%08x\n",
2290                             wIndex, dwc_otg_hcd->flags.d32);
2291                 if (!wIndex || wIndex > 1)
2292                         goto error;
2293
2294                 port_status = 0;
2295
2296                 if (dwc_otg_hcd->flags.b.port_connect_status_change)
2297                         port_status |= (1 << UHF_C_PORT_CONNECTION);
2298
2299                 if (dwc_otg_hcd->flags.b.port_enable_change)
2300                         port_status |= (1 << UHF_C_PORT_ENABLE);
2301
2302                 if (dwc_otg_hcd->flags.b.port_suspend_change)
2303                         port_status |= (1 << UHF_C_PORT_SUSPEND);
2304
2305                 if (dwc_otg_hcd->flags.b.port_l1_change)
2306                         port_status |= (1 << UHF_C_PORT_L1);
2307
2308                 if (dwc_otg_hcd->flags.b.port_reset_change) {
2309                         port_status |= (1 << UHF_C_PORT_RESET);
2310                 }
2311
2312                 if (dwc_otg_hcd->flags.b.port_over_current_change) {
2313                         DWC_WARN("Overcurrent change detected\n");
2314                         port_status |= (1 << UHF_C_PORT_OVER_CURRENT);
2315                 }
2316
2317                 if (!dwc_otg_hcd->flags.b.port_connect_status) {
2318                         /*
2319                          * The port is disconnected, which means the core is
2320                          * either in device mode or it soon will be. Just
2321                          * return 0's for the remainder of the port status
2322                          * since the port register can't be read if the core
2323                          * is in device mode.
2324                          */
2325                         *((__le32 *) buf) = dwc_cpu_to_le32(&port_status);
2326                         break;
2327                 }
2328
2329                 hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
2330                 DWC_DEBUGPL(DBG_HCDV, "  HPRT0: 0x%08x\n", hprt0.d32);
2331
2332                 if (hprt0.b.prtconnsts)
2333                         port_status |= (1 << UHF_PORT_CONNECTION);
2334
2335                 if (hprt0.b.prtena)
2336                         port_status |= (1 << UHF_PORT_ENABLE);
2337
2338                 if (hprt0.b.prtsusp)
2339                         port_status |= (1 << UHF_PORT_SUSPEND);
2340
2341                 if (hprt0.b.prtovrcurract)
2342                         port_status |= (1 << UHF_PORT_OVER_CURRENT);
2343
2344                 if (hprt0.b.prtrst)
2345                         port_status |= (1 << UHF_PORT_RESET);
2346
2347                 if (hprt0.b.prtpwr)
2348                         port_status |= (1 << UHF_PORT_POWER);
2349
2350                 if (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_HIGH_SPEED)
2351                         port_status |= (1 << UHF_PORT_HIGH_SPEED);
2352                 else if (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_LOW_SPEED)
2353                         port_status |= (1 << UHF_PORT_LOW_SPEED);
2354
2355                 if (hprt0.b.prttstctl)
2356                         port_status |= (1 << UHF_PORT_TEST);
2357                 if (dwc_otg_get_lpm_portsleepstatus(dwc_otg_hcd->core_if)) {
2358                         port_status |= (1 << UHF_PORT_L1);
2359                 }
2360                 /*
2361                    For Synopsys HW emulation of Power down wkup_control asserts the
2362                    hreset_n and prst_n on suspned. This causes the HPRT0 to be zero.
2363                    We intentionally tell the software that port is in L2Suspend state.
2364                    Only for STE.
2365                  */
2366                 if ((core_if->power_down == 2)
2367                     && (core_if->hibernation_suspend == 1)) {
2368                         port_status |= (1 << UHF_PORT_SUSPEND);
2369                 }
2370                 /* USB_PORT_FEAT_INDICATOR unsupported always 0 */
2371
2372                 *((__le32 *) buf) = dwc_cpu_to_le32(&port_status);
2373
2374                 break;
2375         case UCR_SET_HUB_FEATURE:
2376                 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2377                             "SetHubFeature\n");
2378                 /* No HUB features supported */
2379                 break;
2380         case UCR_SET_PORT_FEATURE:
2381                 if (wValue != UHF_PORT_TEST && (!wIndex || wIndex > 1))
2382                         goto error;
2383
2384                 if (!dwc_otg_hcd->flags.b.port_connect_status) {
2385                         /*
2386                          * The port is disconnected, which means the core is
2387                          * either in device mode or it soon will be. Just
2388                          * return without doing anything since the port
2389                          * register can't be written if the core is in device
2390                          * mode.
2391                          */
2392                         break;
2393                 }
2394
2395                 switch (wValue) {
2396                 case UHF_PORT_SUSPEND:
2397                         DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2398                                     "SetPortFeature - USB_PORT_FEAT_SUSPEND\n");
2399                         if (dwc_otg_hcd_otg_port(dwc_otg_hcd) != wIndex) {
2400                                 goto error;
2401                         }
2402                         if (core_if->power_down == 2) {
2403                                 int timeout = 300;
2404                                 dwc_irqflags_t flags;
2405                                 pcgcctl_data_t pcgcctl = {.d32 = 0 };
2406                                 gpwrdn_data_t gpwrdn = {.d32 = 0 };
2407                                 gusbcfg_data_t gusbcfg = {.d32 = 0 };
2408 #ifdef DWC_DEV_SRPCAP
2409                                 int32_t otg_cap_param =
2410                                     core_if->core_params->otg_cap;
2411 #endif
2412                                 DWC_PRINTF
2413                                     ("Preparing for complete power-off\n");
2414
2415                                 /* Save registers before hibernation */
2416                                 dwc_otg_save_global_regs(core_if);
2417                                 dwc_otg_save_host_regs(core_if);
2418
2419                                 hprt0.d32 = dwc_otg_read_hprt0(core_if);
2420                                 hprt0.b.prtsusp = 1;
2421                                 hprt0.b.prtena = 0;
2422                                 DWC_WRITE_REG32(core_if->host_if->hprt0,
2423                                                 hprt0.d32);
2424                                 /* Spin hprt0.b.prtsusp to became 1 */
2425                                 do {
2426                                         hprt0.d32 = dwc_otg_read_hprt0(core_if);
2427                                         if (hprt0.b.prtsusp) {
2428                                                 break;
2429                                         }
2430                                         dwc_mdelay(1);
2431                                 } while (--timeout);
2432                                 if (!timeout) {
2433                                         DWC_WARN("Suspend wasn't genereted\n");
2434                                 }
2435                                 dwc_udelay(10);
2436
2437                                 /*
2438                                  * We need to disable interrupts to prevent servicing of any IRQ
2439                                  * during going to hibernation
2440                                  */
2441                                 DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &flags);
2442                                 core_if->lx_state = DWC_OTG_L2;
2443 #ifdef DWC_DEV_SRPCAP
2444                                 hprt0.d32 = dwc_otg_read_hprt0(core_if);
2445                                 hprt0.b.prtpwr = 0;
2446                                 hprt0.b.prtena = 0;
2447                                 DWC_WRITE_REG32(core_if->host_if->hprt0,
2448                                                 hprt0.d32);
2449 #endif
2450                                 gusbcfg.d32 =
2451                                     DWC_READ_REG32(&core_if->
2452                                                    core_global_regs->gusbcfg);
2453                                 if (gusbcfg.b.ulpi_utmi_sel == 1) {
2454                                         /* ULPI interface */
2455                                         /* Suspend the Phy Clock */
2456                                         pcgcctl.d32 = 0;
2457                                         pcgcctl.b.stoppclk = 1;
2458                                         DWC_MODIFY_REG32(core_if->pcgcctl, 0,
2459                                                          pcgcctl.d32);
2460                                         dwc_udelay(10);
2461                                         gpwrdn.b.pmuactv = 1;
2462                                         DWC_MODIFY_REG32
2463                                             (&core_if->core_global_regs->gpwrdn,
2464                                              0, gpwrdn.d32);
2465                                 } else {
2466                                         /* UTMI+ Interface */
2467                                         gpwrdn.b.pmuactv = 1;
2468                                         DWC_MODIFY_REG32
2469                                             (&core_if->core_global_regs->gpwrdn,
2470                                              0, gpwrdn.d32);
2471                                         dwc_udelay(10);
2472                                         pcgcctl.b.stoppclk = 1;
2473                                         DWC_MODIFY_REG32(core_if->pcgcctl, 0,
2474                                                          pcgcctl.d32);
2475                                         dwc_udelay(10);
2476                                 }
2477 #ifdef DWC_DEV_SRPCAP
2478                                 gpwrdn.d32 = 0;
2479                                 gpwrdn.b.dis_vbus = 1;
2480                                 DWC_MODIFY_REG32(&core_if->
2481                                                  core_global_regs->gpwrdn, 0,
2482                                                  gpwrdn.d32);
2483 #endif
2484                                 gpwrdn.d32 = 0;
2485                                 gpwrdn.b.pmuintsel = 1;
2486                                 DWC_MODIFY_REG32(&core_if->
2487                                                  core_global_regs->gpwrdn, 0,
2488                                                  gpwrdn.d32);
2489                                 dwc_udelay(10);
2490
2491                                 gpwrdn.d32 = 0;
2492 #ifdef DWC_DEV_SRPCAP
2493                                 gpwrdn.b.srp_det_msk = 1;
2494 #endif
2495                                 gpwrdn.b.disconn_det_msk = 1;
2496                                 gpwrdn.b.lnstchng_msk = 1;
2497                                 gpwrdn.b.sts_chngint_msk = 1;
2498                                 DWC_MODIFY_REG32(&core_if->
2499                                                  core_global_regs->gpwrdn, 0,
2500                                                  gpwrdn.d32);
2501                                 dwc_udelay(10);
2502
2503                                 /* Enable Power Down Clamp and all interrupts in GPWRDN */
2504                                 gpwrdn.d32 = 0;
2505                                 gpwrdn.b.pwrdnclmp = 1;
2506                                 DWC_MODIFY_REG32(&core_if->
2507                                                  core_global_regs->gpwrdn, 0,
2508                                                  gpwrdn.d32);
2509                                 dwc_udelay(10);
2510
2511                                 /* Switch off VDD */
2512                                 gpwrdn.d32 = 0;
2513                                 gpwrdn.b.pwrdnswtch = 1;
2514                                 DWC_MODIFY_REG32(&core_if->
2515                                                  core_global_regs->gpwrdn, 0,
2516                                                  gpwrdn.d32);
2517
2518 #ifdef DWC_DEV_SRPCAP
2519                                 if (otg_cap_param ==
2520                                     DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) {
2521                                         core_if->pwron_timer_started = 1;
2522                                         DWC_TIMER_SCHEDULE(core_if->pwron_timer,
2523                                                            6000 /* 6 secs */);
2524                                 }
2525 #endif
2526                                 /* Save gpwrdn register for further usage if stschng interrupt */
2527                                 core_if->gr_backup->gpwrdn_local =
2528                                     DWC_READ_REG32(&core_if->core_global_regs->
2529                                                    gpwrdn);
2530
2531                                 /* Set flag to indicate that we are in hibernation */
2532                                 core_if->hibernation_suspend = 1;
2533                                 DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock,
2534                                                           flags);
2535
2536                                 DWC_PRINTF("Host hibernation completed\n");
2537                                 /* Exit from case statement */
2538                                 break;
2539
2540                         }
2541                         if (dwc_otg_hcd_otg_port(dwc_otg_hcd) == wIndex &&
2542                             dwc_otg_hcd->fops->get_b_hnp_enable(dwc_otg_hcd)) {
2543                                 gotgctl_data_t gotgctl = {.d32 = 0 };
2544                                 gotgctl.b.hstsethnpen = 1;
2545                                 DWC_MODIFY_REG32(&core_if->
2546                                                  core_global_regs->gotgctl, 0,
2547                                                  gotgctl.d32);
2548                                 core_if->op_state = A_SUSPEND;
2549                         }
2550                         hprt0.d32 = dwc_otg_read_hprt0(core_if);
2551                         hprt0.b.prtsusp = 1;
2552                         DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
2553                         {
2554                                 dwc_irqflags_t flags;
2555                                 /* Update lx_state */
2556                                 DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &flags);
2557                                 core_if->lx_state = DWC_OTG_L2;
2558                                 DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock,
2559                                                           flags);
2560                         }
2561                         /* Suspend the Phy Clock */
2562                         if (core_if->otg_ver == 0) {
2563                                 pcgcctl_data_t pcgcctl = {.d32 = 0 };
2564                                 pcgcctl.b.stoppclk = 1;
2565                                 DWC_MODIFY_REG32(core_if->pcgcctl, 0,
2566                                                  pcgcctl.d32);
2567                                 dwc_udelay(10);
2568                         }
2569
2570                         /* For HNP the bus must be suspended for at least 200ms. */
2571                         if (dwc_otg_hcd->fops->get_b_hnp_enable(dwc_otg_hcd)) {
2572                                 pcgcctl_data_t pcgcctl = {.d32 = 0 };
2573                                 pcgcctl.b.stoppclk = 1;
2574                                 DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32,
2575                                                  0);
2576                                 dwc_mdelay(200);
2577                         }
2578
2579                         /** @todo - check how sw can wait for 1 sec to check asesvld??? */
2580 #if 0
2581                         if (core_if->adp_enable) {
2582                                 gotgctl_data_t gotgctl = {.d32 = 0 };
2583                                 gpwrdn_data_t gpwrdn;
2584
2585                                 while (gotgctl.b.asesvld == 1) {
2586                                         gotgctl.d32 =
2587                                             DWC_READ_REG32
2588                                             (&core_if->core_global_regs->gotgctl);
2589                                         dwc_mdelay(100);
2590                                 }
2591
2592                                 /* Enable Power Down Logic */
2593                                 gpwrdn.d32 = 0;
2594                                 gpwrdn.b.pmuactv = 1;
2595                                 DWC_MODIFY_REG32(&core_if->
2596                                                  core_global_regs->gpwrdn, 0,
2597                                                  gpwrdn.d32);
2598
2599                                 /* Unmask SRP detected interrupt from Power Down Logic */
2600                                 gpwrdn.d32 = 0;
2601                                 gpwrdn.b.srp_det_msk = 1;
2602                                 DWC_MODIFY_REG32(&core_if->
2603                                                  core_global_regs->gpwrdn, 0,
2604                                                  gpwrdn.d32);
2605
2606                                 dwc_otg_adp_probe_start(core_if);
2607                         }
2608 #endif
2609                         break;
2610                 case UHF_PORT_POWER:
2611                         DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2612                                     "SetPortFeature - USB_PORT_FEAT_POWER\n");
2613                         hprt0.d32 = dwc_otg_read_hprt0(core_if);
2614                         hprt0.b.prtpwr = 1;
2615                         DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
2616                         break;
2617                 case UHF_PORT_RESET:
2618                         if ((core_if->power_down == 2)
2619                             && (core_if->hibernation_suspend == 1)) {
2620                                 /* If we are going to exit from Hibernated
2621                                  * state via USB RESET.
2622                                  */
2623                                 dwc_otg_host_hibernation_restore(core_if, 0, 1);
2624                         } else {
2625                                 hprt0.d32 = dwc_otg_read_hprt0(core_if);
2626
2627                                 DWC_DEBUGPL(DBG_HCD,
2628                                             "DWC OTG HCD HUB CONTROL - "
2629                                             "SetPortFeature - USB_PORT_FEAT_RESET\n");
2630                                 {
2631                                         pcgcctl_data_t pcgcctl = {.d32 = 0 };
2632                                         pcgcctl.b.enbl_sleep_gating = 1;
2633                                         pcgcctl.b.stoppclk = 1;
2634                                         DWC_MODIFY_REG32(core_if->pcgcctl,
2635                                                          pcgcctl.d32, 0);
2636                                         DWC_WRITE_REG32(core_if->pcgcctl, 0);
2637                                 }
2638 #ifdef CONFIG_USB_DWC_OTG_LPM
2639                                 {
2640                                         glpmcfg_data_t lpmcfg;
2641                                         lpmcfg.d32 =
2642                                             DWC_READ_REG32(&core_if->
2643                                                            core_global_regs->
2644                                                            glpmcfg);
2645                                         if (lpmcfg.b.prt_sleep_sts) {
2646                                                 lpmcfg.b.en_utmi_sleep = 0;
2647                                                 lpmcfg.b.hird_thres &=
2648                                                     (~(1 << 4));
2649                                                 DWC_WRITE_REG32(&core_if->
2650                                                                 core_global_regs->
2651                                                                 glpmcfg,
2652                                                                 lpmcfg.d32);
2653                                                 dwc_mdelay(1);
2654                                         }
2655                                 }
2656 #endif
2657                                 hprt0.d32 = dwc_otg_read_hprt0(core_if);
2658                                 /* Clear suspend bit if resetting from suspended state. */
2659                                 hprt0.b.prtsusp = 0;
2660                                 /* When B-Host the Port reset bit is set in
2661                                  * the Start HCD Callback function, so that
2662                                  * the reset is started within 1ms of the HNP
2663                                  * success interrupt. */
2664                                 if (!dwc_otg_hcd_is_b_host(dwc_otg_hcd)) {
2665                                         hprt0.b.prtpwr = 1;
2666                                         hprt0.b.prtrst = 1;
2667                                         DWC_PRINTF
2668                                             ("Indeed it is in host mode hprt0 = %08x\n",
2669                                              hprt0.d32);
2670                                         DWC_WRITE_REG32(core_if->host_if->hprt0,
2671                                                         hprt0.d32);
2672                                 }
2673                                 /* Clear reset bit in 10ms (FS/LS) or 50ms (HS) */
2674                                 dwc_mdelay(60);
2675                                 hprt0.b.prtrst = 0;
2676                                 DWC_WRITE_REG32(core_if->host_if->hprt0,
2677                                                 hprt0.d32);
2678                                 core_if->lx_state = DWC_OTG_L0; /* Now back to the on state */
2679                         }
2680                         break;
2681 #ifdef DWC_HS_ELECT_TST
2682                 case UHF_PORT_TEST:
2683                         {
2684                                 uint32_t t;
2685                                 gintmsk_data_t gintmsk;
2686
2687                                 t = (wIndex >> 8);      /* MSB wIndex USB */
2688                                 DWC_DEBUGPL(DBG_HCD,
2689                                             "DWC OTG HCD HUB CONTROL - "
2690                                             "SetPortFeature - USB_PORT_FEAT_TEST %d\n",
2691                                             t);
2692                                 DWC_WARN("USB_PORT_FEAT_TEST %d\n", t);
2693                                 if (t < 6) {
2694                                         hprt0.d32 = dwc_otg_read_hprt0(core_if);
2695                                         hprt0.b.prttstctl = t;
2696                                         DWC_WRITE_REG32(core_if->host_if->hprt0,
2697                                                         hprt0.d32);
2698                                 } else {
2699                                         /* Setup global vars with reg addresses (quick and
2700                                          * dirty hack, should be cleaned up)
2701                                          */
2702                                         global_regs = core_if->core_global_regs;
2703                                         hc_global_regs =
2704                                             core_if->host_if->host_global_regs;
2705                                         hc_regs =
2706                                             (dwc_otg_hc_regs_t *) ((char *)
2707                                                                    global_regs +
2708                                                                    0x500);
2709                                         data_fifo =
2710                                             (uint32_t *) ((char *)global_regs +
2711                                                           0x1000);
2712
2713                                         if (t == 6) {   /* HS_HOST_PORT_SUSPEND_RESUME */
2714                                                 /* Save current interrupt mask */
2715                                                 gintmsk.d32 =
2716                                                     DWC_READ_REG32
2717                                                     (&global_regs->gintmsk);
2718
2719                                                 /* Disable all interrupts while we muck with
2720                                                  * the hardware directly
2721                                                  */
2722                                                 DWC_WRITE_REG32(&global_regs->
2723                                                                 gintmsk, 0);
2724
2725                                                 /* 15 second delay per the test spec */
2726                                                 dwc_mdelay(15000);
2727
2728                                                 /* Drive suspend on the root port */
2729                                                 hprt0.d32 =
2730                                                     dwc_otg_read_hprt0(core_if);
2731                                                 hprt0.b.prtsusp = 1;
2732                                                 hprt0.b.prtres = 0;
2733                                                 DWC_WRITE_REG32(core_if->
2734                                                                 host_if->hprt0,
2735                                                                 hprt0.d32);
2736
2737                                                 /* 15 second delay per the test spec */
2738                                                 dwc_mdelay(15000);
2739
2740                                                 /* Drive resume on the root port */
2741                                                 hprt0.d32 =
2742                                                     dwc_otg_read_hprt0(core_if);
2743                                                 hprt0.b.prtsusp = 0;
2744                                                 hprt0.b.prtres = 1;
2745                                                 DWC_WRITE_REG32(core_if->
2746                                                                 host_if->hprt0,
2747                                                                 hprt0.d32);
2748                                                 dwc_mdelay(100);
2749
2750                                                 /* Clear the resume bit */
2751                                                 hprt0.b.prtres = 0;
2752                                                 DWC_WRITE_REG32(core_if->
2753                                                                 host_if->hprt0,
2754                                                                 hprt0.d32);
2755
2756                                                 /* Restore interrupts */
2757                                                 DWC_WRITE_REG32(&global_regs->
2758                                                                 gintmsk,
2759                                                                 gintmsk.d32);
2760                                         } else if (t == 7) {    /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR setup */
2761                                                 /* Save current interrupt mask */
2762                                                 gintmsk.d32 =
2763                                                     DWC_READ_REG32
2764                                                     (&global_regs->gintmsk);
2765
2766                                                 /* Disable all interrupts while we muck with
2767                                                  * the hardware directly
2768                                                  */
2769                                                 DWC_WRITE_REG32(&global_regs->
2770                                                                 gintmsk, 0);
2771
2772                                                 /* 15 second delay per the test spec */
2773                                                 dwc_mdelay(15000);
2774
2775                                                 /* Send the Setup packet */
2776                                                 do_setup();
2777
2778                                                 /* 15 second delay so nothing else happens for awhile */
2779                                                 dwc_mdelay(15000);
2780
2781                                                 /* Restore interrupts */
2782                                                 DWC_WRITE_REG32(&global_regs->
2783                                                                 gintmsk,
2784                                                                 gintmsk.d32);
2785                                         } else if (t == 8) {    /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR execute */
2786                                                 /* Save current interrupt mask */
2787                                                 gintmsk.d32 =
2788                                                     DWC_READ_REG32
2789                                                     (&global_regs->gintmsk);
2790
2791                                                 /* Disable all interrupts while we muck with
2792                                                  * the hardware directly
2793                                                  */
2794                                                 DWC_WRITE_REG32(&global_regs->
2795                                                                 gintmsk, 0);
2796
2797                                                 /* Send the Setup packet */
2798                                                 do_setup();
2799
2800                                                 /* 15 second delay so nothing else happens for awhile */
2801                                                 dwc_mdelay(15000);
2802
2803                                                 /* Send the In and Ack packets */
2804                                                 do_in_ack();
2805
2806                                                 /* 15 second delay so nothing else happens for awhile */
2807                                                 dwc_mdelay(15000);
2808
2809                                                 /* Restore interrupts */
2810                                                 DWC_WRITE_REG32(&global_regs->
2811                                                                 gintmsk,
2812                                                                 gintmsk.d32);
2813                                         }
2814                                 }
2815                                 break;
2816                         }
2817 #endif /* DWC_HS_ELECT_TST */
2818
2819                 case UHF_PORT_INDICATOR:
2820                         DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
2821                                     "SetPortFeature - USB_PORT_FEAT_INDICATOR\n");
2822                         /* Not supported */
2823                         break;
2824                 default:
2825                         retval = -DWC_E_INVALID;
2826                         DWC_ERROR("DWC OTG HCD - "
2827                                   "SetPortFeature request %xh "
2828                                   "unknown or unsupported\n", wValue);
2829                         break;
2830                 }
2831                 break;
2832 #ifdef CONFIG_USB_DWC_OTG_LPM
2833         case UCR_SET_AND_TEST_PORT_FEATURE:
2834                 if (wValue != UHF_PORT_L1) {
2835                         goto error;
2836                 }
2837                 {
2838                         int portnum, hird, devaddr, remwake;
2839                         glpmcfg_data_t lpmcfg;
2840                         uint32_t time_usecs;
2841                         gintsts_data_t gintsts;
2842                         gintmsk_data_t gintmsk;
2843
2844                         if (!dwc_otg_get_param_lpm_enable(core_if)) {
2845                                 goto error;
2846                         }
2847                         if (wValue != UHF_PORT_L1 || wLength != 1) {
2848                                 goto error;
2849                         }
2850                         /* Check if the port currently is in SLEEP state */
2851                         lpmcfg.d32 =
2852                             DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
2853                         if (lpmcfg.b.prt_sleep_sts) {
2854                                 DWC_INFO("Port is already in sleep mode\n");
2855                                 buf[0] = 0;     /* Return success */
2856                                 break;
2857                         }
2858
2859                         portnum = wIndex & 0xf;
2860                         hird = (wIndex >> 4) & 0xf;
2861                         devaddr = (wIndex >> 8) & 0x7f;
2862                         remwake = (wIndex >> 15);
2863
2864                         if (portnum != 1) {
2865                                 retval = -DWC_E_INVALID;
2866                                 DWC_WARN
2867                                     ("Wrong port number(%d) in SetandTestPortFeature request\n",
2868                                      portnum);
2869                                 break;
2870                         }
2871
2872                         DWC_PRINTF
2873                             ("SetandTestPortFeature request: portnum = %d, hird = %d, devaddr = %d, rewake = %d\n",
2874                              portnum, hird, devaddr, remwake);
2875                         /* Disable LPM interrupt */
2876                         gintmsk.d32 = 0;
2877                         gintmsk.b.lpmtranrcvd = 1;
2878                         DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk,
2879                                          gintmsk.d32, 0);
2880
2881                         if (dwc_otg_hcd_send_lpm
2882                             (dwc_otg_hcd, devaddr, hird, remwake)) {
2883                                 retval = -DWC_E_INVALID;
2884                                 break;
2885                         }
2886
2887                         time_usecs = 10 * (lpmcfg.b.retry_count + 1);
2888                         /* We will consider timeout if time_usecs microseconds pass,
2889                          * and we don't receive LPM transaction status.
2890                          * After receiving non-error responce(ACK/NYET/STALL) from device,
2891                          *  core will set lpmtranrcvd bit.
2892                          */
2893                         do {
2894                                 gintsts.d32 =
2895                                     DWC_READ_REG32(&core_if->core_global_regs->
2896                                                    gintsts);
2897                                 if (gintsts.b.lpmtranrcvd) {
2898                                         break;
2899                                 }
2900                                 dwc_udelay(1);
2901                         } while (--time_usecs);
2902                         /* lpm_int bit will be cleared in LPM interrupt handler */
2903
2904                         /* Now fill status
2905                          * 0x00 - Success
2906                          * 0x10 - NYET
2907                          * 0x11 - Timeout
2908                          */
2909                         if (!gintsts.b.lpmtranrcvd) {
2910                                 buf[0] = 0x3;   /* Completion code is Timeout */
2911                                 dwc_otg_hcd_free_hc_from_lpm(dwc_otg_hcd);
2912                         } else {
2913                                 lpmcfg.d32 =
2914                                     DWC_READ_REG32(&core_if->core_global_regs->
2915                                                    glpmcfg);
2916                                 if (lpmcfg.b.lpm_resp == 0x3) {
2917                                         /* ACK responce from the device */
2918                                         buf[0] = 0x00;  /* Success */
2919                                 } else if (lpmcfg.b.lpm_resp == 0x2) {
2920                                         /* NYET responce from the device */
2921                                         buf[0] = 0x2;
2922                                 } else {
2923                                         /* Otherwise responce with Timeout */
2924                                         buf[0] = 0x3;
2925                                 }
2926                         }
2927                         DWC_PRINTF("Device responce to LPM trans is %x\n",
2928                                    lpmcfg.b.lpm_resp);
2929                         DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, 0,
2930                                          gintmsk.d32);
2931
2932                         break;
2933                 }
2934 #endif /* CONFIG_USB_DWC_OTG_LPM */
2935         default:
2936 error:
2937                 retval = -DWC_E_INVALID;
2938                 DWC_WARN("DWC OTG HCD - "
2939                          "Unknown hub control request type or invalid typeReq: %xh wIndex: %xh wValue: %xh\n",
2940                          typeReq, wIndex, wValue);
2941                 break;
2942         }
2943
2944         return retval;
2945 }
2946
2947 #ifdef CONFIG_USB_DWC_OTG_LPM
2948 /** Returns index of host channel to perform LPM transaction. */
2949 int dwc_otg_hcd_get_hc_for_lpm_tran(dwc_otg_hcd_t *hcd, uint8_t devaddr)
2950 {
2951         dwc_otg_core_if_t *core_if = hcd->core_if;
2952         dwc_hc_t *hc;
2953         hcchar_data_t hcchar;
2954         gintmsk_data_t gintmsk = {.d32 = 0 };
2955
2956         if (DWC_CIRCLEQ_EMPTY(&hcd->free_hc_list)) {
2957                 DWC_PRINTF("No free channel to select for LPM transaction\n");
2958                 return -1;
2959         }
2960
2961         hc = DWC_CIRCLEQ_FIRST(&hcd->free_hc_list);
2962
2963         /* Mask host channel interrupts. */
2964         gintmsk.b.hcintr = 1;
2965         DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, gintmsk.d32, 0);
2966
2967         /* Fill fields that core needs for LPM transaction */
2968         hcchar.b.devaddr = devaddr;
2969         hcchar.b.epnum = 0;
2970         hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;
2971         hcchar.b.mps = 64;
2972         hcchar.b.lspddev = (hc->speed == DWC_OTG_EP_SPEED_LOW);
2973         hcchar.b.epdir = 0;     /* OUT */
2974         DWC_WRITE_REG32(&core_if->host_if->hc_regs[hc->hc_num]->hcchar,
2975                         hcchar.d32);
2976
2977         /* Remove the host channel from the free list. */
2978         DWC_CIRCLEQ_REMOVE_INIT(&hcd->free_hc_list, hc, hc_list_entry);
2979
2980         DWC_PRINTF("hcnum = %d devaddr = %d\n", hc->hc_num, devaddr);
2981
2982         return hc->hc_num;
2983 }
2984
2985 /** Release hc after performing LPM transaction */
2986 void dwc_otg_hcd_free_hc_from_lpm(dwc_otg_hcd_t *hcd)
2987 {
2988         dwc_hc_t *hc;
2989         glpmcfg_data_t lpmcfg;
2990         uint8_t hc_num;
2991
2992         lpmcfg.d32 = DWC_READ_REG32(&hcd->core_if->core_global_regs->glpmcfg);
2993         hc_num = lpmcfg.b.lpm_chan_index;
2994
2995         hc = hcd->hc_ptr_array[hc_num];
2996
2997         DWC_PRINTF("Freeing channel %d after LPM\n", hc_num);
2998         /* Return host channel to free list */
2999         DWC_CIRCLEQ_INSERT_TAIL(&hcd->free_hc_list, hc, hc_list_entry);
3000 }
3001
3002 int dwc_otg_hcd_send_lpm(dwc_otg_hcd_t *hcd, uint8_t devaddr, uint8_t hird,
3003                          uint8_t bRemoteWake)
3004 {
3005         glpmcfg_data_t lpmcfg;
3006         pcgcctl_data_t pcgcctl = {.d32 = 0 };
3007         int channel;
3008
3009         channel = dwc_otg_hcd_get_hc_for_lpm_tran(hcd, devaddr);
3010         if (channel < 0) {
3011                 return channel;
3012         }
3013
3014         pcgcctl.b.enbl_sleep_gating = 1;
3015         DWC_MODIFY_REG32(hcd->core_if->pcgcctl, 0, pcgcctl.d32);
3016
3017         /* Read LPM config register */
3018         lpmcfg.d32 = DWC_READ_REG32(&hcd->core_if->core_global_regs->glpmcfg);
3019
3020         /* Program LPM transaction fields */
3021         lpmcfg.b.rem_wkup_en = bRemoteWake;
3022         lpmcfg.b.hird = hird;
3023
3024         if (dwc_otg_get_param_besl_enable(hcd->core_if)) {
3025                 lpmcfg.b.hird_thres = 0x16;
3026                 lpmcfg.b.en_besl = 1;
3027         } else {
3028                 lpmcfg.b.hird_thres = 0x1c;
3029         }
3030
3031         lpmcfg.b.lpm_chan_index = channel;
3032         lpmcfg.b.en_utmi_sleep = 1;
3033         /* Program LPM config register */
3034         DWC_WRITE_REG32(&hcd->core_if->core_global_regs->glpmcfg, lpmcfg.d32);
3035
3036         /* Send LPM transaction */
3037         lpmcfg.b.send_lpm = 1;
3038         DWC_WRITE_REG32(&hcd->core_if->core_global_regs->glpmcfg, lpmcfg.d32);
3039
3040         return 0;
3041 }
3042
3043 #endif /* CONFIG_USB_DWC_OTG_LPM */
3044
3045 int dwc_otg_hcd_is_status_changed(dwc_otg_hcd_t *hcd, int port)
3046 {
3047         int retval;
3048
3049         if (port != 1) {
3050                 return -DWC_E_INVALID;
3051         }
3052
3053         retval = (hcd->flags.b.port_connect_status_change ||
3054                   hcd->flags.b.port_reset_change ||
3055                   hcd->flags.b.port_enable_change ||
3056                   hcd->flags.b.port_suspend_change ||
3057                   hcd->flags.b.port_over_current_change);
3058 #ifdef DEBUG
3059         if (retval) {
3060                 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB STATUS DATA:"
3061                             " Root port status changed\n");
3062                 DWC_DEBUGPL(DBG_HCDV, "  port_connect_status_change: %d\n",
3063                             hcd->flags.b.port_connect_status_change);
3064                 DWC_DEBUGPL(DBG_HCDV, "  port_reset_change: %d\n",
3065                             hcd->flags.b.port_reset_change);
3066                 DWC_DEBUGPL(DBG_HCDV, "  port_enable_change: %d\n",
3067                             hcd->flags.b.port_enable_change);
3068                 DWC_DEBUGPL(DBG_HCDV, "  port_suspend_change: %d\n",
3069                             hcd->flags.b.port_suspend_change);
3070                 DWC_DEBUGPL(DBG_HCDV, "  port_over_current_change: %d\n",
3071                             hcd->flags.b.port_over_current_change);
3072         }
3073 #endif
3074         return retval;
3075 }
3076
3077 int dwc_otg_hcd_get_frame_number(dwc_otg_hcd_t *dwc_otg_hcd)
3078 {
3079         hfnum_data_t hfnum;
3080         hfnum.d32 =
3081             DWC_READ_REG32(&dwc_otg_hcd->core_if->host_if->
3082                            host_global_regs->hfnum);
3083
3084 #ifdef DEBUG_SOF
3085         DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD GET FRAME NUMBER %d\n",
3086                     hfnum.b.frnum);
3087 #endif
3088         return hfnum.b.frnum;
3089 }
3090
3091 int dwc_otg_hcd_start(dwc_otg_hcd_t *hcd,
3092                       struct dwc_otg_hcd_function_ops *fops)
3093 {
3094         int retval = 0;
3095
3096         hcd->fops = fops;
3097         if (!dwc_otg_is_device_mode(hcd->core_if) &&
3098             (!hcd->core_if->adp_enable || hcd->core_if->adp.adp_started)) {
3099                 dwc_otg_hcd_reinit(hcd);
3100         } else {
3101                 retval = -DWC_E_NO_DEVICE;
3102         }
3103
3104         return retval;
3105 }
3106
3107 void *dwc_otg_hcd_get_priv_data(dwc_otg_hcd_t *hcd)
3108 {
3109         return hcd->priv;
3110 }
3111
3112 void dwc_otg_hcd_set_priv_data(dwc_otg_hcd_t *hcd, void *priv_data)
3113 {
3114         hcd->priv = priv_data;
3115 }
3116
3117 uint32_t dwc_otg_hcd_otg_port(dwc_otg_hcd_t *hcd)
3118 {
3119         return hcd->otg_port;
3120 }
3121
3122 uint32_t dwc_otg_hcd_is_b_host(dwc_otg_hcd_t *hcd)
3123 {
3124         uint32_t is_b_host;
3125         if (hcd->core_if->op_state == B_HOST) {
3126                 is_b_host = 1;
3127         } else {
3128                 is_b_host = 0;
3129         }
3130
3131         return is_b_host;
3132 }
3133
3134 dwc_otg_hcd_urb_t *dwc_otg_hcd_urb_alloc(dwc_otg_hcd_t *hcd,
3135                                          int iso_desc_count, int atomic_alloc)
3136 {
3137         dwc_otg_hcd_urb_t *dwc_otg_urb;
3138         uint32_t size;
3139
3140         size =
3141             sizeof(*dwc_otg_urb) +
3142             iso_desc_count * sizeof(struct dwc_otg_hcd_iso_packet_desc);
3143         if (atomic_alloc)
3144                 dwc_otg_urb = DWC_ALLOC_ATOMIC(size);
3145         else
3146                 dwc_otg_urb = DWC_ALLOC(size);
3147
3148         dwc_otg_urb->packet_count = iso_desc_count;
3149
3150         return dwc_otg_urb;
3151 }
3152
3153 void dwc_otg_hcd_urb_set_pipeinfo(dwc_otg_hcd_urb_t *dwc_otg_urb,
3154                                   uint8_t dev_addr, uint8_t ep_num,
3155                                   uint8_t ep_type, uint8_t ep_dir, uint16_t mps)
3156 {
3157         dwc_otg_hcd_fill_pipe(&dwc_otg_urb->pipe_info, dev_addr, ep_num,
3158                               ep_type, ep_dir, mps);
3159 #if 0
3160         DWC_PRINTF
3161             ("addr = %d, ep_num = %d, ep_dir = 0x%x, ep_type = 0x%x, mps = %d\n",
3162              dev_addr, ep_num, ep_dir, ep_type, mps);
3163 #endif
3164 }
3165
3166 void dwc_otg_hcd_urb_set_params(dwc_otg_hcd_urb_t *dwc_otg_urb,
3167                                 void *urb_handle, void *buf, dwc_dma_t dma,
3168                                 uint32_t buflen, void *setup_packet,
3169                                 dwc_dma_t setup_dma, uint32_t flags,
3170                                 uint16_t interval)
3171 {
3172         dwc_otg_urb->priv = urb_handle;
3173         dwc_otg_urb->buf = buf;
3174         dwc_otg_urb->dma = dma;
3175         dwc_otg_urb->length = buflen;
3176         dwc_otg_urb->setup_packet = setup_packet;
3177         dwc_otg_urb->setup_dma = setup_dma;
3178         dwc_otg_urb->flags = flags;
3179         dwc_otg_urb->interval = interval;
3180         dwc_otg_urb->status = -DWC_E_IN_PROGRESS;
3181 }
3182
3183 uint32_t dwc_otg_hcd_urb_get_status(dwc_otg_hcd_urb_t *dwc_otg_urb)
3184 {
3185         return dwc_otg_urb->status;
3186 }
3187
3188 uint32_t dwc_otg_hcd_urb_get_actual_length(dwc_otg_hcd_urb_t *dwc_otg_urb)
3189 {
3190         return dwc_otg_urb->actual_length;
3191 }
3192
3193 uint32_t dwc_otg_hcd_urb_get_error_count(dwc_otg_hcd_urb_t *dwc_otg_urb)
3194 {
3195         return dwc_otg_urb->error_count;
3196 }
3197
3198 void dwc_otg_hcd_urb_set_iso_desc_params(dwc_otg_hcd_urb_t *dwc_otg_urb,
3199                                          int desc_num, uint32_t offset,
3200                                          uint32_t length)
3201 {
3202         dwc_otg_urb->iso_descs[desc_num].offset = offset;
3203         dwc_otg_urb->iso_descs[desc_num].length = length;
3204 }
3205
3206 uint32_t dwc_otg_hcd_urb_get_iso_desc_status(dwc_otg_hcd_urb_t *dwc_otg_urb,
3207                                              int desc_num)
3208 {
3209         return dwc_otg_urb->iso_descs[desc_num].status;
3210 }
3211
3212 uint32_t dwc_otg_hcd_urb_get_iso_desc_actual_length(dwc_otg_hcd_urb_t *
3213                                                     dwc_otg_urb, int desc_num)
3214 {
3215         return dwc_otg_urb->iso_descs[desc_num].actual_length;
3216 }
3217
3218 int dwc_otg_hcd_is_bandwidth_allocated(dwc_otg_hcd_t *hcd, void *ep_handle)
3219 {
3220         int allocated = 0;
3221         dwc_otg_qh_t *qh = (dwc_otg_qh_t *) ep_handle;
3222
3223         if (qh) {
3224                 if (!DWC_LIST_EMPTY(&qh->qh_list_entry)) {
3225                         allocated = 1;
3226                 }
3227         }
3228         return allocated;
3229 }
3230
3231 int dwc_otg_hcd_is_bandwidth_freed(dwc_otg_hcd_t *hcd, void *ep_handle)
3232 {
3233         dwc_otg_qh_t *qh = (dwc_otg_qh_t *) ep_handle;
3234         int freed = 0;
3235         DWC_ASSERT(qh, "qh is not allocated\n");
3236
3237         if (DWC_LIST_EMPTY(&qh->qh_list_entry)) {
3238                 freed = 1;
3239         }
3240
3241         return freed;
3242 }
3243
3244 uint8_t dwc_otg_hcd_get_ep_bandwidth(dwc_otg_hcd_t *hcd, void *ep_handle)
3245 {
3246         dwc_otg_qh_t *qh = (dwc_otg_qh_t *) ep_handle;
3247         DWC_ASSERT(qh, "qh is not allocated\n");
3248         return qh->usecs;
3249 }
3250
3251 void dwc_otg_hcd_dump_state(dwc_otg_hcd_t *hcd)
3252 {
3253 #ifdef DEBUG
3254         int num_channels;
3255         int i;
3256         gnptxsts_data_t np_tx_status;
3257         hptxsts_data_t p_tx_status;
3258
3259         num_channels = hcd->core_if->core_params->host_channels;
3260         DWC_PRINTF("\n");
3261         DWC_PRINTF
3262             ("************************************************************\n");
3263         DWC_PRINTF("HCD State:\n");
3264         DWC_PRINTF("  Num channels: %d\n", num_channels);
3265         for (i = 0; i < num_channels; i++) {
3266                 dwc_hc_t *hc = hcd->hc_ptr_array[i];
3267                 DWC_PRINTF("  Channel %d:\n", i);
3268                 DWC_PRINTF("    dev_addr: %d, ep_num: %d, ep_is_in: %d\n",
3269                            hc->dev_addr, hc->ep_num, hc->ep_is_in);
3270                 DWC_PRINTF("    speed: %d\n", hc->speed);
3271                 DWC_PRINTF("    ep_type: %d\n", hc->ep_type);
3272                 DWC_PRINTF("    max_packet: %d\n", hc->max_packet);
3273                 DWC_PRINTF("    data_pid_start: %d\n", hc->data_pid_start);
3274                 DWC_PRINTF("    multi_count: %d\n", hc->multi_count);
3275                 DWC_PRINTF("    xfer_started: %d\n", hc->xfer_started);
3276                 DWC_PRINTF("    xfer_buff: %p\n", hc->xfer_buff);
3277                 DWC_PRINTF("    xfer_len: %d\n", hc->xfer_len);
3278                 DWC_PRINTF("    xfer_count: %d\n", hc->xfer_count);
3279                 DWC_PRINTF("    halt_on_queue: %d\n", hc->halt_on_queue);
3280                 DWC_PRINTF("    halt_pending: %d\n", hc->halt_pending);
3281                 DWC_PRINTF("    halt_status: %d\n", hc->halt_status);
3282                 DWC_PRINTF("    do_split: %d\n", hc->do_split);
3283                 DWC_PRINTF("    complete_split: %d\n", hc->complete_split);
3284                 DWC_PRINTF("    hub_addr: %d\n", hc->hub_addr);
3285                 DWC_PRINTF("    port_addr: %d\n", hc->port_addr);
3286                 DWC_PRINTF("    xact_pos: %d\n", hc->xact_pos);
3287                 DWC_PRINTF("    requests: %d\n", hc->requests);
3288                 DWC_PRINTF("    qh: %p\n", hc->qh);
3289                 if (hc->xfer_started) {
3290                         hfnum_data_t hfnum;
3291                         hcchar_data_t hcchar;
3292                         hctsiz_data_t hctsiz;
3293                         hcint_data_t hcint;
3294                         hcintmsk_data_t hcintmsk;
3295                         hfnum.d32 =
3296                             DWC_READ_REG32(&hcd->core_if->host_if->
3297                                            host_global_regs->hfnum);
3298                         hcchar.d32 =
3299                             DWC_READ_REG32(&hcd->core_if->host_if->hc_regs[i]->
3300                                            hcchar);
3301                         hctsiz.d32 =
3302                             DWC_READ_REG32(&hcd->core_if->host_if->hc_regs[i]->
3303                                            hctsiz);
3304                         hcint.d32 =
3305                             DWC_READ_REG32(&hcd->core_if->host_if->hc_regs[i]->
3306                                            hcint);
3307                         hcintmsk.d32 =
3308                             DWC_READ_REG32(&hcd->core_if->host_if->hc_regs[i]->
3309                                            hcintmsk);
3310                         DWC_PRINTF("    hfnum: 0x%08x\n", hfnum.d32);
3311                         DWC_PRINTF("    hcchar: 0x%08x\n", hcchar.d32);
3312                         DWC_PRINTF("    hctsiz: 0x%08x\n", hctsiz.d32);
3313                         DWC_PRINTF("    hcint: 0x%08x\n", hcint.d32);
3314                         DWC_PRINTF("    hcintmsk: 0x%08x\n", hcintmsk.d32);
3315                 }
3316                 if (hc->xfer_started && hc->qh) {
3317                         dwc_otg_qtd_t *qtd;
3318                         dwc_otg_hcd_urb_t *urb;
3319
3320                         DWC_CIRCLEQ_FOREACH(qtd, &hc->qh->qtd_list,
3321                                             qtd_list_entry) {
3322                                 if (!qtd->in_process)
3323                                         break;
3324
3325                                 urb = qtd->urb;
3326                                 DWC_PRINTF("    URB Info:\n");
3327                                 DWC_PRINTF("      qtd: %p, urb: %p\n", qtd,
3328                                            urb);
3329                                 if (urb) {
3330                                         DWC_PRINTF("      Dev: %d, EP: %d %s\n",
3331                                                    dwc_otg_hcd_get_dev_addr
3332                                                    (&urb->pipe_info),
3333                                                    dwc_otg_hcd_get_ep_num
3334                                                    (&urb->pipe_info),
3335                                                    dwc_otg_hcd_is_pipe_in
3336                                                    (&urb->pipe_info) ? "IN" :
3337                                                    "OUT");
3338                                         DWC_PRINTF
3339                                             ("      Max packet size: %d\n",
3340                                              dwc_otg_hcd_get_mps
3341                                              (&urb->pipe_info));
3342                                         DWC_PRINTF
3343                                             ("      transfer_buffer: %p\n",
3344                                              urb->buf);
3345                                         DWC_PRINTF("      transfer_dma: %p\n",
3346                                                    (void *)urb->dma);
3347                                         DWC_PRINTF
3348                                             ("      transfer_buffer_length: %d\n",
3349                                              urb->length);
3350                                         DWC_PRINTF("      actual_length: %d\n",
3351                                                    urb->actual_length);
3352                                 }
3353                         }
3354                 }
3355         }
3356         DWC_PRINTF("  non_periodic_channels: %d\n", hcd->non_periodic_channels);
3357         DWC_PRINTF("  periodic_channels: %d\n", hcd->periodic_channels);
3358         DWC_PRINTF("  periodic_usecs: %d\n", hcd->periodic_usecs);
3359         np_tx_status.d32 =
3360             DWC_READ_REG32(&hcd->core_if->core_global_regs->gnptxsts);
3361         DWC_PRINTF("  NP Tx Req Queue Space Avail: %d\n",
3362                    np_tx_status.b.nptxqspcavail);
3363         DWC_PRINTF("  NP Tx FIFO Space Avail: %d\n",
3364                    np_tx_status.b.nptxfspcavail);
3365         p_tx_status.d32 =
3366             DWC_READ_REG32(&hcd->core_if->host_if->host_global_regs->hptxsts);
3367         DWC_PRINTF("  P Tx Req Queue Space Avail: %d\n",
3368                    p_tx_status.b.ptxqspcavail);
3369         DWC_PRINTF("  P Tx FIFO Space Avail: %d\n", p_tx_status.b.ptxfspcavail);
3370         dwc_otg_hcd_dump_frrem(hcd);
3371         dwc_otg_dump_global_registers(hcd->core_if);
3372         dwc_otg_dump_host_registers(hcd->core_if);
3373         DWC_PRINTF
3374             ("************************************************************\n");
3375         DWC_PRINTF("\n");
3376 #endif
3377 }
3378
3379 #ifdef DEBUG
3380 void dwc_print_setup_data(uint8_t *setup)
3381 {
3382         int i;
3383         if (CHK_DEBUG_LEVEL(DBG_HCD)) {
3384                 DWC_PRINTF("Setup Data = MSB ");
3385                 for (i = 7; i >= 0; i--)
3386                         DWC_PRINTF("%02x ", setup[i]);
3387                 DWC_PRINTF("\n");
3388                 DWC_PRINTF("  bmRequestType Tranfer = %s\n",
3389                            (setup[0] & 0x80) ? "Device-to-Host" :
3390                            "Host-to-Device");
3391                 DWC_PRINTF("  bmRequestType Type = ");
3392                 switch ((setup[0] & 0x60) >> 5) {
3393                 case 0:
3394                         DWC_PRINTF("Standard\n");
3395                         break;
3396                 case 1:
3397                         DWC_PRINTF("Class\n");
3398                         break;
3399                 case 2:
3400                         DWC_PRINTF("Vendor\n");
3401                         break;
3402                 case 3:
3403                         DWC_PRINTF("Reserved\n");
3404                         break;
3405                 }
3406                 DWC_PRINTF("  bmRequestType Recipient = ");
3407                 switch (setup[0] & 0x1f) {
3408                 case 0:
3409                         DWC_PRINTF("Device\n");
3410                         break;
3411                 case 1:
3412                         DWC_PRINTF("Interface\n");
3413                         break;
3414                 case 2:
3415                         DWC_PRINTF("Endpoint\n");
3416                         break;
3417                 case 3:
3418                         DWC_PRINTF("Other\n");
3419                         break;
3420                 default:
3421                         DWC_PRINTF("Reserved\n");
3422                         break;
3423                 }
3424                 DWC_PRINTF("  bRequest = 0x%0x\n", setup[1]);
3425                 DWC_PRINTF("  wValue = 0x%0x\n", *((uint16_t *)&setup[2]));
3426                 DWC_PRINTF("  wIndex = 0x%0x\n", *((uint16_t *)&setup[4]));
3427                 DWC_PRINTF("  wLength = 0x%0x\n\n", *((uint16_t *)&setup[6]));
3428         }
3429 }
3430 #endif
3431
3432 void dwc_otg_hcd_dump_frrem(dwc_otg_hcd_t *hcd)
3433 {
3434 #if 0
3435         DWC_PRINTF("Frame remaining at SOF:\n");
3436         DWC_PRINTF("  samples %u, accum %llu, avg %llu\n",
3437                    hcd->frrem_samples, hcd->frrem_accum,
3438                    (hcd->frrem_samples > 0) ?
3439                    hcd->frrem_accum / hcd->frrem_samples : 0);
3440
3441         DWC_PRINTF("\n");
3442         DWC_PRINTF("Frame remaining at start_transfer (uframe 7):\n");
3443         DWC_PRINTF("  samples %u, accum %llu, avg %llu\n",
3444                    hcd->core_if->hfnum_7_samples,
3445                    hcd->core_if->hfnum_7_frrem_accum,
3446                    (hcd->core_if->hfnum_7_samples >
3447                     0) ? hcd->core_if->hfnum_7_frrem_accum /
3448                    hcd->core_if->hfnum_7_samples : 0);
3449         DWC_PRINTF("Frame remaining at start_transfer (uframe 0):\n");
3450         DWC_PRINTF("  samples %u, accum %llu, avg %llu\n",
3451                    hcd->core_if->hfnum_0_samples,
3452                    hcd->core_if->hfnum_0_frrem_accum,
3453                    (hcd->core_if->hfnum_0_samples >
3454                     0) ? hcd->core_if->hfnum_0_frrem_accum /
3455                    hcd->core_if->hfnum_0_samples : 0);
3456         DWC_PRINTF("Frame remaining at start_transfer (uframe 1-6):\n");
3457         DWC_PRINTF("  samples %u, accum %llu, avg %llu\n",
3458                    hcd->core_if->hfnum_other_samples,
3459                    hcd->core_if->hfnum_other_frrem_accum,
3460                    (hcd->core_if->hfnum_other_samples >
3461                     0) ? hcd->core_if->hfnum_other_frrem_accum /
3462                    hcd->core_if->hfnum_other_samples : 0);
3463
3464         DWC_PRINTF("\n");
3465         DWC_PRINTF("Frame remaining at sample point A (uframe 7):\n");
3466         DWC_PRINTF("  samples %u, accum %llu, avg %llu\n",
3467                    hcd->hfnum_7_samples_a, hcd->hfnum_7_frrem_accum_a,
3468                    (hcd->hfnum_7_samples_a > 0) ?
3469                    hcd->hfnum_7_frrem_accum_a / hcd->hfnum_7_samples_a : 0);
3470         DWC_PRINTF("Frame remaining at sample point A (uframe 0):\n");
3471         DWC_PRINTF("  samples %u, accum %llu, avg %llu\n",
3472                    hcd->hfnum_0_samples_a, hcd->hfnum_0_frrem_accum_a,
3473                    (hcd->hfnum_0_samples_a > 0) ?
3474                    hcd->hfnum_0_frrem_accum_a / hcd->hfnum_0_samples_a : 0);
3475         DWC_PRINTF("Frame remaining at sample point A (uframe 1-6):\n");
3476         DWC_PRINTF("  samples %u, accum %llu, avg %llu\n",
3477                    hcd->hfnum_other_samples_a, hcd->hfnum_other_frrem_accum_a,
3478                    (hcd->hfnum_other_samples_a > 0) ?
3479                    hcd->hfnum_other_frrem_accum_a /
3480                    hcd->hfnum_other_samples_a : 0);
3481
3482         DWC_PRINTF("\n");
3483         DWC_PRINTF("Frame remaining at sample point B (uframe 7):\n");
3484         DWC_PRINTF("  samples %u, accum %llu, avg %llu\n",
3485                    hcd->hfnum_7_samples_b, hcd->hfnum_7_frrem_accum_b,
3486                    (hcd->hfnum_7_samples_b > 0) ?
3487                    hcd->hfnum_7_frrem_accum_b / hcd->hfnum_7_samples_b : 0);
3488         DWC_PRINTF("Frame remaining at sample point B (uframe 0):\n");
3489         DWC_PRINTF("  samples %u, accum %llu, avg %llu\n",
3490                    hcd->hfnum_0_samples_b, hcd->hfnum_0_frrem_accum_b,
3491                    (hcd->hfnum_0_samples_b > 0) ?
3492                    hcd->hfnum_0_frrem_accum_b / hcd->hfnum_0_samples_b : 0);
3493         DWC_PRINTF("Frame remaining at sample point B (uframe 1-6):\n");
3494         DWC_PRINTF("  samples %u, accum %llu, avg %llu\n",
3495                    hcd->hfnum_other_samples_b, hcd->hfnum_other_frrem_accum_b,
3496                    (hcd->hfnum_other_samples_b > 0) ?
3497                    hcd->hfnum_other_frrem_accum_b /
3498                    hcd->hfnum_other_samples_b : 0);
3499 #endif
3500 }
3501
3502 #endif /* DWC_DEVICE_ONLY */