USB: fix Coding Style.
[firefly-linux-kernel-4.4.55.git] / drivers / usb / dwc_otg_310 / dwc_otg_pcd_intr.c
1 /* ==========================================================================
2  * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_pcd_intr.c $
3  * $Revision: #119 $
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_HOST_ONLY
34
35 #include "dwc_otg_pcd.h"
36 #include "dwc_otg_driver.h"
37
38 #ifdef DWC_UTE_CFI
39 #include "dwc_otg_cfi.h"
40 #endif
41
42 #ifdef DWC_UTE_PER_IO
43 extern void complete_xiso_ep(dwc_otg_pcd_ep_t *ep);
44 #endif
45 /* #define PRINT_CFI_DMA_DESCS */
46
47 #define DEBUG_EP0
48
49 /**
50  * This function updates OTG.
51  */
52 static void dwc_otg_pcd_update_otg(dwc_otg_pcd_t *pcd, const unsigned reset)
53 {
54
55         if (reset) {
56                 pcd->b_hnp_enable = 0;
57                 pcd->a_hnp_support = 0;
58                 pcd->a_alt_hnp_support = 0;
59         }
60
61         if (pcd->fops->hnp_changed) {
62                 pcd->fops->hnp_changed(pcd);
63         }
64 }
65
66 /** @file
67  * This file contains the implementation of the PCD Interrupt handlers.
68  *
69  * The PCD handles the device interrupts.  Many conditions can cause a
70  * device interrupt. When an interrupt occurs, the device interrupt
71  * service routine determines the cause of the interrupt and
72  * dispatches handling to the appropriate function. These interrupt
73  * handling functions are described below.
74  * All interrupt registers are processed from LSB to MSB.
75  */
76
77 /**
78  * This function prints the ep0 state for debug purposes.
79  */
80 static inline void print_ep0_state(dwc_otg_pcd_t *pcd)
81 {
82 #ifdef DEBUG
83         char str[40];
84
85         switch (pcd->ep0state) {
86         case EP0_DISCONNECT:
87                 dwc_strcpy(str, "EP0_DISCONNECT");
88                 break;
89         case EP0_IDLE:
90                 dwc_strcpy(str, "EP0_IDLE");
91                 break;
92         case EP0_IN_DATA_PHASE:
93                 dwc_strcpy(str, "EP0_IN_DATA_PHASE");
94                 break;
95         case EP0_OUT_DATA_PHASE:
96                 dwc_strcpy(str, "EP0_OUT_DATA_PHASE");
97                 break;
98         case EP0_IN_STATUS_PHASE:
99                 dwc_strcpy(str, "EP0_IN_STATUS_PHASE");
100                 break;
101         case EP0_OUT_STATUS_PHASE:
102                 dwc_strcpy(str, "EP0_OUT_STATUS_PHASE");
103                 break;
104         case EP0_STALL:
105                 dwc_strcpy(str, "EP0_STALL");
106                 break;
107         default:
108                 dwc_strcpy(str, "EP0_INVALID");
109         }
110
111         DWC_DEBUGPL(DBG_ANY, "%s(%d)\n", str, pcd->ep0state);
112 #endif
113 }
114
115 /**
116  * This function calculate the size of the payload in the memory
117  * for out endpoints and prints size for debug purposes(used in
118  * 2.93a DevOutNak feature).
119  */
120 static inline void print_memory_payload(dwc_otg_pcd_t *pcd, dwc_ep_t *ep)
121 {
122 #ifdef DEBUG
123         deptsiz_data_t deptsiz_init = {.d32 = 0 };
124         deptsiz_data_t deptsiz_updt = {.d32 = 0 };
125         int pack_num;
126         unsigned payload;
127
128         deptsiz_init.d32 = pcd->core_if->start_doeptsiz_val[ep->num];
129         deptsiz_updt.d32 =
130             DWC_READ_REG32(&pcd->core_if->dev_if->
131                            out_ep_regs[ep->num]->doeptsiz);
132         /* Payload will be */
133         payload = deptsiz_init.b.xfersize - deptsiz_updt.b.xfersize;
134         /* Packet count is decremented every time a packet
135          * is written to the RxFIFO not in to the external memory
136          * So, if payload == 0, then it means no packet was sent to ext memory*/
137         pack_num =
138             (!payload) ? 0 : (deptsiz_init.b.pktcnt - deptsiz_updt.b.pktcnt);
139         DWC_DEBUGPL(DBG_PCDV, "Payload for EP%d-%s\n", ep->num,
140                     (ep->is_in ? "IN" : "OUT"));
141         DWC_DEBUGPL(DBG_PCDV, "Number of transfered bytes = 0x%08x\n", payload);
142         DWC_DEBUGPL(DBG_PCDV, "Number of transfered packets = %d\n", pack_num);
143 #endif
144 }
145
146 #ifdef DWC_UTE_CFI
147 static inline void print_desc(struct dwc_otg_dma_desc *ddesc,
148                               const uint8_t *epname, int descnum)
149 {
150         CFI_INFO
151             ("%s DMA_DESC(%d) buf=0x%08x bytes=0x%04x; sp=0x%x; l=0x%x; sts=0x%02x; bs=0x%02x\n",
152              epname, descnum, ddesc->buf, ddesc->status.b.bytes,
153              ddesc->status.b.sp, ddesc->status.b.l, ddesc->status.b.sts,
154              ddesc->status.b.bs);
155 }
156 #endif
157
158 /**
159  * This function returns pointer to in ep struct with number ep_num
160  */
161 static inline dwc_otg_pcd_ep_t *get_in_ep(dwc_otg_pcd_t *pcd, uint32_t ep_num)
162 {
163         int i;
164         int num_in_eps = GET_CORE_IF(pcd)->dev_if->num_in_eps;
165         if (ep_num == 0) {
166                 return &pcd->ep0;
167         } else {
168                 for (i = 0; i < num_in_eps; ++i) {
169                         if (pcd->in_ep[i].dwc_ep.num == ep_num)
170                                 return &pcd->in_ep[i];
171                 }
172                 return 0;
173         }
174 }
175
176 /**
177  * This function returns pointer to out ep struct with number ep_num
178  */
179 static inline dwc_otg_pcd_ep_t *get_out_ep(dwc_otg_pcd_t *pcd, uint32_t ep_num)
180 {
181         int i;
182         int num_out_eps = GET_CORE_IF(pcd)->dev_if->num_out_eps;
183         if (ep_num == 0) {
184                 return &pcd->ep0;
185         } else {
186                 for (i = 0; i < num_out_eps; ++i) {
187                         if (pcd->out_ep[i].dwc_ep.num == ep_num)
188                                 return &pcd->out_ep[i];
189                 }
190                 return 0;
191         }
192 }
193
194 /**
195  * This functions gets a pointer to an EP from the wIndex address
196  * value of the control request.
197  */
198 dwc_otg_pcd_ep_t *get_ep_by_addr(dwc_otg_pcd_t *pcd, u16 wIndex)
199 {
200         dwc_otg_pcd_ep_t *ep;
201         uint32_t ep_num = UE_GET_ADDR(wIndex);
202
203         if (ep_num == 0) {
204                 ep = &pcd->ep0;
205         } else if (UE_GET_DIR(wIndex) == UE_DIR_IN) {   /* in ep */
206                 ep = &pcd->in_ep[ep_num - 1];
207         } else {
208                 ep = &pcd->out_ep[ep_num - 1];
209         }
210
211         return ep;
212 }
213
214 /**
215  * This function checks the EP request queue, if the queue is not
216  * empty the next request is started.
217  */
218 void start_next_request(dwc_otg_pcd_ep_t *ep)
219 {
220         dwc_otg_pcd_request_t *req = 0;
221         uint32_t max_transfer =
222             GET_CORE_IF(ep->pcd)->core_params->max_transfer_size;
223
224 #ifdef DWC_UTE_CFI
225         struct dwc_otg_pcd *pcd;
226         pcd = ep->pcd;
227 #endif
228
229         if (!DWC_CIRCLEQ_EMPTY(&ep->queue)) {
230                 req = DWC_CIRCLEQ_FIRST(&ep->queue);
231
232 #ifdef DWC_UTE_CFI
233                 if (ep->dwc_ep.buff_mode != BM_STANDARD) {
234                         ep->dwc_ep.cfi_req_len = req->length;
235                         pcd->cfi->ops.build_descriptors(pcd->cfi, pcd, ep, req);
236                 } else {
237 #endif
238                         /* Setup and start the Transfer */
239                         if (req->dw_align_buf) {
240                                 ep->dwc_ep.dma_addr = req->dw_align_buf_dma;
241                                 ep->dwc_ep.start_xfer_buff = req->dw_align_buf;
242                                 ep->dwc_ep.xfer_buff = req->dw_align_buf;
243                         } else {
244                                 ep->dwc_ep.dma_addr = req->dma;
245                                 ep->dwc_ep.start_xfer_buff = req->buf;
246                                 ep->dwc_ep.xfer_buff = req->buf;
247                         }
248                         ep->dwc_ep.sent_zlp = 0;
249                         ep->dwc_ep.total_len = req->length;
250                         ep->dwc_ep.xfer_len = 0;
251                         ep->dwc_ep.xfer_count = 0;
252
253                         ep->dwc_ep.maxxfer = max_transfer;
254                         if (GET_CORE_IF(ep->pcd)->dma_desc_enable) {
255                                 uint32_t out_max_xfer = DDMA_MAX_TRANSFER_SIZE
256                                     - (DDMA_MAX_TRANSFER_SIZE % 4);
257                                 if (ep->dwc_ep.is_in) {
258                                         if (ep->dwc_ep.maxxfer >
259                                             DDMA_MAX_TRANSFER_SIZE) {
260                                                 ep->dwc_ep.maxxfer =
261                                                     DDMA_MAX_TRANSFER_SIZE;
262                                         }
263                                 } else {
264                                         if (ep->dwc_ep.maxxfer > out_max_xfer) {
265                                                 ep->dwc_ep.maxxfer =
266                                                     out_max_xfer;
267                                         }
268                                 }
269                         }
270                         if (ep->dwc_ep.maxxfer < ep->dwc_ep.total_len) {
271                                 ep->dwc_ep.maxxfer -=
272                                     (ep->dwc_ep.maxxfer % ep->dwc_ep.maxpacket);
273                         }
274                         if (req->sent_zlp) {
275                                 if ((ep->dwc_ep.total_len %
276                                      ep->dwc_ep.maxpacket == 0)
277                                     && (ep->dwc_ep.total_len != 0)) {
278                                         ep->dwc_ep.sent_zlp = 1;
279                                 }
280
281                         }
282 #ifdef DWC_UTE_CFI
283                 }
284 #endif
285                 dwc_otg_ep_start_transfer(GET_CORE_IF(ep->pcd), &ep->dwc_ep);
286         } else if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) {
287                 DWC_PRINTF("There are no more ISOC requests \n");
288                 ep->dwc_ep.frame_num = 0xFFFFFFFF;
289         }
290 }
291
292 /**
293  * This function handles the SOF Interrupts. At this time the SOF
294  * Interrupt is disabled.
295  */
296 int32_t dwc_otg_pcd_handle_sof_intr(dwc_otg_pcd_t *pcd)
297 {
298         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
299
300         gintsts_data_t gintsts;
301
302         DWC_DEBUGPL(DBG_PCD, "SOF\n");
303
304         /* Clear interrupt */
305         gintsts.d32 = 0;
306         gintsts.b.sofintr = 1;
307         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
308
309         return 1;
310 }
311
312 /**
313  * This function handles the Rx Status Queue Level Interrupt, which
314  * indicates that there is a least one packet in the Rx FIFO.  The
315  * packets are moved from the FIFO to memory, where they will be
316  * processed when the Endpoint Interrupt Register indicates Transfer
317  * Complete or SETUP Phase Done.
318  *
319  * Repeat the following until the Rx Status Queue is empty:
320  *       -# Read the Receive Status Pop Register (GRXSTSP) to get Packet
321  *              info
322  *       -# If Receive FIFO is empty then skip to step Clear the interrupt
323  *              and exit
324  *       -# If SETUP Packet call dwc_otg_read_setup_packet to copy the
325  *              SETUP data to the buffer
326  *       -# If OUT Data Packet call dwc_otg_read_packet to copy the data
327  *              to the destination buffer
328  */
329 int32_t dwc_otg_pcd_handle_rx_status_q_level_intr(dwc_otg_pcd_t *pcd)
330 {
331         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
332         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
333         gintmsk_data_t gintmask = {.d32 = 0 };
334         device_grxsts_data_t status;
335         dwc_otg_pcd_ep_t *ep;
336         gintsts_data_t gintsts;
337 #ifdef DEBUG
338         static char *dpid_str[] = { "D0", "D2", "D1", "MDATA" };
339 #endif
340
341         /* DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, _pcd); */
342         /* Disable the Rx Status Queue Level interrupt */
343         gintmask.b.rxstsqlvl = 1;
344         DWC_MODIFY_REG32(&global_regs->gintmsk, gintmask.d32, 0);
345
346         /* Get the Status from the top of the FIFO */
347         status.d32 = DWC_READ_REG32(&global_regs->grxstsp);
348
349         DWC_DEBUGPL(DBG_PCD, "EP:%d BCnt:%d DPID:%s "
350                     "pktsts:%x Frame:%d(0x%0x)\n",
351                     status.b.epnum, status.b.bcnt,
352                     dpid_str[status.b.dpid],
353                     status.b.pktsts, status.b.fn, status.b.fn);
354         /* Get pointer to EP structure */
355         ep = get_out_ep(pcd, status.b.epnum);
356
357         switch (status.b.pktsts) {
358         case DWC_DSTS_GOUT_NAK:
359                 DWC_DEBUGPL(DBG_PCDV, "Global OUT NAK\n");
360                 break;
361         case DWC_STS_DATA_UPDT:
362                 DWC_DEBUGPL(DBG_PCDV, "OUT Data Packet\n");
363                 if (status.b.bcnt && ep->dwc_ep.xfer_buff) {
364                         /** @todo NGS Check for buffer overflow? */
365                         dwc_otg_read_packet(core_if,
366                                             ep->dwc_ep.xfer_buff,
367                                             status.b.bcnt);
368                         ep->dwc_ep.xfer_count += status.b.bcnt;
369                         ep->dwc_ep.xfer_buff += status.b.bcnt;
370                 }
371                 break;
372         case DWC_STS_XFER_COMP:
373                 DWC_DEBUGPL(DBG_PCDV, "OUT Complete\n");
374                 break;
375         case DWC_DSTS_SETUP_COMP:
376 #ifdef DEBUG_EP0
377                 DWC_DEBUGPL(DBG_PCDV, "Setup Complete\n");
378 #endif
379                 break;
380         case DWC_DSTS_SETUP_UPDT:
381                 dwc_otg_read_setup_packet(core_if, pcd->setup_pkt->d32);
382 #ifdef DEBUG_EP0
383                 DWC_DEBUGPL(DBG_PCD,
384                             "SETUP PKT: %02x.%02x v%04x i%04x l%04x\n",
385                             pcd->setup_pkt->req.bmRequestType,
386                             pcd->setup_pkt->req.bRequest,
387                             UGETW(pcd->setup_pkt->req.wValue),
388                             UGETW(pcd->setup_pkt->req.wIndex),
389                             UGETW(pcd->setup_pkt->req.wLength));
390 #endif
391                 ep->dwc_ep.xfer_count += status.b.bcnt;
392                 break;
393         default:
394                 DWC_DEBUGPL(DBG_PCDV, "Invalid Packet Status (0x%0x)\n",
395                             status.b.pktsts);
396                 break;
397         }
398
399         /* Enable the Rx Status Queue Level interrupt */
400         DWC_MODIFY_REG32(&global_regs->gintmsk, 0, gintmask.d32);
401         /* Clear interrupt */
402         gintsts.d32 = 0;
403         gintsts.b.rxstsqlvl = 1;
404         DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
405
406         /* DWC_DEBUGPL(DBG_PCDV, "EXIT: %s\n", __func__); */
407         return 1;
408 }
409
410 /**
411  * This function examines the Device IN Token Learning Queue to
412  * determine the EP number of the last IN token received.  This
413  * implementation is for the Mass Storage device where there are only
414  * 2 IN EPs (Control-IN and BULK-IN).
415  *
416  * The EP numbers for the first six IN Tokens are in DTKNQR1 and there
417  * are 8 EP Numbers in each of the other possible DTKNQ Registers.
418  *
419  * @param core_if Programming view of DWC_otg controller.
420  *
421  */
422 static inline int get_ep_of_last_in_token(dwc_otg_core_if_t *core_if)
423 {
424         dwc_otg_device_global_regs_t *dev_global_regs =
425             core_if->dev_if->dev_global_regs;
426         const uint32_t TOKEN_Q_DEPTH = core_if->hwcfg2.b.dev_token_q_depth;
427         /* Number of Token Queue Registers */
428         const int DTKNQ_REG_CNT = (TOKEN_Q_DEPTH + 7) / 8;
429         dtknq1_data_t dtknqr1;
430         uint32_t in_tkn_epnums[4];
431         int ndx = 0;
432         int i = 0;
433         volatile uint32_t *addr = &dev_global_regs->dtknqr1;
434         int epnum = 0;
435
436         /* DWC_DEBUGPL(DBG_PCD,"dev_token_q_depth=%d\n",TOKEN_Q_DEPTH); */
437
438         /* Read the DTKNQ Registers */
439         for (i = 0; i < DTKNQ_REG_CNT; i++) {
440                 in_tkn_epnums[i] = DWC_READ_REG32(addr);
441                 DWC_DEBUGPL(DBG_PCDV, "DTKNQR%d=0x%08x\n", i + 1,
442                             in_tkn_epnums[i]);
443                 if (addr == &dev_global_regs->dvbusdis) {
444                         addr = &dev_global_regs->dtknqr3_dthrctl;
445                 } else {
446                         ++addr;
447                 }
448
449         }
450
451         /* Copy the DTKNQR1 data to the bit field. */
452         dtknqr1.d32 = in_tkn_epnums[0];
453         /* Get the EP numbers */
454         in_tkn_epnums[0] = dtknqr1.b.epnums0_5;
455         ndx = dtknqr1.b.intknwptr - 1;
456
457         /* DWC_DEBUGPL(DBG_PCDV,"ndx=%d\n",ndx); */
458         if (ndx == -1) {
459                 /** @todo Find a simpler way to calculate the max
460                  * queue position.*/
461                 int cnt = TOKEN_Q_DEPTH;
462                 if (TOKEN_Q_DEPTH <= 6) {
463                         cnt = TOKEN_Q_DEPTH - 1;
464                 } else if (TOKEN_Q_DEPTH <= 14) {
465                         cnt = TOKEN_Q_DEPTH - 7;
466                 } else if (TOKEN_Q_DEPTH <= 22) {
467                         cnt = TOKEN_Q_DEPTH - 15;
468                 } else {
469                         cnt = TOKEN_Q_DEPTH - 23;
470                 }
471                 epnum = (in_tkn_epnums[DTKNQ_REG_CNT - 1] >> (cnt * 4)) & 0xF;
472         } else {
473                 if (ndx <= 5) {
474                         epnum = (in_tkn_epnums[0] >> (ndx * 4)) & 0xF;
475                 } else if (ndx <= 13) {
476                         ndx -= 6;
477                         epnum = (in_tkn_epnums[1] >> (ndx * 4)) & 0xF;
478                 } else if (ndx <= 21) {
479                         ndx -= 14;
480                         epnum = (in_tkn_epnums[2] >> (ndx * 4)) & 0xF;
481                 } else if (ndx <= 29) {
482                         ndx -= 22;
483                         epnum = (in_tkn_epnums[3] >> (ndx * 4)) & 0xF;
484                 }
485         }
486         /* DWC_DEBUGPL(DBG_PCD,"epnum=%d\n",epnum); */
487         return epnum;
488 }
489
490 /**
491  * This interrupt occurs when the non-periodic Tx FIFO is half-empty.
492  * The active request is checked for the next packet to be loaded into
493  * the non-periodic Tx FIFO.
494  */
495 int32_t dwc_otg_pcd_handle_np_tx_fifo_empty_intr(dwc_otg_pcd_t *pcd)
496 {
497         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
498         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
499         dwc_otg_dev_in_ep_regs_t *ep_regs;
500         gnptxsts_data_t txstatus = {.d32 = 0 };
501         gintsts_data_t gintsts;
502
503         int epnum = 0;
504         dwc_otg_pcd_ep_t *ep = 0;
505         uint32_t len = 0;
506         int dwords;
507
508         /* Get the epnum from the IN Token Learning Queue. */
509         epnum = get_ep_of_last_in_token(core_if);
510         ep = get_in_ep(pcd, epnum);
511
512         DWC_DEBUGPL(DBG_PCD, "NP TxFifo Empty: %d \n", epnum);
513
514         ep_regs = core_if->dev_if->in_ep_regs[epnum];
515
516         len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
517         if (len > ep->dwc_ep.maxpacket) {
518                 len = ep->dwc_ep.maxpacket;
519         }
520         dwords = (len + 3) / 4;
521
522         /* While there is space in the queue and space in the FIFO and
523          * More data to tranfer, Write packets to the Tx FIFO */
524         txstatus.d32 = DWC_READ_REG32(&global_regs->gnptxsts);
525         DWC_DEBUGPL(DBG_PCDV, "b4 GNPTXSTS=0x%08x\n", txstatus.d32);
526
527         while (txstatus.b.nptxqspcavail > 0 &&
528                txstatus.b.nptxfspcavail > dwords &&
529                ep->dwc_ep.xfer_count < ep->dwc_ep.xfer_len) {
530                 /* Write the FIFO */
531                 dwc_otg_ep_write_packet(core_if, &ep->dwc_ep, 0);
532                 len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
533
534                 if (len > ep->dwc_ep.maxpacket) {
535                         len = ep->dwc_ep.maxpacket;
536                 }
537
538                 dwords = (len + 3) / 4;
539                 txstatus.d32 = DWC_READ_REG32(&global_regs->gnptxsts);
540                 DWC_DEBUGPL(DBG_PCDV, "GNPTXSTS=0x%08x\n", txstatus.d32);
541         }
542
543         DWC_DEBUGPL(DBG_PCDV, "GNPTXSTS=0x%08x\n",
544                     DWC_READ_REG32(&global_regs->gnptxsts));
545
546         /* Clear interrupt */
547         gintsts.d32 = 0;
548         gintsts.b.nptxfempty = 1;
549         DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
550
551         return 1;
552 }
553
554 /**
555  * This function is called when dedicated Tx FIFO Empty interrupt occurs.
556  * The active request is checked for the next packet to be loaded into
557  * apropriate Tx FIFO.
558  */
559 static int32_t write_empty_tx_fifo(dwc_otg_pcd_t *pcd, uint32_t epnum)
560 {
561         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
562         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
563         dwc_otg_dev_in_ep_regs_t *ep_regs;
564         dtxfsts_data_t txstatus = {.d32 = 0 };
565         dwc_otg_pcd_ep_t *ep = 0;
566         uint32_t len = 0;
567         int dwords;
568
569         ep = get_in_ep(pcd, epnum);
570
571         DWC_DEBUGPL(DBG_PCD, "Dedicated TxFifo Empty: %d \n", epnum);
572
573         ep_regs = core_if->dev_if->in_ep_regs[epnum];
574
575         len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
576
577         if (len > ep->dwc_ep.maxpacket) {
578                 len = ep->dwc_ep.maxpacket;
579         }
580
581         dwords = (len + 3) / 4;
582
583         /* While there is space in the queue and space in the FIFO and
584          * More data to tranfer, Write packets to the Tx FIFO */
585         txstatus.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts);
586         DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", epnum, txstatus.d32);
587
588         while (txstatus.b.txfspcavail > dwords &&
589                ep->dwc_ep.xfer_count < ep->dwc_ep.xfer_len &&
590                ep->dwc_ep.xfer_len != 0) {
591                 /* Write the FIFO */
592                 dwc_otg_ep_write_packet(core_if, &ep->dwc_ep, 0);
593
594                 len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
595                 if (len > ep->dwc_ep.maxpacket) {
596                         len = ep->dwc_ep.maxpacket;
597                 }
598
599                 dwords = (len + 3) / 4;
600                 txstatus.d32 =
601                     DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts);
602                 DWC_DEBUGPL(DBG_PCDV, "dtxfsts[%d]=0x%08x\n", epnum,
603                             txstatus.d32);
604         }
605
606         DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", epnum,
607                     DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts));
608
609         return 1;
610 }
611
612 /**
613  * This function is called when the Device is disconnected. It stops
614  * any active requests and informs the Gadget driver of the
615  * disconnect.
616  */
617 void dwc_otg_pcd_stop(dwc_otg_pcd_t *pcd)
618 {
619         int i, num_in_eps, num_out_eps;
620         dwc_otg_pcd_ep_t *ep;
621         gintmsk_data_t intr_mask = {.d32 = 0 };
622
623         DWC_SPINLOCK(pcd->lock);
624
625         num_in_eps = GET_CORE_IF(pcd)->dev_if->num_in_eps;
626         num_out_eps = GET_CORE_IF(pcd)->dev_if->num_out_eps;
627
628         DWC_DEBUGPL(DBG_PCDV, "%s() \n", __func__);
629         /* don't disconnect drivers more than once */
630         if (pcd->ep0state == EP0_DISCONNECT) {
631                 DWC_DEBUGPL(DBG_ANY, "%s() Already Disconnected\n", __func__);
632                 DWC_SPINUNLOCK(pcd->lock);
633                 return;
634         }
635         pcd->ep0state = EP0_DISCONNECT;
636
637         /* Reset the OTG state. */
638         dwc_otg_pcd_update_otg(pcd, 1);
639
640         /* Disable the NP Tx Fifo Empty Interrupt. */
641         intr_mask.b.nptxfempty = 1;
642         DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
643                          intr_mask.d32, 0);
644
645         /* Flush the FIFOs */
646         /**@todo NGS Flush Periodic FIFOs */
647         dwc_otg_flush_tx_fifo(GET_CORE_IF(pcd), 0x10);
648         dwc_otg_flush_rx_fifo(GET_CORE_IF(pcd));
649
650         /* prevent new request submissions, kill any outstanding requests  */
651         ep = &pcd->ep0;
652         dwc_otg_request_nuke(ep);
653         /* prevent new request submissions, kill any outstanding requests  */
654         for (i = 0; i < num_in_eps; i++) {
655                 dwc_otg_pcd_ep_t *ep = &pcd->in_ep[i];
656                 dwc_otg_request_nuke(ep);
657         }
658         /* prevent new request submissions, kill any outstanding requests  */
659         for (i = 0; i < num_out_eps; i++) {
660                 dwc_otg_pcd_ep_t *ep = &pcd->out_ep[i];
661                 dwc_otg_request_nuke(ep);
662         }
663
664         /* report disconnect; the driver is already quiesced */
665         if (pcd->fops->disconnect) {
666                 DWC_SPINUNLOCK(pcd->lock);
667                 pcd->fops->disconnect(pcd);
668                 DWC_SPINLOCK(pcd->lock);
669         }
670         DWC_SPINUNLOCK(pcd->lock);
671 }
672
673 /**
674  * This interrupt indicates that ...
675  */
676 int32_t dwc_otg_pcd_handle_i2c_intr(dwc_otg_pcd_t *pcd)
677 {
678         gintmsk_data_t intr_mask = {.d32 = 0 };
679         gintsts_data_t gintsts;
680
681         DWC_PRINTF("INTERRUPT Handler not implemented for %s\n", "i2cintr");
682         intr_mask.b.i2cintr = 1;
683         DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
684                          intr_mask.d32, 0);
685
686         /* Clear interrupt */
687         gintsts.d32 = 0;
688         gintsts.b.i2cintr = 1;
689         DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
690                         gintsts.d32);
691         return 1;
692 }
693
694 /**
695  * This interrupt indicates that ...
696  */
697 int32_t dwc_otg_pcd_handle_early_suspend_intr(dwc_otg_pcd_t *pcd)
698 {
699         gintsts_data_t gintsts;
700 #if defined(VERBOSE)
701         DWC_PRINTF("Early Suspend Detected\n");
702 #endif
703
704         /* Clear interrupt */
705         gintsts.d32 = 0;
706         gintsts.b.erlysuspend = 1;
707         DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
708                         gintsts.d32);
709         return 1;
710 }
711
712 /**
713  * This function configures EPO to receive SETUP packets.
714  *
715  * @todo NGS: Update the comments from the HW FS.
716  *
717  *      -# Program the following fields in the endpoint specific registers
718  *      for Control OUT EP 0, in order to receive a setup packet
719  *      - DOEPTSIZ0.Packet Count = 3 (To receive up to 3 back to back
720  *        setup packets)
721  *      - DOEPTSIZE0.Transfer Size = 24 Bytes (To receive up to 3 back
722  *        to back setup packets)
723  *              - In DMA mode, DOEPDMA0 Register with a memory address to
724  *                store any setup packets received
725  *
726  * @param core_if Programming view of DWC_otg controller.
727  * @param pcd     Programming view of the PCD.
728  */
729 static inline void ep0_out_start(dwc_otg_core_if_t *core_if,
730                                  dwc_otg_pcd_t *pcd)
731 {
732         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
733         deptsiz0_data_t doeptsize0 = {.d32 = 0 };
734         dwc_otg_dev_dma_desc_t *dma_desc;
735         depctl_data_t doepctl = {.d32 = 0 };
736
737 #ifdef VERBOSE
738         DWC_DEBUGPL(DBG_PCDV, "%s() doepctl0=%0x\n", __func__,
739                     DWC_READ_REG32(&dev_if->out_ep_regs[0]->doepctl));
740 #endif
741         if (core_if->snpsid >= OTG_CORE_REV_3_00a) {
742                 doepctl.d32 = DWC_READ_REG32(&dev_if->out_ep_regs[0]->doepctl);
743                 if (doepctl.b.epena) {
744                         return;
745                 }
746         }
747
748         doeptsize0.b.supcnt = 3;
749         doeptsize0.b.pktcnt = 1;
750         doeptsize0.b.xfersize = 8 * 3;
751
752         if (core_if->dma_enable) {
753                 if (!core_if->dma_desc_enable) {
754                         /** put here as for Hermes mode deptisz register should not be written */
755                         DWC_WRITE_REG32(&dev_if->out_ep_regs[0]->doeptsiz,
756                                         doeptsize0.d32);
757
758                         /** @todo dma needs to handle multiple setup packets (up to 3) */
759                         DWC_WRITE_REG32(&dev_if->out_ep_regs[0]->doepdma,
760                                         pcd->setup_pkt_dma_handle);
761                 } else {
762                         dev_if->setup_desc_index =
763                             (dev_if->setup_desc_index + 1) & 1;
764                         dma_desc =
765                             dev_if->setup_desc_addr[dev_if->setup_desc_index];
766
767                         /** DMA Descriptor Setup */
768                         dma_desc->status.b.bs = BS_HOST_BUSY;
769                         if (core_if->snpsid >= OTG_CORE_REV_3_00a) {
770                                 dma_desc->status.b.sr = 0;
771                                 dma_desc->status.b.mtrf = 0;
772                         }
773                         dma_desc->status.b.l = 1;
774                         dma_desc->status.b.ioc = 1;
775                         dma_desc->status.b.bytes = pcd->ep0.dwc_ep.maxpacket;
776                         dma_desc->buf = pcd->setup_pkt_dma_handle;
777                         dma_desc->status.b.sts = 0;
778                         dma_desc->status.b.bs = BS_HOST_READY;
779
780                         /** DOEPDMA0 Register write */
781                         DWC_WRITE_REG32(&dev_if->out_ep_regs[0]->doepdma,
782                                         dev_if->dma_setup_desc_addr
783                                         [dev_if->setup_desc_index]);
784                 }
785
786         } else {
787                 /** put here as for Hermes mode deptisz register should not be written */
788                 DWC_WRITE_REG32(&dev_if->out_ep_regs[0]->doeptsiz,
789                                 doeptsize0.d32);
790         }
791
792         /** DOEPCTL0 Register write cnak will be set after setup interrupt */
793         doepctl.d32 = 0;
794         doepctl.b.epena = 1;
795         if (core_if->snpsid <= OTG_CORE_REV_2_94a) {
796                 doepctl.b.cnak = 1;
797                 DWC_WRITE_REG32(&dev_if->out_ep_regs[0]->doepctl, doepctl.d32);
798         } else {
799                 DWC_MODIFY_REG32(&dev_if->out_ep_regs[0]->doepctl, 0,
800                                  doepctl.d32);
801         }
802
803 #ifdef VERBOSE
804         DWC_DEBUGPL(DBG_PCDV, "doepctl0=%0x\n",
805                     DWC_READ_REG32(&dev_if->out_ep_regs[0]->doepctl));
806         DWC_DEBUGPL(DBG_PCDV, "diepctl0=%0x\n",
807                     DWC_READ_REG32(&dev_if->in_ep_regs[0]->diepctl));
808 #endif
809 }
810
811 /**
812  * This interrupt occurs when a USB Reset is detected. When the USB
813  * Reset Interrupt occurs the device state is set to DEFAULT and the
814  * EP0 state is set to IDLE.
815  *      -#      Set the NAK bit for all OUT endpoints (DOEPCTLn.SNAK = 1)
816  *      -#      Unmask the following interrupt bits
817  *              - DAINTMSK.INEP0 = 1 (Control 0 IN endpoint)
818  *      - DAINTMSK.OUTEP0 = 1 (Control 0 OUT endpoint)
819  *      - DOEPMSK.SETUP = 1
820  *      - DOEPMSK.XferCompl = 1
821  *      - DIEPMSK.XferCompl = 1
822  *      - DIEPMSK.TimeOut = 1
823  *      -# Program the following fields in the endpoint specific registers
824  *      for Control OUT EP 0, in order to receive a setup packet
825  *      - DOEPTSIZ0.Packet Count = 3 (To receive up to 3 back to back
826  *        setup packets)
827  *      - DOEPTSIZE0.Transfer Size = 24 Bytes (To receive up to 3 back
828  *        to back setup packets)
829  *              - In DMA mode, DOEPDMA0 Register with a memory address to
830  *                store any setup packets received
831  * At this point, all the required initialization, except for enabling
832  * the control 0 OUT endpoint is done, for receiving SETUP packets.
833  */
834 int32_t dwc_otg_pcd_handle_usb_reset_intr(dwc_otg_pcd_t *pcd)
835 {
836         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
837         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
838         depctl_data_t doepctl = {.d32 = 0 };
839         depctl_data_t diepctl = {.d32 = 0 };
840         daint_data_t daintmsk = {.d32 = 0 };
841         doepmsk_data_t doepmsk = {.d32 = 0 };
842         diepmsk_data_t diepmsk = {.d32 = 0 };
843         dcfg_data_t dcfg = {.d32 = 0 };
844         grstctl_t resetctl = {.d32 = 0 };
845         dctl_data_t dctl = {.d32 = 0 };
846         int i = 0;
847         gintsts_data_t gintsts;
848         pcgcctl_data_t power = {.d32 = 0 };
849
850         power.d32 = DWC_READ_REG32(core_if->pcgcctl);
851         if (power.b.stoppclk) {
852                 power.d32 = 0;
853                 power.b.stoppclk = 1;
854                 DWC_MODIFY_REG32(core_if->pcgcctl, power.d32, 0);
855
856                 power.b.pwrclmp = 1;
857                 DWC_MODIFY_REG32(core_if->pcgcctl, power.d32, 0);
858
859                 power.b.rstpdwnmodule = 1;
860                 DWC_MODIFY_REG32(core_if->pcgcctl, power.d32, 0);
861         }
862
863         core_if->lx_state = DWC_OTG_L0;
864         core_if->otg_sts = 0;
865
866         DWC_PRINTF("USB RESET\n");
867 #ifdef DWC_EN_ISOC
868         for (i = 1; i < 16; ++i) {
869                 dwc_otg_pcd_ep_t *ep;
870                 dwc_ep_t *dwc_ep;
871                 ep = get_in_ep(pcd, i);
872                 if (ep != 0) {
873                         dwc_ep = &ep->dwc_ep;
874                         dwc_ep->next_frame = 0xffffffff;
875                 }
876         }
877 #endif /* DWC_EN_ISOC */
878
879         /* reset the HNP settings */
880         dwc_otg_pcd_update_otg(pcd, 1);
881
882         /* Clear the Remote Wakeup Signalling */
883         dctl.b.rmtwkupsig = 1;
884         DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32, 0);
885
886         /* Set NAK for all OUT EPs */
887         doepctl.b.snak = 1;
888         for (i = 0; i <= dev_if->num_out_eps; i++) {
889                 DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepctl, doepctl.d32);
890         }
891
892         /* Flush the NP Tx FIFO */
893         dwc_otg_flush_tx_fifo(core_if, 0x10);
894         /* Flush the Learning Queue */
895         resetctl.b.intknqflsh = 1;
896         DWC_WRITE_REG32(&core_if->core_global_regs->grstctl, resetctl.d32);
897
898         if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable) {
899                 core_if->start_predict = 0;
900                 for (i = 0; i <= core_if->dev_if->num_in_eps; ++i) {
901                         core_if->nextep_seq[i] = 0xff; /*0xff - EP not active */
902                 }
903                 core_if->nextep_seq[0] = 0;
904                 core_if->first_in_nextep_seq = 0;
905                 diepctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[0]->diepctl);
906                 diepctl.b.nextep = 0;
907                 DWC_WRITE_REG32(&dev_if->in_ep_regs[0]->diepctl, diepctl.d32);
908
909                 /* Update IN Endpoint Mismatch Count by active IN NP EP count + 1 */
910                 dcfg.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dcfg);
911                 dcfg.b.epmscnt = 2;
912                 DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
913
914                 DWC_DEBUGPL(DBG_PCDV,
915                             "%s first_in_nextep_seq= %2d; nextep_seq[]:\n",
916                             __func__, core_if->first_in_nextep_seq);
917                 for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
918                         DWC_DEBUGPL(DBG_PCDV, "%2d\n", core_if->nextep_seq[i]);
919                 }
920         }
921
922         if (core_if->multiproc_int_enable) {
923                 daintmsk.b.inep0 = 1;
924                 daintmsk.b.outep0 = 1;
925                 DWC_WRITE_REG32(&dev_if->dev_global_regs->deachintmsk,
926                                 daintmsk.d32);
927
928                 doepmsk.b.setup = 1;
929                 doepmsk.b.xfercompl = 1;
930                 doepmsk.b.ahberr = 1;
931                 doepmsk.b.epdisabled = 1;
932
933                 if ((core_if->dma_desc_enable) ||
934                     (core_if->dma_enable
935                      && core_if->snpsid >= OTG_CORE_REV_3_00a)) {
936                         doepmsk.b.stsphsercvd = 1;
937                 }
938                 if (core_if->dma_desc_enable)
939                         doepmsk.b.bna = 1;
940 /*
941                 doepmsk.b.babble = 1;
942                 doepmsk.b.nyet = 1;
943
944                 if (core_if->dma_enable) {
945                         doepmsk.b.nak = 1;
946                 }
947 */
948                 DWC_WRITE_REG32(&dev_if->dev_global_regs->doepeachintmsk[0],
949                                 doepmsk.d32);
950
951                 diepmsk.b.xfercompl = 1;
952                 diepmsk.b.timeout = 1;
953                 diepmsk.b.epdisabled = 1;
954                 diepmsk.b.ahberr = 1;
955                 diepmsk.b.intknepmis = 1;
956                 if (!core_if->en_multiple_tx_fifo && core_if->dma_enable)
957                         diepmsk.b.intknepmis = 0;
958
959 /*              if (core_if->dma_desc_enable) {
960                         diepmsk.b.bna = 1;
961                 }
962 */
963 /*
964                 if (core_if->dma_enable) {
965                         diepmsk.b.nak = 1;
966                 }
967 */
968                 DWC_WRITE_REG32(&dev_if->dev_global_regs->diepeachintmsk[0],
969                                 diepmsk.d32);
970         } else {
971                 daintmsk.b.inep0 = 1;
972                 daintmsk.b.outep0 = 1;
973                 DWC_WRITE_REG32(&dev_if->dev_global_regs->daintmsk,
974                                 daintmsk.d32);
975
976                 doepmsk.b.setup = 1;
977                 doepmsk.b.xfercompl = 1;
978                 doepmsk.b.ahberr = 1;
979                 doepmsk.b.epdisabled = 1;
980
981                 if ((core_if->dma_desc_enable) ||
982                     (core_if->dma_enable
983                      && core_if->snpsid >= OTG_CORE_REV_3_00a)) {
984                         doepmsk.b.stsphsercvd = 1;
985                 }
986                 if (core_if->dma_desc_enable)
987                         doepmsk.b.bna = 1;
988                 DWC_WRITE_REG32(&dev_if->dev_global_regs->doepmsk, doepmsk.d32);
989
990                 diepmsk.b.xfercompl = 1;
991                 diepmsk.b.timeout = 1;
992                 diepmsk.b.epdisabled = 1;
993                 diepmsk.b.ahberr = 1;
994                 if (!core_if->en_multiple_tx_fifo && core_if->dma_enable)
995                         diepmsk.b.intknepmis = 0;
996 /*
997                 if (core_if->dma_desc_enable) {
998                         diepmsk.b.bna = 1;
999                 }
1000 */
1001
1002                 DWC_WRITE_REG32(&dev_if->dev_global_regs->diepmsk, diepmsk.d32);
1003         }
1004
1005         /* Reset Device Address */
1006         dcfg.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dcfg);
1007         dcfg.b.devaddr = 0;
1008         DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
1009
1010         /* setup EP0 to receive SETUP packets */
1011         if (core_if->snpsid <= OTG_CORE_REV_2_94a)
1012                 ep0_out_start(core_if, pcd);
1013
1014         /* Clear interrupt */
1015         gintsts.d32 = 0;
1016         gintsts.b.usbreset = 1;
1017         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
1018
1019         return 1;
1020 }
1021
1022 /**
1023  * Get the device speed from the device status register and convert it
1024  * to USB speed constant.
1025  *
1026  * @param core_if Programming view of DWC_otg controller.
1027  */
1028 static int get_device_speed(dwc_otg_core_if_t *core_if)
1029 {
1030         dsts_data_t dsts;
1031         int speed = 0;
1032         dsts.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);
1033
1034         switch (dsts.b.enumspd) {
1035         case DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
1036                 speed = USB_SPEED_HIGH;
1037                 break;
1038         case DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
1039         case DWC_DSTS_ENUMSPD_FS_PHY_48MHZ:
1040                 speed = USB_SPEED_FULL;
1041                 break;
1042
1043         case DWC_DSTS_ENUMSPD_LS_PHY_6MHZ:
1044                 speed = USB_SPEED_LOW;
1045                 break;
1046         }
1047
1048         return speed;
1049 }
1050
1051 /**
1052  * Read the device status register and set the device speed in the
1053  * data structure.
1054  * Set up EP0 to receive SETUP packets by calling dwc_ep0_activate.
1055  */
1056 int32_t dwc_otg_pcd_handle_enum_done_intr(dwc_otg_pcd_t *pcd)
1057 {
1058         dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
1059         gintsts_data_t gintsts;
1060         gusbcfg_data_t gusbcfg;
1061         dwc_otg_core_global_regs_t *global_regs =
1062             GET_CORE_IF(pcd)->core_global_regs;
1063         uint8_t utmi16b, utmi8b;
1064         int speed;
1065
1066         DWC_DEBUGPL(DBG_PCD, "SPEED ENUM\n");
1067
1068         if (GET_CORE_IF(pcd)->snpsid >= OTG_CORE_REV_2_60a) {
1069                 utmi16b = 5;    /* vahrama old value was 6; */
1070                 utmi8b = 9;
1071         } else {
1072                 utmi16b = 4;
1073                 utmi8b = 8;
1074         }
1075         dwc_otg_ep0_activate(GET_CORE_IF(pcd), &ep0->dwc_ep);
1076         if (GET_CORE_IF(pcd)->snpsid >= OTG_CORE_REV_3_00a) {
1077                 ep0_out_start(GET_CORE_IF(pcd), pcd);
1078         }
1079 #ifdef DEBUG_EP0
1080         print_ep0_state(pcd);
1081 #endif
1082
1083         if (pcd->ep0state == EP0_DISCONNECT) {
1084                 pcd->ep0state = EP0_IDLE;
1085         } else if (pcd->ep0state == EP0_STALL) {
1086                 pcd->ep0state = EP0_IDLE;
1087         }
1088
1089         pcd->ep0state = EP0_IDLE;
1090
1091         ep0->stopped = 0;
1092
1093         speed = get_device_speed(GET_CORE_IF(pcd));
1094         pcd->fops->connect(pcd, speed);
1095
1096         /* Set USB turnaround time based on device speed and PHY interface. */
1097         gusbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
1098         if (speed == USB_SPEED_HIGH) {
1099                 if (GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type ==
1100                     DWC_HWCFG2_HS_PHY_TYPE_ULPI) {
1101                         /* ULPI interface */
1102                         gusbcfg.b.usbtrdtim = 9;
1103                 }
1104                 if (GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type ==
1105                     DWC_HWCFG2_HS_PHY_TYPE_UTMI) {
1106                         /* UTMI+ interface */
1107                         if (GET_CORE_IF(pcd)->hwcfg4.b.utmi_phy_data_width == 0) {
1108                                 gusbcfg.b.usbtrdtim = utmi8b;
1109                         } else if (GET_CORE_IF(pcd)->hwcfg4.
1110                                    b.utmi_phy_data_width == 1) {
1111                                 gusbcfg.b.usbtrdtim = utmi16b;
1112                         } else if (GET_CORE_IF(pcd)->
1113                                    core_params->phy_utmi_width == 8) {
1114                                 gusbcfg.b.usbtrdtim = utmi8b;
1115                         } else {
1116                                 gusbcfg.b.usbtrdtim = utmi16b;
1117                         }
1118                 }
1119                 if (GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type ==
1120                     DWC_HWCFG2_HS_PHY_TYPE_UTMI_ULPI) {
1121                         /* UTMI+  OR  ULPI interface */
1122                         if (gusbcfg.b.ulpi_utmi_sel == 1) {
1123                                 /* ULPI interface */
1124                                 gusbcfg.b.usbtrdtim = 9;
1125                         } else {
1126                                 /* UTMI+ interface */
1127                                 if (GET_CORE_IF(pcd)->
1128                                     core_params->phy_utmi_width == 16) {
1129                                         gusbcfg.b.usbtrdtim = utmi16b;
1130                                 } else {
1131                                         gusbcfg.b.usbtrdtim = utmi8b;
1132                                 }
1133                         }
1134                 }
1135         } else {
1136                 /* Full or low speed */
1137                 gusbcfg.b.usbtrdtim = 9;
1138         }
1139         DWC_WRITE_REG32(&global_regs->gusbcfg, gusbcfg.d32);
1140
1141         /* Clear interrupt */
1142         gintsts.d32 = 0;
1143         gintsts.b.enumdone = 1;
1144         DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
1145                         gintsts.d32);
1146         return 1;
1147 }
1148
1149 /**
1150  * This interrupt indicates that the ISO OUT Packet was dropped due to
1151  * Rx FIFO full or Rx Status Queue Full.  If this interrupt occurs
1152  * read all the data from the Rx FIFO.
1153  */
1154 int32_t dwc_otg_pcd_handle_isoc_out_packet_dropped_intr(dwc_otg_pcd_t *pcd)
1155 {
1156         gintmsk_data_t intr_mask = {.d32 = 0 };
1157         gintsts_data_t gintsts;
1158
1159         DWC_WARN("INTERRUPT Handler not implemented for %s\n",
1160                  "ISOC Out Dropped");
1161
1162         intr_mask.b.isooutdrop = 1;
1163         DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
1164                          intr_mask.d32, 0);
1165
1166         /* Clear interrupt */
1167         gintsts.d32 = 0;
1168         gintsts.b.isooutdrop = 1;
1169         DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
1170                         gintsts.d32);
1171
1172         return 1;
1173 }
1174
1175 /**
1176  * This interrupt indicates the end of the portion of the micro-frame
1177  * for periodic transactions.  If there is a periodic transaction for
1178  * the next frame, load the packets into the EP periodic Tx FIFO.
1179  */
1180 int32_t dwc_otg_pcd_handle_end_periodic_frame_intr(dwc_otg_pcd_t *pcd)
1181 {
1182         gintmsk_data_t intr_mask = {.d32 = 0 };
1183         gintsts_data_t gintsts;
1184         DWC_PRINTF("INTERRUPT Handler not implemented for %s\n", "EOP");
1185
1186         intr_mask.b.eopframe = 1;
1187         DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
1188                          intr_mask.d32, 0);
1189
1190         /* Clear interrupt */
1191         gintsts.d32 = 0;
1192         gintsts.b.eopframe = 1;
1193         DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
1194                         gintsts.d32);
1195
1196         return 1;
1197 }
1198
1199 /**
1200  * This interrupt indicates that EP of the packet on the top of the
1201  * non-periodic Tx FIFO does not match EP of the IN Token received.
1202  *
1203  * The "Device IN Token Queue" Registers are read to determine the
1204  * order the IN Tokens have been received. The non-periodic Tx FIFO
1205  * is flushed, so it can be reloaded in the order seen in the IN Token
1206  * Queue.
1207  */
1208 int32_t dwc_otg_pcd_handle_ep_mismatch_intr(dwc_otg_pcd_t *pcd)
1209 {
1210         gintsts_data_t gintsts;
1211         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
1212         dctl_data_t dctl;
1213         gintmsk_data_t intr_mask = {.d32 = 0 };
1214
1215         if (!core_if->en_multiple_tx_fifo && core_if->dma_enable) {
1216                 core_if->start_predict = 1;
1217
1218                 DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, core_if);
1219
1220                 gintsts.d32 =
1221                     DWC_READ_REG32(&core_if->core_global_regs->gintsts);
1222                 if (!gintsts.b.ginnakeff) {
1223                         /* Disable EP Mismatch interrupt */
1224                         intr_mask.d32 = 0;
1225                         intr_mask.b.epmismatch = 1;
1226                         DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk,
1227                                          intr_mask.d32, 0);
1228                         /* Enable the Global IN NAK Effective Interrupt */
1229                         intr_mask.d32 = 0;
1230                         intr_mask.b.ginnakeff = 1;
1231                         DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, 0,
1232                                          intr_mask.d32);
1233                         /* Set the global non-periodic IN NAK handshake */
1234                         dctl.d32 =
1235                             DWC_READ_REG32(&core_if->dev_if->
1236                                            dev_global_regs->dctl);
1237                         dctl.b.sgnpinnak = 1;
1238                         DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl,
1239                                         dctl.d32);
1240                 } else {
1241                         DWC_PRINTF
1242                             ("gintsts.b.ginnakeff = 1! dctl.b.sgnpinnak not set\n");
1243                 }
1244                 /* Disabling of all EP's will be done in dwc_otg_pcd_handle_in_nak_effective()
1245                  * handler after Global IN NAK Effective interrupt will be asserted */
1246         }
1247         /* Clear interrupt */
1248         gintsts.d32 = 0;
1249         gintsts.b.epmismatch = 1;
1250         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
1251
1252         return 1;
1253 }
1254
1255 /**
1256  * This interrupt is valid only in DMA mode. This interrupt indicates that the
1257  * core has stopped fetching data for IN endpoints due to the unavailability of
1258  * TxFIFO space or Request Queue space. This interrupt is used by the
1259  * application for an endpoint mismatch algorithm.
1260  *
1261  * @param pcd The PCD
1262  */
1263 int32_t dwc_otg_pcd_handle_ep_fetsusp_intr(dwc_otg_pcd_t *pcd)
1264 {
1265         gintsts_data_t gintsts;
1266         gintmsk_data_t gintmsk_data;
1267         dctl_data_t dctl;
1268         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
1269         DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, core_if);
1270
1271         /* Clear the global non-periodic IN NAK handshake */
1272         dctl.d32 = 0;
1273         dctl.b.cgnpinnak = 1;
1274         DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32,
1275                          dctl.d32);
1276
1277         /* Mask GINTSTS.FETSUSP interrupt */
1278         gintmsk_data.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintmsk);
1279         gintmsk_data.b.fetsusp = 0;
1280         DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, gintmsk_data.d32);
1281
1282         /* Clear interrupt */
1283         gintsts.d32 = 0;
1284         gintsts.b.fetsusp = 1;
1285         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
1286
1287         return 1;
1288 }
1289
1290 /**
1291  * This funcion stalls EP0.
1292  */
1293 static inline void ep0_do_stall(dwc_otg_pcd_t *pcd, const int err_val)
1294 {
1295         dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
1296         usb_device_request_t *ctrl = &pcd->setup_pkt->req;
1297         DWC_WARN("req %02x.%02x protocol STALL; err %d\n",
1298                  ctrl->bmRequestType, ctrl->bRequest, err_val);
1299
1300         ep0->dwc_ep.is_in = 1;
1301         dwc_otg_ep_set_stall(GET_CORE_IF(pcd), &ep0->dwc_ep);
1302         ep0->dwc_ep.is_in = 0;
1303         dwc_otg_ep_set_stall(GET_CORE_IF(pcd), &ep0->dwc_ep);
1304         pcd->ep0.stopped = 1;
1305         pcd->ep0state = EP0_IDLE;
1306         ep0_out_start(GET_CORE_IF(pcd), pcd);
1307 }
1308
1309 /**
1310  * This functions delegates the setup command to the gadget driver.
1311  */
1312 static inline void do_gadget_setup(dwc_otg_pcd_t *pcd,
1313                                    usb_device_request_t *ctrl)
1314 {
1315         int ret = 0;
1316         DWC_SPINUNLOCK(pcd->lock);
1317         ret = pcd->fops->setup(pcd, (uint8_t *) ctrl);
1318         if (spin_is_locked((spinlock_t *) pcd->lock))
1319                 DWC_WARN("%s warning: pcd->lock locked without unlock\n",
1320                          __func__);
1321         DWC_SPINLOCK(pcd->lock);
1322         if (ret < 0) {
1323                 ep0_do_stall(pcd, ret);
1324         }
1325
1326         /** @todo This is a g_file_storage gadget driver specific
1327          * workaround: a DELAYED_STATUS result from the fsg_setup
1328          * routine will result in the gadget queueing a EP0 IN status
1329          * phase for a two-stage control transfer. Exactly the same as
1330          * a SET_CONFIGURATION/SET_INTERFACE except that this is a class
1331          * specific request.  Need a generic way to know when the gadget
1332          * driver will queue the status phase. Can we assume when we
1333          * call the gadget driver setup() function that it will always
1334          * queue and require the following flag? Need to look into
1335          * this.
1336          */
1337
1338         if (ret == 256 + 999) {
1339                 pcd->request_config = 1;
1340         }
1341 }
1342
1343 #ifdef DWC_UTE_CFI
1344 /**
1345  * This functions delegates the CFI setup commands to the gadget driver.
1346  * This function will return a negative value to indicate a failure.
1347  */
1348 static inline int cfi_gadget_setup(dwc_otg_pcd_t *pcd,
1349                                    struct cfi_usb_ctrlrequest *ctrl_req)
1350 {
1351         int ret = 0;
1352
1353         if (pcd->fops && pcd->fops->cfi_setup) {
1354                 DWC_SPINUNLOCK(pcd->lock);
1355                 ret = pcd->fops->cfi_setup(pcd, ctrl_req);
1356                 DWC_SPINLOCK(pcd->lock);
1357                 if (ret < 0) {
1358                         ep0_do_stall(pcd, ret);
1359                         return ret;
1360                 }
1361         }
1362
1363         return ret;
1364 }
1365 #endif
1366
1367 /**
1368  * This function starts the Zero-Length Packet for the IN status phase
1369  * of a 2 stage control transfer.
1370  */
1371 static inline void do_setup_in_status_phase(dwc_otg_pcd_t *pcd)
1372 {
1373         dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
1374         if (pcd->ep0state == EP0_STALL) {
1375                 return;
1376         }
1377
1378         pcd->ep0state = EP0_IN_STATUS_PHASE;
1379
1380         /* Prepare for more SETUP Packets */
1381         DWC_DEBUGPL(DBG_PCD, "EP0 IN ZLP\n");
1382         if ((GET_CORE_IF(pcd)->snpsid >= OTG_CORE_REV_3_00a)
1383             && (pcd->core_if->dma_desc_enable)
1384             && (ep0->dwc_ep.xfer_count < ep0->dwc_ep.total_len)) {
1385                 DWC_DEBUGPL(DBG_PCDV,
1386                             "Data terminated wait next packet in out_desc_addr\n");
1387                 pcd->backup_buf = phys_to_virt(ep0->dwc_ep.dma_addr);
1388                 pcd->data_terminated = 1;
1389         }
1390         ep0->dwc_ep.xfer_len = 0;
1391         ep0->dwc_ep.xfer_count = 0;
1392         ep0->dwc_ep.is_in = 1;
1393         ep0->dwc_ep.dma_addr = pcd->setup_pkt_dma_handle;
1394         dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
1395
1396         /* Prepare for more SETUP Packets */
1397         /* ep0_out_start(GET_CORE_IF(pcd), pcd); */
1398 }
1399
1400 /**
1401  * This function starts the Zero-Length Packet for the OUT status phase
1402  * of a 2 stage control transfer.
1403  */
1404 static inline void do_setup_out_status_phase(dwc_otg_pcd_t *pcd)
1405 {
1406         dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
1407         if (pcd->ep0state == EP0_STALL) {
1408                 DWC_DEBUGPL(DBG_PCD, "EP0 STALLED\n");
1409                 return;
1410         }
1411         pcd->ep0state = EP0_OUT_STATUS_PHASE;
1412
1413         DWC_DEBUGPL(DBG_PCD, "EP0 OUT ZLP\n");
1414         ep0->dwc_ep.xfer_len = 0;
1415         ep0->dwc_ep.xfer_count = 0;
1416         ep0->dwc_ep.is_in = 0;
1417         ep0->dwc_ep.dma_addr = pcd->setup_pkt_dma_handle;
1418         dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
1419
1420         /* Prepare for more SETUP Packets */
1421         if (GET_CORE_IF(pcd)->dma_enable == 0) {
1422                 ep0_out_start(GET_CORE_IF(pcd), pcd);
1423         }
1424 }
1425
1426 /**
1427  * Clear the EP halt (STALL) and if pending requests start the
1428  * transfer.
1429  */
1430 static inline void pcd_clear_halt(dwc_otg_pcd_t *pcd, dwc_otg_pcd_ep_t *ep)
1431 {
1432         if (ep->dwc_ep.stall_clear_flag) {
1433                 /* Start Control Status Phase */
1434                 do_setup_in_status_phase(pcd);
1435                 return;
1436         }
1437
1438         dwc_otg_ep_clear_stall(GET_CORE_IF(pcd), &ep->dwc_ep);
1439
1440         /* Reactive the EP */
1441         dwc_otg_ep_activate(GET_CORE_IF(pcd), &ep->dwc_ep);
1442         if (ep->stopped) {
1443                 ep->stopped = 0;
1444                 /* If there is a request in the EP queue start it */
1445
1446                 /** @todo FIXME: this causes an EP mismatch in DMA mode.
1447                  * epmismatch not yet implemented. */
1448
1449                 /*
1450                  * Above fixme is solved by implmenting a tasklet to call the
1451                  * start_next_request(), outside of interrupt context at some
1452                  * time after the current time, after a clear-halt setup packet.
1453                  * Still need to implement ep mismatch in the future if a gadget
1454                  * ever uses more than one endpoint at once
1455                  */
1456                 ep->queue_sof = 1;
1457                 DWC_TASK_SCHEDULE(pcd->start_xfer_tasklet);
1458         }
1459         /* Start Control Status Phase */
1460         do_setup_in_status_phase(pcd);
1461 }
1462
1463 /**
1464  * This function is called when the SET_FEATURE TEST_MODE Setup packet
1465  * is sent from the host.  The Device Control register is written with
1466  * the Test Mode bits set to the specified Test Mode.  This is done as
1467  * a tasklet so that the "Status" phase of the control transfer
1468  * completes before transmitting the TEST packets.
1469  *
1470  * @todo This has not been tested since the tasklet struct was put
1471  * into the PCD struct!
1472  *
1473  */
1474 void do_test_mode(void *data)
1475 {
1476         dctl_data_t dctl;
1477         dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *) data;
1478         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
1479         int test_mode = pcd->test_mode;
1480
1481         /* DWC_WARN("%s() has not been tested since being rewritten!\n", __func__); */
1482
1483         dctl.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl);
1484         switch (test_mode) {
1485         case 1:         /* TEST_J */
1486                 dctl.b.tstctl = 1;
1487                 break;
1488
1489         case 2:         /* TEST_K */
1490                 dctl.b.tstctl = 2;
1491                 break;
1492
1493         case 3:         /* TEST_SE0_NAK */
1494                 dctl.b.tstctl = 3;
1495                 break;
1496
1497         case 4:         /* TEST_PACKET */
1498                 dctl.b.tstctl = 4;
1499                 break;
1500
1501         case 5:         /* TEST_FORCE_ENABLE */
1502                 dctl.b.tstctl = 5;
1503                 break;
1504         case 7:
1505                 dwc_otg_set_hnpreq(core_if, 1);
1506         }
1507         DWC_PRINTF("test mode = %d\n", test_mode);
1508         core_if->test_mode = test_mode;
1509         DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32);
1510 }
1511
1512 /**
1513  * This function process the GET_STATUS Setup Commands.
1514  */
1515 static inline void do_get_status(dwc_otg_pcd_t *pcd)
1516 {
1517         usb_device_request_t ctrl = pcd->setup_pkt->req;
1518         dwc_otg_pcd_ep_t *ep;
1519         dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
1520         uint16_t *status = pcd->status_buf;
1521         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
1522
1523 #ifdef DEBUG_EP0
1524         DWC_DEBUGPL(DBG_PCD,
1525                     "GET_STATUS %02x.%02x v%04x i%04x l%04x\n",
1526                     ctrl.bmRequestType, ctrl.bRequest,
1527                     UGETW(ctrl.wValue), UGETW(ctrl.wIndex),
1528                     UGETW(ctrl.wLength));
1529 #endif
1530
1531         switch (UT_GET_RECIPIENT(ctrl.bmRequestType)) {
1532         case UT_DEVICE:
1533                 if (UGETW(ctrl.wIndex) == 0xF000) {     /* OTG Status selector */
1534                         DWC_PRINTF("wIndex - %d\n", UGETW(ctrl.wIndex));
1535                         DWC_PRINTF("OTG VERSION - %d\n", core_if->otg_ver);
1536                         DWC_PRINTF("OTG CAP - %d, %d\n",
1537                                    core_if->core_params->otg_cap,
1538                                    DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE);
1539                         if (core_if->otg_ver == 1
1540                             && core_if->core_params->otg_cap ==
1541                             DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) {
1542                                 uint8_t *otgsts = (uint8_t *) pcd->status_buf;
1543                                 *otgsts = (core_if->otg_sts & 0x1);
1544                                 pcd->ep0_pending = 1;
1545                                 ep0->dwc_ep.start_xfer_buff =
1546                                     (uint8_t *) otgsts;
1547                                 ep0->dwc_ep.xfer_buff = (uint8_t *) otgsts;
1548                                 ep0->dwc_ep.dma_addr =
1549                                     pcd->status_buf_dma_handle;
1550                                 ep0->dwc_ep.xfer_len = 1;
1551                                 ep0->dwc_ep.xfer_count = 0;
1552                                 ep0->dwc_ep.total_len = ep0->dwc_ep.xfer_len;
1553                                 dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd),
1554                                                            &ep0->dwc_ep);
1555                                 return;
1556                         } else {
1557                                 ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
1558                                 return;
1559                         }
1560                         break;
1561                 } else {
1562                         *status = 0x1;  /* Self powered */
1563                         *status |= pcd->remote_wakeup_enable << 1;
1564                         break;
1565                 }
1566         case UT_INTERFACE:
1567                 *status = 0;
1568                 break;
1569
1570         case UT_ENDPOINT:
1571                 ep = get_ep_by_addr(pcd, UGETW(ctrl.wIndex));
1572                 if (ep == 0 || UGETW(ctrl.wLength) > 2) {
1573                         ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
1574                         return;
1575                 }
1576                 /** @todo check for EP stall */
1577                 *status = ep->stopped;
1578                 break;
1579         }
1580         pcd->ep0_pending = 1;
1581         ep0->dwc_ep.start_xfer_buff = (uint8_t *) status;
1582         ep0->dwc_ep.xfer_buff = (uint8_t *) status;
1583         ep0->dwc_ep.dma_addr = pcd->status_buf_dma_handle;
1584         ep0->dwc_ep.xfer_len = 2;
1585         ep0->dwc_ep.xfer_count = 0;
1586         ep0->dwc_ep.total_len = ep0->dwc_ep.xfer_len;
1587         dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
1588 }
1589
1590 /**
1591  * This function process the SET_FEATURE Setup Commands.
1592  */
1593 static inline void do_set_feature(dwc_otg_pcd_t *pcd)
1594 {
1595         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
1596         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
1597         usb_device_request_t ctrl = pcd->setup_pkt->req;
1598         dwc_otg_pcd_ep_t *ep = 0;
1599         int32_t otg_cap_param = core_if->core_params->otg_cap;
1600         gotgctl_data_t gotgctl = {.d32 = 0 };
1601
1602         DWC_DEBUGPL(DBG_PCD, "SET_FEATURE:%02x.%02x v%04x i%04x l%04x\n",
1603                     ctrl.bmRequestType, ctrl.bRequest,
1604                     UGETW(ctrl.wValue), UGETW(ctrl.wIndex),
1605                     UGETW(ctrl.wLength));
1606         DWC_DEBUGPL(DBG_PCD, "otg_cap=%d\n", otg_cap_param);
1607
1608         switch (UT_GET_RECIPIENT(ctrl.bmRequestType)) {
1609         case UT_DEVICE:
1610                 switch (UGETW(ctrl.wValue)) {
1611                 case UF_DEVICE_REMOTE_WAKEUP:
1612                         pcd->remote_wakeup_enable = 1;
1613                         break;
1614
1615                 case UF_TEST_MODE:
1616                         /* Setup the Test Mode tasklet to do the Test
1617                          * Packet generation after the SETUP Status
1618                          * phase has completed. */
1619
1620                         /** @todo This has not been tested since the
1621                          * tasklet struct was put into the PCD
1622                          * struct! */
1623                         pcd->test_mode = UGETW(ctrl.wIndex) >> 8;
1624                         DWC_TASK_SCHEDULE(pcd->test_mode_tasklet);
1625                         break;
1626
1627                 case UF_DEVICE_B_HNP_ENABLE:
1628                         DWC_DEBUGPL(DBG_PCDV,
1629                                     "SET_FEATURE: USB_DEVICE_B_HNP_ENABLE\n");
1630
1631                         /* dev may initiate HNP */
1632                         if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) {
1633                                 gotgctl.b.devhnpen = 1;
1634                                 if (core_if->otg_ver == 1)
1635                                         DWC_MODIFY_REG32(&global_regs->gotgctl,
1636                                                          0, gotgctl.d32);
1637                                 else {
1638                                         pcd->b_hnp_enable = 1;
1639                                         dwc_otg_pcd_update_otg(pcd, 0);
1640                                         DWC_DEBUGPL(DBG_PCD, "Request B HNP\n");
1641                                         /**@todo Is the gotgctl.devhnpen cleared
1642                                          * by a USB Reset? */
1643                                         gotgctl.b.hnpreq = 1;
1644                                         DWC_WRITE_REG32(&global_regs->gotgctl,
1645                                                         gotgctl.d32);
1646                                 }
1647                         } else {
1648                                 ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
1649                                 return;
1650                         }
1651                         break;
1652
1653                 case UF_DEVICE_A_HNP_SUPPORT:
1654                         /* RH port supports HNP */
1655                         DWC_DEBUGPL(DBG_PCDV,
1656                                     "SET_FEATURE: USB_DEVICE_A_HNP_SUPPORT\n");
1657                         if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) {
1658                                 pcd->a_hnp_support = 1;
1659                                 dwc_otg_pcd_update_otg(pcd, 0);
1660                         } else {
1661                                 ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
1662                                 return;
1663                         }
1664                         break;
1665
1666                 case UF_DEVICE_A_ALT_HNP_SUPPORT:
1667                         /* other RH port does */
1668                         DWC_DEBUGPL(DBG_PCDV,
1669                                     "SET_FEATURE: USB_DEVICE_A_ALT_HNP_SUPPORT\n");
1670                         if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) {
1671                                 pcd->a_alt_hnp_support = 1;
1672                                 dwc_otg_pcd_update_otg(pcd, 0);
1673                         } else {
1674                                 ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
1675                                 return;
1676                         }
1677                         break;
1678
1679                 default:
1680                         ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
1681                         return;
1682
1683                 }
1684                 do_setup_in_status_phase(pcd);
1685                 break;
1686
1687         case UT_INTERFACE:
1688                 do_gadget_setup(pcd, &ctrl);
1689                 break;
1690
1691         case UT_ENDPOINT:
1692                 if (UGETW(ctrl.wValue) == UF_ENDPOINT_HALT) {
1693                         ep = get_ep_by_addr(pcd, UGETW(ctrl.wIndex));
1694                         if (ep == 0) {
1695                                 ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
1696                                 return;
1697                         }
1698                         ep->stopped = 1;
1699                         dwc_otg_ep_set_stall(core_if, &ep->dwc_ep);
1700                 }
1701                 do_setup_in_status_phase(pcd);
1702                 break;
1703         }
1704 }
1705
1706 /**
1707  * This function process the CLEAR_FEATURE Setup Commands.
1708  */
1709 static inline void do_clear_feature(dwc_otg_pcd_t *pcd)
1710 {
1711         usb_device_request_t ctrl = pcd->setup_pkt->req;
1712         dwc_otg_pcd_ep_t *ep = 0;
1713
1714         DWC_DEBUGPL(DBG_PCD,
1715                     "CLEAR_FEATURE:%02x.%02x v%04x i%04x l%04x\n",
1716                     ctrl.bmRequestType, ctrl.bRequest,
1717                     UGETW(ctrl.wValue), UGETW(ctrl.wIndex),
1718                     UGETW(ctrl.wLength));
1719
1720         switch (UT_GET_RECIPIENT(ctrl.bmRequestType)) {
1721         case UT_DEVICE:
1722                 switch (UGETW(ctrl.wValue)) {
1723                 case UF_DEVICE_REMOTE_WAKEUP:
1724                         pcd->remote_wakeup_enable = 0;
1725                         break;
1726
1727                 case UF_TEST_MODE:
1728                         /** @todo Add CLEAR_FEATURE for TEST modes. */
1729                         break;
1730
1731                 default:
1732                         ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
1733                         return;
1734                 }
1735                 do_setup_in_status_phase(pcd);
1736                 break;
1737
1738         case UT_ENDPOINT:
1739                 ep = get_ep_by_addr(pcd, UGETW(ctrl.wIndex));
1740                 if (ep == 0) {
1741                         ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
1742                         return;
1743                 }
1744
1745                 pcd_clear_halt(pcd, ep);
1746
1747                 break;
1748         }
1749 }
1750
1751 /**
1752  * This function process the SET_ADDRESS Setup Commands.
1753  */
1754 static inline void do_set_address(dwc_otg_pcd_t *pcd)
1755 {
1756         dwc_otg_dev_if_t *dev_if = GET_CORE_IF(pcd)->dev_if;
1757         usb_device_request_t ctrl = pcd->setup_pkt->req;
1758
1759         if (ctrl.bmRequestType == UT_DEVICE) {
1760                 dcfg_data_t dcfg = {.d32 = 0 };
1761
1762 #ifdef DEBUG_EP0
1763                 /* DWC_DEBUGPL(DBG_PCDV, "SET_ADDRESS:%d\n", ctrl.wValue); */
1764 #endif
1765                 dcfg.b.devaddr = UGETW(ctrl.wValue);
1766                 DWC_MODIFY_REG32(&dev_if->dev_global_regs->dcfg, 0, dcfg.d32);
1767                 do_setup_in_status_phase(pcd);
1768         }
1769 }
1770
1771 /**
1772  *      This function processes SETUP commands. In Linux, the USB Command
1773  *      processing is done in two places - the first being the PCD and the
1774  *      second in the Gadget Driver (for example, the File-Backed Storage
1775  *      Gadget Driver).
1776  *
1777  * <table>
1778  * <tr><td>Command      </td><td>Driver </td><td>Description</td></tr>
1779  *
1780  * <tr><td>GET_STATUS </td><td>PCD </td><td>Command is processed as
1781  * defined in chapter 9 of the USB 2.0 Specification chapter 9
1782  * </td></tr>
1783  *
1784  * <tr><td>CLEAR_FEATURE </td><td>PCD </td><td>The Device and Endpoint
1785  * requests are the ENDPOINT_HALT feature is procesed, all others the
1786  * interface requests are ignored.</td></tr>
1787  *
1788  * <tr><td>SET_FEATURE </td><td>PCD </td><td>The Device and Endpoint
1789  * requests are processed by the PCD.  Interface requests are passed
1790  * to the Gadget Driver.</td></tr>
1791  *
1792  * <tr><td>SET_ADDRESS </td><td>PCD </td><td>Program the DCFG reg,
1793  * with device address received </td></tr>
1794  *
1795  * <tr><td>GET_DESCRIPTOR </td><td>Gadget Driver </td><td>Return the
1796  * requested descriptor</td></tr>
1797  *
1798  * <tr><td>SET_DESCRIPTOR </td><td>Gadget Driver </td><td>Optional -
1799  * not implemented by any of the existing Gadget Drivers.</td></tr>
1800  *
1801  * <tr><td>SET_CONFIGURATION </td><td>Gadget Driver </td><td>Disable
1802  * all EPs and enable EPs for new configuration.</td></tr>
1803  *
1804  * <tr><td>GET_CONFIGURATION </td><td>Gadget Driver </td><td>Return
1805  * the current configuration</td></tr>
1806  *
1807  * <tr><td>SET_INTERFACE </td><td>Gadget Driver </td><td>Disable all
1808  * EPs and enable EPs for new configuration.</td></tr>
1809  *
1810  * <tr><td>GET_INTERFACE </td><td>Gadget Driver </td><td>Return the
1811  * current interface.</td></tr>
1812  *
1813  * <tr><td>SYNC_FRAME </td><td>PCD </td><td>Display debug
1814  * message.</td></tr>
1815  * </table>
1816  *
1817  * When the SETUP Phase Done interrupt occurs, the PCD SETUP commands are
1818  * processed by pcd_setup. Calling the Function Driver's setup function from
1819  *pcd_setup processes the gadget SETUP commands.
1820  */
1821 static inline void pcd_setup(dwc_otg_pcd_t *pcd)
1822 {
1823         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
1824         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
1825         usb_device_request_t ctrl = pcd->setup_pkt->req;
1826         dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
1827
1828         deptsiz0_data_t doeptsize0 = {.d32 = 0 };
1829
1830 #ifdef DWC_UTE_CFI
1831         int retval = 0;
1832         struct cfi_usb_ctrlrequest cfi_req;
1833 #endif
1834
1835         doeptsize0.d32 = DWC_READ_REG32(&dev_if->out_ep_regs[0]->doeptsiz);
1836
1837         /** In BDMA more then 1 setup packet is not supported till 3.00a */
1838         if (core_if->dma_enable && core_if->dma_desc_enable == 0
1839             && (doeptsize0.b.supcnt < 2)
1840             && (core_if->snpsid < OTG_CORE_REV_2_94a)) {
1841                 DWC_ERROR
1842                     ("\n\n-----------    CANNOT handle > 1 setup packet in DMA mode\n\n");
1843         }
1844         if ((core_if->snpsid >= OTG_CORE_REV_3_00a)
1845             && (core_if->dma_enable == 1) && (core_if->dma_desc_enable == 0)) {
1846                 ctrl =
1847                     (pcd->setup_pkt +
1848                      (3 - doeptsize0.b.supcnt - 1 +
1849                       ep0->dwc_ep.stp_rollover))->req;
1850         }
1851 #ifdef DEBUG_EP0
1852         DWC_DEBUGPL(DBG_PCD, "SETUP %02x.%02x v%04x i%04x l%04x\n",
1853                     ctrl.bmRequestType, ctrl.bRequest,
1854                     UGETW(ctrl.wValue), UGETW(ctrl.wIndex),
1855                     UGETW(ctrl.wLength));
1856 #endif
1857
1858         /* Clean up the request queue */
1859         dwc_otg_request_nuke(ep0);
1860         ep0->stopped = 0;
1861
1862         if (ctrl.bmRequestType & UE_DIR_IN) {
1863                 ep0->dwc_ep.is_in = 1;
1864                 pcd->ep0state = EP0_IN_DATA_PHASE;
1865         } else {
1866                 ep0->dwc_ep.is_in = 0;
1867                 pcd->ep0state = EP0_OUT_DATA_PHASE;
1868         }
1869
1870         if (UGETW(ctrl.wLength) == 0) {
1871                 ep0->dwc_ep.is_in = 1;
1872                 pcd->ep0state = EP0_IN_STATUS_PHASE;
1873         }
1874
1875         if (UT_GET_TYPE(ctrl.bmRequestType) != UT_STANDARD) {
1876
1877 #ifdef DWC_UTE_CFI
1878                 DWC_MEMCPY(&cfi_req, &ctrl, sizeof(usb_device_request_t));
1879
1880                 /* printk(KERN_ALERT "CFI: req_type=0x%02x; req=0x%02x\n",
1881                  * ctrl.bRequestType, ctrl.bRequest); */
1882                 if (UT_GET_TYPE(cfi_req.bRequestType) == UT_VENDOR) {
1883                         if (cfi_req.bRequest > 0xB0 && cfi_req.bRequest < 0xBF) {
1884                                 retval = cfi_setup(pcd, &cfi_req);
1885                                 if (retval < 0) {
1886                                         ep0_do_stall(pcd, retval);
1887                                         pcd->ep0_pending = 0;
1888                                         return;
1889                                 }
1890
1891                                 /* if need gadget setup then call it and check the retval */
1892                                 if (pcd->cfi->need_gadget_att) {
1893                                         retval =
1894                                             cfi_gadget_setup(pcd,
1895                                                              &pcd->
1896                                                              cfi->ctrl_req);
1897                                         if (retval < 0) {
1898                                                 pcd->ep0_pending = 0;
1899                                                 return;
1900                                         }
1901                                 }
1902
1903                                 if (pcd->cfi->need_status_in_complete) {
1904                                         do_setup_in_status_phase(pcd);
1905                                 }
1906                                 return;
1907                         }
1908                 }
1909 #endif
1910
1911                 /* handle non-standard (class/vendor) requests in the gadget driver */
1912                 do_gadget_setup(pcd, &ctrl);
1913                 return;
1914         }
1915
1916         /** @todo NGS: Handle bad setup packet? */
1917
1918         /* --- Standard Request handling --- */
1919
1920         switch (ctrl.bRequest) {
1921         case UR_GET_STATUS:
1922                 do_get_status(pcd);
1923                 break;
1924
1925         case UR_CLEAR_FEATURE:
1926                 do_clear_feature(pcd);
1927                 break;
1928
1929         case UR_SET_FEATURE:
1930                 do_set_feature(pcd);
1931                 break;
1932
1933         case UR_SET_ADDRESS:
1934                 do_set_address(pcd);
1935                 break;
1936
1937         case UR_SET_INTERFACE:
1938         case UR_SET_CONFIG:
1939                 /* _pcd->request_config = 1; */      /* Configuration changed */
1940                 do_gadget_setup(pcd, &ctrl);
1941                 break;
1942
1943         case UR_SYNCH_FRAME:
1944                 do_gadget_setup(pcd, &ctrl);
1945                 break;
1946
1947         default:
1948                 /* Call the Gadget Driver's setup functions */
1949                 do_gadget_setup(pcd, &ctrl);
1950                 break;
1951         }
1952 }
1953
1954 /**
1955  * This function completes the ep0 control transfer.
1956  */
1957 static int32_t ep0_complete_request(dwc_otg_pcd_ep_t *ep)
1958 {
1959         dwc_otg_core_if_t *core_if = GET_CORE_IF(ep->pcd);
1960         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
1961         dwc_otg_dev_in_ep_regs_t *in_ep_regs =
1962             dev_if->in_ep_regs[ep->dwc_ep.num];
1963 #ifdef DEBUG_EP0
1964         dwc_otg_dev_out_ep_regs_t *out_ep_regs =
1965             dev_if->out_ep_regs[ep->dwc_ep.num];
1966 #endif
1967         deptsiz0_data_t deptsiz;
1968         dev_dma_desc_sts_t desc_sts;
1969         dwc_otg_pcd_request_t *req;
1970         int is_last = 0;
1971         dwc_otg_pcd_t *pcd = ep->pcd;
1972
1973 #ifdef DWC_UTE_CFI
1974         struct cfi_usb_ctrlrequest *ctrlreq;
1975         int retval = -DWC_E_NOT_SUPPORTED;
1976 #endif
1977
1978         if (pcd->ep0_pending && DWC_CIRCLEQ_EMPTY(&ep->queue)) {
1979                 if (ep->dwc_ep.is_in) {
1980 #ifdef DEBUG_EP0
1981                         DWC_DEBUGPL(DBG_PCDV, "Do setup OUT status phase\n");
1982 #endif
1983                         do_setup_out_status_phase(pcd);
1984                 } else {
1985 #ifdef DEBUG_EP0
1986                         DWC_DEBUGPL(DBG_PCDV, "Do setup IN status phase\n");
1987 #endif
1988
1989 #ifdef DWC_UTE_CFI
1990                         ctrlreq = &pcd->cfi->ctrl_req;
1991
1992                         if (UT_GET_TYPE(ctrlreq->bRequestType) == UT_VENDOR) {
1993                                 if (ctrlreq->bRequest > 0xB0
1994                                     && ctrlreq->bRequest < 0xBF) {
1995
1996                                         /* Return if the PCD failed to handle the request */
1997                                         retval = pcd->cfi->ops.
1998                                                  ctrl_write_complete(pcd->cfi, pcd);
1999                                         if (retval < 0) {
2000                                                 CFI_INFO
2001                                                     ("ERROR setting a new value in the PCD(%d)\n",
2002                                                      retval);
2003                                                 ep0_do_stall(pcd, retval);
2004                                                 pcd->ep0_pending = 0;
2005                                                 return 0;
2006                                         }
2007
2008                                         /* If the gadget needs to be notified on the request */
2009                                         if (pcd->cfi->need_gadget_att == 1) {
2010                                                 /* retval = do_gadget_setup(pcd, &pcd->cfi->ctrl_req); */
2011                                                 retval =
2012                                                     cfi_gadget_setup(pcd,
2013                                                                      &pcd->cfi->
2014                                                                      ctrl_req);
2015
2016                                                 /* Return from the function if the gadget failed to process
2017                                                  * the request properly - this should never happen !!!
2018                                                  */
2019                                                 if (retval < 0) {
2020                                                         CFI_INFO
2021                                                             ("ERROR setting a new value in the gadget(%d)\n",
2022                                                              retval);
2023                                                         pcd->ep0_pending = 0;
2024                                                         return 0;
2025                                                 }
2026                                         }
2027
2028                                         CFI_INFO("%s: RETVAL=%d\n", __func__,
2029                                                  retval);
2030                                         /* If we hit here then the PCD and the gadget has properly
2031                                          * handled the request - so send the ZLP IN to the host.
2032                                          */
2033                                         /* @todo: MAS - decide whether we need to start the setup
2034                                          * stage based on the need_setup value of the cfi object
2035                                          */
2036                                         do_setup_in_status_phase(pcd);
2037                                         pcd->ep0_pending = 0;
2038                                         return 1;
2039                                 }
2040                         }
2041 #endif
2042
2043                         do_setup_in_status_phase(pcd);
2044                 }
2045                 pcd->ep0_pending = 0;
2046                 return 1;
2047         }
2048
2049         if (DWC_CIRCLEQ_EMPTY(&ep->queue)) {
2050                 return 0;
2051         }
2052         req = DWC_CIRCLEQ_FIRST(&ep->queue);
2053
2054         if (pcd->ep0state == EP0_OUT_STATUS_PHASE
2055             || pcd->ep0state == EP0_IN_STATUS_PHASE) {
2056                 is_last = 1;
2057         } else if (ep->dwc_ep.is_in) {
2058                 deptsiz.d32 = DWC_READ_REG32(&in_ep_regs->dieptsiz);
2059                 if (core_if->dma_desc_enable != 0)
2060                         desc_sts = dev_if->in_desc_addr->status;
2061 #ifdef DEBUG_EP0
2062                 DWC_DEBUGPL(DBG_PCDV, "%d len=%d  xfersize=%d pktcnt=%d\n",
2063                             ep->dwc_ep.num, ep->dwc_ep.xfer_len,
2064                             deptsiz.b.xfersize, deptsiz.b.pktcnt);
2065 #endif
2066
2067                 if (((core_if->dma_desc_enable == 0)
2068                      && (deptsiz.b.xfersize == 0))
2069                     || ((core_if->dma_desc_enable != 0)
2070                         && (desc_sts.b.bytes == 0))) {
2071                         req->actual = ep->dwc_ep.xfer_count;
2072                         /* Is a Zero Len Packet needed? */
2073                         if (req->sent_zlp) {
2074 #ifdef DEBUG_EP0
2075                                 DWC_DEBUGPL(DBG_PCD, "Setup Rx ZLP\n");
2076 #endif
2077                                 req->sent_zlp = 0;
2078                         }
2079                         do_setup_out_status_phase(pcd);
2080                 }
2081         } else {
2082                 /* ep0-OUT */
2083 #ifdef DEBUG_EP0
2084                 deptsiz.d32 = DWC_READ_REG32(&out_ep_regs->doeptsiz);
2085                 DWC_DEBUGPL(DBG_PCDV, "%d len=%d xsize=%d pktcnt=%d\n",
2086                             ep->dwc_ep.num, ep->dwc_ep.xfer_len,
2087                             deptsiz.b.xfersize, deptsiz.b.pktcnt);
2088 #endif
2089                 req->actual = ep->dwc_ep.xfer_count;
2090
2091                 /* Is a Zero Len Packet needed? */
2092                 if (req->sent_zlp) {
2093 #ifdef DEBUG_EP0
2094                         DWC_DEBUGPL(DBG_PCDV, "Setup Tx ZLP\n");
2095 #endif
2096                         req->sent_zlp = 0;
2097                 }
2098                 /* For older cores do setup in status phase in Slave/BDMA modes,
2099                  * starting from 3.00 do that only in slave, and for DMA modes
2100                  * just re-enable ep 0 OUT here*/
2101                 if (core_if->dma_enable == 0
2102                     || (core_if->dma_desc_enable == 0
2103                         && core_if->snpsid <= OTG_CORE_REV_2_94a)) {
2104                         do_setup_in_status_phase(pcd);
2105                 } else if (core_if->snpsid >= OTG_CORE_REV_3_00a) {
2106                         DWC_DEBUGPL(DBG_PCDV,
2107                                     "Enable out ep before in status phase\n");
2108                         ep0_out_start(core_if, pcd);
2109                 }
2110         }
2111
2112         /* Complete the request */
2113         if (is_last) {
2114                 dwc_otg_request_done(ep, req, 0);
2115                 ep->dwc_ep.start_xfer_buff = 0;
2116                 ep->dwc_ep.xfer_buff = 0;
2117                 ep->dwc_ep.xfer_len = 0;
2118                 return 1;
2119         }
2120         return 0;
2121 }
2122
2123 #ifdef DWC_UTE_CFI
2124 /**
2125  * This function calculates traverses all the CFI DMA descriptors and
2126  * and accumulates the bytes that are left to be transfered.
2127  *
2128  * @return The total bytes left to transfered, or a negative value as failure
2129  */
2130 static inline int cfi_calc_desc_residue(dwc_otg_pcd_ep_t *ep)
2131 {
2132         int32_t ret = 0;
2133         int i;
2134         struct dwc_otg_dma_desc *ddesc = NULL;
2135         struct cfi_ep *cfiep;
2136
2137         /* See if the pcd_ep has its respective cfi_ep mapped */
2138         cfiep = get_cfi_ep_by_pcd_ep(ep->pcd->cfi, ep);
2139         if (!cfiep) {
2140                 CFI_INFO("%s: Failed to find ep\n", __func__);
2141                 return -1;
2142         }
2143
2144         ddesc = ep->dwc_ep.descs;
2145
2146         for (i = 0; (i < cfiep->desc_count) && (i < MAX_DMA_DESCS_PER_EP); i++) {
2147
2148 #if defined(PRINT_CFI_DMA_DESCS)
2149                 print_desc(ddesc, ep->ep.name, i);
2150 #endif
2151                 ret += ddesc->status.b.bytes;
2152                 ddesc++;
2153         }
2154
2155         if (ret)
2156                 CFI_INFO("!!!!!!!!!! WARNING (%s) - residue=%d\n", __func__,
2157                          ret);
2158
2159         return ret;
2160 }
2161 #endif
2162
2163 /**
2164  * This function completes the request for the EP. If there are
2165  * additional requests for the EP in the queue they will be started.
2166  */
2167 static void complete_ep(dwc_otg_pcd_ep_t *ep)
2168 {
2169         dwc_otg_core_if_t *core_if = GET_CORE_IF(ep->pcd);
2170         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
2171         dwc_otg_dev_in_ep_regs_t *in_ep_regs =
2172             dev_if->in_ep_regs[ep->dwc_ep.num];
2173         deptsiz_data_t deptsiz;
2174         dev_dma_desc_sts_t desc_sts;
2175         dwc_otg_pcd_request_t *req = 0;
2176         dwc_otg_dev_dma_desc_t *dma_desc;
2177         uint32_t byte_count = 0;
2178         int is_last = 0;
2179         int i;
2180
2181         DWC_DEBUGPL(DBG_PCDV, "%s() %d-%s\n", __func__, ep->dwc_ep.num,
2182                     (ep->dwc_ep.is_in ? "IN" : "OUT"));
2183
2184         /* Get any pending requests */
2185         if (!DWC_CIRCLEQ_EMPTY(&ep->queue)) {
2186                 req = DWC_CIRCLEQ_FIRST(&ep->queue);
2187                 if (!req) {
2188                         DWC_PRINTF("complete_ep 0x%p, req = NULL!\n", ep);
2189                         return;
2190                 }
2191         } else {
2192                 DWC_PRINTF("complete_ep 0x%p, ep->queue empty!\n", ep);
2193                 return;
2194         }
2195
2196         DWC_DEBUGPL(DBG_PCD, "Requests %d\n", ep->pcd->request_pending);
2197
2198         if (ep->dwc_ep.is_in) {
2199                 deptsiz.d32 = DWC_READ_REG32(&in_ep_regs->dieptsiz);
2200
2201                 if (core_if->dma_enable) {
2202                         if (core_if->dma_desc_enable == 0) {
2203                                 if (deptsiz.b.xfersize == 0
2204                                     && deptsiz.b.pktcnt == 0) {
2205                                         byte_count =
2206                                             ep->dwc_ep.xfer_len -
2207                                             ep->dwc_ep.xfer_count;
2208
2209                                         ep->dwc_ep.xfer_buff += byte_count;
2210                                         ep->dwc_ep.dma_addr += byte_count;
2211                                         ep->dwc_ep.xfer_count += byte_count;
2212
2213                                         DWC_DEBUGPL(DBG_PCDV,
2214                                                     "%d-%s len=%d  xfersize=%d pktcnt=%d\n",
2215                                                     ep->dwc_ep.num,
2216                                                     (ep->dwc_ep.is_in ? "IN" :
2217                                                      "OUT"),
2218                                                     ep->dwc_ep.xfer_len,
2219                                                     deptsiz.b.xfersize,
2220                                                     deptsiz.b.pktcnt);
2221
2222                                         if (ep->dwc_ep.xfer_len <
2223                                             ep->dwc_ep.total_len) {
2224                                                 dwc_otg_ep_start_transfer
2225                                                     (core_if, &ep->dwc_ep);
2226                                         } else if (ep->dwc_ep.sent_zlp) {
2227                                                 /*
2228                                                  * This fragment of code should initiate 0
2229                                                  * length transfer in case if it is queued
2230                                                  * a transfer with size divisible to EPs max
2231                                                  * packet size and with usb_request zero field
2232                                                  * is set, which means that after data is transfered,
2233                                                  * it is also should be transfered
2234                                                  * a 0 length packet at the end. For Slave and
2235                                                  * Buffer DMA modes in this case SW has
2236                                                  * to initiate 2 transfers one with transfer size,
2237                                                  * and the second with 0 size. For Descriptor
2238                                                  * DMA mode SW is able to initiate a transfer,
2239                                                  * which will handle all the packets including
2240                                                  * the last  0 length.
2241                                                  */
2242                                                 ep->dwc_ep.sent_zlp = 0;
2243                                                 dwc_otg_ep_start_zl_transfer
2244                                                     (core_if, &ep->dwc_ep);
2245                                         } else {
2246                                                 is_last = 1;
2247                                         }
2248                                 } else {
2249                                         if (ep->dwc_ep.type ==
2250                                             DWC_OTG_EP_TYPE_ISOC) {
2251                                                 req->actual = 0;
2252                                                 dwc_otg_request_done(ep, req,
2253                                                                      0);
2254
2255                                                 ep->dwc_ep.start_xfer_buff = 0;
2256                                                 ep->dwc_ep.xfer_buff = 0;
2257                                                 ep->dwc_ep.xfer_len = 0;
2258
2259                                                 /* If there is a request in the queue start it. */
2260                                                 start_next_request(ep);
2261                                         } else
2262                                                 DWC_WARN
2263                                                     ("Incomplete transfer (%d - %s [siz=%d pkt=%d])\n",
2264                                                      ep->dwc_ep.num,
2265                                                      (ep->
2266                                                       dwc_ep.is_in ? "IN" :
2267                                                       "OUT"),
2268                                                      deptsiz.b.xfersize,
2269                                                      deptsiz.b.pktcnt);
2270                                 }
2271                         } else {
2272                                 dma_desc = ep->dwc_ep.desc_addr;
2273                                 byte_count = 0;
2274                                 ep->dwc_ep.sent_zlp = 0;
2275
2276 #ifdef DWC_UTE_CFI
2277                                 CFI_INFO("%s: BUFFER_MODE=%d\n", __func__,
2278                                          ep->dwc_ep.buff_mode);
2279                                 if (ep->dwc_ep.buff_mode != BM_STANDARD) {
2280                                         int residue;
2281
2282                                         residue = cfi_calc_desc_residue(ep);
2283                                         if (residue < 0)
2284                                                 return;
2285
2286                                         byte_count = residue;
2287                                 } else {
2288 #endif
2289                                         for (i = 0; i < ep->dwc_ep.desc_cnt;
2290                                              ++i) {
2291                                                 desc_sts = dma_desc->status;
2292                                                 byte_count += desc_sts.b.bytes;
2293                                                 dma_desc++;
2294                                         }
2295 #ifdef DWC_UTE_CFI
2296                                 }
2297 #endif
2298                                 if (byte_count == 0) {
2299                                         ep->dwc_ep.xfer_count =
2300                                             ep->dwc_ep.total_len;
2301                                         is_last = 1;
2302                                 } else {
2303                                         DWC_WARN("Incomplete transfer\n");
2304                                 }
2305                         }
2306                 } else {
2307                         if (deptsiz.b.xfersize == 0 && deptsiz.b.pktcnt == 0) {
2308                                 DWC_DEBUGPL(DBG_PCDV,
2309                                             "%d-%s len=%d  xfersize=%d pktcnt=%d\n",
2310                                             ep->dwc_ep.num,
2311                                             ep->dwc_ep.is_in ? "IN" : "OUT",
2312                                             ep->dwc_ep.xfer_len,
2313                                             deptsiz.b.xfersize,
2314                                             deptsiz.b.pktcnt);
2315
2316                                 /*      Check if the whole transfer was completed,
2317                                  *      if no, setup transfer for next portion of data
2318                                  */
2319                                 if (ep->dwc_ep.xfer_len < ep->dwc_ep.total_len) {
2320                                         dwc_otg_ep_start_transfer(core_if,
2321                                                                   &ep->dwc_ep);
2322                                 } else if (ep->dwc_ep.sent_zlp) {
2323                                         /*
2324                                          * This fragment of code should initiate 0
2325                                          * length trasfer in case if it is queued
2326                                          * a trasfer with size divisible to EPs max
2327                                          * packet size and with usb_request zero field
2328                                          * is set, which means that after data is transfered,
2329                                          * it is also should be transfered
2330                                          * a 0 length packet at the end. For Slave and
2331                                          * Buffer DMA modes in this case SW has
2332                                          * to initiate 2 transfers one with transfer size,
2333                                          * and the second with 0 size. For Desriptor
2334                                          * DMA mode SW is able to initiate a transfer,
2335                                          * which will handle all the packets including
2336                                          * the last  0 legth.
2337                                          */
2338                                         ep->dwc_ep.sent_zlp = 0;
2339                                         dwc_otg_ep_start_zl_transfer(core_if,
2340                                                                      &ep->dwc_ep);
2341                                 } else {
2342                                         is_last = 1;
2343                                 }
2344                         } else {
2345                                 DWC_WARN
2346                                     ("Incomplete transfer (%d-%s [siz=%d pkt=%d])\n",
2347                                      ep->dwc_ep.num,
2348                                      (ep->dwc_ep.is_in ? "IN" : "OUT"),
2349                                      deptsiz.b.xfersize, deptsiz.b.pktcnt);
2350                         }
2351                 }
2352         } else {
2353                 dwc_otg_dev_out_ep_regs_t *out_ep_regs =
2354                     dev_if->out_ep_regs[ep->dwc_ep.num];
2355                 desc_sts.d32 = 0;
2356                 if (core_if->dma_enable) {
2357                         if (core_if->dma_desc_enable) {
2358                                 dma_desc = ep->dwc_ep.desc_addr;
2359                                 byte_count = 0;
2360                                 ep->dwc_ep.sent_zlp = 0;
2361
2362 #ifdef DWC_UTE_CFI
2363                                 CFI_INFO("%s: BUFFER_MODE=%d\n", __func__,
2364                                          ep->dwc_ep.buff_mode);
2365                                 if (ep->dwc_ep.buff_mode != BM_STANDARD) {
2366                                         int residue;
2367                                         residue = cfi_calc_desc_residue(ep);
2368                                         if (residue < 0)
2369                                                 return;
2370                                         byte_count = residue;
2371                                 } else {
2372 #endif
2373
2374                                         for (i = 0; i < ep->dwc_ep.desc_cnt;
2375                                              ++i) {
2376                                                 desc_sts = dma_desc->status;
2377                                                 byte_count += desc_sts.b.bytes;
2378                                                 dma_desc++;
2379                                         }
2380
2381 #ifdef DWC_UTE_CFI
2382                                 }
2383 #endif
2384                                 /* Checking for interrupt Out transfers with not
2385                                  * dword aligned mps sizes
2386                                  */
2387                                 if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_INTR &&
2388                                     (ep->dwc_ep.maxpacket % 4)) {
2389                                         ep->dwc_ep.xfer_count =
2390                                             ep->dwc_ep.total_len - byte_count;
2391                                         if ((ep->dwc_ep.xfer_len %
2392                                              ep->dwc_ep.maxpacket)
2393                                             && (ep->dwc_ep.xfer_len /
2394                                                 ep->dwc_ep.maxpacket <
2395                                                 MAX_DMA_DESC_CNT))
2396                                                 ep->dwc_ep.xfer_len -=
2397                                                     (ep->dwc_ep.desc_cnt -
2398                                                      1)*ep->dwc_ep.maxpacket +
2399                                                     ep->dwc_ep.xfer_len %
2400                                                     ep->dwc_ep.maxpacket;
2401                                         else
2402                                                 ep->dwc_ep.xfer_len -=
2403                                                     ep->dwc_ep.desc_cnt *
2404                                                     ep->dwc_ep.maxpacket;
2405                                         if (ep->dwc_ep.xfer_len > 0) {
2406                                                 dwc_otg_ep_start_transfer
2407                                                     (core_if, &ep->dwc_ep);
2408                                         } else {
2409                                                 is_last = 1;
2410                                         }
2411                                 } else {
2412                                         ep->dwc_ep.xfer_count =
2413                                             ep->dwc_ep.total_len - byte_count +
2414                                             ((4 -
2415                                               (ep->dwc_ep.
2416                                                total_len & 0x3)) & 0x3);
2417                                         is_last = 1;
2418                                 }
2419                         } else {
2420                                 deptsiz.d32 = 0;
2421                                 deptsiz.d32 =
2422                                     DWC_READ_REG32(&out_ep_regs->doeptsiz);
2423
2424                                 byte_count = (ep->dwc_ep.xfer_len -
2425                                               ep->dwc_ep.xfer_count -
2426                                               deptsiz.b.xfersize);
2427                                 ep->dwc_ep.xfer_buff += byte_count;
2428                                 ep->dwc_ep.dma_addr += byte_count;
2429                                 ep->dwc_ep.xfer_count += byte_count;
2430
2431                                 /*      Check if the whole transfer was completed,
2432                                  *      if no, setup transfer for next portion of data
2433                                  */
2434                                 if (ep->dwc_ep.xfer_len < ep->dwc_ep.total_len) {
2435                                         dwc_otg_ep_start_transfer(core_if,
2436                                                                   &ep->dwc_ep);
2437                                 } else if (ep->dwc_ep.sent_zlp) {
2438                                         /*
2439                                          * This fragment of code should initiate 0
2440                                          * length trasfer in case if it is queued
2441                                          * a trasfer with size divisible to EPs max
2442                                          * packet size and with usb_request zero field
2443                                          * is set, which means that after data is transfered,
2444                                          * it is also should be transfered
2445                                          * a 0 length packet at the end. For Slave and
2446                                          * Buffer DMA modes in this case SW has
2447                                          * to initiate 2 transfers one with transfer size,
2448                                          * and the second with 0 size. For Desriptor
2449                                          * DMA mode SW is able to initiate a transfer,
2450                                          * which will handle all the packets including
2451                                          * the last  0 legth.
2452                                          */
2453                                         ep->dwc_ep.sent_zlp = 0;
2454                                         dwc_otg_ep_start_zl_transfer(core_if,
2455                                                                      &ep->dwc_ep);
2456                                 } else {
2457                                         is_last = 1;
2458                                 }
2459                         }
2460                 } else {
2461                         /*      Check if the whole transfer was completed,
2462                          *      if no, setup transfer for next portion of data
2463                          */
2464                         if (ep->dwc_ep.xfer_len < ep->dwc_ep.total_len) {
2465                                 dwc_otg_ep_start_transfer(core_if, &ep->dwc_ep);
2466                         } else if (ep->dwc_ep.sent_zlp) {
2467                                 /*
2468                                  * This fragment of code should initiate 0
2469                                  * length transfer in case if it is queued
2470                                  * a transfer with size divisible to EPs max
2471                                  * packet size and with usb_request zero field
2472                                  * is set, which means that after data is transfered,
2473                                  * it is also should be transfered
2474                                  * a 0 length packet at the end. For Slave and
2475                                  * Buffer DMA modes in this case SW has
2476                                  * to initiate 2 transfers one with transfer size,
2477                                  * and the second with 0 size. For Descriptor
2478                                  * DMA mode SW is able to initiate a transfer,
2479                                  * which will handle all the packets including
2480                                  * the last  0 length.
2481                                  */
2482                                 ep->dwc_ep.sent_zlp = 0;
2483                                 dwc_otg_ep_start_zl_transfer(core_if,
2484                                                              &ep->dwc_ep);
2485                         } else {
2486                                 is_last = 1;
2487                         }
2488                 }
2489
2490                 DWC_DEBUGPL(DBG_PCDV,
2491                             "addr %p,    %d-%s len=%d cnt=%d xsize=%d pktcnt=%d\n",
2492                             &out_ep_regs->doeptsiz, ep->dwc_ep.num,
2493                             ep->dwc_ep.is_in ? "IN" : "OUT",
2494                             ep->dwc_ep.xfer_len, ep->dwc_ep.xfer_count,
2495                             deptsiz.b.xfersize, deptsiz.b.pktcnt);
2496         }
2497
2498         /* Complete the request */
2499         if (is_last) {
2500 #ifdef DWC_UTE_CFI
2501                 if (ep->dwc_ep.buff_mode != BM_STANDARD) {
2502                         req->actual = ep->dwc_ep.cfi_req_len - byte_count;
2503                 } else {
2504 #endif
2505                         req->actual = ep->dwc_ep.xfer_count;
2506 #ifdef DWC_UTE_CFI
2507                 }
2508 #endif
2509                 if (req->dw_align_buf) {
2510                         if (!ep->dwc_ep.is_in) {
2511                                 dwc_memcpy(req->buf, req->dw_align_buf,
2512                                            req->length);
2513                         }
2514                         DWC_DMA_FREE(req->length, req->dw_align_buf,
2515                                      req->dw_align_buf_dma);
2516                 }
2517
2518                 dwc_otg_request_done(ep, req, 0);
2519
2520                 ep->dwc_ep.start_xfer_buff = 0;
2521                 ep->dwc_ep.xfer_buff = 0;
2522                 ep->dwc_ep.xfer_len = 0;
2523
2524                 /* If there is a request in the queue start it. */
2525                 start_next_request(ep);
2526         }
2527 }
2528
2529 #ifdef DWC_EN_ISOC
2530
2531 /**
2532  * This function BNA interrupt for Isochronous EPs
2533  *
2534  */
2535 static void dwc_otg_pcd_handle_iso_bna(dwc_otg_pcd_ep_t *ep)
2536 {
2537         dwc_ep_t *dwc_ep = &ep->dwc_ep;
2538         volatile uint32_t *addr;
2539         depctl_data_t depctl = {
2540         .d32 = 0};
2541         dwc_otg_pcd_t *pcd = ep->pcd;
2542         dwc_otg_dev_dma_desc_t *dma_desc;
2543         int i;
2544
2545         dma_desc =
2546             dwc_ep->iso_desc_addr + dwc_ep->desc_cnt * (dwc_ep->proc_buf_num);
2547
2548         if (dwc_ep->is_in) {
2549                 dev_dma_desc_sts_t sts = {
2550                 .d32 = 0};
2551                 for (i = 0; i < dwc_ep->desc_cnt; ++i, ++dma_desc) {
2552                         sts.d32 = dma_desc->status.d32;
2553                         sts.b_iso_in.bs = BS_HOST_READY;
2554                         dma_desc->status.d32 = sts.d32;
2555                 }
2556         } else {
2557                 dev_dma_desc_sts_t sts = {
2558                 .d32 = 0};
2559                 for (i = 0; i < dwc_ep->desc_cnt; ++i, ++dma_desc) {
2560                         sts.d32 = dma_desc->status.d32;
2561                         sts.b_iso_out.bs = BS_HOST_READY;
2562                         dma_desc->status.d32 = sts.d32;
2563                 }
2564         }
2565
2566         if (dwc_ep->is_in == 0) {
2567                 addr =
2568                     &GET_CORE_IF(pcd)->dev_if->out_ep_regs[dwc_ep->
2569                                                            num]->doepctl;
2570         } else {
2571                 addr =
2572                     &GET_CORE_IF(pcd)->dev_if->in_ep_regs[dwc_ep->num]->diepctl;
2573         }
2574         depctl.b.epena = 1;
2575         DWC_MODIFY_REG32(addr, depctl.d32, depctl.d32);
2576 }
2577
2578 /**
2579  * This function sets latest iso packet information(non-PTI mode)
2580  *
2581  * @param core_if Programming view of DWC_otg controller.
2582  * @param ep The EP to start the transfer on.
2583  *
2584  */
2585 void set_current_pkt_info(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
2586 {
2587         deptsiz_data_t deptsiz = {
2588         .d32 = 0};
2589         dma_addr_t dma_addr;
2590         uint32_t offset;
2591
2592         if (ep->proc_buf_num)
2593                 dma_addr = ep->dma_addr1;
2594         else
2595                 dma_addr = ep->dma_addr0;
2596
2597         if (ep->is_in) {
2598                 deptsiz.d32 =
2599                     DWC_READ_REG32(&core_if->dev_if->
2600                                    in_ep_regs[ep->num]->dieptsiz);
2601                 offset = ep->data_per_frame;
2602         } else {
2603                 deptsiz.d32 =
2604                     DWC_READ_REG32(&core_if->dev_if->
2605                                    out_ep_regs[ep->num]->doeptsiz);
2606                 offset =
2607                     ep->data_per_frame +
2608                     (0x4 & (0x4 - (ep->data_per_frame & 0x3)));
2609         }
2610
2611         if (!deptsiz.b.xfersize) {
2612                 ep->pkt_info[ep->cur_pkt].length = ep->data_per_frame;
2613                 ep->pkt_info[ep->cur_pkt].offset =
2614                     ep->cur_pkt_dma_addr - dma_addr;
2615                 ep->pkt_info[ep->cur_pkt].status = 0;
2616         } else {
2617                 ep->pkt_info[ep->cur_pkt].length = ep->data_per_frame;
2618                 ep->pkt_info[ep->cur_pkt].offset =
2619                     ep->cur_pkt_dma_addr - dma_addr;
2620                 ep->pkt_info[ep->cur_pkt].status = -DWC_E_NO_DATA;
2621         }
2622         ep->cur_pkt_addr += offset;
2623         ep->cur_pkt_dma_addr += offset;
2624         ep->cur_pkt++;
2625 }
2626
2627 /**
2628  * This function sets latest iso packet information(DDMA mode)
2629  *
2630  * @param core_if Programming view of DWC_otg controller.
2631  * @param dwc_ep The EP to start the transfer on.
2632  *
2633  */
2634 static void set_ddma_iso_pkts_info(dwc_otg_core_if_t *core_if,
2635                                    dwc_ep_t *dwc_ep) {
2636         dwc_otg_dev_dma_desc_t *dma_desc;
2637         dev_dma_desc_sts_t sts = {
2638         .d32 = 0};
2639         iso_pkt_info_t *iso_packet;
2640         uint32_t data_per_desc;
2641         uint32_t offset;
2642         int i, j;
2643
2644         iso_packet = dwc_ep->pkt_info;
2645
2646         /** Reinit closed DMA Descriptors*/
2647         /** ISO OUT EP */
2648         if (dwc_ep->is_in == 0) {
2649                 dma_desc =
2650                     dwc_ep->iso_desc_addr +
2651                     dwc_ep->desc_cnt*dwc_ep->proc_buf_num;
2652                 offset = 0;
2653
2654                 for (i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm;
2655                      i += dwc_ep->pkt_per_frm) {
2656                         for (j = 0; j < dwc_ep->pkt_per_frm; ++j) {
2657                                 data_per_desc =
2658                                     ((j + 1)*dwc_ep->maxpacket >
2659                                      dwc_ep->
2660                                      data_per_frame) ? dwc_ep->data_per_frame -
2661                                     j*dwc_ep->maxpacket : dwc_ep->maxpacket;
2662                                 data_per_desc +=
2663                                     (data_per_desc % 4) ? (4 -
2664                                                            data_per_desc %
2665                                                            4) : 0;
2666
2667                                 sts.d32 = dma_desc->status.d32;
2668
2669                                 /* Write status in iso_packet_decsriptor  */
2670                                 iso_packet->status =
2671                                     sts.b_iso_out.rxsts +
2672                                     (sts.b_iso_out.bs ^ BS_DMA_DONE);
2673                                 if (iso_packet->status) {
2674                                         iso_packet->status = -DWC_E_NO_DATA;
2675                                 }
2676
2677                                 /* Received data length */
2678                                 if (!sts.b_iso_out.rxbytes) {
2679                                         iso_packet->length =
2680                                             data_per_desc -
2681                                             sts.b_iso_out.rxbytes;
2682                                 } else {
2683                                         iso_packet->length =
2684                                             data_per_desc -
2685                                             sts.b_iso_out.rxbytes + (4 -
2686                                                                      dwc_ep->data_per_frame
2687                                                                      % 4);
2688                                 }
2689
2690                                 iso_packet->offset = offset;
2691
2692                                 offset += data_per_desc;
2693                                 dma_desc++;
2694                                 iso_packet++;
2695                         }
2696                 }
2697
2698                 for (j = 0; j < dwc_ep->pkt_per_frm - 1; ++j) {
2699                         data_per_desc =
2700                             ((j + 1)*dwc_ep->maxpacket >
2701                              dwc_ep->data_per_frame) ? dwc_ep->data_per_frame -
2702                             j*dwc_ep->maxpacket : dwc_ep->maxpacket;
2703                         data_per_desc +=
2704                             (data_per_desc % 4) ? (4 - data_per_desc % 4) : 0;
2705
2706                         sts.d32 = dma_desc->status.d32;
2707
2708                         /* Write status in iso_packet_decsriptor  */
2709                         iso_packet->status =
2710                             sts.b_iso_out.rxsts +
2711                             (sts.b_iso_out.bs ^ BS_DMA_DONE);
2712                         if (iso_packet->status) {
2713                                 iso_packet->status = -DWC_E_NO_DATA;
2714                         }
2715
2716                         /* Received data length */
2717                         iso_packet->length =
2718                             dwc_ep->data_per_frame - sts.b_iso_out.rxbytes;
2719
2720                         iso_packet->offset = offset;
2721
2722                         offset += data_per_desc;
2723                         iso_packet++;
2724                         dma_desc++;
2725                 }
2726
2727                 sts.d32 = dma_desc->status.d32;
2728
2729                 /* Write status in iso_packet_decsriptor  */
2730                 iso_packet->status =
2731                     sts.b_iso_out.rxsts + (sts.b_iso_out.bs ^ BS_DMA_DONE);
2732                 if (iso_packet->status) {
2733                         iso_packet->status = -DWC_E_NO_DATA;
2734                 }
2735                 /* Received data length */
2736                 if (!sts.b_iso_out.rxbytes) {
2737                         iso_packet->length =
2738                             dwc_ep->data_per_frame - sts.b_iso_out.rxbytes;
2739                 } else {
2740                         iso_packet->length =
2741                             dwc_ep->data_per_frame - sts.b_iso_out.rxbytes +
2742                             (4 - dwc_ep->data_per_frame % 4);
2743                 }
2744
2745                 iso_packet->offset = offset;
2746         } else {
2747 /** ISO IN EP */
2748
2749                 dma_desc =
2750                     dwc_ep->iso_desc_addr +
2751                     dwc_ep->desc_cnt*dwc_ep->proc_buf_num;
2752
2753                 for (i = 0; i < dwc_ep->desc_cnt - 1; i++) {
2754                         sts.d32 = dma_desc->status.d32;
2755
2756                         /* Write status in iso packet descriptor */
2757                         iso_packet->status =
2758                             sts.b_iso_in.txsts +
2759                             (sts.b_iso_in.bs ^ BS_DMA_DONE);
2760                         if (iso_packet->status != 0) {
2761                                 iso_packet->status = -DWC_E_NO_DATA;
2762
2763                         }
2764                         /* Bytes has been transfered */
2765                         iso_packet->length =
2766                             dwc_ep->data_per_frame - sts.b_iso_in.txbytes;
2767
2768                         dma_desc++;
2769                         iso_packet++;
2770                 }
2771
2772                 sts.d32 = dma_desc->status.d32;
2773                 while (sts.b_iso_in.bs == BS_DMA_BUSY) {
2774                         sts.d32 = dma_desc->status.d32;
2775                 }
2776
2777                 /* Write status in iso packet descriptor ??? do be done with ERROR codes */
2778                 iso_packet->status =
2779                     sts.b_iso_in.txsts + (sts.b_iso_in.bs ^ BS_DMA_DONE);
2780                 if (iso_packet->status != 0) {
2781                         iso_packet->status = -DWC_E_NO_DATA;
2782                 }
2783
2784                 /* Bytes has been transfered */
2785                 iso_packet->length =
2786                     dwc_ep->data_per_frame - sts.b_iso_in.txbytes;
2787         }
2788 }
2789
2790 /**
2791  * This function reinitialize DMA Descriptors for Isochronous transfer
2792  *
2793  * @param core_if Programming view of DWC_otg controller.
2794  * @param dwc_ep The EP to start the transfer on.
2795  *
2796  */
2797 static void reinit_ddma_iso_xfer(dwc_otg_core_if_t *core_if, dwc_ep_t *dwc_ep)
2798 {
2799         int i, j;
2800         dwc_otg_dev_dma_desc_t *dma_desc;
2801         dma_addr_t dma_ad;
2802         volatile uint32_t *addr;
2803         dev_dma_desc_sts_t sts = {
2804         .d32 = 0};
2805         uint32_t data_per_desc;
2806
2807         if (dwc_ep->is_in == 0) {
2808                 addr = &core_if->dev_if->out_ep_regs[dwc_ep->num]->doepctl;
2809         } else {
2810                 addr = &core_if->dev_if->in_ep_regs[dwc_ep->num]->diepctl;
2811         }
2812
2813         if (dwc_ep->proc_buf_num == 0) {
2814                 /** Buffer 0 descriptors setup */
2815                 dma_ad = dwc_ep->dma_addr0;
2816         } else {
2817                 /** Buffer 1 descriptors setup */
2818                 dma_ad = dwc_ep->dma_addr1;
2819         }
2820
2821         /** Reinit closed DMA Descriptors*/
2822         /** ISO OUT EP */
2823         if (dwc_ep->is_in == 0) {
2824                 dma_desc =
2825                     dwc_ep->iso_desc_addr +
2826                     dwc_ep->desc_cnt*dwc_ep->proc_buf_num;
2827
2828                 sts.b_iso_out.bs = BS_HOST_READY;
2829                 sts.b_iso_out.rxsts = 0;
2830                 sts.b_iso_out.l = 0;
2831                 sts.b_iso_out.sp = 0;
2832                 sts.b_iso_out.ioc = 0;
2833                 sts.b_iso_out.pid = 0;
2834                 sts.b_iso_out.framenum = 0;
2835
2836                 for (i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm;
2837                      i += dwc_ep->pkt_per_frm) {
2838                         for (j = 0; j < dwc_ep->pkt_per_frm; ++j) {
2839                                 data_per_desc =
2840                                     ((j + 1)*dwc_ep->maxpacket >
2841                                      dwc_ep->
2842                                      data_per_frame) ? dwc_ep->data_per_frame -
2843                                     j*dwc_ep->maxpacket : dwc_ep->maxpacket;
2844                                 data_per_desc +=
2845                                     (data_per_desc % 4) ? (4 -
2846                                                            data_per_desc %
2847                                                            4) : 0;
2848                                 sts.b_iso_out.rxbytes = data_per_desc;
2849                                 dma_desc->buf = dma_ad;
2850                                 dma_desc->status.d32 = sts.d32;
2851
2852                                 dma_ad += data_per_desc;
2853                                 dma_desc++;
2854                         }
2855                 }
2856
2857                 for (j = 0; j < dwc_ep->pkt_per_frm - 1; ++j) {
2858
2859                         data_per_desc =
2860                             ((j + 1)*dwc_ep->maxpacket >
2861                              dwc_ep->data_per_frame) ? dwc_ep->data_per_frame -
2862                             j*dwc_ep->maxpacket : dwc_ep->maxpacket;
2863                         data_per_desc +=
2864                             (data_per_desc % 4) ? (4 - data_per_desc % 4) : 0;
2865                         sts.b_iso_out.rxbytes = data_per_desc;
2866
2867                         dma_desc->buf = dma_ad;
2868                         dma_desc->status.d32 = sts.d32;
2869
2870                         dma_desc++;
2871                         dma_ad += data_per_desc;
2872                 }
2873
2874                 sts.b_iso_out.ioc = 1;
2875                 sts.b_iso_out.l = dwc_ep->proc_buf_num;
2876
2877                 data_per_desc =
2878                     ((j + 1)*dwc_ep->maxpacket >
2879                      dwc_ep->data_per_frame) ? dwc_ep->data_per_frame -
2880                     j*dwc_ep->maxpacket : dwc_ep->maxpacket;
2881                 data_per_desc +=
2882                     (data_per_desc % 4) ? (4 - data_per_desc % 4) : 0;
2883                 sts.b_iso_out.rxbytes = data_per_desc;
2884
2885                 dma_desc->buf = dma_ad;
2886                 dma_desc->status.d32 = sts.d32;
2887         } else {
2888 /** ISO IN EP */
2889
2890                 dma_desc =
2891                     dwc_ep->iso_desc_addr +
2892                     dwc_ep->desc_cnt*dwc_ep->proc_buf_num;
2893
2894                 sts.b_iso_in.bs = BS_HOST_READY;
2895                 sts.b_iso_in.txsts = 0;
2896                 sts.b_iso_in.sp = 0;
2897                 sts.b_iso_in.ioc = 0;
2898                 sts.b_iso_in.pid = dwc_ep->pkt_per_frm;
2899                 sts.b_iso_in.framenum = dwc_ep->next_frame;
2900                 sts.b_iso_in.txbytes = dwc_ep->data_per_frame;
2901                 sts.b_iso_in.l = 0;
2902
2903                 for (i = 0; i < dwc_ep->desc_cnt - 1; i++) {
2904                         dma_desc->buf = dma_ad;
2905                         dma_desc->status.d32 = sts.d32;
2906
2907                         sts.b_iso_in.framenum += dwc_ep->bInterval;
2908                         dma_ad += dwc_ep->data_per_frame;
2909                         dma_desc++;
2910                 }
2911
2912                 sts.b_iso_in.ioc = 1;
2913                 sts.b_iso_in.l = dwc_ep->proc_buf_num;
2914
2915                 dma_desc->buf = dma_ad;
2916                 dma_desc->status.d32 = sts.d32;
2917
2918                 dwc_ep->next_frame =
2919                     sts.b_iso_in.framenum + dwc_ep->bInterval * 1;
2920         }
2921         dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1;
2922 }
2923
2924 /**
2925  * This function is to handle Iso EP transfer complete interrupt
2926  * in case Iso out packet was dropped
2927  *
2928  * @param core_if Programming view of DWC_otg controller.
2929  * @param dwc_ep The EP for wihich transfer complete was asserted
2930  *
2931  */
2932 static uint32_t handle_iso_out_pkt_dropped(dwc_otg_core_if_t *core_if,
2933                                            dwc_ep_t *dwc_ep) {
2934         uint32_t dma_addr;
2935         uint32_t drp_pkt;
2936         uint32_t drp_pkt_cnt;
2937         deptsiz_data_t deptsiz = {
2938         .d32 = 0};
2939         depctl_data_t depctl = {
2940         .d32 = 0};
2941         int i;
2942
2943         deptsiz.d32 =
2944             DWC_READ_REG32(&core_if->dev_if->
2945                            out_ep_regs[dwc_ep->num]->doeptsiz);
2946
2947         drp_pkt = dwc_ep->pkt_cnt - deptsiz.b.pktcnt;
2948         drp_pkt_cnt = dwc_ep->pkt_per_frm - (drp_pkt % dwc_ep->pkt_per_frm);
2949
2950         /* Setting dropped packets status */
2951         for (i = 0; i < drp_pkt_cnt; ++i) {
2952                 dwc_ep->pkt_info[drp_pkt].status = -DWC_E_NO_DATA;
2953                 drp_pkt++;
2954                 deptsiz.b.pktcnt--;
2955         }
2956
2957         if (deptsiz.b.pktcnt > 0) {
2958                 deptsiz.b.xfersize =
2959                     dwc_ep->xfer_len - (dwc_ep->pkt_cnt -
2960                                         deptsiz.b.pktcnt)*dwc_ep->maxpacket;
2961         } else {
2962                 deptsiz.b.xfersize = 0;
2963                 deptsiz.b.pktcnt = 0;
2964         }
2965
2966         DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doeptsiz,
2967                         deptsiz.d32);
2968
2969         if (deptsiz.b.pktcnt > 0) {
2970                 if (dwc_ep->proc_buf_num) {
2971                         dma_addr =
2972                             dwc_ep->dma_addr1 + dwc_ep->xfer_len -
2973                             deptsiz.b.xfersize;
2974                 } else {
2975                         dma_addr =
2976                             dwc_ep->dma_addr0 + dwc_ep->xfer_len -
2977                             deptsiz.b.xfersize;;
2978                 }
2979
2980                 DWC_WRITE_REG32(&core_if->dev_if->
2981                                 out_ep_regs[dwc_ep->num]->doepdma, dma_addr);
2982
2983                 /** Re-enable endpoint, clear nak  */
2984                 depctl.d32 = 0;
2985                 depctl.b.epena = 1;
2986                 depctl.b.cnak = 1;
2987
2988                 DWC_MODIFY_REG32(&core_if->dev_if->
2989                                  out_ep_regs[dwc_ep->num]->doepctl, depctl.d32,
2990                                  depctl.d32);
2991                 return 0;
2992         } else {
2993                 return 1;
2994         }
2995 }
2996
2997 /**
2998  * This function sets iso packets information(PTI mode)
2999  *
3000  * @param core_if Programming view of DWC_otg controller.
3001  * @param ep The EP to start the transfer on.
3002  *
3003  */
3004 static uint32_t set_iso_pkts_info(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
3005 {
3006         int i, j;
3007         dma_addr_t dma_ad;
3008         iso_pkt_info_t *packet_info = ep->pkt_info;
3009         uint32_t offset;
3010         uint32_t frame_data;
3011         deptsiz_data_t deptsiz;
3012
3013         if (ep->proc_buf_num == 0) {
3014                 /** Buffer 0 descriptors setup */
3015                 dma_ad = ep->dma_addr0;
3016         } else {
3017                 /** Buffer 1 descriptors setup */
3018                 dma_ad = ep->dma_addr1;
3019         }
3020
3021         if (ep->is_in) {
3022                 deptsiz.d32 =
3023                     DWC_READ_REG32(&core_if->dev_if->in_ep_regs[ep->num]->
3024                                    dieptsiz);
3025         } else {
3026                 deptsiz.d32 =
3027                     DWC_READ_REG32(&core_if->dev_if->out_ep_regs[ep->num]->
3028                                    doeptsiz);
3029         }
3030
3031         if (!deptsiz.b.xfersize) {
3032                 offset = 0;
3033                 for (i = 0; i < ep->pkt_cnt; i += ep->pkt_per_frm) {
3034                         frame_data = ep->data_per_frame;
3035                         for (j = 0; j < ep->pkt_per_frm; ++j) {
3036
3037                                 /* Packet status - is not set as initially
3038                                  * it is set to 0 and if packet was sent
3039                                  successfully, status field will remain 0*/
3040
3041                                 /* Bytes has been transfered */
3042                                 packet_info->length =
3043                                     (ep->maxpacket <
3044                                      frame_data) ? ep->maxpacket : frame_data;
3045
3046                                 /* Received packet offset */
3047                                 packet_info->offset = offset;
3048                                 offset += packet_info->length;
3049                                 frame_data -= packet_info->length;
3050
3051                                 packet_info++;
3052                         }
3053                 }
3054                 return 1;
3055         } else {
3056                 /* This is a workaround for in case of Transfer Complete with
3057                  * PktDrpSts interrupts merging - in this case Transfer complete
3058                  * interrupt for Isoc Out Endpoint is asserted without PktDrpSts
3059                  * set and with DOEPTSIZ register non zero. Investigations showed,
3060                  * that this happens when Out packet is dropped, but because of
3061                  * interrupts merging during first interrupt handling PktDrpSts
3062                  * bit is cleared and for next merged interrupts it is not reset.
3063                  * In this case SW hadles the interrupt as if PktDrpSts bit is set.
3064                  */
3065                 if (ep->is_in) {
3066                         return 1;
3067                 } else {
3068                         return handle_iso_out_pkt_dropped(core_if, ep);
3069                 }
3070         }
3071 }
3072
3073 /**
3074  * This function is to handle Iso EP transfer complete interrupt
3075  *
3076  * @param pcd The PCD
3077  * @param ep The EP for which transfer complete was asserted
3078  *
3079  */
3080 static void complete_iso_ep(dwc_otg_pcd_t *pcd, dwc_otg_pcd_ep_t *ep)
3081 {
3082         dwc_otg_core_if_t *core_if = GET_CORE_IF(ep->pcd);
3083         dwc_ep_t *dwc_ep = &ep->dwc_ep;
3084         uint8_t is_last = 0;
3085
3086         if (ep->dwc_ep.next_frame == 0xffffffff) {
3087                 DWC_WARN("Next frame is not set!\n");
3088                 return;
3089         }
3090
3091         if (core_if->dma_enable) {
3092                 if (core_if->dma_desc_enable) {
3093                         set_ddma_iso_pkts_info(core_if, dwc_ep);
3094                         reinit_ddma_iso_xfer(core_if, dwc_ep);
3095                         is_last = 1;
3096                 } else {
3097                         if (core_if->pti_enh_enable) {
3098                                 if (set_iso_pkts_info(core_if, dwc_ep)) {
3099                                         dwc_ep->proc_buf_num =
3100                                             (dwc_ep->proc_buf_num ^ 1) & 0x1;
3101                                         dwc_otg_iso_ep_start_buf_transfer
3102                                             (core_if, dwc_ep);
3103                                         is_last = 1;
3104                                 }
3105                         } else {
3106                                 set_current_pkt_info(core_if, dwc_ep);
3107                                 if (dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
3108                                         is_last = 1;
3109                                         dwc_ep->cur_pkt = 0;
3110                                         dwc_ep->proc_buf_num =
3111                                             (dwc_ep->proc_buf_num ^ 1) & 0x1;
3112                                         if (dwc_ep->proc_buf_num) {
3113                                                 dwc_ep->cur_pkt_addr =
3114                                                     dwc_ep->xfer_buff1;
3115                                                 dwc_ep->cur_pkt_dma_addr =
3116                                                     dwc_ep->dma_addr1;
3117                                         } else {
3118                                                 dwc_ep->cur_pkt_addr =
3119                                                     dwc_ep->xfer_buff0;
3120                                                 dwc_ep->cur_pkt_dma_addr =
3121                                                     dwc_ep->dma_addr0;
3122                                         }
3123
3124                                 }
3125                                 dwc_otg_iso_ep_start_frm_transfer(core_if,
3126                                                                   dwc_ep);
3127                         }
3128                 }
3129         } else {
3130                 set_current_pkt_info(core_if, dwc_ep);
3131                 if (dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
3132                         is_last = 1;
3133                         dwc_ep->cur_pkt = 0;
3134                         dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1;
3135                         if (dwc_ep->proc_buf_num) {
3136                                 dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff1;
3137                                 dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr1;
3138                         } else {
3139                                 dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff0;
3140                                 dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr0;
3141                         }
3142
3143                 }
3144                 dwc_otg_iso_ep_start_frm_transfer(core_if, dwc_ep);
3145         }
3146         if (is_last)
3147                 dwc_otg_iso_buffer_done(pcd, ep, ep->iso_req_handle);
3148 }
3149 #endif /* DWC_EN_ISOC */
3150
3151 /**
3152  * This function handle BNA interrupt for Non Isochronous EPs
3153  *
3154  */
3155 static void dwc_otg_pcd_handle_noniso_bna(dwc_otg_pcd_ep_t *ep)
3156 {
3157         dwc_ep_t *dwc_ep = &ep->dwc_ep;
3158         volatile uint32_t *addr;
3159         depctl_data_t depctl = {
3160         .d32 = 0};
3161         dwc_otg_pcd_t *pcd = ep->pcd;
3162         dwc_otg_dev_dma_desc_t *dma_desc;
3163         dev_dma_desc_sts_t sts = {
3164         .d32 = 0};
3165         dwc_otg_core_if_t *core_if = ep->pcd->core_if;
3166         int i, start;
3167
3168         if (!dwc_ep->desc_cnt)
3169                 DWC_WARN("Ep%d %s Descriptor count = %d \n", dwc_ep->num,
3170                          (dwc_ep->is_in ? "IN" : "OUT"), dwc_ep->desc_cnt);
3171
3172         if (core_if->core_params->cont_on_bna && !dwc_ep->is_in
3173             && dwc_ep->type != DWC_OTG_EP_TYPE_CONTROL) {
3174                 uint32_t doepdma;
3175                 dwc_otg_dev_out_ep_regs_t *out_regs =
3176                     core_if->dev_if->out_ep_regs[dwc_ep->num];
3177                 doepdma = DWC_READ_REG32(&(out_regs->doepdma));
3178                 start =
3179                     (doepdma -
3180                      dwc_ep->dma_desc_addr) / sizeof(dwc_otg_dev_dma_desc_t);
3181                 dma_desc = &(dwc_ep->desc_addr[start]);
3182         } else {
3183                 start = 0;
3184                 dma_desc = dwc_ep->desc_addr;
3185         }
3186
3187         for (i = start; i < dwc_ep->desc_cnt; ++i, ++dma_desc) {
3188                 sts.d32 = dma_desc->status.d32;
3189                 sts.b.bs = BS_HOST_READY;
3190                 dma_desc->status.d32 = sts.d32;
3191         }
3192
3193         if (dwc_ep->is_in == 0) {
3194                 addr =
3195                     &GET_CORE_IF(pcd)->dev_if->out_ep_regs[dwc_ep->num]->
3196                     doepctl;
3197         } else {
3198                 addr =
3199                     &GET_CORE_IF(pcd)->dev_if->in_ep_regs[dwc_ep->num]->diepctl;
3200         }
3201         depctl.b.epena = 1;
3202         depctl.b.cnak = 1;
3203         DWC_MODIFY_REG32(addr, 0, depctl.d32);
3204 }
3205
3206 /**
3207  * This function handles EP0 Control transfers.
3208  *
3209  * The state of the control transfers are tracked in
3210  * <code>ep0state</code>.
3211  */
3212 static void handle_ep0(dwc_otg_pcd_t *pcd)
3213 {
3214         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
3215         dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
3216         dev_dma_desc_sts_t desc_sts;
3217         deptsiz0_data_t deptsiz;
3218         uint32_t byte_count;
3219
3220 #ifdef DEBUG_EP0
3221         DWC_DEBUGPL(DBG_PCDV, "%s()\n", __func__);
3222         print_ep0_state(pcd);
3223 #endif
3224
3225         switch (pcd->ep0state) {
3226         case EP0_DISCONNECT:
3227                 break;
3228
3229         case EP0_IDLE:
3230                 pcd->request_config = 0;
3231
3232                 pcd_setup(pcd);
3233                 break;
3234
3235         case EP0_IN_DATA_PHASE:
3236 #ifdef DEBUG_EP0
3237                 DWC_DEBUGPL(DBG_PCD, "DATA_IN EP%d-%s: type=%d, mps=%d\n",
3238                             ep0->dwc_ep.num, (ep0->dwc_ep.is_in ? "IN" : "OUT"),
3239                             ep0->dwc_ep.type, ep0->dwc_ep.maxpacket);
3240 #endif
3241
3242                 if (core_if->dma_enable != 0) {
3243                         /*
3244                          * For EP0 we can only program 1 packet at a time so we
3245                          * need to do the make calculations after each complete.
3246                          * Call write_packet to make the calculations, as in
3247                          * slave mode, and use those values to determine if we
3248                          * can complete.
3249                          */
3250                         if (core_if->dma_desc_enable == 0) {
3251                                 deptsiz.d32 =
3252                                     DWC_READ_REG32(&core_if->
3253                                                    dev_if->in_ep_regs[0]->
3254                                                    dieptsiz);
3255                                 byte_count =
3256                                     ep0->dwc_ep.xfer_len - deptsiz.b.xfersize;
3257                         } else {
3258                                 desc_sts =
3259                                     core_if->dev_if->in_desc_addr->status;
3260                                 byte_count =
3261                                     ep0->dwc_ep.xfer_len - desc_sts.b.bytes;
3262                         }
3263                         ep0->dwc_ep.xfer_count += byte_count;
3264                         ep0->dwc_ep.xfer_buff += byte_count;
3265                         ep0->dwc_ep.dma_addr += byte_count;
3266                 }
3267                 if (ep0->dwc_ep.xfer_count < ep0->dwc_ep.total_len) {
3268                         dwc_otg_ep0_continue_transfer(GET_CORE_IF(pcd),
3269                                                       &ep0->dwc_ep);
3270                         DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");
3271                 } else if (ep0->dwc_ep.sent_zlp) {
3272                         dwc_otg_ep0_continue_transfer(GET_CORE_IF(pcd),
3273                                                       &ep0->dwc_ep);
3274                         ep0->dwc_ep.sent_zlp = 0;
3275                         DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER sent zlp\n");
3276                 } else {
3277                         ep0_complete_request(ep0);
3278                         DWC_DEBUGPL(DBG_PCD, "COMPLETE TRANSFER\n");
3279                 }
3280                 break;
3281         case EP0_OUT_DATA_PHASE:
3282 #ifdef DEBUG_EP0
3283                 DWC_DEBUGPL(DBG_PCD, "DATA_OUT EP%d-%s: type=%d, mps=%d\n",
3284                             ep0->dwc_ep.num, (ep0->dwc_ep.is_in ? "IN" : "OUT"),
3285                             ep0->dwc_ep.type, ep0->dwc_ep.maxpacket);
3286 #endif
3287                 if (core_if->dma_enable != 0) {
3288                         if (core_if->dma_desc_enable == 0) {
3289                                 deptsiz.d32 =
3290                                     DWC_READ_REG32(&core_if->
3291                                                    dev_if->out_ep_regs[0]->
3292                                                    doeptsiz);
3293                                 byte_count =
3294                                     ep0->dwc_ep.maxpacket - deptsiz.b.xfersize;
3295                         } else {
3296                                 desc_sts =
3297                                     core_if->dev_if->out_desc_addr->status;
3298                                 byte_count =
3299                                     ep0->dwc_ep.maxpacket - desc_sts.b.bytes;
3300                         }
3301                         ep0->dwc_ep.xfer_count += byte_count;
3302                         ep0->dwc_ep.xfer_buff += byte_count;
3303                         ep0->dwc_ep.dma_addr += byte_count;
3304                 }
3305                 if (ep0->dwc_ep.xfer_count < ep0->dwc_ep.total_len) {
3306                         dwc_otg_ep0_continue_transfer(GET_CORE_IF(pcd),
3307                                                       &ep0->dwc_ep);
3308                         DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");
3309                 } else if (ep0->dwc_ep.sent_zlp) {
3310                         dwc_otg_ep0_continue_transfer(GET_CORE_IF(pcd),
3311                                                       &ep0->dwc_ep);
3312                         ep0->dwc_ep.sent_zlp = 0;
3313                         DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER sent zlp\n");
3314                 } else {
3315                         ep0_complete_request(ep0);
3316                         DWC_DEBUGPL(DBG_PCD, "COMPLETE TRANSFER\n");
3317                 }
3318                 break;
3319
3320         case EP0_IN_STATUS_PHASE:
3321         case EP0_OUT_STATUS_PHASE:
3322                 DWC_DEBUGPL(DBG_PCD, "CASE: EP0_STATUS\n");
3323                 ep0_complete_request(ep0);
3324                 pcd->ep0state = EP0_IDLE;
3325                 ep0->stopped = 1;
3326                 ep0->dwc_ep.is_in = 0;  /* OUT for next SETUP */
3327
3328                 /* Prepare for more SETUP Packets */
3329                 if (core_if->dma_enable) {
3330                         ep0_out_start(core_if, pcd);
3331                 }
3332                 break;
3333
3334         case EP0_STALL:
3335                 DWC_ERROR("EP0 STALLed, should not get here pcd_setup()\n");
3336                 break;
3337         }
3338 #ifdef DEBUG_EP0
3339         print_ep0_state(pcd);
3340 #endif
3341 }
3342
3343 /**
3344  * Restart transfer
3345  */
3346 static void restart_transfer(dwc_otg_pcd_t *pcd, const uint32_t epnum)
3347 {
3348         dwc_otg_core_if_t *core_if;
3349         dwc_otg_dev_if_t *dev_if;
3350         deptsiz_data_t dieptsiz = {
3351         .d32 = 0};
3352         dwc_otg_pcd_ep_t *ep;
3353
3354         ep = get_in_ep(pcd, epnum);
3355
3356 #ifdef DWC_EN_ISOC
3357         if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) {
3358                 return;
3359         }
3360 #endif /* DWC_EN_ISOC  */
3361
3362         core_if = GET_CORE_IF(pcd);
3363         dev_if = core_if->dev_if;
3364
3365         dieptsiz.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dieptsiz);
3366
3367         DWC_DEBUGPL(DBG_PCD, "xfer_buff=%p xfer_count=%0x xfer_len=%0x"
3368                     " stopped=%d\n", ep->dwc_ep.xfer_buff,
3369                     ep->dwc_ep.xfer_count, ep->dwc_ep.xfer_len, ep->stopped);
3370         /*
3371          * If xfersize is 0 and pktcnt in not 0, resend the last packet.
3372          */
3373         if (dieptsiz.b.pktcnt && dieptsiz.b.xfersize == 0 &&
3374             ep->dwc_ep.start_xfer_buff != 0) {
3375                 if (ep->dwc_ep.total_len <= ep->dwc_ep.maxpacket) {
3376                         ep->dwc_ep.xfer_count = 0;
3377                         ep->dwc_ep.xfer_buff = ep->dwc_ep.start_xfer_buff;
3378                         ep->dwc_ep.xfer_len = ep->dwc_ep.xfer_count;
3379                 } else {
3380                         ep->dwc_ep.xfer_count -= ep->dwc_ep.maxpacket;
3381                         /* convert packet size to dwords. */
3382                         ep->dwc_ep.xfer_buff -= ep->dwc_ep.maxpacket;
3383                         ep->dwc_ep.xfer_len = ep->dwc_ep.xfer_count;
3384                 }
3385                 ep->stopped = 0;
3386                 DWC_DEBUGPL(DBG_PCD, "xfer_buff=%p xfer_count=%0x "
3387                             "xfer_len=%0x stopped=%d\n",
3388                             ep->dwc_ep.xfer_buff,
3389                             ep->dwc_ep.xfer_count, ep->dwc_ep.xfer_len,
3390                             ep->stopped);
3391                 if (epnum == 0) {
3392                         dwc_otg_ep0_start_transfer(core_if, &ep->dwc_ep);
3393                 } else {
3394                         dwc_otg_ep_start_transfer(core_if, &ep->dwc_ep);
3395                 }
3396         }
3397 }
3398
3399 /*
3400  * This function create new nextep sequnce based on Learn Queue.
3401  *
3402  * @param core_if Programming view of DWC_otg controller
3403  */
3404 void predict_nextep_seq(dwc_otg_core_if_t *core_if)
3405 {
3406         dwc_otg_device_global_regs_t *dev_global_regs =
3407             core_if->dev_if->dev_global_regs;
3408         const uint32_t TOKEN_Q_DEPTH = core_if->hwcfg2.b.dev_token_q_depth;
3409         /* Number of Token Queue Registers */
3410         const int DTKNQ_REG_CNT = (TOKEN_Q_DEPTH + 7) / 8;
3411         dtknq1_data_t dtknqr1;
3412         uint32_t in_tkn_epnums[4];
3413         uint8_t seqnum[MAX_EPS_CHANNELS];
3414         uint8_t intkn_seq[TOKEN_Q_DEPTH];
3415         grstctl_t resetctl = {
3416         .d32 = 0};
3417         uint8_t temp;
3418         int ndx = 0;
3419         int start = 0;
3420         int end = 0;
3421         int sort_done = 0;
3422         int i = 0;
3423         volatile uint32_t *addr = &dev_global_regs->dtknqr1;
3424
3425         DWC_DEBUGPL(DBG_PCD, "dev_token_q_depth=%d\n", TOKEN_Q_DEPTH);
3426
3427         /* Read the DTKNQ Registers */
3428         for (i = 0; i < DTKNQ_REG_CNT; i++) {
3429                 in_tkn_epnums[i] = DWC_READ_REG32(addr);
3430                 DWC_DEBUGPL(DBG_PCDV, "DTKNQR%d=0x%08x\n", i + 1,
3431                             in_tkn_epnums[i]);
3432                 if (addr == &dev_global_regs->dvbusdis) {
3433                         addr = &dev_global_regs->dtknqr3_dthrctl;
3434                 } else {
3435                         ++addr;
3436                 }
3437
3438         }
3439
3440         /* Copy the DTKNQR1 data to the bit field. */
3441         dtknqr1.d32 = in_tkn_epnums[0];
3442         if (dtknqr1.b.wrap_bit) {
3443                 ndx = dtknqr1.b.intknwptr;
3444                 end = ndx - 1;
3445                 if (end < 0)
3446                         end = TOKEN_Q_DEPTH - 1;
3447         } else {
3448                 ndx = 0;
3449                 end = dtknqr1.b.intknwptr - 1;
3450                 if (end < 0)
3451                         end = 0;
3452         }
3453         start = ndx;
3454
3455         /* Fill seqnum[] by initial values: EP number + 31 */
3456         for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
3457                 seqnum[i] = i + 31;
3458         }
3459
3460         /* Fill intkn_seq[] from in_tkn_epnums[0] */
3461         for (i = 0; i < 6; i++)
3462                 intkn_seq[i] = (in_tkn_epnums[0] >> ((7 - i) * 4)) & 0xf;
3463
3464         if (TOKEN_Q_DEPTH > 6) {
3465                 /* Fill intkn_seq[] from in_tkn_epnums[1] */
3466                 for (i = 6; i < 14; i++)
3467                         intkn_seq[i] =
3468                             (in_tkn_epnums[1] >> ((7 - (i - 6)) * 4)) & 0xf;
3469         }
3470
3471         if (TOKEN_Q_DEPTH > 14) {
3472                 /* Fill intkn_seq[] from in_tkn_epnums[1] */
3473                 for (i = 14; i < 22; i++)
3474                         intkn_seq[i] =
3475                             (in_tkn_epnums[2] >> ((7 - (i - 14)) * 4)) & 0xf;
3476         }
3477
3478         if (TOKEN_Q_DEPTH > 22) {
3479                 /* Fill intkn_seq[] from in_tkn_epnums[1] */
3480                 for (i = 22; i < 30; i++)
3481                         intkn_seq[i] =
3482                             (in_tkn_epnums[3] >> ((7 - (i - 22)) * 4)) & 0xf;
3483         }
3484
3485         DWC_DEBUGPL(DBG_PCDV, "%s start=%d end=%d intkn_seq[]:\n", __func__,
3486                     start, end);
3487         for (i = 0; i < TOKEN_Q_DEPTH; i++)
3488                 DWC_DEBUGPL(DBG_PCDV, "%d\n", intkn_seq[i]);
3489
3490         /* Update seqnum based on intkn_seq[] */
3491         i = 0;
3492         do {
3493                 seqnum[intkn_seq[ndx]] = i;
3494                 ndx++;
3495                 i++;
3496                 if (ndx == TOKEN_Q_DEPTH)
3497                         ndx = 0;
3498         } while (i < TOKEN_Q_DEPTH);
3499
3500         /* Mark non active EP's in seqnum[] by 0xff */
3501         for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
3502                 if (core_if->nextep_seq[i] == 0xff)
3503                         seqnum[i] = 0xff;
3504         }
3505
3506         /* Sort seqnum[] */
3507         sort_done = 0;
3508         while (!sort_done) {
3509                 sort_done = 1;
3510                 for (i = 0; i < core_if->dev_if->num_in_eps; i++) {
3511                         if (seqnum[i] > seqnum[i + 1]) {
3512                                 temp = seqnum[i];
3513                                 seqnum[i] = seqnum[i + 1];
3514                                 seqnum[i + 1] = temp;
3515                                 sort_done = 0;
3516                         }
3517                 }
3518         }
3519
3520         ndx = start + seqnum[0];
3521         if (ndx >= TOKEN_Q_DEPTH)
3522                 ndx = ndx % TOKEN_Q_DEPTH;
3523         core_if->first_in_nextep_seq = intkn_seq[ndx];
3524
3525         /* Update seqnum[] by EP numbers  */
3526         for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
3527                 ndx = start + i;
3528                 if (seqnum[i] < 31) {
3529                         ndx = start + seqnum[i];
3530                         if (ndx >= TOKEN_Q_DEPTH)
3531                                 ndx = ndx % TOKEN_Q_DEPTH;
3532                         seqnum[i] = intkn_seq[ndx];
3533                 } else {
3534                         if (seqnum[i] < 0xff) {
3535                                 seqnum[i] = seqnum[i] - 31;
3536                         } else {
3537                                 break;
3538                         }
3539                 }
3540         }
3541
3542         /* Update nextep_seq[] based on seqnum[] */
3543         for (i = 0; i < core_if->dev_if->num_in_eps; i++) {
3544                 if (seqnum[i] != 0xff) {
3545                         if (seqnum[i + 1] != 0xff) {
3546                                 core_if->nextep_seq[seqnum[i]] = seqnum[i + 1];
3547                         } else {
3548                                 core_if->nextep_seq[seqnum[i]] =
3549                                     core_if->first_in_nextep_seq;
3550                                 break;
3551                         }
3552                 } else {
3553                         break;
3554                 }
3555         }
3556
3557         DWC_DEBUGPL(DBG_PCDV, "%s first_in_nextep_seq= %2d; nextep_seq[]:\n",
3558                     __func__, core_if->first_in_nextep_seq);
3559         for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
3560                 DWC_DEBUGPL(DBG_PCDV, "%2d\n", core_if->nextep_seq[i]);
3561         }
3562
3563         /* Flush the Learning Queue */
3564         resetctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->grstctl);
3565         resetctl.b.intknqflsh = 1;
3566         DWC_WRITE_REG32(&core_if->core_global_regs->grstctl, resetctl.d32);
3567
3568 }
3569
3570 /**
3571  * handle the IN EP disable interrupt.
3572  */
3573 static inline void handle_in_ep_disable_intr(dwc_otg_pcd_t *pcd,
3574                                              const uint32_t epnum)
3575 {
3576         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
3577         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
3578         deptsiz_data_t dieptsiz = {
3579         .d32 = 0};
3580         dctl_data_t dctl = {
3581         .d32 = 0};
3582         dwc_otg_pcd_ep_t *ep;
3583         dwc_ep_t *dwc_ep;
3584         gintmsk_data_t gintmsk_data;
3585         depctl_data_t depctl;
3586         uint32_t diepdma;
3587         uint32_t remain_to_transfer = 0;
3588         uint8_t i;
3589         uint32_t xfer_size;
3590
3591         ep = get_in_ep(pcd, epnum);
3592         dwc_ep = &ep->dwc_ep;
3593
3594         if (dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
3595                 dwc_otg_flush_tx_fifo(core_if, dwc_ep->tx_fifo_num);
3596                 complete_ep(ep);
3597                 return;
3598         }
3599
3600         DWC_DEBUGPL(DBG_PCD, "diepctl%d=%0x\n", epnum,
3601                     DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->diepctl));
3602         dieptsiz.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dieptsiz);
3603         depctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->diepctl);
3604
3605         DWC_DEBUGPL(DBG_ANY, "pktcnt=%d size=%d\n",
3606                     dieptsiz.b.pktcnt, dieptsiz.b.xfersize);
3607
3608         if ((core_if->start_predict == 0) || (depctl.b.eptype & 1)) {
3609                 if (ep->stopped) {
3610                         if (core_if->en_multiple_tx_fifo)
3611                                 /* Flush the Tx FIFO */
3612                                 dwc_otg_flush_tx_fifo(core_if,
3613                                                       dwc_ep->tx_fifo_num);
3614                         /* Clear the Global IN NP NAK */
3615                         dctl.d32 = 0;
3616                         dctl.b.cgnpinnak = 1;
3617                         DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl,
3618                                          dctl.d32, dctl.d32);
3619                         /* Restart the transaction */
3620                         if (dieptsiz.b.pktcnt != 0 || dieptsiz.b.xfersize != 0) {
3621                                 restart_transfer(pcd, epnum);
3622                         }
3623                 } else {
3624                         /* Restart the transaction */
3625                         if (dieptsiz.b.pktcnt != 0 || dieptsiz.b.xfersize != 0) {
3626                                 restart_transfer(pcd, epnum);
3627                         }
3628                         DWC_DEBUGPL(DBG_ANY, "STOPPED!!!\n");
3629                 }
3630                 return;
3631         }
3632
3633         if (core_if->start_predict > 2) {
3634                 /* NP IN EP */
3635                 core_if->start_predict--;
3636                 return;
3637         }
3638
3639         core_if->start_predict--;
3640
3641         if (core_if->start_predict == 1) {
3642                 /* All NP IN Ep's disabled now */
3643                 predict_nextep_seq(core_if);
3644
3645                 /* Update all active IN EP's NextEP field based of nextep_seq[] */
3646                 for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
3647                         depctl.d32 =
3648                             DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl);
3649                         if (core_if->nextep_seq[i] != 0xff) {
3650                                 /* Active NP IN EP */
3651                                 depctl.b.nextep = core_if->nextep_seq[i];
3652                                 DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepctl,
3653                                                 depctl.d32);
3654                         }
3655                 }
3656                 /* Flush Shared NP TxFIFO */
3657                 dwc_otg_flush_tx_fifo(core_if, 0);
3658                 /* Rewind buffers */
3659                 if (!core_if->dma_desc_enable) {
3660                         i = core_if->first_in_nextep_seq;
3661                         do {
3662                                 ep = get_in_ep(pcd, i);
3663                                 dieptsiz.d32 =
3664                                     DWC_READ_REG32(&dev_if->
3665                                                    in_ep_regs[i]->dieptsiz);
3666                                 xfer_size =
3667                                     ep->dwc_ep.total_len -
3668                                     ep->dwc_ep.xfer_count;
3669                                 if (xfer_size > ep->dwc_ep.maxxfer)
3670                                         xfer_size = ep->dwc_ep.maxxfer;
3671                                 depctl.d32 =
3672                                     DWC_READ_REG32(&dev_if->
3673                                                    in_ep_regs[i]->diepctl);
3674                                 if (dieptsiz.b.pktcnt != 0) {
3675                                         if (xfer_size == 0) {
3676                                                 remain_to_transfer = 0;
3677                                         } else {
3678                                                 if ((xfer_size %
3679                                                      ep->dwc_ep.maxpacket) ==
3680                                                     0) {
3681                                                         remain_to_transfer =
3682                                                             dieptsiz.b.pktcnt *
3683                                                             ep->
3684                                                             dwc_ep.maxpacket;
3685                                                 } else {
3686                                                         remain_to_transfer =
3687                                                             ((dieptsiz.
3688                                                               b.pktcnt -
3689                                                               1) *
3690                                                              ep->
3691                                                              dwc_ep.maxpacket)
3692                                                             +
3693                                                             (xfer_size %
3694                                                              ep->
3695                                                              dwc_ep.maxpacket);
3696                                                 }
3697                                         }
3698                                         diepdma =
3699                                             DWC_READ_REG32(&dev_if->in_ep_regs
3700                                                            [i]->diepdma);
3701                                         dieptsiz.b.xfersize =
3702                                             remain_to_transfer;
3703                                         DWC_WRITE_REG32(&dev_if->
3704                                                         in_ep_regs[i]->dieptsiz,
3705                                                         dieptsiz.d32);
3706                                         diepdma =
3707                                             ep->dwc_ep.dma_addr + (xfer_size -
3708                                                                    remain_to_transfer);
3709                                         DWC_WRITE_REG32(&dev_if->
3710                                                         in_ep_regs[i]->diepdma,
3711                                                         diepdma);
3712                                 }
3713                                 i = core_if->nextep_seq[i];
3714                         } while (i != core_if->first_in_nextep_seq);
3715                 } else {        /* dma_desc_enable */
3716                         DWC_PRINTF("%s Learning Queue not supported in DDMA\n",
3717                                    __func__);
3718                 }
3719
3720                 /* Restart transfers in predicted sequences */
3721                 i = core_if->first_in_nextep_seq;
3722                 do {
3723                         dieptsiz.d32 =
3724                             DWC_READ_REG32(&dev_if->in_ep_regs[i]->dieptsiz);
3725                         depctl.d32 =
3726                             DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl);
3727                         if (dieptsiz.b.pktcnt != 0) {
3728                                 depctl.d32 =
3729                                     DWC_READ_REG32(&dev_if->
3730                                                    in_ep_regs[i]->diepctl);
3731                                 depctl.b.epena = 1;
3732                                 depctl.b.cnak = 1;
3733                                 DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepctl,
3734                                                 depctl.d32);
3735                         }
3736                         i = core_if->nextep_seq[i];
3737                 } while (i != core_if->first_in_nextep_seq);
3738
3739                 /* Clear the global non-periodic IN NAK handshake */
3740                 dctl.d32 = 0;
3741                 dctl.b.cgnpinnak = 1;
3742                 DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl, dctl.d32,
3743                                  dctl.d32);
3744
3745                 /* Unmask EP Mismatch interrupt */
3746                 gintmsk_data.d32 = 0;
3747                 gintmsk_data.b.epmismatch = 1;
3748                 DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, 0,
3749                                  gintmsk_data.d32);
3750
3751                 core_if->start_predict = 0;
3752
3753         }
3754 }
3755
3756 /**
3757  * Handler for the IN EP timeout handshake interrupt.
3758  */
3759 static inline void handle_in_ep_timeout_intr(dwc_otg_pcd_t *pcd,
3760                                              const uint32_t epnum)
3761 {
3762         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
3763         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
3764
3765 #ifdef DEBUG
3766         deptsiz_data_t dieptsiz = {
3767         .d32 = 0};
3768         uint32_t num = 0;
3769 #endif
3770         dctl_data_t dctl = {
3771         .d32 = 0};
3772         dwc_otg_pcd_ep_t *ep;
3773
3774         gintmsk_data_t intr_mask = {
3775         .d32 = 0};
3776
3777         ep = get_in_ep(pcd, epnum);
3778
3779         /* Disable the NP Tx Fifo Empty Interrrupt */
3780         if (!core_if->dma_enable) {
3781                 intr_mask.b.nptxfempty = 1;
3782                 DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk,
3783                                  intr_mask.d32, 0);
3784         }
3785         /** @todo NGS Check EP type.
3786          * Implement for Periodic EPs */
3787         /*
3788          * Non-periodic EP
3789          */
3790         /* Enable the Global IN NAK Effective Interrupt */
3791         intr_mask.b.ginnakeff = 1;
3792         DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, 0, intr_mask.d32);
3793
3794         /* Set Global IN NAK */
3795         dctl.b.sgnpinnak = 1;
3796         DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl, dctl.d32, dctl.d32);
3797
3798         ep->stopped = 1;
3799
3800 #ifdef DEBUG
3801         dieptsiz.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[num]->dieptsiz);
3802         DWC_DEBUGPL(DBG_ANY, "pktcnt=%d size=%d\n",
3803                     dieptsiz.b.pktcnt, dieptsiz.b.xfersize);
3804 #endif
3805
3806 #ifdef DISABLE_PERIODIC_EP
3807         /*
3808          * Set the NAK bit for this EP to
3809          * start the disable process.
3810          */
3811         diepctl.d32 = 0;
3812         diepctl.b.snak = 1;
3813         DWC_MODIFY_REG32(&dev_if->in_ep_regs[num]->diepctl, diepctl.d32,
3814                          diepctl.d32);
3815         ep->disabling = 1;
3816         ep->stopped = 1;
3817 #endif
3818 }
3819
3820 /**
3821  * Handler for the IN EP NAK interrupt.
3822  */
3823 static inline int32_t handle_in_ep_nak_intr(dwc_otg_pcd_t *pcd,
3824                                             const uint32_t epnum)
3825 {
3826         /** @todo implement ISR */
3827         dwc_otg_core_if_t *core_if;
3828         diepmsk_data_t intr_mask = {
3829         .d32 = 0};
3830
3831         DWC_PRINTF("INTERRUPT Handler not implemented for %s\n", "IN EP NAK");
3832         core_if = GET_CORE_IF(pcd);
3833         intr_mask.b.nak = 1;
3834
3835         if (core_if->multiproc_int_enable) {
3836                 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->
3837                                  diepeachintmsk[epnum], intr_mask.d32, 0);
3838         } else {
3839                 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->diepmsk,
3840                                  intr_mask.d32, 0);
3841         }
3842
3843         return 1;
3844 }
3845
3846 /**
3847  * Handler for the OUT EP Babble interrupt.
3848  */
3849 static inline int32_t handle_out_ep_babble_intr(dwc_otg_pcd_t *pcd,
3850                                                 const uint32_t epnum)
3851 {
3852         /** @todo implement ISR */
3853         dwc_otg_core_if_t *core_if;
3854         doepmsk_data_t intr_mask = {
3855         .d32 = 0};
3856
3857         DWC_PRINTF("INTERRUPT Handler not implemented for %s\n",
3858                    "OUT EP Babble");
3859         core_if = GET_CORE_IF(pcd);
3860         intr_mask.b.babble = 1;
3861
3862         if (core_if->multiproc_int_enable) {
3863                 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->
3864                                  doepeachintmsk[epnum], intr_mask.d32, 0);
3865         } else {
3866                 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->doepmsk,
3867                                  intr_mask.d32, 0);
3868         }
3869
3870         return 1;
3871 }
3872
3873 /**
3874  * Handler for the OUT EP NAK interrupt.
3875  */
3876 static inline int32_t handle_out_ep_nak_intr(dwc_otg_pcd_t *pcd,
3877                                              const uint32_t epnum)
3878 {
3879         /** @todo implement ISR */
3880         dwc_otg_core_if_t *core_if;
3881         doepmsk_data_t intr_mask = {
3882         .d32 = 0};
3883
3884         DWC_DEBUGPL(DBG_ANY, "INTERRUPT Handler not implemented for %s\n",
3885                     "OUT EP NAK");
3886         core_if = GET_CORE_IF(pcd);
3887         intr_mask.b.nak = 1;
3888
3889         if (core_if->multiproc_int_enable) {
3890                 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->
3891                                  doepeachintmsk[epnum], intr_mask.d32, 0);
3892         } else {
3893                 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->doepmsk,
3894                                  intr_mask.d32, 0);
3895         }
3896
3897         return 1;
3898 }
3899
3900 /**
3901  * Handler for the OUT EP NYET interrupt.
3902  */
3903 static inline int32_t handle_out_ep_nyet_intr(dwc_otg_pcd_t *pcd,
3904                                               const uint32_t epnum)
3905 {
3906         /** @todo implement ISR */
3907         dwc_otg_core_if_t *core_if;
3908         doepmsk_data_t intr_mask = {
3909         .d32 = 0};
3910
3911         DWC_PRINTF("INTERRUPT Handler not implemented for %s\n", "OUT EP NYET");
3912         core_if = GET_CORE_IF(pcd);
3913         intr_mask.b.nyet = 1;
3914
3915         if (core_if->multiproc_int_enable) {
3916                 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->
3917                                  doepeachintmsk[epnum], intr_mask.d32, 0);
3918         } else {
3919                 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->doepmsk,
3920                                  intr_mask.d32, 0);
3921         }
3922
3923         return 1;
3924 }
3925
3926 /**
3927  * This interrupt indicates that an IN EP has a pending Interrupt.
3928  * The sequence for handling the IN EP interrupt is shown below:
3929  * -#   Read the Device All Endpoint Interrupt register
3930  * -#   Repeat the following for each IN EP interrupt bit set (from
3931  *              LSB to MSB).
3932  * -#   Read the Device Endpoint Interrupt (DIEPINTn) register
3933  * -#   If "Transfer Complete" call the request complete function
3934  * -#   If "Endpoint Disabled" complete the EP disable procedure.
3935  * -#   If "AHB Error Interrupt" log error
3936  * -#   If "Time-out Handshake" log error
3937  * -#   If "IN Token Received when TxFIFO Empty" write packet to Tx
3938  *              FIFO.
3939  * -#   If "IN Token EP Mismatch" (disable, this is handled by EP
3940  *              Mismatch Interrupt)
3941  */
3942 static int32_t dwc_otg_pcd_handle_in_ep_intr(dwc_otg_pcd_t *pcd)
3943 {
3944 #define CLEAR_IN_EP_INTR(__core_if, __epnum, __intr) \
3945 do { \
3946                 diepint_data_t diepint = {.d32 = 0}; \
3947                 diepint.b.__intr = 1; \
3948                 DWC_WRITE_REG32(&__core_if->dev_if->in_ep_regs[__epnum]->diepint, \
3949                 diepint.d32); \
3950 } while (0)
3951
3952         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
3953         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
3954         diepint_data_t diepint = {
3955         .d32 = 0};
3956         depctl_data_t depctl = {
3957         .d32 = 0};
3958         uint32_t ep_intr;
3959         uint32_t epnum = 0;
3960         dwc_otg_pcd_ep_t *ep;
3961         dwc_ep_t *dwc_ep;
3962         gintmsk_data_t intr_mask = {
3963         .d32 = 0};
3964         dctl_data_t dctl = {
3965         .d32 = 0};
3966
3967         DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, pcd);
3968
3969         /* Read in the device interrupt bits */
3970         ep_intr = dwc_otg_read_dev_all_in_ep_intr(core_if);
3971
3972         /* Service the Device IN interrupts for each endpoint */
3973         while (ep_intr) {
3974                 if (ep_intr & 0x1) {
3975                         uint32_t empty_msk;
3976                         /* Get EP pointer */
3977                         ep = get_in_ep(pcd, epnum);
3978                         dwc_ep = &ep->dwc_ep;
3979
3980                         depctl.d32 =
3981                             DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->diepctl);
3982                         empty_msk =
3983                             DWC_READ_REG32(&dev_if->
3984                                            dev_global_regs->dtknqr4_fifoemptymsk);
3985
3986                         DWC_DEBUGPL(DBG_PCDV,
3987                                     "IN EP INTERRUPT - %d\nepmty_msk - %8x  diepctl - %8x\n",
3988                                     epnum, empty_msk, depctl.d32);
3989
3990                         DWC_DEBUGPL(DBG_PCD,
3991                                     "EP%d-%s: type=%d, mps=%d\n",
3992                                     dwc_ep->num, (dwc_ep->is_in ? "IN" : "OUT"),
3993                                     dwc_ep->type, dwc_ep->maxpacket);
3994
3995                         diepint.d32 =
3996                             dwc_otg_read_dev_in_ep_intr(core_if, dwc_ep);
3997
3998                         DWC_DEBUGPL(DBG_PCDV,
3999                                     "EP %d Interrupt Register - 0x%x\n", epnum,
4000                                     diepint.d32);
4001                         /* Transfer complete */
4002                         if (diepint.b.xfercompl) {
4003                                 /* Disable the NP Tx FIFO Empty
4004                                  * Interrupt */
4005                                 if (core_if->en_multiple_tx_fifo == 0) {
4006                                         intr_mask.b.nptxfempty = 1;
4007                                         DWC_MODIFY_REG32
4008                                             (&core_if->
4009                                              core_global_regs->gintmsk,
4010                                              intr_mask.d32, 0);
4011                                 } else {
4012                                         /* Disable the Tx FIFO Empty Interrupt for this EP */
4013                                         uint32_t fifoemptymsk =
4014                                             0x1 << dwc_ep->num;
4015                                         DWC_MODIFY_REG32(&core_if->
4016                                                          dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
4017                                                          fifoemptymsk, 0);
4018                                 }
4019                                 /* Clear the bit in DIEPINTn for this interrupt */
4020                                 CLEAR_IN_EP_INTR(core_if, epnum, xfercompl);
4021
4022                                 /* Complete the transfer */
4023                                 if (epnum == 0) {
4024                                         handle_ep0(pcd);
4025                                 }
4026 #ifdef DWC_EN_ISOC
4027                                 else if (dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
4028                                         if (!ep->stopped)
4029                                                 complete_iso_ep(pcd, ep);
4030                                 }
4031 #endif /* DWC_EN_ISOC */
4032 #ifdef DWC_UTE_PER_IO
4033                                 else if (dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
4034                                         if (!ep->stopped)
4035                                                 complete_xiso_ep(ep);
4036                                 }
4037 #endif /* DWC_UTE_PER_IO */
4038                                 else {
4039                                         if (dwc_ep->type == DWC_OTG_EP_TYPE_ISOC
4040                                             && dwc_ep->bInterval > 1) {
4041                                                 dwc_ep->frame_num +=
4042                                                     dwc_ep->bInterval;
4043                                                 if (dwc_ep->frame_num > 0x3FFF) {
4044                                                         dwc_ep->frm_overrun = 1;
4045                                                         dwc_ep->frame_num &=
4046                                                             0x3FFF;
4047                                                 } else
4048                                                         dwc_ep->frm_overrun = 0;
4049                                         }
4050                                         complete_ep(ep);
4051                                         if (diepint.b.nak)
4052                                                 CLEAR_IN_EP_INTR(core_if, epnum,
4053                                                                  nak);
4054                                 }
4055                         }
4056                         /* Endpoint disable      */
4057                         if (diepint.b.epdisabled) {
4058                                 DWC_DEBUGPL(DBG_ANY, "EP%d IN disabled\n",
4059                                             epnum);
4060                                 handle_in_ep_disable_intr(pcd, epnum);
4061
4062                                 /* Clear the bit in DIEPINTn for this interrupt */
4063                                 CLEAR_IN_EP_INTR(core_if, epnum, epdisabled);
4064                         }
4065                         /* AHB Error */
4066                         if (diepint.b.ahberr) {
4067                                 DWC_ERROR("EP%d IN AHB Error\n", epnum);
4068                                 /* Clear the bit in DIEPINTn for this interrupt */
4069                                 DWC_ERROR("EP%d DEPDMA=0x%08x \n",
4070                                           epnum,
4071                                           core_if->dev_if->
4072                                           in_ep_regs[epnum]->diepdma);
4073                                 CLEAR_IN_EP_INTR(core_if, epnum, ahberr);
4074                                 dctl.d32 =
4075                                     DWC_READ_REG32(&core_if->
4076                                                    dev_if->dev_global_regs->
4077                                                    dctl);
4078                                 dctl.b.sftdiscon = 1;
4079                                 DWC_WRITE_REG32(&core_if->
4080                                                 dev_if->dev_global_regs->dctl,
4081                                                 dctl.d32);
4082                                 dwc_otg_disable_global_interrupts(core_if);
4083                                 ep->pcd->vbus_status = 0;
4084                                 if (ep->pcd->conn_status) {
4085                                         ep->pcd->conn_status = 0;
4086                                 }
4087                                 DWC_SPINUNLOCK(pcd->lock);
4088                                 cil_pcd_stop(core_if);
4089                                 DWC_SPINLOCK(pcd->lock);
4090                         }
4091                         /* TimeOUT Handshake (non-ISOC IN EPs) */
4092                         if (diepint.b.timeout) {
4093                                 DWC_ERROR("EP%d IN Time-out\n", epnum);
4094                                 handle_in_ep_timeout_intr(pcd, epnum);
4095
4096                                 CLEAR_IN_EP_INTR(core_if, epnum, timeout);
4097                         }
4098                         /** IN Token received with TxF Empty */
4099                         if (diepint.b.intktxfemp) {
4100                                 DWC_DEBUGPL(DBG_ANY,
4101                                             "EP%d IN TKN TxFifo Empty\n",
4102                                             epnum);
4103                                 if (!ep->stopped && epnum != 0) {
4104
4105                                         diepmsk_data_t diepmsk = {
4106                                         .d32 = 0};
4107                                         diepmsk.b.intktxfemp = 1;
4108
4109                                         if (core_if->multiproc_int_enable) {
4110                                                 DWC_MODIFY_REG32
4111                                                     (&dev_if->
4112                                                      dev_global_regs->diepeachintmsk
4113                                                      [epnum], diepmsk.d32, 0);
4114                                         } else {
4115                                                 DWC_MODIFY_REG32
4116                                                     (&dev_if->
4117                                                      dev_global_regs->diepmsk,
4118                                                      diepmsk.d32, 0);
4119                                         }
4120                                 } else if (core_if->dma_desc_enable
4121                                            && epnum == 0
4122                                            && pcd->ep0state ==
4123                                            EP0_OUT_STATUS_PHASE) {
4124                                         /* EP0 IN set STALL */
4125                                         depctl.d32 =
4126                                             DWC_READ_REG32(&dev_if->in_ep_regs
4127                                                            [epnum]->diepctl);
4128
4129                                         /* set the disable and stall bits */
4130                                         if (depctl.b.epena) {
4131                                                 depctl.b.epdis = 1;
4132                                         }
4133                                         depctl.b.stall = 1;
4134                                         DWC_WRITE_REG32(&dev_if->in_ep_regs
4135                                                         [epnum]->diepctl,
4136                                                         depctl.d32);
4137                                 }
4138                                 CLEAR_IN_EP_INTR(core_if, epnum, intktxfemp);
4139                         }
4140                         /** IN Token Received with EP mismatch */
4141                         if (diepint.b.intknepmis) {
4142                                 DWC_DEBUGPL(DBG_ANY,
4143                                             "EP%d IN TKN EP Mismatch\n", epnum);
4144                                 CLEAR_IN_EP_INTR(core_if, epnum, intknepmis);
4145                         }
4146                         /** IN Endpoint NAK Effective */
4147                         if (diepint.b.inepnakeff) {
4148                                 DWC_DEBUGPL(DBG_ANY,
4149                                             "EP%d IN EP NAK Effective\n",
4150                                             epnum);
4151                                 /* Periodic EP */
4152                                 if (ep->disabling) {
4153                                         depctl.d32 = 0;
4154                                         depctl.b.snak = 1;
4155                                         depctl.b.epdis = 1;
4156                                         DWC_MODIFY_REG32(&dev_if->in_ep_regs
4157                                                          [epnum]->diepctl,
4158                                                          depctl.d32,
4159                                                          depctl.d32);
4160                                 }
4161                                 CLEAR_IN_EP_INTR(core_if, epnum, inepnakeff);
4162
4163                         }
4164
4165                         /** IN EP Tx FIFO Empty Intr */
4166                         if (diepint.b.emptyintr) {
4167                                 DWC_DEBUGPL(DBG_ANY,
4168                                             "EP%d Tx FIFO Empty Intr \n",
4169                                             epnum);
4170                                 write_empty_tx_fifo(pcd, epnum);
4171
4172                                 CLEAR_IN_EP_INTR(core_if, epnum, emptyintr);
4173
4174                         }
4175
4176                         /** IN EP BNA Intr */
4177                         if (diepint.b.bna) {
4178                                 CLEAR_IN_EP_INTR(core_if, epnum, bna);
4179                                 if (core_if->dma_desc_enable) {
4180 #ifdef DWC_EN_ISOC
4181                                         if (dwc_ep->type ==
4182                                             DWC_OTG_EP_TYPE_ISOC) {
4183                                                 /*
4184                                                  * This checking is performed to prevent first "false" BNA
4185                                                  * handling occuring right after reconnect
4186                                                  */
4187                                                 if (dwc_ep->next_frame !=
4188                                                     0xffffffff)
4189                                                         dwc_otg_pcd_handle_iso_bna
4190                                                             (ep);
4191                                         } else
4192 #endif /* DWC_EN_ISOC */
4193                                         {
4194                                                 dwc_otg_pcd_handle_noniso_bna
4195                                                     (ep);
4196                                         }
4197                                 }
4198                         }
4199                         /* NAK Interrutp */
4200                         if (diepint.b.nak) {
4201                                 DWC_DEBUGPL(DBG_ANY, "EP%d IN NAK Interrupt\n",
4202                                             epnum);
4203                                 if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) {
4204                                         depctl_data_t depctl;
4205                                         if (ep->dwc_ep.frame_num == 0xFFFFFFFF) {
4206                                                 ep->dwc_ep.frame_num =
4207                                                     core_if->frame_num;
4208                                                 if (ep->dwc_ep.bInterval > 1) {
4209                                                         depctl.d32 = 0;
4210                                                         depctl.d32 =
4211                                                             DWC_READ_REG32
4212                                                             (&dev_if->in_ep_regs
4213                                                              [epnum]->diepctl);
4214                                                         if (ep->
4215                                                             dwc_ep.frame_num &
4216                                                             0x1) {
4217                                                                 depctl.
4218                                                                     b.setd1pid =
4219                                                                     1;
4220                                                                 depctl.
4221                                                                     b.setd0pid =
4222                                                                     0;
4223                                                         } else {
4224                                                                 depctl.
4225                                                                     b.setd0pid =
4226                                                                     1;
4227                                                                 depctl.
4228                                                                     b.setd1pid =
4229                                                                     0;
4230                                                         }
4231                                                         DWC_WRITE_REG32
4232                                                             (&dev_if->in_ep_regs
4233                                                              [epnum]->diepctl,
4234                                                              depctl.d32);
4235                                                 }
4236                                                 start_next_request(ep);
4237                                         }
4238                                         ep->dwc_ep.frame_num +=
4239                                             ep->dwc_ep.bInterval;
4240                                         if (dwc_ep->frame_num > 0x3FFF) {
4241                                                 dwc_ep->frm_overrun = 1;
4242                                                 dwc_ep->frame_num &= 0x3FFF;
4243                                         } else
4244                                                 dwc_ep->frm_overrun = 0;
4245                                 }
4246
4247                                 CLEAR_IN_EP_INTR(core_if, epnum, nak);
4248                         }
4249                 }
4250                 epnum++;
4251                 ep_intr >>= 1;
4252         }
4253
4254         return 1;
4255 #undef CLEAR_IN_EP_INTR
4256 }
4257
4258 /**
4259  * This interrupt indicates that an OUT EP has a pending Interrupt.
4260  * The sequence for handling the OUT EP interrupt is shown below:
4261  * -#   Read the Device All Endpoint Interrupt register
4262  * -#   Repeat the following for each OUT EP interrupt bit set (from
4263  *              LSB to MSB).
4264  * -#   Read the Device Endpoint Interrupt (DOEPINTn) register
4265  * -#   If "Transfer Complete" call the request complete function
4266  * -#   If "Endpoint Disabled" complete the EP disable procedure.
4267  * -#   If "AHB Error Interrupt" log error
4268  * -#   If "Setup Phase Done" process Setup Packet (See Standard USB
4269  *              Command Processing)
4270  */
4271 static int32_t dwc_otg_pcd_handle_out_ep_intr(dwc_otg_pcd_t *pcd)
4272 {
4273 #define CLEAR_OUT_EP_INTR(__core_if, __epnum, __intr) \
4274 do { \
4275                 doepint_data_t doepint = {.d32 = 0}; \
4276                 doepint.b.__intr = 1; \
4277                 DWC_WRITE_REG32(&__core_if->dev_if->out_ep_regs[__epnum]->doepint, \
4278                 doepint.d32); \
4279 } while (0)
4280
4281         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
4282         uint32_t ep_intr;
4283         doepint_data_t doepint = {
4284         .d32 = 0};
4285         uint32_t epnum = 0;
4286         dwc_otg_pcd_ep_t *ep;
4287         dwc_ep_t *dwc_ep;
4288         dctl_data_t dctl = {
4289         .d32 = 0};
4290         gintmsk_data_t gintmsk = {
4291         .d32 = 0};
4292
4293         DWC_DEBUGPL(DBG_PCDV, "%s()\n", __func__);
4294
4295         /* Read in the device interrupt bits */
4296         ep_intr = dwc_otg_read_dev_all_out_ep_intr(core_if);
4297
4298         while (ep_intr) {
4299                 if (ep_intr & 0x1) {
4300                         /* Get EP pointer */
4301                         ep = get_out_ep(pcd, epnum);
4302                         dwc_ep = &ep->dwc_ep;
4303
4304 #ifdef VERBOSE
4305                         DWC_DEBUGPL(DBG_PCDV,
4306                                     "EP%d-%s: type=%d, mps=%d\n",
4307                                     dwc_ep->num, (dwc_ep->is_in ? "IN" : "OUT"),
4308                                     dwc_ep->type, dwc_ep->maxpacket);
4309 #endif
4310                         doepint.d32 =
4311                             dwc_otg_read_dev_out_ep_intr(core_if, dwc_ep);
4312                         /* Transfer complete */
4313                         if (doepint.b.xfercompl) {
4314
4315                                 if (epnum == 0) {
4316                                         /* Clear the bit in DOEPINTn for this interrupt */
4317                                         CLEAR_OUT_EP_INTR(core_if, epnum,
4318                                                           xfercompl);
4319                                         if (core_if->snpsid >=
4320                                             OTG_CORE_REV_3_00a) {
4321                                                 DWC_DEBUGPL(DBG_PCDV,
4322                                                             "in xfer xomplete DOEPINT=%x doepint=%x\n",
4323                                                             DWC_READ_REG32
4324                                                             (&core_if->
4325                                                              dev_if->out_ep_regs
4326                                                              [0]->doepint),
4327                                                             doepint.d32);
4328                                                 DWC_DEBUGPL(DBG_PCDV,
4329                                                             "DOEPCTL=%x \n",
4330                                                             DWC_READ_REG32
4331                                                             (&core_if->
4332                                                              dev_if->out_ep_regs
4333                                                              [0]->doepctl));
4334
4335                                                 if (core_if->snpsid >=
4336                                                     OTG_CORE_REV_3_00a
4337                                                     && core_if->dma_enable ==
4338                                                     0) {
4339                                                         doepint_data_t doepint;
4340                                                         doepint.d32 =
4341                                                             DWC_READ_REG32
4342                                                             (&core_if->dev_if->
4343                                                              out_ep_regs[0]->
4344                                                              doepint);
4345                                                         if (pcd->ep0state ==
4346                                                             EP0_IDLE
4347                                                             && doepint.b.sr) {
4348                                                                 CLEAR_OUT_EP_INTR
4349                                                                     (core_if,
4350                                                                      epnum, sr);
4351                                                                 goto exit_xfercompl;
4352                                                         }
4353                                                 }
4354                                                 /* In case of DDMA  look at SR bit to go to the Data Stage */
4355                                                 if (core_if->dma_desc_enable) {
4356                                                         dev_dma_desc_sts_t
4357                                                             status = {
4358                                                         .d32 = 0};
4359                                                         if (pcd->ep0state ==
4360                                                             EP0_IDLE) {
4361                                                                 status.d32 =
4362                                                                     core_if->dev_if->setup_desc_addr
4363                                                                     [core_if->
4364                                                                      dev_if->setup_desc_index]->status.
4365                                                                     d32;
4366                                                                 if (pcd->data_terminated) {
4367                                                                         pcd->data_terminated
4368                                                                             = 0;
4369                                                                         status.d32
4370                                                                             =
4371                                                                             core_if->dev_if->out_desc_addr->status.d32;
4372                                                                         dwc_memcpy
4373                                                                             (&pcd->setup_pkt->req,
4374                                                                              pcd->backup_buf,
4375                                                                              8);
4376                                                                 }
4377                                                                 if (status.b.sr) {
4378                                                                         if (doepint.b.setup) {
4379                                                                                 DWC_DEBUGPL
4380                                                                                     (DBG_PCDV,
4381                                                                                      "DMA DESC EP0_IDLE SR=1 setup=1\n");
4382                                                                                 /* Already started data stage, clear setup */
4383                                                                                 CLEAR_OUT_EP_INTR
4384                                                                                     (core_if,
4385                                                                                      epnum,
4386                                                                                      setup);
4387                                                                                 doepint.b.setup
4388                                                                                     =
4389                                                                                     0;
4390                                                                                 handle_ep0
4391                                                                                     (pcd);
4392                                                                                 /* Prepare for more setup packets */
4393                                                                                 if (pcd->ep0state == EP0_IN_STATUS_PHASE || pcd->ep0state == EP0_IN_DATA_PHASE) {
4394                                                                                         ep0_out_start
4395                                                                                             (core_if,
4396                                                                                              pcd);
4397                                                                                 }
4398
4399                                                                                 goto exit_xfercompl;
4400                                                                         } else {
4401                                                                                 /* Prepare for more setup packets */
4402                                                                                 DWC_DEBUGPL
4403                                                                                     (DBG_PCDV,
4404                                                                                      "EP0_IDLE SR=1 setup=0 new setup comes\n");
4405                                                                                 ep0_out_start
4406                                                                                     (core_if,
4407                                                                                      pcd);
4408                                                                         }
4409                                                                 }
4410                                                         } else {
4411                                                                 dwc_otg_pcd_request_t
4412                                                                     *req;
4413                                                                 dev_dma_desc_sts_t
4414                                                                     status = {
4415                                                                 .d32 = 0};
4416                                                                 diepint_data_t
4417                                                                     diepint0;
4418                                                                 diepint0.d32 =
4419                                                                     DWC_READ_REG32
4420                                                                     (&core_if->dev_if->
4421                                                                      in_ep_regs
4422                                                                      [0]->diepint);
4423
4424                                                                 if (pcd->ep0state == EP0_STALL || pcd->ep0state == EP0_DISCONNECT) {
4425                                                                         DWC_ERROR
4426                                                                             ("EP0 is stalled/disconnected\n");
4427                                                                 }
4428
4429                                                                 /* Clear IN xfercompl if set */
4430                                                                 if (diepint0.
4431                                                                     b.xfercompl
4432                                                                     &&
4433                                                                     (pcd->ep0state
4434                                                                      ==
4435                                                                      EP0_IN_STATUS_PHASE
4436                                                                      ||
4437                                                                      pcd->ep0state
4438                                                                      ==
4439                                                                      EP0_IN_DATA_PHASE)) {
4440                                                                         DWC_WRITE_REG32
4441                                                                             (&core_if->dev_if->
4442                                                                              in_ep_regs
4443                                                                              [0]->diepint,
4444                                                                              diepint0.d32);
4445                                                                 }
4446
4447                                                                 status.d32 =
4448                                                                     core_if->dev_if->setup_desc_addr
4449                                                                     [core_if->
4450                                                                      dev_if->setup_desc_index]->status.
4451                                                                     d32;
4452
4453                                                                 if (ep->
4454                                                                     dwc_ep.xfer_count
4455                                                                     !=
4456                                                                     ep->
4457                                                                     dwc_ep.total_len
4458                                                                     &&
4459                                                                     (pcd->ep0state
4460                                                                      ==
4461                                                                      EP0_OUT_DATA_PHASE))
4462                                                                         status.d32
4463                                                                             =
4464                                                                             core_if->dev_if->out_desc_addr->status.d32;
4465                                                                 if (pcd->ep0state == EP0_OUT_STATUS_PHASE)
4466                                                                         status.d32
4467                                                                             =
4468                                                                             core_if->dev_if->
4469                                                                             out_desc_addr->status.d32;
4470
4471                                                                 if (status.b.sr) {
4472                                                                         if (DWC_CIRCLEQ_EMPTY(&ep->queue)) {
4473                                                                                 DWC_DEBUGPL
4474                                                                                     (DBG_PCDV,
4475                                                                                      "Request queue empty!!\n");
4476                                                                         } else {
4477                                                                                 DWC_DEBUGPL
4478                                                                                     (DBG_PCDV,
4479                                                                                      "complete req!!\n");
4480                                                                                 req = DWC_CIRCLEQ_FIRST(&ep->queue);
4481                                                                                 if (ep->dwc_ep.xfer_count != ep->dwc_ep.total_len && pcd->ep0state == EP0_OUT_DATA_PHASE) {
4482                                                                                         /* Read arrived setup packet from req->buf */
4483                                                                                         dwc_memcpy
4484                                                                                             (&pcd->setup_pkt->req,
4485                                                                                              req->buf
4486                                                                                              +
4487                                                                                              ep->dwc_ep.xfer_count,
4488                                                                                              8);
4489                                                                                 }
4490                                                                                 req->actual
4491                                                                                     =
4492                                                                                     ep->dwc_ep.xfer_count;
4493                                                                                 dwc_otg_request_done
4494                                                                                     (ep,
4495                                                                                      req,
4496                                                                                      -ECONNRESET);
4497                                                                                 ep->dwc_ep.start_xfer_buff = 0;
4498                                                                                 ep->dwc_ep.xfer_buff = 0;
4499                                                                                 ep->dwc_ep.xfer_len = 0;
4500                                                                         }
4501                                                                         pcd->ep0state
4502                                                                             =
4503                                                                             EP0_IDLE;
4504                                                                         if (doepint.b.setup) {
4505                                                                                 DWC_DEBUGPL
4506                                                                                     (DBG_PCDV,
4507                                                                                      "EP0_IDLE SR=1 setup=1\n");
4508                                                                                 /* Data stage started, clear setup */
4509                                                                                 CLEAR_OUT_EP_INTR
4510                                                                                     (core_if,
4511                                                                                      epnum,
4512                                                                                      setup);
4513                                                                                 doepint.b.setup
4514                                                                                     =
4515                                                                                     0;
4516                                                                                 handle_ep0
4517                                                                                     (pcd);
4518                                                                                 /* Prepare for setup packets if ep0in was enabled */
4519                                                                                 if (pcd->ep0state == EP0_IN_STATUS_PHASE) {
4520                                                                                         ep0_out_start
4521                                                                                             (core_if,
4522                                                                                              pcd);
4523                                                                                 }
4524
4525                                                                                 goto exit_xfercompl;
4526                                                                         } else {
4527                                                                                 /* Prepare for more setup packets */
4528                                                                                 DWC_DEBUGPL
4529                                                                                     (DBG_PCDV,
4530                                                                                      "EP0_IDLE SR=1 setup=0 new setup comes 2\n");
4531                                                                                 ep0_out_start
4532                                                                                     (core_if,
4533                                                                                      pcd);
4534                                                                         }
4535                                                                 }
4536                                                         }
4537                                                 }
4538                                                 if (core_if->snpsid >=
4539                                                     OTG_CORE_REV_3_00a
4540                                                     && core_if->dma_enable
4541                                                     && core_if->dma_desc_enable
4542                                                     == 0) {
4543                                                         doepint_data_t
4544                                                             doepint_temp = {
4545                                                         .d32 = 0};
4546                                                         deptsiz0_data_t
4547                                                             doeptsize0 = {
4548                                                         .d32 = 0};
4549                                                         doepint_temp.d32 =
4550                                                             DWC_READ_REG32
4551                                                             (&core_if->dev_if->
4552                                                              out_ep_regs[ep->
4553                                                                          dwc_ep.
4554                                                                          num]->doepint);
4555                                                         doeptsize0.d32 =
4556                                                             DWC_READ_REG32
4557                                                             (&core_if->dev_if->
4558                                                              out_ep_regs[ep->
4559                                                                          dwc_ep.
4560                                                                          num]->doeptsiz);
4561                                                         if (((ep->
4562                                                               dwc_ep.xfer_count
4563                                                               ==
4564                                                               ep->
4565                                                               dwc_ep.total_len
4566                                                               || doeptsize0.
4567                                                               b.xfersize == 64)
4568                                                              && pcd->ep0state ==
4569                                                              EP0_OUT_DATA_PHASE
4570                                                              && doepint.
4571                                                              b.stsphsercvd)
4572                                                             || (doeptsize0.
4573                                                                 b.xfersize == 24
4574                                                                 && pcd->ep0state
4575                                                                 ==
4576                                                                 EP0_IN_STATUS_PHASE)){
4577                                                                 CLEAR_OUT_EP_INTR
4578                                                                     (core_if,
4579                                                                      epnum,
4580                                                                      xfercompl);
4581                                                                 DWC_DEBUGPL
4582                                                                     (DBG_PCDV,
4583                                                                      "WA for xfercompl along with stsphs \n");
4584                                                                 doepint.
4585                                                                     b.xfercompl
4586                                                                     = 0;
4587                                                                 ep0_out_start
4588                                                                     (core_if,
4589                                                                      pcd);
4590                                                                 goto exit_xfercompl;
4591                                                         }
4592
4593                                                         if (pcd->ep0state ==
4594                                                             EP0_IDLE) {
4595                                                                 if (doepint_temp.b.sr) {
4596                                                                         CLEAR_OUT_EP_INTR
4597                                                                             (core_if,
4598                                                                              epnum,
4599                                                                              sr);
4600                                                                 }
4601                                                                 /* Delay is needed for core to update setup
4602                                                                  * packet count from 3 to 2 after receiving
4603                                                                  * setup packet*/
4604                                                                 dwc_udelay(100);
4605                                                                 doepint.d32 =
4606                                                                     DWC_READ_REG32
4607                                                                     (&core_if->dev_if->
4608                                                                      out_ep_regs
4609                                                                      [0]->doepint);
4610                                                                 if (doeptsize0.b.supcnt == 3) {
4611                                                                         DWC_DEBUGPL
4612                                                                             (DBG_ANY,
4613                                                                              "Rolling over!!!!!!!\n");
4614                                                                         ep->dwc_ep.stp_rollover = 1;
4615                                                                 }
4616                                                                 if (doepint.
4617                                                                     b.setup) {
4618 retry:
4619                                                                         /* Already started data stage, clear setup */
4620                                                                         CLEAR_OUT_EP_INTR(core_if, epnum, setup);
4621                                                                         doepint.b.setup
4622                                                                             = 0;
4623                                                                         handle_ep0
4624                                                                             (pcd);
4625                                                                         ep->dwc_ep.stp_rollover = 0;
4626                                                                         /* Prepare for more setup packets */
4627                                                                         if (pcd->ep0state == EP0_IN_STATUS_PHASE || pcd->ep0state == EP0_IN_DATA_PHASE) {
4628                                                                                 depctl_data_t
4629                                                                                     depctl
4630                                                                                     = {
4631                                                                                 .d32 = 0};
4632                                                                                 depctl.b.cnak
4633                                                                                     =
4634                                                                                     1;
4635                                                                                 ep0_out_start
4636                                                                                     (core_if,
4637                                                                                      pcd);
4638                                                                                 /* Core not updating setup packet count
4639                                                                                  * in case of PET testing - @TODO vahrama
4640                                                                                  * to check with HW team further */
4641                                                                                 if (!core_if->otg_ver) {
4642                                                                                         DWC_MODIFY_REG32
4643                                                                                             (&core_if->dev_if->
4644                                                                                              out_ep_regs
4645                                                                                              [0]->doepctl,
4646                                                                                              0,
4647                                                                                              depctl.d32);
4648                                                                                 }
4649                                                                         }
4650                                                                         goto exit_xfercompl;
4651                                                                 } else {
4652                                                                         /* Prepare for more setup packets */
4653                                                                         DWC_DEBUGPL
4654                                                                             (DBG_ANY,
4655                                                                              "EP0_IDLE SR=1 setup=0 new setup comes\n");
4656                                                                         doepint.d32
4657                                                                             =
4658                                                                             DWC_READ_REG32
4659                                                                             (&core_if->dev_if->
4660                                                                              out_ep_regs
4661                                                                              [0]->doepint);
4662                                                                         if (doepint.b.setup)
4663                                                                                 goto retry;
4664                                                                         ep0_out_start
4665                                                                             (core_if,
4666                                                                              pcd);
4667                                                                 }
4668                                                         } else {
4669                                                                 dwc_otg_pcd_request_t
4670                                                                     *req;
4671                                                                 diepint_data_t
4672                                                                     diepint0 = {
4673                                                                 .d32 = 0};
4674                                                                 doepint_data_t
4675                                                                     doepint_temp
4676                                                                     = {
4677                                                                 .d32 = 0};
4678                                                                 depctl_data_t
4679                                                                     diepctl0;
4680                                                                 diepint0.d32 =
4681                                                                     DWC_READ_REG32
4682                                                                     (&core_if->dev_if->
4683                                                                      in_ep_regs
4684                                                                      [0]->diepint);
4685                                                                 diepctl0.d32 =
4686                                                                     DWC_READ_REG32
4687                                                                     (&core_if->dev_if->
4688                                                                      in_ep_regs
4689                                                                      [0]->diepctl);
4690
4691                                                                 if (pcd->ep0state == EP0_IN_DATA_PHASE || pcd->ep0state == EP0_IN_STATUS_PHASE) {
4692                                                                         if (diepint0.b.xfercompl) {
4693                                                                                 DWC_WRITE_REG32
4694                                                                                     (&core_if->dev_if->
4695                                                                                      in_ep_regs
4696                                                                                      [0]->diepint,
4697                                                                                      diepint0.d32);
4698                                                                         }
4699                                                                         if (diepctl0.b.epena) {
4700                                                                                 diepint_data_t
4701                                                                                     diepint
4702                                                                                     = {
4703                                                                                 .d32 = 0};
4704                                                                                 diepctl0.b.snak
4705                                                                                     =
4706                                                                                     1;
4707                                                                                 DWC_WRITE_REG32
4708                                                                                     (&core_if->dev_if->
4709                                                                                      in_ep_regs
4710                                                                                      [0]->diepctl,
4711                                                                                      diepctl0.d32);
4712                                                                                 do {
4713                                                                                         dwc_udelay
4714                                                                                             (10);
4715                                                                                         diepint.d32
4716                                                                                             =
4717                                                                                             DWC_READ_REG32
4718                                                                                             (&core_if->dev_if->
4719                                                                                              in_ep_regs
4720                                                                                              [0]->diepint);
4721                                                                                 } while (!diepint.b.inepnakeff);
4722                                                                                 diepint.b.inepnakeff
4723                                                                                     =
4724                                                                                     1;
4725                                                                                 DWC_WRITE_REG32
4726                                                                                     (&core_if->dev_if->
4727                                                                                      in_ep_regs
4728                                                                                      [0]->diepint,
4729                                                                                      diepint.d32);
4730                                                                                 diepctl0.d32
4731                                                                                     =
4732                                                                                     0;
4733                                                                                 diepctl0.b.epdis
4734                                                                                     =
4735                                                                                     1;
4736                                                                                 DWC_WRITE_REG32
4737                                                                                     (&core_if->dev_if->in_ep_regs
4738                                                                                      [0]->diepctl,
4739                                                                                      diepctl0.d32);
4740                                                                                 do {
4741                                                                                         dwc_udelay
4742                                                                                             (10);
4743                                                                                         diepint.d32
4744                                                                                             =
4745                                                                                             DWC_READ_REG32
4746                                                                                             (&core_if->dev_if->
4747                                                                                              in_ep_regs
4748                                                                                              [0]->diepint);
4749                                                                                 } while (!diepint.b.epdisabled);
4750                                                                                 diepint.b.epdisabled
4751                                                                                     =
4752                                                                                     1;
4753                                                                                 DWC_WRITE_REG32
4754                                                                                     (&core_if->dev_if->in_ep_regs
4755                                                                                      [0]->diepint,
4756                                                                                      diepint.d32);
4757                                                                         }
4758                                                                 }
4759                                                                 doepint_temp.d32
4760                                                                     =
4761                                                                     DWC_READ_REG32
4762                                                                     (&core_if->dev_if->
4763                                                                      out_ep_regs
4764                                                                      [ep->dwc_ep.num]->doepint);
4765                                                                 if (doepint_temp.b.sr) {
4766                                                                         CLEAR_OUT_EP_INTR
4767                                                                             (core_if,
4768                                                                              epnum,
4769                                                                              sr);
4770                                                                         if (DWC_CIRCLEQ_EMPTY(&ep->queue)) {
4771                                                                                 DWC_DEBUGPL
4772                                                                                     (DBG_PCDV,
4773                                                                                      "Request queue empty!!\n");
4774                                                                         } else {
4775                                                                                 DWC_DEBUGPL
4776                                                                                     (DBG_PCDV,
4777                                                                                      "complete req!!\n");
4778                                                                                 req = DWC_CIRCLEQ_FIRST(&ep->queue);
4779                                                                                 if (ep->dwc_ep.xfer_count != ep->dwc_ep.total_len && pcd->ep0state == EP0_OUT_DATA_PHASE) {
4780                                                                                         /* Read arrived setup packet from req->buf */
4781                                                                                         dwc_memcpy
4782                                                                                             (&pcd->setup_pkt->req,
4783                                                                                              req->buf
4784                                                                                              +
4785                                                                                              ep->dwc_ep.xfer_count,
4786                                                                                              8);
4787                                                                                 }
4788                                                                                 req->actual
4789                                                                                     =
4790                                                                                     ep->dwc_ep.xfer_count;
4791                                                                                 dwc_otg_request_done
4792                                                                                     (ep,
4793                                                                                      req,
4794                                                                                      -ECONNRESET);
4795                                                                                 ep->dwc_ep.start_xfer_buff = 0;
4796                                                                                 ep->dwc_ep.xfer_buff = 0;
4797                                                                                 ep->dwc_ep.xfer_len = 0;
4798                                                                         }
4799                                                                         pcd->ep0state
4800                                                                             =
4801                                                                             EP0_IDLE;
4802                                                                         if (doepint.b.setup) {
4803                                                                                 DWC_DEBUGPL
4804                                                                                     (DBG_PCDV,
4805                                                                                      "EP0_IDLE SR=1 setup=1\n");
4806                                                                                 /* Data stage started, clear setup */
4807                                                                                 CLEAR_OUT_EP_INTR
4808                                                                                     (core_if,
4809                                                                                      epnum,
4810                                                                                      setup);
4811                                                                                 doepint.b.setup
4812                                                                                     =
4813                                                                                     0;
4814                                                                                 handle_ep0
4815                                                                                     (pcd);
4816                                                                                 /* Prepare for setup packets if ep0in was enabled */
4817                                                                                 if (pcd->ep0state == EP0_IN_STATUS_PHASE) {
4818                                                                                         depctl_data_t
4819                                                                                             depctl
4820                                                                                             = {
4821                                                                                         .d32 = 0};
4822                                                                                         depctl.b.cnak
4823                                                                                             =
4824                                                                                             1;
4825                                                                                         ep0_out_start
4826                                                                                             (core_if,
4827                                                                                              pcd);
4828                                                                                         /* Core not updating setup packet count
4829                                                                                          * in case of PET testing - @TODO vahrama
4830                                                                                          * to check with HW team further */
4831                                                                                         if (!core_if->otg_ver) {
4832                                                                                                 DWC_MODIFY_REG32
4833                                                                                                     (&core_if->dev_if->
4834                                                                                                      out_ep_regs
4835                                                                                                      [0]->doepctl,
4836                                                                                                      0,
4837                                                                                                      depctl.d32);
4838                                                                                         }
4839                                                                                 }
4840                                                                                 goto exit_xfercompl;
4841                                                                         } else {
4842                                                                                 /* Prepare for more setup packets */
4843                                                                                 DWC_DEBUGPL
4844                                                                                     (DBG_PCDV,
4845                                                                                      "EP0_IDLE SR=1 setup=0 new setup comes 2\n");
4846                                                                                 ep0_out_start
4847                                                                                     (core_if,
4848                                                                                      pcd);
4849                                                                         }
4850                                                                 }
4851                                                         }
4852                                                 }
4853                                                 if (core_if->dma_enable == 0
4854                                                     || pcd->ep0state !=
4855                                                     EP0_IDLE)
4856                                                         handle_ep0(pcd);
4857 exit_xfercompl:
4858                                                 DWC_DEBUGPL(DBG_PCDV,
4859                                                             "after DOEPINT=%x doepint=%x\n",
4860                                                             dwc_otg_read_dev_out_ep_intr
4861                                                             (core_if, dwc_ep),
4862                                                             doepint.d32);
4863                                         } else {
4864                                                 if (core_if->dma_desc_enable ==
4865                                                     0
4866                                                     || pcd->ep0state !=
4867                                                     EP0_IDLE)
4868                                                         handle_ep0(pcd);
4869                                         }
4870 #ifdef DWC_EN_ISOC
4871                                 } else if (dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
4872                                         if (doepint.b.pktdrpsts == 0) {
4873                                                 /* Clear the bit in DOEPINTn for this interrupt */
4874                                                 CLEAR_OUT_EP_INTR(core_if,
4875                                                                   epnum,
4876                                                                   xfercompl);
4877                                                 complete_iso_ep(pcd, ep);
4878                                         } else {
4879
4880                                                 doepint_data_t doepint = {
4881                                                 .d32 = 0};
4882                                                 doepint.b.xfercompl = 1;
4883                                                 doepint.b.pktdrpsts = 1;
4884                                                 DWC_WRITE_REG32
4885                                                     (&core_if->
4886                                                      dev_if->out_ep_regs
4887                                                      [epnum]->doepint,
4888                                                      doepint.d32);
4889                                                 if (handle_iso_out_pkt_dropped
4890                                                     (core_if, dwc_ep)) {
4891                                                         complete_iso_ep(pcd,
4892                                                                         ep);
4893                                                 }
4894                                         }
4895 #endif /* DWC_EN_ISOC */
4896 #ifdef DWC_UTE_PER_IO
4897                                 } else if (dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
4898                                         CLEAR_OUT_EP_INTR(core_if, epnum,
4899                                                           xfercompl);
4900                                         if (!ep->stopped)
4901                                                 complete_xiso_ep(ep);
4902 #endif /* DWC_UTE_PER_IO */
4903                                 } else {
4904                                         /* Clear the bit in DOEPINTn for this interrupt */
4905                                         CLEAR_OUT_EP_INTR(core_if, epnum,
4906                                                           xfercompl);
4907
4908                                         if (core_if->core_params->dev_out_nak) {
4909                                                 DWC_TIMER_CANCEL(pcd->
4910                                                                  core_if->ep_xfer_timer
4911                                                                  [epnum]);
4912                                                 pcd->
4913                                                     core_if->ep_xfer_info
4914                                                     [epnum].state = 0;
4915 #ifdef DEBUG
4916                                                 print_memory_payload(pcd,
4917                                                                      dwc_ep);
4918 #endif
4919                                         }
4920                                         complete_ep(ep);
4921                                 }
4922
4923                         }
4924
4925                         if (doepint.b.stsphsercvd) {
4926                                 deptsiz0_data_t deptsiz;
4927                                 CLEAR_OUT_EP_INTR(core_if, epnum, stsphsercvd);
4928                                 deptsiz.d32 =
4929                                     DWC_READ_REG32(&core_if->dev_if->
4930                                                    out_ep_regs[0]->doeptsiz);
4931                                 if ((core_if->dma_desc_enable)
4932                                     || (core_if->dma_enable
4933                                         && core_if->snpsid >=
4934                                         OTG_CORE_REV_3_00a)) {
4935                                         do_setup_in_status_phase(pcd);
4936                                 }
4937                         }
4938
4939                         /* Endpoint disable      */
4940                         if (doepint.b.epdisabled) {
4941
4942                                 /* Clear the bit in DOEPINTn for this interrupt */
4943                                 CLEAR_OUT_EP_INTR(core_if, epnum, epdisabled);
4944                                 if (core_if->core_params->dev_out_nak) {
4945 #ifdef DEBUG
4946                                         print_memory_payload(pcd, dwc_ep);
4947 #endif
4948                                         /* In case of timeout condition */
4949                                         if (core_if->
4950                                             ep_xfer_info[epnum].state == 2) {
4951                                                 dctl.d32 =
4952                                                     DWC_READ_REG32
4953                                                     (&core_if->dev_if->
4954                                                      dev_global_regs->dctl);
4955                                                 dctl.b.cgoutnak = 1;
4956                                                 DWC_WRITE_REG32
4957                                                     (&core_if->dev_if->dev_global_regs->dctl,
4958                                                      dctl.d32);
4959                                                 /* Unmask goutnakeff interrupt which was masked
4960                                                  * during handle nak out interrupt */
4961                                                 gintmsk.b.goutnakeff = 1;
4962                                                 DWC_MODIFY_REG32
4963                                                     (&core_if->core_global_regs->gintmsk,
4964                                                      0, gintmsk.d32);
4965
4966                                                 complete_ep(ep);
4967                                         }
4968                                 }
4969                                 if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) {
4970                                         dctl_data_t dctl;
4971                                         gintmsk_data_t intr_mask = {
4972                                         .d32 = 0};
4973                                         dwc_otg_pcd_request_t *req = 0;
4974
4975                                         dctl.d32 =
4976                                             DWC_READ_REG32(&core_if->dev_if->
4977                                                            dev_global_regs->dctl);
4978                                         dctl.b.cgoutnak = 1;
4979                                         DWC_WRITE_REG32(&core_if->
4980                                                         dev_if->dev_global_regs->
4981                                                         dctl, dctl.d32);
4982
4983                                         intr_mask.d32 = 0;
4984                                         intr_mask.b.incomplisoout = 1;
4985
4986                                         /* Get any pending requests */
4987                                         if (!DWC_CIRCLEQ_EMPTY(&ep->queue)) {
4988                                                 req =
4989                                                     DWC_CIRCLEQ_FIRST
4990                                                     (&ep->queue);
4991                                                 if (!req) {
4992                                                         DWC_PRINTF
4993                                                             ("complete_ep 0x%p, req = NULL!\n",
4994                                                              ep);
4995                                                 } else {
4996                                                         dwc_otg_request_done(ep,
4997                                                                              req,
4998                                                                              0);
4999                                                         start_next_request(ep);
5000                                                 }
5001                                         } else {
5002                                                 DWC_PRINTF
5003                                                     ("complete_ep 0x%p, ep->queue empty!\n",
5004                                                      ep);
5005                                         }
5006                                 }
5007                         }
5008                         /* AHB Error */
5009                         if (doepint.b.ahberr) {
5010                                 DWC_ERROR("EP%d OUT AHB Error\n", epnum);
5011                                 DWC_ERROR("EP%d DEPDMA=0x%08x \n",
5012                                           epnum,
5013                                           core_if->dev_if->
5014                                           out_ep_regs[epnum]->doepdma);
5015                                 CLEAR_OUT_EP_INTR(core_if, epnum, ahberr);
5016                         }
5017                         /* Setup Phase Done (contorl EPs) */
5018                         if (doepint.b.setup) {
5019 #ifdef DEBUG_EP0
5020                                 DWC_DEBUGPL(DBG_PCD, "EP%d SETUP Done\n",
5021                                             epnum);
5022 #endif
5023                                 CLEAR_OUT_EP_INTR(core_if, epnum, setup);
5024
5025                                 handle_ep0(pcd);
5026                         }
5027
5028                         /** OUT EP BNA Intr */
5029                         if (doepint.b.bna) {
5030                                 CLEAR_OUT_EP_INTR(core_if, epnum, bna);
5031                                 if (core_if->dma_desc_enable) {
5032 #ifdef DWC_EN_ISOC
5033                                         if (dwc_ep->type ==
5034                                             DWC_OTG_EP_TYPE_ISOC) {
5035                                                 /*
5036                                                  * This checking is performed to prevent first "false" BNA
5037                                                  * handling occuring right after reconnect
5038                                                  */
5039                                                 if (dwc_ep->next_frame !=
5040                                                     0xffffffff)
5041                                                         dwc_otg_pcd_handle_iso_bna
5042                                                             (ep);
5043                                         } else
5044 #endif /* DWC_EN_ISOC */
5045                                         {
5046                                                 dwc_otg_pcd_handle_noniso_bna
5047                                                     (ep);
5048                                         }
5049                                 }
5050                         }
5051                         /* Babble Interrupt */
5052                         if (doepint.b.babble) {
5053                                 DWC_DEBUGPL(DBG_ANY, "EP%d OUT Babble\n",
5054                                             epnum);
5055                                 handle_out_ep_babble_intr(pcd, epnum);
5056
5057                                 CLEAR_OUT_EP_INTR(core_if, epnum, babble);
5058                         }
5059                         if (doepint.b.outtknepdis) {
5060                                 DWC_DEBUGPL(DBG_ANY, "EP%d OUT Token received when EP is \
5061                                         disabled\n",
5062                                             epnum);
5063                                 if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) {
5064                                         doepmsk_data_t doepmsk = {
5065                                         .d32 = 0};
5066                                         ep->dwc_ep.frame_num =
5067                                             core_if->frame_num;
5068                                         if (ep->dwc_ep.bInterval > 1) {
5069                                                 depctl_data_t depctl;
5070                                                 depctl.d32 =
5071                                                     DWC_READ_REG32
5072                                                     (&core_if->dev_if->
5073                                                      out_ep_regs
5074                                                      [epnum]->doepctl);
5075                                                 if (ep->dwc_ep.frame_num & 0x1) {
5076                                                         depctl.b.setd1pid = 1;
5077                                                         depctl.b.setd0pid = 0;
5078                                                 } else {
5079                                                         depctl.b.setd0pid = 1;
5080                                                         depctl.b.setd1pid = 0;
5081                                                 }
5082                                                 DWC_WRITE_REG32
5083                                                     (&core_if->dev_if->
5084                                                      out_ep_regs
5085                                                      [epnum]->doepctl,
5086                                                      depctl.d32);
5087                                         }
5088                                         start_next_request(ep);
5089                                         doepmsk.b.outtknepdis = 1;
5090                                         DWC_MODIFY_REG32(&core_if->
5091                                                          dev_if->dev_global_regs->doepmsk,
5092                                                          doepmsk.d32, 0);
5093                                 }
5094                                 CLEAR_OUT_EP_INTR(core_if, epnum, outtknepdis);
5095                         }
5096
5097                         /* NAK Interrutp */
5098                         if (doepint.b.nak) {
5099                                 DWC_DEBUGPL(DBG_ANY, "EP%d OUT NAK\n", epnum);
5100                                 handle_out_ep_nak_intr(pcd, epnum);
5101
5102                                 CLEAR_OUT_EP_INTR(core_if, epnum, nak);
5103                         }
5104                         /* NYET Interrutp */
5105                         if (doepint.b.nyet) {
5106                                 DWC_DEBUGPL(DBG_ANY, "EP%d OUT NYET\n", epnum);
5107                                 handle_out_ep_nyet_intr(pcd, epnum);
5108
5109                                 CLEAR_OUT_EP_INTR(core_if, epnum, nyet);
5110                         }
5111                 }
5112
5113                 epnum++;
5114                 ep_intr >>= 1;
5115         }
5116
5117         return 1;
5118
5119 #undef CLEAR_OUT_EP_INTR
5120 }
5121
5122 static int drop_transfer(uint32_t trgt_fr, uint32_t curr_fr,
5123                          uint8_t frm_overrun)
5124 {
5125         int retval = 0;
5126         if (!frm_overrun && curr_fr >= trgt_fr)
5127                 retval = 1;
5128         else if (frm_overrun
5129                  && (curr_fr >= trgt_fr && ((curr_fr - trgt_fr) < 0x3FFF / 2)))
5130                 retval = 1;
5131         return retval;
5132 }
5133
5134 /**
5135  * Incomplete ISO IN Transfer Interrupt.
5136  * This interrupt indicates one of the following conditions occurred
5137  * while transmitting an ISOC transaction.
5138  * - Corrupted IN Token for ISOC EP.
5139  * - Packet not complete in FIFO.
5140  * The follow actions will be taken:
5141  *      -#      Determine the EP
5142  *      -#      Set incomplete flag in dwc_ep structure
5143  *      -#      Disable EP; when "Endpoint Disabled" interrupt is received
5144  *              Flush FIFO
5145  */
5146 int32_t dwc_otg_pcd_handle_incomplete_isoc_in_intr(dwc_otg_pcd_t *pcd)
5147 {
5148         gintsts_data_t gintsts;
5149
5150 #ifdef DWC_EN_ISOC
5151         dwc_otg_dev_if_t *dev_if;
5152         deptsiz_data_t deptsiz = {
5153         .d32 = 0};
5154         depctl_data_t depctl = {
5155         .d32 = 0};
5156         dsts_data_t dsts = {
5157         .d32 = 0};
5158         dwc_ep_t *dwc_ep;
5159         int i;
5160
5161         dev_if = GET_CORE_IF(pcd)->dev_if;
5162
5163         for (i = 1; i <= dev_if->num_in_eps; ++i) {
5164                 dwc_ep = &pcd->in_ep[i].dwc_ep;
5165                 if (dwc_ep->active && dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
5166                         deptsiz.d32 =
5167                             DWC_READ_REG32(&dev_if->in_ep_regs[i]->dieptsiz);
5168                         depctl.d32 =
5169                             DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl);
5170
5171                         if (depctl.b.epdis && deptsiz.d32) {
5172                                 set_current_pkt_info(GET_CORE_IF(pcd), dwc_ep);
5173                                 if (dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
5174                                         dwc_ep->cur_pkt = 0;
5175                                         dwc_ep->proc_buf_num =
5176                                             (dwc_ep->proc_buf_num ^ 1) & 0x1;
5177
5178                                         if (dwc_ep->proc_buf_num) {
5179                                                 dwc_ep->cur_pkt_addr =
5180                                                     dwc_ep->xfer_buff1;
5181                                                 dwc_ep->cur_pkt_dma_addr =
5182                                                     dwc_ep->dma_addr1;
5183                                         } else {
5184                                                 dwc_ep->cur_pkt_addr =
5185                                                     dwc_ep->xfer_buff0;
5186                                                 dwc_ep->cur_pkt_dma_addr =
5187                                                     dwc_ep->dma_addr0;
5188                                         }
5189
5190                                 }
5191
5192                                 dsts.d32 =
5193                                     DWC_READ_REG32(&GET_CORE_IF(pcd)->dev_if->
5194                                                    dev_global_regs->dsts);
5195                                 dwc_ep->next_frame = dsts.b.soffn;
5196
5197                                 dwc_otg_iso_ep_start_frm_transfer(GET_CORE_IF
5198                                                                   (pcd),
5199                                                                   dwc_ep);
5200                         }
5201                 }
5202         }
5203
5204 #else
5205         depctl_data_t depctl = {
5206         .d32 = 0};
5207         dwc_ep_t *dwc_ep;
5208         dwc_otg_dev_if_t *dev_if;
5209         int i;
5210         dev_if = GET_CORE_IF(pcd)->dev_if;
5211
5212         DWC_DEBUGPL(DBG_PCD, "Incomplete ISO IN \n");
5213
5214         for (i = 1; i <= dev_if->num_in_eps; ++i) {
5215                 dwc_ep = &pcd->in_ep[i - 1].dwc_ep;
5216                 depctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl);
5217                 if (depctl.b.epena && dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
5218                         if (drop_transfer
5219                             (dwc_ep->frame_num, GET_CORE_IF(pcd)->frame_num,
5220                              dwc_ep->frm_overrun)) {
5221                                 depctl.d32 =
5222                                     DWC_READ_REG32(&dev_if->
5223                                                    in_ep_regs[i]->diepctl);
5224                                 depctl.b.snak = 1;
5225                                 depctl.b.epdis = 1;
5226                                 DWC_MODIFY_REG32(&dev_if->
5227                                                  in_ep_regs[i]->diepctl,
5228                                                  depctl.d32, depctl.d32);
5229                         }
5230                 }
5231         }
5232
5233         /*intr_mask.b.incomplisoin = 1;
5234            DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
5235            intr_mask.d32, 0);    */
5236 #endif /* DWC_EN_ISOC */
5237
5238         /* Clear interrupt */
5239         gintsts.d32 = 0;
5240         gintsts.b.incomplisoin = 1;
5241         DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
5242                         gintsts.d32);
5243
5244         return 1;
5245 }
5246
5247 /**
5248  * Incomplete ISO OUT Transfer Interrupt.
5249  *
5250  * This interrupt indicates that the core has dropped an ISO OUT
5251  * packet. The following conditions can be the cause:
5252  * - FIFO Full, the entire packet would not fit in the FIFO.
5253  * - CRC Error
5254  * - Corrupted Token
5255  * The follow actions will be taken:
5256  *      -#      Determine the EP
5257  *      -#      Set incomplete flag in dwc_ep structure
5258  *      -#      Read any data from the FIFO
5259  *      -#      Disable EP. When "Endpoint Disabled" interrupt is received
5260  *              re-enable EP.
5261  */
5262 int32_t dwc_otg_pcd_handle_incomplete_isoc_out_intr(dwc_otg_pcd_t *pcd)
5263 {
5264
5265         gintsts_data_t gintsts;
5266
5267 #ifdef DWC_EN_ISOC
5268         dwc_otg_dev_if_t *dev_if;
5269         deptsiz_data_t deptsiz = {
5270         .d32 = 0};
5271         depctl_data_t depctl = {
5272         .d32 = 0};
5273         dsts_data_t dsts = {
5274         .d32 = 0};
5275         dwc_ep_t *dwc_ep;
5276         int i;
5277
5278         dev_if = GET_CORE_IF(pcd)->dev_if;
5279
5280         for (i = 1; i <= dev_if->num_out_eps; ++i) {
5281                 dwc_ep = &pcd->in_ep[i].dwc_ep;
5282                 if (pcd->out_ep[i].dwc_ep.active &&
5283                     pcd->out_ep[i].dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) {
5284                         deptsiz.d32 =
5285                             DWC_READ_REG32(&dev_if->out_ep_regs[i]->doeptsiz);
5286                         depctl.d32 =
5287                             DWC_READ_REG32(&dev_if->out_ep_regs[i]->doepctl);
5288
5289                         if (depctl.b.epdis && deptsiz.d32) {
5290                                 set_current_pkt_info(GET_CORE_IF(pcd),
5291                                                      &pcd->out_ep[i].dwc_ep);
5292                                 if (dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
5293                                         dwc_ep->cur_pkt = 0;
5294                                         dwc_ep->proc_buf_num =
5295                                             (dwc_ep->proc_buf_num ^ 1) & 0x1;
5296
5297                                         if (dwc_ep->proc_buf_num) {
5298                                                 dwc_ep->cur_pkt_addr =
5299                                                     dwc_ep->xfer_buff1;
5300                                                 dwc_ep->cur_pkt_dma_addr =
5301                                                     dwc_ep->dma_addr1;
5302                                         } else {
5303                                                 dwc_ep->cur_pkt_addr =
5304                                                     dwc_ep->xfer_buff0;
5305                                                 dwc_ep->cur_pkt_dma_addr =
5306                                                     dwc_ep->dma_addr0;
5307                                         }
5308
5309                                 }
5310
5311                                 dsts.d32 =
5312                                     DWC_READ_REG32(&GET_CORE_IF(pcd)->dev_if->
5313                                                    dev_global_regs->dsts);
5314                                 dwc_ep->next_frame = dsts.b.soffn;
5315
5316                                 dwc_otg_iso_ep_start_frm_transfer(GET_CORE_IF
5317                                                                   (pcd),
5318                                                                   dwc_ep);
5319                         }
5320                 }
5321         }
5322 #else
5323         /** @todo implement ISR */
5324         gintmsk_data_t intr_mask = {
5325         .d32 = 0};
5326         dwc_otg_core_if_t *core_if;
5327         deptsiz_data_t deptsiz = {
5328         .d32 = 0};
5329         depctl_data_t depctl = {
5330         .d32 = 0};
5331         dctl_data_t dctl = {
5332         .d32 = 0};
5333         dwc_ep_t *dwc_ep = NULL;
5334         int i;
5335         core_if = GET_CORE_IF(pcd);
5336
5337         for (i = 0; i < core_if->dev_if->num_out_eps; ++i) {
5338                 dwc_ep = &pcd->out_ep[i].dwc_ep;
5339                 depctl.d32 =
5340                     DWC_READ_REG32(&core_if->dev_if->
5341                                    out_ep_regs[dwc_ep->num]->doepctl);
5342                 if (depctl.b.epena
5343                     && depctl.b.dpid == (core_if->frame_num & 0x1)) {
5344                         core_if->dev_if->isoc_ep = dwc_ep;
5345                         deptsiz.d32 =
5346                             DWC_READ_REG32(&core_if->
5347                                            dev_if->out_ep_regs[dwc_ep->num]->
5348                                            doeptsiz);
5349                         break;
5350                 }
5351         }
5352         dctl.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl);
5353         gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
5354         intr_mask.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintmsk);
5355
5356         if (!intr_mask.b.goutnakeff) {
5357                 /* Unmask it */
5358                 intr_mask.b.goutnakeff = 1;
5359                 DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk,
5360                                 intr_mask.d32);
5361         }
5362         if (!gintsts.b.goutnakeff) {
5363                 dctl.b.sgoutnak = 1;
5364         }
5365         DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32);
5366
5367         depctl.d32 =
5368             DWC_READ_REG32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doepctl);
5369         if (depctl.b.epena) {
5370                 depctl.b.epdis = 1;
5371                 depctl.b.snak = 1;
5372         }
5373         DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doepctl,
5374                         depctl.d32);
5375
5376         intr_mask.d32 = 0;
5377         intr_mask.b.incomplisoout = 1;
5378
5379 #endif /* DWC_EN_ISOC */
5380
5381         /* Clear interrupt */
5382         gintsts.d32 = 0;
5383         gintsts.b.incomplisoout = 1;
5384         DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
5385                         gintsts.d32);
5386
5387         return 1;
5388 }
5389
5390 /**
5391  * This function handles the Global IN NAK Effective interrupt.
5392  *
5393  */
5394 int32_t dwc_otg_pcd_handle_in_nak_effective(dwc_otg_pcd_t *pcd)
5395 {
5396         dwc_otg_dev_if_t *dev_if = GET_CORE_IF(pcd)->dev_if;
5397         depctl_data_t diepctl = {
5398         .d32 = 0};
5399         gintmsk_data_t intr_mask = {
5400         .d32 = 0};
5401         gintsts_data_t gintsts;
5402         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
5403         int i;
5404
5405         DWC_DEBUGPL(DBG_PCD, "Global IN NAK Effective\n");
5406
5407         /* Disable all active IN EPs */
5408         for (i = 0; i <= dev_if->num_in_eps; i++) {
5409                 diepctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl);
5410                 if (!(diepctl.b.eptype & 1) && diepctl.b.epena) {
5411                         if (core_if->start_predict > 0)
5412                                 core_if->start_predict++;
5413                         diepctl.b.epdis = 1;
5414                         diepctl.b.snak = 1;
5415                         DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepctl,
5416                                         diepctl.d32);
5417                 }
5418         }
5419
5420         /* Disable the Global IN NAK Effective Interrupt */
5421         intr_mask.b.ginnakeff = 1;
5422         DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
5423                          intr_mask.d32, 0);
5424
5425         /* Clear interrupt */
5426         gintsts.d32 = 0;
5427         gintsts.b.ginnakeff = 1;
5428         DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
5429                         gintsts.d32);
5430
5431         return 1;
5432 }
5433
5434 /**
5435  * OUT NAK Effective.
5436  *
5437  */
5438 int32_t dwc_otg_pcd_handle_out_nak_effective(dwc_otg_pcd_t *pcd)
5439 {
5440         dwc_otg_dev_if_t *dev_if = GET_CORE_IF(pcd)->dev_if;
5441         gintmsk_data_t intr_mask = {
5442         .d32 = 0};
5443         gintsts_data_t gintsts;
5444         depctl_data_t doepctl;
5445         int i;
5446
5447         /* Disable the Global OUT NAK Effective Interrupt */
5448         intr_mask.b.goutnakeff = 1;
5449         DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
5450                          intr_mask.d32, 0);
5451
5452         /* If DEV OUT NAK enabled */
5453         if (pcd->core_if->core_params->dev_out_nak) {
5454                 /* Run over all out endpoints to determine the ep number on
5455                  * which the timeout has happened
5456                  */
5457                 for (i = 0; i <= dev_if->num_out_eps; i++) {
5458                         if (pcd->core_if->ep_xfer_info[i].state == 2)
5459                                 break;
5460                 }
5461                 if (i > dev_if->num_out_eps) {
5462                         dctl_data_t dctl;
5463                         dctl.d32 =
5464                             DWC_READ_REG32(&dev_if->dev_global_regs->dctl);
5465                         dctl.b.cgoutnak = 1;
5466                         DWC_WRITE_REG32(&dev_if->dev_global_regs->dctl,
5467                                         dctl.d32);
5468                         goto out;
5469                 }
5470
5471                 /* Disable the endpoint */
5472                 doepctl.d32 = DWC_READ_REG32(&dev_if->out_ep_regs[i]->doepctl);
5473                 if (doepctl.b.epena) {
5474                         doepctl.b.epdis = 1;
5475                         doepctl.b.snak = 1;
5476                 }
5477                 DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepctl, doepctl.d32);
5478                 return 1;
5479         }
5480         /* We come here from Incomplete ISO OUT handler */
5481         if (dev_if->isoc_ep) {
5482                 dwc_ep_t *dwc_ep = (dwc_ep_t *) dev_if->isoc_ep;
5483                 uint32_t epnum = dwc_ep->num;
5484                 doepint_data_t doepint;
5485                 doepint.d32 =
5486                     DWC_READ_REG32(&dev_if->out_ep_regs[dwc_ep->num]->doepint);
5487                 dev_if->isoc_ep = NULL;
5488                 doepctl.d32 =
5489                     DWC_READ_REG32(&dev_if->out_ep_regs[epnum]->doepctl);
5490                 DWC_PRINTF("Before disable DOEPCTL = %08x\n", doepctl.d32);
5491                 if (doepctl.b.epena) {
5492                         doepctl.b.epdis = 1;
5493                         doepctl.b.snak = 1;
5494                 }
5495                 DWC_WRITE_REG32(&dev_if->out_ep_regs[epnum]->doepctl,
5496                                 doepctl.d32);
5497                 return 1;
5498         } else
5499                 DWC_PRINTF("INTERRUPT Handler not implemented for %s\n",
5500                            "Global OUT NAK Effective\n");
5501
5502 out:
5503         /* Clear interrupt */
5504         gintsts.d32 = 0;
5505         gintsts.b.goutnakeff = 1;
5506         DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
5507                         gintsts.d32);
5508
5509         return 1;
5510 }
5511
5512 /**
5513  * PCD interrupt handler.
5514  *
5515  * The PCD handles the device interrupts.  Many conditions can cause a
5516  * device interrupt. When an interrupt occurs, the device interrupt
5517  * service routine determines the cause of the interrupt and
5518  * dispatches handling to the appropriate function. These interrupt
5519  * handling functions are described below.
5520  *
5521  * All interrupt registers are processed from LSB to MSB.
5522  *
5523  */
5524 int32_t dwc_otg_pcd_handle_intr(dwc_otg_pcd_t *pcd)
5525 {
5526         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
5527 #ifdef VERBOSE
5528         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
5529 #endif
5530         gintsts_data_t gintr_status;
5531         int32_t retval = 0;
5532
5533         if (dwc_otg_check_haps_status(core_if) == -1) {
5534                 DWC_WARN("HAPS is disconnected");
5535                 return retval;
5536         }
5537
5538         /* Exit from ISR if core is hibernated */
5539         if (core_if->hibernation_suspend == 1) {
5540                 return retval;
5541         }
5542 #ifdef VERBOSE
5543         DWC_DEBUGPL(DBG_ANY, "%s() gintsts=%08x  gintmsk=%08x\n",
5544                     __func__,
5545                     DWC_READ_REG32(&global_regs->gintsts),
5546                     DWC_READ_REG32(&global_regs->gintmsk));
5547 #endif
5548
5549         if (dwc_otg_is_device_mode(core_if)) {
5550                 DWC_SPINLOCK(pcd->lock);
5551 #ifdef VERBOSE
5552                 DWC_DEBUGPL(DBG_PCDV, "%s() gintsts=%08x  gintmsk=%08x\n",
5553                             __func__,
5554                             DWC_READ_REG32(&global_regs->gintsts),
5555                             DWC_READ_REG32(&global_regs->gintmsk));
5556 #endif
5557
5558                 gintr_status.d32 = dwc_otg_read_core_intr(core_if);
5559
5560                 DWC_DEBUGPL(DBG_PCDV, "%s: gintsts&gintmsk=%08x\n",
5561                             __func__, gintr_status.d32);
5562
5563                 if (gintr_status.b.sofintr) {
5564                         retval |= dwc_otg_pcd_handle_sof_intr(pcd);
5565                 }
5566                 if (gintr_status.b.rxstsqlvl) {
5567                         retval |=
5568                             dwc_otg_pcd_handle_rx_status_q_level_intr(pcd);
5569                 }
5570                 if (gintr_status.b.nptxfempty) {
5571                         retval |= dwc_otg_pcd_handle_np_tx_fifo_empty_intr(pcd);
5572                 }
5573                 if (gintr_status.b.goutnakeff) {
5574                         retval |= dwc_otg_pcd_handle_out_nak_effective(pcd);
5575                 }
5576                 if (gintr_status.b.i2cintr) {
5577                         retval |= dwc_otg_pcd_handle_i2c_intr(pcd);
5578                 }
5579                 if (gintr_status.b.erlysuspend) {
5580                         retval |= dwc_otg_pcd_handle_early_suspend_intr(pcd);
5581                 }
5582                 if (gintr_status.b.usbreset) {
5583                         retval |= dwc_otg_pcd_handle_usb_reset_intr(pcd);
5584                         pcd->conn_status = -1;
5585                 }
5586                 if (gintr_status.b.enumdone) {
5587                         retval |= dwc_otg_pcd_handle_enum_done_intr(pcd);
5588                 }
5589                 if (gintr_status.b.isooutdrop) {
5590                         retval |=
5591                             dwc_otg_pcd_handle_isoc_out_packet_dropped_intr
5592                             (pcd);
5593                 }
5594                 if (gintr_status.b.eopframe) {
5595                         retval |=
5596                             dwc_otg_pcd_handle_end_periodic_frame_intr(pcd);
5597                 }
5598                 if (gintr_status.b.inepint) {
5599                         if (!core_if->multiproc_int_enable) {
5600                                 retval |= dwc_otg_pcd_handle_in_ep_intr(pcd);
5601                         }
5602                 }
5603                 if (gintr_status.b.outepintr) {
5604                         if (!core_if->multiproc_int_enable) {
5605                                 retval |= dwc_otg_pcd_handle_out_ep_intr(pcd);
5606                         }
5607                 }
5608                 if (gintr_status.b.epmismatch) {
5609                         retval |= dwc_otg_pcd_handle_ep_mismatch_intr(pcd);
5610                 }
5611                 if (gintr_status.b.fetsusp) {
5612                         retval |= dwc_otg_pcd_handle_ep_fetsusp_intr(pcd);
5613                 }
5614                 if (gintr_status.b.ginnakeff) {
5615                         retval |= dwc_otg_pcd_handle_in_nak_effective(pcd);
5616                 }
5617                 if (gintr_status.b.incomplisoin) {
5618                         retval |=
5619                             dwc_otg_pcd_handle_incomplete_isoc_in_intr(pcd);
5620                 }
5621                 if (gintr_status.b.incomplisoout) {
5622                         retval |=
5623                             dwc_otg_pcd_handle_incomplete_isoc_out_intr(pcd);
5624                 }
5625
5626                 /* In MPI mode Device Endpoints interrupts are asserted
5627                  * without setting outepintr and inepint bits set, so these
5628                  * Interrupt handlers are called without checking these bit-fields
5629                  */
5630                 if (core_if->multiproc_int_enable) {
5631                         retval |= dwc_otg_pcd_handle_in_ep_intr(pcd);
5632                         retval |= dwc_otg_pcd_handle_out_ep_intr(pcd);
5633                 }
5634 #ifdef VERBOSE
5635                 DWC_DEBUGPL(DBG_PCDV, "%s() gintsts=%0x\n", __func__,
5636                             DWC_READ_REG32(&global_regs->gintsts));
5637 #endif
5638                 DWC_SPINUNLOCK(pcd->lock);
5639         }
5640         return retval;
5641 }
5642
5643 #endif /* DWC_HOST_ONLY */