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