[ramips] add feature gpio
[openwrt/svn-archive/archive.git] / target / linux / ramips / files / drivers / usb / dwc_otg / dwc_otg_pcd_intr.c
1 /* ==========================================================================
2 * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_pcd_intr.c $
3 * $Revision: 1.2 $
4 * $Date: 2008-11-21 05:39:15 $
5 * $Change: 1115682 $
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 #include <linux/interrupt.h>
35 #include <linux/dma-mapping.h>
36 #include <linux/version.h>
37
38 #include "dwc_otg_driver.h"
39 #include "dwc_otg_pcd.h"
40
41
42 #define DEBUG_EP0
43
44 /* request functions defined in "dwc_otg_pcd.c" */
45
46 /** @file
47 * This file contains the implementation of the PCD Interrupt handlers.
48 *
49 * The PCD handles the device interrupts. Many conditions can cause a
50 * device interrupt. When an interrupt occurs, the device interrupt
51 * service routine determines the cause of the interrupt and
52 * dispatches handling to the appropriate function. These interrupt
53 * handling functions are described below.
54 * All interrupt registers are processed from LSB to MSB.
55 */
56
57
58 /**
59 * This function prints the ep0 state for debug purposes.
60 */
61 static inline void print_ep0_state(dwc_otg_pcd_t *pcd)
62 {
63 #ifdef DEBUG
64 char str[40];
65
66 switch (pcd->ep0state) {
67 case EP0_DISCONNECT:
68 strcpy(str, "EP0_DISCONNECT");
69 break;
70 case EP0_IDLE:
71 strcpy(str, "EP0_IDLE");
72 break;
73 case EP0_IN_DATA_PHASE:
74 strcpy(str, "EP0_IN_DATA_PHASE");
75 break;
76 case EP0_OUT_DATA_PHASE:
77 strcpy(str, "EP0_OUT_DATA_PHASE");
78 break;
79 case EP0_IN_STATUS_PHASE:
80 strcpy(str,"EP0_IN_STATUS_PHASE");
81 break;
82 case EP0_OUT_STATUS_PHASE:
83 strcpy(str,"EP0_OUT_STATUS_PHASE");
84 break;
85 case EP0_STALL:
86 strcpy(str,"EP0_STALL");
87 break;
88 default:
89 strcpy(str,"EP0_INVALID");
90 }
91
92 DWC_DEBUGPL(DBG_ANY, "%s(%d)\n", str, pcd->ep0state);
93 #endif
94 }
95
96 /**
97 * This function returns pointer to in ep struct with number ep_num
98 */
99 static inline dwc_otg_pcd_ep_t* get_in_ep(dwc_otg_pcd_t *pcd, uint32_t ep_num)
100 {
101 int i;
102 int num_in_eps = GET_CORE_IF(pcd)->dev_if->num_in_eps;
103 if(ep_num == 0) {
104 return &pcd->ep0;
105 }
106 else {
107 for(i = 0; i < num_in_eps; ++i)
108 {
109 if(pcd->in_ep[i].dwc_ep.num == ep_num)
110 return &pcd->in_ep[i];
111 }
112 return 0;
113 }
114 }
115 /**
116 * This function returns pointer to out ep struct with number ep_num
117 */
118 static inline dwc_otg_pcd_ep_t* get_out_ep(dwc_otg_pcd_t *pcd, uint32_t ep_num)
119 {
120 int i;
121 int num_out_eps = GET_CORE_IF(pcd)->dev_if->num_out_eps;
122 if(ep_num == 0) {
123 return &pcd->ep0;
124 }
125 else {
126 for(i = 0; i < num_out_eps; ++i)
127 {
128 if(pcd->out_ep[i].dwc_ep.num == ep_num)
129 return &pcd->out_ep[i];
130 }
131 return 0;
132 }
133 }
134 /**
135 * This functions gets a pointer to an EP from the wIndex address
136 * value of the control request.
137 */
138 static dwc_otg_pcd_ep_t *get_ep_by_addr (dwc_otg_pcd_t *pcd, u16 wIndex)
139 {
140 dwc_otg_pcd_ep_t *ep;
141
142 if ((wIndex & USB_ENDPOINT_NUMBER_MASK) == 0)
143 return &pcd->ep0;
144 list_for_each_entry(ep, &pcd->gadget.ep_list, ep.ep_list)
145 {
146 u8 bEndpointAddress;
147
148 if (!ep->desc)
149 continue;
150
151 bEndpointAddress = ep->desc->bEndpointAddress;
152 if((wIndex & (USB_DIR_IN | USB_ENDPOINT_NUMBER_MASK))
153 == (bEndpointAddress & (USB_DIR_IN | USB_ENDPOINT_NUMBER_MASK)))
154 return ep;
155 }
156 return NULL;
157 }
158
159 /**
160 * This function checks the EP request queue, if the queue is not
161 * empty the next request is started.
162 */
163 void start_next_request(dwc_otg_pcd_ep_t *ep)
164 {
165 dwc_otg_pcd_request_t *req = 0;
166 uint32_t max_transfer = GET_CORE_IF(ep->pcd)->core_params->max_transfer_size;
167
168 if (!list_empty(&ep->queue)) {
169 req = list_entry(ep->queue.next,
170 dwc_otg_pcd_request_t, queue);
171
172 /* Setup and start the Transfer */
173 ep->dwc_ep.dma_addr = req->req.dma;
174 ep->dwc_ep.start_xfer_buff = req->req.buf;
175 ep->dwc_ep.xfer_buff = req->req.buf;
176 ep->dwc_ep.sent_zlp = 0;
177 ep->dwc_ep.total_len = req->req.length;
178 ep->dwc_ep.xfer_len = 0;
179 ep->dwc_ep.xfer_count = 0;
180
181 if(max_transfer > MAX_TRANSFER_SIZE) {
182 ep->dwc_ep.maxxfer = max_transfer - (max_transfer % ep->dwc_ep.maxpacket);
183 } else {
184 ep->dwc_ep.maxxfer = max_transfer;
185 }
186
187 if(req->req.zero) {
188 if((ep->dwc_ep.total_len % ep->dwc_ep.maxpacket == 0)
189 && (ep->dwc_ep.total_len != 0)) {
190 ep->dwc_ep.sent_zlp = 1;
191 }
192
193 }
194
195 dwc_otg_ep_start_transfer(GET_CORE_IF(ep->pcd), &ep->dwc_ep);
196 }
197 }
198
199 /**
200 * This function handles the SOF Interrupts. At this time the SOF
201 * Interrupt is disabled.
202 */
203 int32_t dwc_otg_pcd_handle_sof_intr(dwc_otg_pcd_t *pcd)
204 {
205 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
206
207 gintsts_data_t gintsts;
208
209 DWC_DEBUGPL(DBG_PCD, "SOF\n");
210
211 /* Clear interrupt */
212 gintsts.d32 = 0;
213 gintsts.b.sofintr = 1;
214 dwc_write_reg32 (&core_if->core_global_regs->gintsts, gintsts.d32);
215
216 return 1;
217 }
218
219
220 /**
221 * This function handles the Rx Status Queue Level Interrupt, which
222 * indicates that there is a least one packet in the Rx FIFO. The
223 * packets are moved from the FIFO to memory, where they will be
224 * processed when the Endpoint Interrupt Register indicates Transfer
225 * Complete or SETUP Phase Done.
226 *
227 * Repeat the following until the Rx Status Queue is empty:
228 * -# Read the Receive Status Pop Register (GRXSTSP) to get Packet
229 * info
230 * -# If Receive FIFO is empty then skip to step Clear the interrupt
231 * and exit
232 * -# If SETUP Packet call dwc_otg_read_setup_packet to copy the
233 * SETUP data to the buffer
234 * -# If OUT Data Packet call dwc_otg_read_packet to copy the data
235 * to the destination buffer
236 */
237 int32_t dwc_otg_pcd_handle_rx_status_q_level_intr(dwc_otg_pcd_t *pcd)
238 {
239 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
240 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
241 gintmsk_data_t gintmask = {.d32=0};
242 device_grxsts_data_t status;
243 dwc_otg_pcd_ep_t *ep;
244 gintsts_data_t gintsts;
245 #ifdef DEBUG
246 static char *dpid_str[] ={ "D0", "D2", "D1", "MDATA" };
247 #endif
248
249 //DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, _pcd);
250 /* Disable the Rx Status Queue Level interrupt */
251 gintmask.b.rxstsqlvl= 1;
252 dwc_modify_reg32(&global_regs->gintmsk, gintmask.d32, 0);
253
254 /* Get the Status from the top of the FIFO */
255 status.d32 = dwc_read_reg32(&global_regs->grxstsp);
256
257 DWC_DEBUGPL(DBG_PCD, "EP:%d BCnt:%d DPID:%s "
258 "pktsts:%x Frame:%d(0x%0x)\n",
259 status.b.epnum, status.b.bcnt,
260 dpid_str[status.b.dpid],
261 status.b.pktsts, status.b.fn, status.b.fn);
262 /* Get pointer to EP structure */
263 ep = get_out_ep(pcd, status.b.epnum);
264
265 switch (status.b.pktsts) {
266 case DWC_DSTS_GOUT_NAK:
267 DWC_DEBUGPL(DBG_PCDV, "Global OUT NAK\n");
268 break;
269 case DWC_STS_DATA_UPDT:
270 DWC_DEBUGPL(DBG_PCDV, "OUT Data Packet\n");
271 if (status.b.bcnt && ep->dwc_ep.xfer_buff) {
272 /** @todo NGS Check for buffer overflow? */
273 dwc_otg_read_packet(core_if,
274 ep->dwc_ep.xfer_buff,
275 status.b.bcnt);
276 ep->dwc_ep.xfer_count += status.b.bcnt;
277 ep->dwc_ep.xfer_buff += status.b.bcnt;
278 }
279 break;
280 case DWC_STS_XFER_COMP:
281 DWC_DEBUGPL(DBG_PCDV, "OUT Complete\n");
282 break;
283 case DWC_DSTS_SETUP_COMP:
284 #ifdef DEBUG_EP0
285 DWC_DEBUGPL(DBG_PCDV, "Setup Complete\n");
286 #endif
287 break;
288 case DWC_DSTS_SETUP_UPDT:
289 dwc_otg_read_setup_packet(core_if, pcd->setup_pkt->d32);
290 #ifdef DEBUG_EP0
291 DWC_DEBUGPL(DBG_PCD,
292 "SETUP PKT: %02x.%02x v%04x i%04x l%04x\n",
293 pcd->setup_pkt->req.bRequestType,
294 pcd->setup_pkt->req.bRequest,
295 pcd->setup_pkt->req.wValue,
296 pcd->setup_pkt->req.wIndex,
297 pcd->setup_pkt->req.wLength);
298 #endif
299 ep->dwc_ep.xfer_count += status.b.bcnt;
300 break;
301 default:
302 DWC_DEBUGPL(DBG_PCDV, "Invalid Packet Status (0x%0x)\n",
303 status.b.pktsts);
304 break;
305 }
306
307 /* Enable the Rx Status Queue Level interrupt */
308 dwc_modify_reg32(&global_regs->gintmsk, 0, gintmask.d32);
309 /* Clear interrupt */
310 gintsts.d32 = 0;
311 gintsts.b.rxstsqlvl = 1;
312 dwc_write_reg32 (&global_regs->gintsts, gintsts.d32);
313
314 //DWC_DEBUGPL(DBG_PCDV, "EXIT: %s\n", __func__);
315 return 1;
316 }
317 /**
318 * This function examines the Device IN Token Learning Queue to
319 * determine the EP number of the last IN token received. This
320 * implementation is for the Mass Storage device where there are only
321 * 2 IN EPs (Control-IN and BULK-IN).
322 *
323 * The EP numbers for the first six IN Tokens are in DTKNQR1 and there
324 * are 8 EP Numbers in each of the other possible DTKNQ Registers.
325 *
326 * @param core_if Programming view of DWC_otg controller.
327 *
328 */
329 static inline int get_ep_of_last_in_token(dwc_otg_core_if_t *core_if)
330 {
331 dwc_otg_device_global_regs_t *dev_global_regs =
332 core_if->dev_if->dev_global_regs;
333 const uint32_t TOKEN_Q_DEPTH = core_if->hwcfg2.b.dev_token_q_depth;
334 /* Number of Token Queue Registers */
335 const int DTKNQ_REG_CNT = (TOKEN_Q_DEPTH + 7) / 8;
336 dtknq1_data_t dtknqr1;
337 uint32_t in_tkn_epnums[4];
338 int ndx = 0;
339 int i = 0;
340 volatile uint32_t *addr = &dev_global_regs->dtknqr1;
341 int epnum = 0;
342
343 //DWC_DEBUGPL(DBG_PCD,"dev_token_q_depth=%d\n",TOKEN_Q_DEPTH);
344
345
346 /* Read the DTKNQ Registers */
347 for (i = 0; i < DTKNQ_REG_CNT; i++)
348 {
349 in_tkn_epnums[ i ] = dwc_read_reg32(addr);
350 DWC_DEBUGPL(DBG_PCDV, "DTKNQR%d=0x%08x\n", i+1,
351 in_tkn_epnums[i]);
352 if (addr == &dev_global_regs->dvbusdis) {
353 addr = &dev_global_regs->dtknqr3_dthrctl;
354 }
355 else {
356 ++addr;
357 }
358
359 }
360
361 /* Copy the DTKNQR1 data to the bit field. */
362 dtknqr1.d32 = in_tkn_epnums[0];
363 /* Get the EP numbers */
364 in_tkn_epnums[0] = dtknqr1.b.epnums0_5;
365 ndx = dtknqr1.b.intknwptr - 1;
366
367 //DWC_DEBUGPL(DBG_PCDV,"ndx=%d\n",ndx);
368 if (ndx == -1) {
369 /** @todo Find a simpler way to calculate the max
370 * queue position.*/
371 int cnt = TOKEN_Q_DEPTH;
372 if (TOKEN_Q_DEPTH <= 6) {
373 cnt = TOKEN_Q_DEPTH - 1;
374 }
375 else if (TOKEN_Q_DEPTH <= 14) {
376 cnt = TOKEN_Q_DEPTH - 7;
377 }
378 else if (TOKEN_Q_DEPTH <= 22) {
379 cnt = TOKEN_Q_DEPTH - 15;
380 }
381 else {
382 cnt = TOKEN_Q_DEPTH - 23;
383 }
384 epnum = (in_tkn_epnums[ DTKNQ_REG_CNT - 1 ] >> (cnt * 4)) & 0xF;
385 }
386 else {
387 if (ndx <= 5) {
388 epnum = (in_tkn_epnums[0] >> (ndx * 4)) & 0xF;
389 }
390 else if (ndx <= 13) {
391 ndx -= 6;
392 epnum = (in_tkn_epnums[1] >> (ndx * 4)) & 0xF;
393 }
394 else if (ndx <= 21) {
395 ndx -= 14;
396 epnum = (in_tkn_epnums[2] >> (ndx * 4)) & 0xF;
397 }
398 else if (ndx <= 29) {
399 ndx -= 22;
400 epnum = (in_tkn_epnums[3] >> (ndx * 4)) & 0xF;
401 }
402 }
403 //DWC_DEBUGPL(DBG_PCD,"epnum=%d\n",epnum);
404 return epnum;
405 }
406
407 /**
408 * This interrupt occurs when the non-periodic Tx FIFO is half-empty.
409 * The active request is checked for the next packet to be loaded into
410 * the non-periodic Tx FIFO.
411 */
412 int32_t dwc_otg_pcd_handle_np_tx_fifo_empty_intr(dwc_otg_pcd_t *pcd)
413 {
414 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
415 dwc_otg_core_global_regs_t *global_regs =
416 core_if->core_global_regs;
417 dwc_otg_dev_in_ep_regs_t *ep_regs;
418 gnptxsts_data_t txstatus = {.d32 = 0};
419 gintsts_data_t gintsts;
420
421 int epnum = 0;
422 dwc_otg_pcd_ep_t *ep = 0;
423 uint32_t len = 0;
424 int dwords;
425
426 /* Get the epnum from the IN Token Learning Queue. */
427 epnum = get_ep_of_last_in_token(core_if);
428 ep = get_in_ep(pcd, epnum);
429
430 DWC_DEBUGPL(DBG_PCD, "NP TxFifo Empty: %s(%d) \n", ep->ep.name, epnum);
431 ep_regs = core_if->dev_if->in_ep_regs[epnum];
432
433 len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
434 if (len > ep->dwc_ep.maxpacket) {
435 len = ep->dwc_ep.maxpacket;
436 }
437 dwords = (len + 3)/4;
438
439
440 /* While there is space in the queue and space in the FIFO and
441 * More data to tranfer, Write packets to the Tx FIFO */
442 txstatus.d32 = dwc_read_reg32(&global_regs->gnptxsts);
443 DWC_DEBUGPL(DBG_PCDV, "b4 GNPTXSTS=0x%08x\n",txstatus.d32);
444
445 while (txstatus.b.nptxqspcavail > 0 &&
446 txstatus.b.nptxfspcavail > dwords &&
447 ep->dwc_ep.xfer_count < ep->dwc_ep.xfer_len) {
448 /* Write the FIFO */
449 dwc_otg_ep_write_packet(core_if, &ep->dwc_ep, 0);
450 len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
451
452 if (len > ep->dwc_ep.maxpacket) {
453 len = ep->dwc_ep.maxpacket;
454 }
455
456 dwords = (len + 3)/4;
457 txstatus.d32 = dwc_read_reg32(&global_regs->gnptxsts);
458 DWC_DEBUGPL(DBG_PCDV,"GNPTXSTS=0x%08x\n",txstatus.d32);
459 }
460
461 DWC_DEBUGPL(DBG_PCDV, "GNPTXSTS=0x%08x\n",
462 dwc_read_reg32(&global_regs->gnptxsts));
463
464 /* Clear interrupt */
465 gintsts.d32 = 0;
466 gintsts.b.nptxfempty = 1;
467 dwc_write_reg32 (&global_regs->gintsts, gintsts.d32);
468
469 return 1;
470 }
471
472 /**
473 * This function is called when dedicated Tx FIFO Empty interrupt occurs.
474 * The active request is checked for the next packet to be loaded into
475 * apropriate Tx FIFO.
476 */
477 static int32_t write_empty_tx_fifo(dwc_otg_pcd_t *pcd, uint32_t epnum)
478 {
479 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
480 dwc_otg_dev_if_t* dev_if = core_if->dev_if;
481 dwc_otg_dev_in_ep_regs_t *ep_regs;
482 dtxfsts_data_t txstatus = {.d32 = 0};
483 dwc_otg_pcd_ep_t *ep = 0;
484 uint32_t len = 0;
485 int dwords;
486
487 ep = get_in_ep(pcd, epnum);
488
489 DWC_DEBUGPL(DBG_PCD, "Dedicated TxFifo Empty: %s(%d) \n", ep->ep.name, epnum);
490
491 ep_regs = core_if->dev_if->in_ep_regs[epnum];
492
493 len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
494
495 if (len > ep->dwc_ep.maxpacket) {
496 len = ep->dwc_ep.maxpacket;
497 }
498
499 dwords = (len + 3)/4;
500
501 /* While there is space in the queue and space in the FIFO and
502 * More data to tranfer, Write packets to the Tx FIFO */
503 txstatus.d32 = dwc_read_reg32(&dev_if->in_ep_regs[epnum]->dtxfsts);
504 DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n",epnum,txstatus.d32);
505
506 while (txstatus.b.txfspcavail > dwords &&
507 ep->dwc_ep.xfer_count < ep->dwc_ep.xfer_len &&
508 ep->dwc_ep.xfer_len != 0) {
509 /* Write the FIFO */
510 dwc_otg_ep_write_packet(core_if, &ep->dwc_ep, 0);
511
512 len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
513 if (len > ep->dwc_ep.maxpacket) {
514 len = ep->dwc_ep.maxpacket;
515 }
516
517 dwords = (len + 3)/4;
518 txstatus.d32 = dwc_read_reg32(&dev_if->in_ep_regs[epnum]->dtxfsts);
519 DWC_DEBUGPL(DBG_PCDV,"dtxfsts[%d]=0x%08x\n", epnum, txstatus.d32);
520 }
521
522 DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n",epnum,dwc_read_reg32(&dev_if->in_ep_regs[epnum]->dtxfsts));
523
524 return 1;
525 }
526
527
528 /**
529 * This function is called when the Device is disconnected. It stops
530 * any active requests and informs the Gadget driver of the
531 * disconnect.
532 */
533 void dwc_otg_pcd_stop(dwc_otg_pcd_t *pcd)
534 {
535 int i, num_in_eps, num_out_eps;
536 dwc_otg_pcd_ep_t *ep;
537
538 gintmsk_data_t intr_mask = {.d32 = 0};
539
540 num_in_eps = GET_CORE_IF(pcd)->dev_if->num_in_eps;
541 num_out_eps = GET_CORE_IF(pcd)->dev_if->num_out_eps;
542
543 DWC_DEBUGPL(DBG_PCDV, "%s() \n", __func__);
544 /* don't disconnect drivers more than once */
545 if (pcd->ep0state == EP0_DISCONNECT) {
546 DWC_DEBUGPL(DBG_ANY, "%s() Already Disconnected\n", __func__);
547 return;
548 }
549 pcd->ep0state = EP0_DISCONNECT;
550
551 /* Reset the OTG state. */
552 dwc_otg_pcd_update_otg(pcd, 1);
553
554 /* Disable the NP Tx Fifo Empty Interrupt. */
555 intr_mask.b.nptxfempty = 1;
556 dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
557 intr_mask.d32, 0);
558
559 /* Flush the FIFOs */
560 /**@todo NGS Flush Periodic FIFOs */
561 dwc_otg_flush_tx_fifo(GET_CORE_IF(pcd), 0x10);
562 dwc_otg_flush_rx_fifo(GET_CORE_IF(pcd));
563
564 /* prevent new request submissions, kill any outstanding requests */
565 ep = &pcd->ep0;
566 dwc_otg_request_nuke(ep);
567 /* prevent new request submissions, kill any outstanding requests */
568 for (i = 0; i < num_in_eps; i++)
569 {
570 dwc_otg_pcd_ep_t *ep = &pcd->in_ep[i];
571 dwc_otg_request_nuke(ep);
572 }
573 /* prevent new request submissions, kill any outstanding requests */
574 for (i = 0; i < num_out_eps; i++)
575 {
576 dwc_otg_pcd_ep_t *ep = &pcd->out_ep[i];
577 dwc_otg_request_nuke(ep);
578 }
579
580 /* report disconnect; the driver is already quiesced */
581 if (pcd->driver && pcd->driver->disconnect) {
582 SPIN_UNLOCK(&pcd->lock);
583 pcd->driver->disconnect(&pcd->gadget);
584 SPIN_LOCK(&pcd->lock);
585 }
586 }
587
588 /**
589 * This interrupt indicates that ...
590 */
591 int32_t dwc_otg_pcd_handle_i2c_intr(dwc_otg_pcd_t *pcd)
592 {
593 gintmsk_data_t intr_mask = { .d32 = 0};
594 gintsts_data_t gintsts;
595
596 DWC_PRINT("INTERRUPT Handler not implemented for %s\n", "i2cintr");
597 intr_mask.b.i2cintr = 1;
598 dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
599 intr_mask.d32, 0);
600
601 /* Clear interrupt */
602 gintsts.d32 = 0;
603 gintsts.b.i2cintr = 1;
604 dwc_write_reg32 (&GET_CORE_IF(pcd)->core_global_regs->gintsts,
605 gintsts.d32);
606 return 1;
607 }
608
609
610 /**
611 * This interrupt indicates that ...
612 */
613 int32_t dwc_otg_pcd_handle_early_suspend_intr(dwc_otg_pcd_t *pcd)
614 {
615 gintsts_data_t gintsts;
616 #if defined(VERBOSE)
617 DWC_PRINT("Early Suspend Detected\n");
618 #endif
619 /* Clear interrupt */
620 gintsts.d32 = 0;
621 gintsts.b.erlysuspend = 1;
622 dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
623 gintsts.d32);
624 return 1;
625 }
626
627 /**
628 * This function configures EPO to receive SETUP packets.
629 *
630 * @todo NGS: Update the comments from the HW FS.
631 *
632 * -# Program the following fields in the endpoint specific registers
633 * for Control OUT EP 0, in order to receive a setup packet
634 * - DOEPTSIZ0.Packet Count = 3 (To receive up to 3 back to back
635 * setup packets)
636 * - DOEPTSIZE0.Transfer Size = 24 Bytes (To receive up to 3 back
637 * to back setup packets)
638 * - In DMA mode, DOEPDMA0 Register with a memory address to
639 * store any setup packets received
640 *
641 * @param core_if Programming view of DWC_otg controller.
642 * @param pcd Programming view of the PCD.
643 */
644 static inline void ep0_out_start(dwc_otg_core_if_t *core_if, dwc_otg_pcd_t *pcd)
645 {
646 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
647 deptsiz0_data_t doeptsize0 = { .d32 = 0};
648 dwc_otg_dma_desc_t* dma_desc;
649 depctl_data_t doepctl = { .d32 = 0 };
650
651 #ifdef VERBOSE
652 DWC_DEBUGPL(DBG_PCDV,"%s() doepctl0=%0x\n", __func__,
653 dwc_read_reg32(&dev_if->out_ep_regs[0]->doepctl));
654 #endif
655
656 doeptsize0.b.supcnt = 3;
657 doeptsize0.b.pktcnt = 1;
658 doeptsize0.b.xfersize = 8*3;
659
660
661 if (core_if->dma_enable) {
662 if (!core_if->dma_desc_enable) {
663 /** put here as for Hermes mode deptisz register should not be written */
664 dwc_write_reg32(&dev_if->out_ep_regs[0]->doeptsiz,
665 doeptsize0.d32);
666
667 /** @todo dma needs to handle multiple setup packets (up to 3) */
668 dwc_write_reg32(&dev_if->out_ep_regs[0]->doepdma,
669 pcd->setup_pkt_dma_handle);
670 } else {
671 dev_if->setup_desc_index = (dev_if->setup_desc_index + 1) & 1;
672 dma_desc = dev_if->setup_desc_addr[dev_if->setup_desc_index];
673
674 /** DMA Descriptor Setup */
675 dma_desc->status.b.bs = BS_HOST_BUSY;
676 dma_desc->status.b.l = 1;
677 dma_desc->status.b.ioc = 1;
678 dma_desc->status.b.bytes = pcd->ep0.dwc_ep.maxpacket;
679 dma_desc->buf = pcd->setup_pkt_dma_handle;
680 dma_desc->status.b.bs = BS_HOST_READY;
681
682 /** DOEPDMA0 Register write */
683 dwc_write_reg32(&dev_if->out_ep_regs[0]->doepdma, dev_if->dma_setup_desc_addr[dev_if->setup_desc_index]);
684 }
685
686 } else {
687 /** put here as for Hermes mode deptisz register should not be written */
688 dwc_write_reg32(&dev_if->out_ep_regs[0]->doeptsiz,
689 doeptsize0.d32);
690 }
691
692 /** DOEPCTL0 Register write */
693 doepctl.b.epena = 1;
694 doepctl.b.cnak = 1;
695 dwc_write_reg32(&dev_if->out_ep_regs[0]->doepctl, doepctl.d32);
696
697 #ifdef VERBOSE
698 DWC_DEBUGPL(DBG_PCDV,"doepctl0=%0x\n",
699 dwc_read_reg32(&dev_if->out_ep_regs[0]->doepctl));
700 DWC_DEBUGPL(DBG_PCDV,"diepctl0=%0x\n",
701 dwc_read_reg32(&dev_if->in_ep_regs[0]->diepctl));
702 #endif
703 }
704
705
706 /**
707 * This interrupt occurs when a USB Reset is detected. When the USB
708 * Reset Interrupt occurs the device state is set to DEFAULT and the
709 * EP0 state is set to IDLE.
710 * -# Set the NAK bit for all OUT endpoints (DOEPCTLn.SNAK = 1)
711 * -# Unmask the following interrupt bits
712 * - DAINTMSK.INEP0 = 1 (Control 0 IN endpoint)
713 * - DAINTMSK.OUTEP0 = 1 (Control 0 OUT endpoint)
714 * - DOEPMSK.SETUP = 1
715 * - DOEPMSK.XferCompl = 1
716 * - DIEPMSK.XferCompl = 1
717 * - DIEPMSK.TimeOut = 1
718 * -# Program the following fields in the endpoint specific registers
719 * for Control OUT EP 0, in order to receive a setup packet
720 * - DOEPTSIZ0.Packet Count = 3 (To receive up to 3 back to back
721 * setup packets)
722 * - DOEPTSIZE0.Transfer Size = 24 Bytes (To receive up to 3 back
723 * to back setup packets)
724 * - In DMA mode, DOEPDMA0 Register with a memory address to
725 * store any setup packets received
726 * At this point, all the required initialization, except for enabling
727 * the control 0 OUT endpoint is done, for receiving SETUP packets.
728 */
729 int32_t dwc_otg_pcd_handle_usb_reset_intr(dwc_otg_pcd_t * pcd)
730 {
731 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
732 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
733 depctl_data_t doepctl = { .d32 = 0};
734
735 daint_data_t daintmsk = { .d32 = 0};
736 doepmsk_data_t doepmsk = { .d32 = 0};
737 diepmsk_data_t diepmsk = { .d32 = 0};
738
739 dcfg_data_t dcfg = { .d32=0 };
740 grstctl_t resetctl = { .d32=0 };
741 dctl_data_t dctl = {.d32=0};
742 int i = 0;
743 gintsts_data_t gintsts;
744
745 DWC_PRINT("USB RESET\n");
746 #ifdef DWC_EN_ISOC
747 for(i = 1;i < 16; ++i)
748 {
749 dwc_otg_pcd_ep_t *ep;
750 dwc_ep_t *dwc_ep;
751 ep = get_in_ep(pcd,i);
752 if(ep != 0){
753 dwc_ep = &ep->dwc_ep;
754 dwc_ep->next_frame = 0xffffffff;
755 }
756 }
757 #endif /* DWC_EN_ISOC */
758
759 /* reset the HNP settings */
760 dwc_otg_pcd_update_otg(pcd, 1);
761
762 /* Clear the Remote Wakeup Signalling */
763 dctl.b.rmtwkupsig = 1;
764 dwc_modify_reg32(&core_if->dev_if->dev_global_regs->dctl,
765 dctl.d32, 0);
766
767 /* Set NAK for all OUT EPs */
768 doepctl.b.snak = 1;
769 for (i=0; i <= dev_if->num_out_eps; i++)
770 {
771 dwc_write_reg32(&dev_if->out_ep_regs[i]->doepctl,
772 doepctl.d32);
773 }
774
775 /* Flush the NP Tx FIFO */
776 dwc_otg_flush_tx_fifo(core_if, 0x10);
777 /* Flush the Learning Queue */
778 resetctl.b.intknqflsh = 1;
779 dwc_write_reg32(&core_if->core_global_regs->grstctl, resetctl.d32);
780
781 if(core_if->multiproc_int_enable) {
782 daintmsk.b.inep0 = 1;
783 daintmsk.b.outep0 = 1;
784 dwc_write_reg32(&dev_if->dev_global_regs->deachintmsk, daintmsk.d32);
785
786 doepmsk.b.setup = 1;
787 doepmsk.b.xfercompl = 1;
788 doepmsk.b.ahberr = 1;
789 doepmsk.b.epdisabled = 1;
790
791 if(core_if->dma_desc_enable) {
792 doepmsk.b.stsphsercvd = 1;
793 doepmsk.b.bna = 1;
794 }
795 /*
796 doepmsk.b.babble = 1;
797 doepmsk.b.nyet = 1;
798
799 if(core_if->dma_enable) {
800 doepmsk.b.nak = 1;
801 }
802 */
803 dwc_write_reg32(&dev_if->dev_global_regs->doepeachintmsk[0], doepmsk.d32);
804
805 diepmsk.b.xfercompl = 1;
806 diepmsk.b.timeout = 1;
807 diepmsk.b.epdisabled = 1;
808 diepmsk.b.ahberr = 1;
809 diepmsk.b.intknepmis = 1;
810
811 if(core_if->dma_desc_enable) {
812 diepmsk.b.bna = 1;
813 }
814 /*
815 if(core_if->dma_enable) {
816 diepmsk.b.nak = 1;
817 }
818 */
819 dwc_write_reg32(&dev_if->dev_global_regs->diepeachintmsk[0], diepmsk.d32);
820 } else{
821 daintmsk.b.inep0 = 1;
822 daintmsk.b.outep0 = 1;
823 dwc_write_reg32(&dev_if->dev_global_regs->daintmsk, daintmsk.d32);
824
825 doepmsk.b.setup = 1;
826 doepmsk.b.xfercompl = 1;
827 doepmsk.b.ahberr = 1;
828 doepmsk.b.epdisabled = 1;
829
830 if(core_if->dma_desc_enable) {
831 doepmsk.b.stsphsercvd = 1;
832 doepmsk.b.bna = 1;
833 }
834 /*
835 doepmsk.b.babble = 1;
836 doepmsk.b.nyet = 1;
837 doepmsk.b.nak = 1;
838 */
839 dwc_write_reg32(&dev_if->dev_global_regs->doepmsk, doepmsk.d32);
840
841 diepmsk.b.xfercompl = 1;
842 diepmsk.b.timeout = 1;
843 diepmsk.b.epdisabled = 1;
844 diepmsk.b.ahberr = 1;
845 diepmsk.b.intknepmis = 1;
846
847 if(core_if->dma_desc_enable) {
848 diepmsk.b.bna = 1;
849 }
850
851 // diepmsk.b.nak = 1;
852
853 dwc_write_reg32(&dev_if->dev_global_regs->diepmsk, diepmsk.d32);
854 }
855
856 /* Reset Device Address */
857 dcfg.d32 = dwc_read_reg32(&dev_if->dev_global_regs->dcfg);
858 dcfg.b.devaddr = 0;
859 dwc_write_reg32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
860
861 /* setup EP0 to receive SETUP packets */
862 ep0_out_start(core_if, pcd);
863
864 /* Clear interrupt */
865 gintsts.d32 = 0;
866 gintsts.b.usbreset = 1;
867 dwc_write_reg32 (&core_if->core_global_regs->gintsts, gintsts.d32);
868
869 return 1;
870 }
871
872 /**
873 * Get the device speed from the device status register and convert it
874 * to USB speed constant.
875 *
876 * @param core_if Programming view of DWC_otg controller.
877 */
878 static int get_device_speed(dwc_otg_core_if_t *core_if)
879 {
880 dsts_data_t dsts;
881 enum usb_device_speed speed = USB_SPEED_UNKNOWN;
882 dsts.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts);
883
884 switch (dsts.b.enumspd) {
885 case DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
886 speed = USB_SPEED_HIGH;
887 break;
888 case DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
889 case DWC_DSTS_ENUMSPD_FS_PHY_48MHZ:
890 speed = USB_SPEED_FULL;
891 break;
892
893 case DWC_DSTS_ENUMSPD_LS_PHY_6MHZ:
894 speed = USB_SPEED_LOW;
895 break;
896 }
897
898 return speed;
899 }
900
901 /**
902 * Read the device status register and set the device speed in the
903 * data structure.
904 * Set up EP0 to receive SETUP packets by calling dwc_ep0_activate.
905 */
906 int32_t dwc_otg_pcd_handle_enum_done_intr(dwc_otg_pcd_t *pcd)
907 {
908 dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
909 gintsts_data_t gintsts;
910 gusbcfg_data_t gusbcfg;
911 dwc_otg_core_global_regs_t *global_regs =
912 GET_CORE_IF(pcd)->core_global_regs;
913 uint8_t utmi16b, utmi8b;
914 DWC_DEBUGPL(DBG_PCD, "SPEED ENUM\n");
915
916 if (GET_CORE_IF(pcd)->snpsid >= 0x4F54260A) {
917 utmi16b = 6;
918 utmi8b = 9;
919 } else {
920 utmi16b = 4;
921 utmi8b = 8;
922 }
923 dwc_otg_ep0_activate(GET_CORE_IF(pcd), &ep0->dwc_ep);
924
925 #ifdef DEBUG_EP0
926 print_ep0_state(pcd);
927 #endif
928
929 if (pcd->ep0state == EP0_DISCONNECT) {
930 pcd->ep0state = EP0_IDLE;
931 }
932 else if (pcd->ep0state == EP0_STALL) {
933 pcd->ep0state = EP0_IDLE;
934 }
935
936 pcd->ep0state = EP0_IDLE;
937
938 ep0->stopped = 0;
939
940 pcd->gadget.speed = get_device_speed(GET_CORE_IF(pcd));
941
942 /* Set USB turnaround time based on device speed and PHY interface. */
943 gusbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
944 if (pcd->gadget.speed == USB_SPEED_HIGH) {
945 if (GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type == DWC_HWCFG2_HS_PHY_TYPE_ULPI) {
946 /* ULPI interface */
947 gusbcfg.b.usbtrdtim = 9;
948 }
949 if (GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type == DWC_HWCFG2_HS_PHY_TYPE_UTMI) {
950 /* UTMI+ interface */
951 if (GET_CORE_IF(pcd)->hwcfg4.b.utmi_phy_data_width == 0) {
952 gusbcfg.b.usbtrdtim = utmi8b;
953 }
954 else if (GET_CORE_IF(pcd)->hwcfg4.b.utmi_phy_data_width == 1) {
955 gusbcfg.b.usbtrdtim = utmi16b;
956 }
957 else if (GET_CORE_IF(pcd)->core_params->phy_utmi_width == 8) {
958 gusbcfg.b.usbtrdtim = utmi8b;
959 }
960 else {
961 gusbcfg.b.usbtrdtim = utmi16b;
962 }
963 }
964 if (GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type == DWC_HWCFG2_HS_PHY_TYPE_UTMI_ULPI) {
965 /* UTMI+ OR ULPI interface */
966 if (gusbcfg.b.ulpi_utmi_sel == 1) {
967 /* ULPI interface */
968 gusbcfg.b.usbtrdtim = 9;
969 }
970 else {
971 /* UTMI+ interface */
972 if (GET_CORE_IF(pcd)->core_params->phy_utmi_width == 16) {
973 gusbcfg.b.usbtrdtim = utmi16b;
974 }
975 else {
976 gusbcfg.b.usbtrdtim = utmi8b;
977 }
978 }
979 }
980 }
981 else {
982 /* Full or low speed */
983 gusbcfg.b.usbtrdtim = 9;
984 }
985 dwc_write_reg32(&global_regs->gusbcfg, gusbcfg.d32);
986
987 /* Clear interrupt */
988 gintsts.d32 = 0;
989 gintsts.b.enumdone = 1;
990 dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
991 gintsts.d32);
992 return 1;
993 }
994
995 /**
996 * This interrupt indicates that the ISO OUT Packet was dropped due to
997 * Rx FIFO full or Rx Status Queue Full. If this interrupt occurs
998 * read all the data from the Rx FIFO.
999 */
1000 int32_t dwc_otg_pcd_handle_isoc_out_packet_dropped_intr(dwc_otg_pcd_t *pcd)
1001 {
1002 gintmsk_data_t intr_mask = { .d32 = 0};
1003 gintsts_data_t gintsts;
1004
1005 DWC_PRINT("INTERRUPT Handler not implemented for %s\n",
1006 "ISOC Out Dropped");
1007
1008 intr_mask.b.isooutdrop = 1;
1009 dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
1010 intr_mask.d32, 0);
1011
1012 /* Clear interrupt */
1013
1014 gintsts.d32 = 0;
1015 gintsts.b.isooutdrop = 1;
1016 dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
1017 gintsts.d32);
1018
1019 return 1;
1020 }
1021
1022 /**
1023 * This interrupt indicates the end of the portion of the micro-frame
1024 * for periodic transactions. If there is a periodic transaction for
1025 * the next frame, load the packets into the EP periodic Tx FIFO.
1026 */
1027 int32_t dwc_otg_pcd_handle_end_periodic_frame_intr(dwc_otg_pcd_t *pcd)
1028 {
1029 gintmsk_data_t intr_mask = { .d32 = 0};
1030 gintsts_data_t gintsts;
1031 DWC_PRINT("INTERRUPT Handler not implemented for %s\n", "EOP");
1032
1033 intr_mask.b.eopframe = 1;
1034 dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
1035 intr_mask.d32, 0);
1036
1037 /* Clear interrupt */
1038 gintsts.d32 = 0;
1039 gintsts.b.eopframe = 1;
1040 dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts, gintsts.d32);
1041
1042 return 1;
1043 }
1044
1045 /**
1046 * This interrupt indicates that EP of the packet on the top of the
1047 * non-periodic Tx FIFO does not match EP of the IN Token received.
1048 *
1049 * The "Device IN Token Queue" Registers are read to determine the
1050 * order the IN Tokens have been received. The non-periodic Tx FIFO
1051 * is flushed, so it can be reloaded in the order seen in the IN Token
1052 * Queue.
1053 */
1054 int32_t dwc_otg_pcd_handle_ep_mismatch_intr(dwc_otg_core_if_t *core_if)
1055 {
1056 gintsts_data_t gintsts;
1057 DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, core_if);
1058
1059 /* Clear interrupt */
1060 gintsts.d32 = 0;
1061 gintsts.b.epmismatch = 1;
1062 dwc_write_reg32 (&core_if->core_global_regs->gintsts, gintsts.d32);
1063
1064 return 1;
1065 }
1066
1067 /**
1068 * This funcion stalls EP0.
1069 */
1070 static inline void ep0_do_stall(dwc_otg_pcd_t *pcd, const int err_val)
1071 {
1072 dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
1073 struct usb_ctrlrequest *ctrl = &pcd->setup_pkt->req;
1074 DWC_WARN("req %02x.%02x protocol STALL; err %d\n",
1075 ctrl->bRequestType, ctrl->bRequest, err_val);
1076
1077 ep0->dwc_ep.is_in = 1;
1078 dwc_otg_ep_set_stall(pcd->otg_dev->core_if, &ep0->dwc_ep);
1079 pcd->ep0.stopped = 1;
1080 pcd->ep0state = EP0_IDLE;
1081 ep0_out_start(GET_CORE_IF(pcd), pcd);
1082 }
1083
1084 /**
1085 * This functions delegates the setup command to the gadget driver.
1086 */
1087 static inline void do_gadget_setup(dwc_otg_pcd_t *pcd,
1088 struct usb_ctrlrequest * ctrl)
1089 {
1090 int ret = 0;
1091 if (pcd->driver && pcd->driver->setup) {
1092 SPIN_UNLOCK(&pcd->lock);
1093 ret = pcd->driver->setup(&pcd->gadget, ctrl);
1094 SPIN_LOCK(&pcd->lock);
1095 if (ret < 0) {
1096 ep0_do_stall(pcd, ret);
1097 }
1098
1099 /** @todo This is a g_file_storage gadget driver specific
1100 * workaround: a DELAYED_STATUS result from the fsg_setup
1101 * routine will result in the gadget queueing a EP0 IN status
1102 * phase for a two-stage control transfer. Exactly the same as
1103 * a SET_CONFIGURATION/SET_INTERFACE except that this is a class
1104 * specific request. Need a generic way to know when the gadget
1105 * driver will queue the status phase. Can we assume when we
1106 * call the gadget driver setup() function that it will always
1107 * queue and require the following flag? Need to look into
1108 * this.
1109 */
1110
1111 if (ret == 256 + 999) {
1112 pcd->request_config = 1;
1113 }
1114 }
1115 }
1116
1117 /**
1118 * This function starts the Zero-Length Packet for the IN status phase
1119 * of a 2 stage control transfer.
1120 */
1121 static inline void do_setup_in_status_phase(dwc_otg_pcd_t *pcd)
1122 {
1123 dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
1124 if (pcd->ep0state == EP0_STALL) {
1125 return;
1126 }
1127
1128 pcd->ep0state = EP0_IN_STATUS_PHASE;
1129
1130 /* Prepare for more SETUP Packets */
1131 DWC_DEBUGPL(DBG_PCD, "EP0 IN ZLP\n");
1132 ep0->dwc_ep.xfer_len = 0;
1133 ep0->dwc_ep.xfer_count = 0;
1134 ep0->dwc_ep.is_in = 1;
1135 ep0->dwc_ep.dma_addr = pcd->setup_pkt_dma_handle;
1136 dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
1137
1138 /* Prepare for more SETUP Packets */
1139 // if(GET_CORE_IF(pcd)->dma_enable == 0) ep0_out_start(GET_CORE_IF(pcd), pcd);
1140 }
1141
1142 /**
1143 * This function starts the Zero-Length Packet for the OUT status phase
1144 * of a 2 stage control transfer.
1145 */
1146 static inline void do_setup_out_status_phase(dwc_otg_pcd_t *pcd)
1147 {
1148 dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
1149 if (pcd->ep0state == EP0_STALL) {
1150 DWC_DEBUGPL(DBG_PCD, "EP0 STALLED\n");
1151 return;
1152 }
1153 pcd->ep0state = EP0_OUT_STATUS_PHASE;
1154
1155 DWC_DEBUGPL(DBG_PCD, "EP0 OUT ZLP\n");
1156 ep0->dwc_ep.xfer_len = 0;
1157 ep0->dwc_ep.xfer_count = 0;
1158 ep0->dwc_ep.is_in = 0;
1159 ep0->dwc_ep.dma_addr = pcd->setup_pkt_dma_handle;
1160 dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
1161
1162 /* Prepare for more SETUP Packets */
1163 if(GET_CORE_IF(pcd)->dma_enable == 0) {
1164 ep0_out_start(GET_CORE_IF(pcd), pcd);
1165 }
1166 }
1167
1168 /**
1169 * Clear the EP halt (STALL) and if pending requests start the
1170 * transfer.
1171 */
1172 static inline void pcd_clear_halt(dwc_otg_pcd_t *pcd, dwc_otg_pcd_ep_t *ep)
1173 {
1174 if(ep->dwc_ep.stall_clear_flag == 0)
1175 dwc_otg_ep_clear_stall(GET_CORE_IF(pcd), &ep->dwc_ep);
1176
1177 /* Reactive the EP */
1178 dwc_otg_ep_activate(GET_CORE_IF(pcd), &ep->dwc_ep);
1179 if (ep->stopped) {
1180 ep->stopped = 0;
1181 /* If there is a request in the EP queue start it */
1182
1183 /** @todo FIXME: this causes an EP mismatch in DMA mode.
1184 * epmismatch not yet implemented. */
1185
1186 /*
1187 * Above fixme is solved by implmenting a tasklet to call the
1188 * start_next_request(), outside of interrupt context at some
1189 * time after the current time, after a clear-halt setup packet.
1190 * Still need to implement ep mismatch in the future if a gadget
1191 * ever uses more than one endpoint at once
1192 */
1193 ep->queue_sof = 1;
1194 tasklet_schedule (pcd->start_xfer_tasklet);
1195 }
1196 /* Start Control Status Phase */
1197 do_setup_in_status_phase(pcd);
1198 }
1199
1200 /**
1201 * This function is called when the SET_FEATURE TEST_MODE Setup packet
1202 * is sent from the host. The Device Control register is written with
1203 * the Test Mode bits set to the specified Test Mode. This is done as
1204 * a tasklet so that the "Status" phase of the control transfer
1205 * completes before transmitting the TEST packets.
1206 *
1207 * @todo This has not been tested since the tasklet struct was put
1208 * into the PCD struct!
1209 *
1210 */
1211 static void do_test_mode(unsigned long data)
1212 {
1213 dctl_data_t dctl;
1214 dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *)data;
1215 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
1216 int test_mode = pcd->test_mode;
1217
1218
1219 // DWC_WARN("%s() has not been tested since being rewritten!\n", __func__);
1220
1221 dctl.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dctl);
1222 switch (test_mode) {
1223 case 1: // TEST_J
1224 dctl.b.tstctl = 1;
1225 break;
1226
1227 case 2: // TEST_K
1228 dctl.b.tstctl = 2;
1229 break;
1230
1231 case 3: // TEST_SE0_NAK
1232 dctl.b.tstctl = 3;
1233 break;
1234
1235 case 4: // TEST_PACKET
1236 dctl.b.tstctl = 4;
1237 break;
1238
1239 case 5: // TEST_FORCE_ENABLE
1240 dctl.b.tstctl = 5;
1241 break;
1242 }
1243 dwc_write_reg32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32);
1244 }
1245
1246 /**
1247 * This function process the GET_STATUS Setup Commands.
1248 */
1249 static inline void do_get_status(dwc_otg_pcd_t *pcd)
1250 {
1251 struct usb_ctrlrequest ctrl = pcd->setup_pkt->req;
1252 dwc_otg_pcd_ep_t *ep;
1253 dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
1254 uint16_t *status = pcd->status_buf;
1255
1256 #ifdef DEBUG_EP0
1257 DWC_DEBUGPL(DBG_PCD,
1258 "GET_STATUS %02x.%02x v%04x i%04x l%04x\n",
1259 ctrl.bRequestType, ctrl.bRequest,
1260 ctrl.wValue, ctrl.wIndex, ctrl.wLength);
1261 #endif
1262
1263 switch (ctrl.bRequestType & USB_RECIP_MASK) {
1264 case USB_RECIP_DEVICE:
1265 *status = 0x1; /* Self powered */
1266 *status |= pcd->remote_wakeup_enable << 1;
1267 break;
1268
1269 case USB_RECIP_INTERFACE:
1270 *status = 0;
1271 break;
1272
1273 case USB_RECIP_ENDPOINT:
1274 ep = get_ep_by_addr(pcd, ctrl.wIndex);
1275 if (ep == 0 || ctrl.wLength > 2) {
1276 ep0_do_stall(pcd, -EOPNOTSUPP);
1277 return;
1278 }
1279 /** @todo check for EP stall */
1280 *status = ep->stopped;
1281 break;
1282 }
1283 pcd->ep0_pending = 1;
1284 ep0->dwc_ep.start_xfer_buff = (uint8_t *)status;
1285 ep0->dwc_ep.xfer_buff = (uint8_t *)status;
1286 ep0->dwc_ep.dma_addr = pcd->status_buf_dma_handle;
1287 ep0->dwc_ep.xfer_len = 2;
1288 ep0->dwc_ep.xfer_count = 0;
1289 ep0->dwc_ep.total_len = ep0->dwc_ep.xfer_len;
1290 dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
1291 }
1292 /**
1293 * This function process the SET_FEATURE Setup Commands.
1294 */
1295 static inline void do_set_feature(dwc_otg_pcd_t *pcd)
1296 {
1297 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
1298 dwc_otg_core_global_regs_t *global_regs =
1299 core_if->core_global_regs;
1300 struct usb_ctrlrequest ctrl = pcd->setup_pkt->req;
1301 dwc_otg_pcd_ep_t *ep = 0;
1302 int32_t otg_cap_param = core_if->core_params->otg_cap;
1303 gotgctl_data_t gotgctl = { .d32 = 0 };
1304
1305 DWC_DEBUGPL(DBG_PCD, "SET_FEATURE:%02x.%02x v%04x i%04x l%04x\n",
1306 ctrl.bRequestType, ctrl.bRequest,
1307 ctrl.wValue, ctrl.wIndex, ctrl.wLength);
1308 DWC_DEBUGPL(DBG_PCD,"otg_cap=%d\n", otg_cap_param);
1309
1310
1311 switch (ctrl.bRequestType & USB_RECIP_MASK) {
1312 case USB_RECIP_DEVICE:
1313 switch (ctrl.wValue) {
1314 case USB_DEVICE_REMOTE_WAKEUP:
1315 pcd->remote_wakeup_enable = 1;
1316 break;
1317
1318 case USB_DEVICE_TEST_MODE:
1319 /* Setup the Test Mode tasklet to do the Test
1320 * Packet generation after the SETUP Status
1321 * phase has completed. */
1322
1323 /** @todo This has not been tested since the
1324 * tasklet struct was put into the PCD
1325 * struct! */
1326 pcd->test_mode_tasklet.next = 0;
1327 pcd->test_mode_tasklet.state = 0;
1328 atomic_set(&pcd->test_mode_tasklet.count, 0);
1329 pcd->test_mode_tasklet.func = do_test_mode;
1330 pcd->test_mode_tasklet.data = (unsigned long)pcd;
1331 pcd->test_mode = ctrl.wIndex >> 8;
1332 tasklet_schedule(&pcd->test_mode_tasklet);
1333 break;
1334
1335 case USB_DEVICE_B_HNP_ENABLE:
1336 DWC_DEBUGPL(DBG_PCDV, "SET_FEATURE: USB_DEVICE_B_HNP_ENABLE\n");
1337
1338 /* dev may initiate HNP */
1339 if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) {
1340 pcd->b_hnp_enable = 1;
1341 dwc_otg_pcd_update_otg(pcd, 0);
1342 DWC_DEBUGPL(DBG_PCD, "Request B HNP\n");
1343 /**@todo Is the gotgctl.devhnpen cleared
1344 * by a USB Reset? */
1345 gotgctl.b.devhnpen = 1;
1346 gotgctl.b.hnpreq = 1;
1347 dwc_write_reg32(&global_regs->gotgctl, gotgctl.d32);
1348 }
1349 else {
1350 ep0_do_stall(pcd, -EOPNOTSUPP);
1351 }
1352 break;
1353
1354 case USB_DEVICE_A_HNP_SUPPORT:
1355 /* RH port supports HNP */
1356 DWC_DEBUGPL(DBG_PCDV, "SET_FEATURE: USB_DEVICE_A_HNP_SUPPORT\n");
1357 if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) {
1358 pcd->a_hnp_support = 1;
1359 dwc_otg_pcd_update_otg(pcd, 0);
1360 }
1361 else {
1362 ep0_do_stall(pcd, -EOPNOTSUPP);
1363 }
1364 break;
1365
1366 case USB_DEVICE_A_ALT_HNP_SUPPORT:
1367 /* other RH port does */
1368 DWC_DEBUGPL(DBG_PCDV, "SET_FEATURE: USB_DEVICE_A_ALT_HNP_SUPPORT\n");
1369 if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) {
1370 pcd->a_alt_hnp_support = 1;
1371 dwc_otg_pcd_update_otg(pcd, 0);
1372 }
1373 else {
1374 ep0_do_stall(pcd, -EOPNOTSUPP);
1375 }
1376 break;
1377 }
1378 do_setup_in_status_phase(pcd);
1379 break;
1380
1381 case USB_RECIP_INTERFACE:
1382 do_gadget_setup(pcd, &ctrl);
1383 break;
1384
1385 case USB_RECIP_ENDPOINT:
1386 if (ctrl.wValue == USB_ENDPOINT_HALT) {
1387 ep = get_ep_by_addr(pcd, ctrl.wIndex);
1388 if (ep == 0) {
1389 ep0_do_stall(pcd, -EOPNOTSUPP);
1390 return;
1391 }
1392 ep->stopped = 1;
1393 dwc_otg_ep_set_stall(core_if, &ep->dwc_ep);
1394 }
1395 do_setup_in_status_phase(pcd);
1396 break;
1397 }
1398 }
1399
1400 /**
1401 * This function process the CLEAR_FEATURE Setup Commands.
1402 */
1403 static inline void do_clear_feature(dwc_otg_pcd_t *pcd)
1404 {
1405 struct usb_ctrlrequest ctrl = pcd->setup_pkt->req;
1406 dwc_otg_pcd_ep_t *ep = 0;
1407
1408 DWC_DEBUGPL(DBG_PCD,
1409 "CLEAR_FEATURE:%02x.%02x v%04x i%04x l%04x\n",
1410 ctrl.bRequestType, ctrl.bRequest,
1411 ctrl.wValue, ctrl.wIndex, ctrl.wLength);
1412
1413 switch (ctrl.bRequestType & USB_RECIP_MASK) {
1414 case USB_RECIP_DEVICE:
1415 switch (ctrl.wValue) {
1416 case USB_DEVICE_REMOTE_WAKEUP:
1417 pcd->remote_wakeup_enable = 0;
1418 break;
1419
1420 case USB_DEVICE_TEST_MODE:
1421 /** @todo Add CLEAR_FEATURE for TEST modes. */
1422 break;
1423 }
1424 do_setup_in_status_phase(pcd);
1425 break;
1426
1427 case USB_RECIP_ENDPOINT:
1428 ep = get_ep_by_addr(pcd, ctrl.wIndex);
1429 if (ep == 0) {
1430 ep0_do_stall(pcd, -EOPNOTSUPP);
1431 return;
1432 }
1433
1434 pcd_clear_halt(pcd, ep);
1435
1436 break;
1437 }
1438 }
1439
1440 /**
1441 * This function process the SET_ADDRESS Setup Commands.
1442 */
1443 static inline void do_set_address(dwc_otg_pcd_t *pcd)
1444 {
1445 dwc_otg_dev_if_t *dev_if = GET_CORE_IF(pcd)->dev_if;
1446 struct usb_ctrlrequest ctrl = pcd->setup_pkt->req;
1447
1448 if (ctrl.bRequestType == USB_RECIP_DEVICE) {
1449 dcfg_data_t dcfg = {.d32=0};
1450
1451 #ifdef DEBUG_EP0
1452 // DWC_DEBUGPL(DBG_PCDV, "SET_ADDRESS:%d\n", ctrl.wValue);
1453 #endif
1454 dcfg.b.devaddr = ctrl.wValue;
1455 dwc_modify_reg32(&dev_if->dev_global_regs->dcfg, 0, dcfg.d32);
1456 do_setup_in_status_phase(pcd);
1457 }
1458 }
1459
1460 /**
1461 * This function processes SETUP commands. In Linux, the USB Command
1462 * processing is done in two places - the first being the PCD and the
1463 * second in the Gadget Driver (for example, the File-Backed Storage
1464 * Gadget Driver).
1465 *
1466 * <table>
1467 * <tr><td>Command </td><td>Driver </td><td>Description</td></tr>
1468 *
1469 * <tr><td>GET_STATUS </td><td>PCD </td><td>Command is processed as
1470 * defined in chapter 9 of the USB 2.0 Specification chapter 9
1471 * </td></tr>
1472 *
1473 * <tr><td>CLEAR_FEATURE </td><td>PCD </td><td>The Device and Endpoint
1474 * requests are the ENDPOINT_HALT feature is procesed, all others the
1475 * interface requests are ignored.</td></tr>
1476 *
1477 * <tr><td>SET_FEATURE </td><td>PCD </td><td>The Device and Endpoint
1478 * requests are processed by the PCD. Interface requests are passed
1479 * to the Gadget Driver.</td></tr>
1480 *
1481 * <tr><td>SET_ADDRESS </td><td>PCD </td><td>Program the DCFG reg,
1482 * with device address received </td></tr>
1483 *
1484 * <tr><td>GET_DESCRIPTOR </td><td>Gadget Driver </td><td>Return the
1485 * requested descriptor</td></tr>
1486 *
1487 * <tr><td>SET_DESCRIPTOR </td><td>Gadget Driver </td><td>Optional -
1488 * not implemented by any of the existing Gadget Drivers.</td></tr>
1489 *
1490 * <tr><td>SET_CONFIGURATION </td><td>Gadget Driver </td><td>Disable
1491 * all EPs and enable EPs for new configuration.</td></tr>
1492 *
1493 * <tr><td>GET_CONFIGURATION </td><td>Gadget Driver </td><td>Return
1494 * the current configuration</td></tr>
1495 *
1496 * <tr><td>SET_INTERFACE </td><td>Gadget Driver </td><td>Disable all
1497 * EPs and enable EPs for new configuration.</td></tr>
1498 *
1499 * <tr><td>GET_INTERFACE </td><td>Gadget Driver </td><td>Return the
1500 * current interface.</td></tr>
1501 *
1502 * <tr><td>SYNC_FRAME </td><td>PCD </td><td>Display debug
1503 * message.</td></tr>
1504 * </table>
1505 *
1506 * When the SETUP Phase Done interrupt occurs, the PCD SETUP commands are
1507 * processed by pcd_setup. Calling the Function Driver's setup function from
1508 * pcd_setup processes the gadget SETUP commands.
1509 */
1510 static inline void pcd_setup(dwc_otg_pcd_t *pcd)
1511 {
1512 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
1513 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
1514 struct usb_ctrlrequest ctrl = pcd->setup_pkt->req;
1515 dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
1516
1517 deptsiz0_data_t doeptsize0 = { .d32 = 0};
1518
1519 #ifdef DEBUG_EP0
1520 DWC_DEBUGPL(DBG_PCD, "SETUP %02x.%02x v%04x i%04x l%04x\n",
1521 ctrl.bRequestType, ctrl.bRequest,
1522 ctrl.wValue, ctrl.wIndex, ctrl.wLength);
1523 #endif
1524
1525 doeptsize0.d32 = dwc_read_reg32(&dev_if->out_ep_regs[0]->doeptsiz);
1526
1527 /** @todo handle > 1 setup packet , assert error for now */
1528
1529 if (core_if->dma_enable && core_if->dma_desc_enable == 0 && (doeptsize0.b.supcnt < 2)) {
1530 DWC_ERROR ("\n\n----------- CANNOT handle > 1 setup packet in DMA mode\n\n");
1531 }
1532
1533 /* Clean up the request queue */
1534 dwc_otg_request_nuke(ep0);
1535 ep0->stopped = 0;
1536
1537 if (ctrl.bRequestType & USB_DIR_IN) {
1538 ep0->dwc_ep.is_in = 1;
1539 pcd->ep0state = EP0_IN_DATA_PHASE;
1540 }
1541 else {
1542 ep0->dwc_ep.is_in = 0;
1543 pcd->ep0state = EP0_OUT_DATA_PHASE;
1544 }
1545
1546 if(ctrl.wLength == 0) {
1547 ep0->dwc_ep.is_in = 1;
1548 pcd->ep0state = EP0_IN_STATUS_PHASE;
1549 }
1550
1551 if ((ctrl.bRequestType & USB_TYPE_MASK) != USB_TYPE_STANDARD) {
1552 /* handle non-standard (class/vendor) requests in the gadget driver */
1553 do_gadget_setup(pcd, &ctrl);
1554 return;
1555 }
1556
1557 /** @todo NGS: Handle bad setup packet? */
1558
1559 ///////////////////////////////////////////
1560 //// --- Standard Request handling --- ////
1561
1562 switch (ctrl.bRequest) {
1563 case USB_REQ_GET_STATUS:
1564 do_get_status(pcd);
1565 break;
1566
1567 case USB_REQ_CLEAR_FEATURE:
1568 do_clear_feature(pcd);
1569 break;
1570
1571 case USB_REQ_SET_FEATURE:
1572 do_set_feature(pcd);
1573 break;
1574
1575 case USB_REQ_SET_ADDRESS:
1576 do_set_address(pcd);
1577 break;
1578
1579 case USB_REQ_SET_INTERFACE:
1580 case USB_REQ_SET_CONFIGURATION:
1581 // _pcd->request_config = 1; /* Configuration changed */
1582 do_gadget_setup(pcd, &ctrl);
1583 break;
1584
1585 case USB_REQ_SYNCH_FRAME:
1586 do_gadget_setup(pcd, &ctrl);
1587 break;
1588
1589 default:
1590 /* Call the Gadget Driver's setup functions */
1591 do_gadget_setup(pcd, &ctrl);
1592 break;
1593 }
1594 }
1595
1596 /**
1597 * This function completes the ep0 control transfer.
1598 */
1599 static int32_t ep0_complete_request(dwc_otg_pcd_ep_t *ep)
1600 {
1601 dwc_otg_core_if_t *core_if = GET_CORE_IF(ep->pcd);
1602 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
1603 dwc_otg_dev_in_ep_regs_t *in_ep_regs =
1604 dev_if->in_ep_regs[ep->dwc_ep.num];
1605 #ifdef DEBUG_EP0
1606 dwc_otg_dev_out_ep_regs_t *out_ep_regs =
1607 dev_if->out_ep_regs[ep->dwc_ep.num];
1608 #endif
1609 deptsiz0_data_t deptsiz;
1610 desc_sts_data_t desc_sts;
1611 dwc_otg_pcd_request_t *req;
1612 int is_last = 0;
1613 dwc_otg_pcd_t *pcd = ep->pcd;
1614
1615 //DWC_DEBUGPL(DBG_PCDV, "%s() %s\n", __func__, _ep->ep.name);
1616
1617 if (pcd->ep0_pending && list_empty(&ep->queue)) {
1618 if (ep->dwc_ep.is_in) {
1619 #ifdef DEBUG_EP0
1620 DWC_DEBUGPL(DBG_PCDV, "Do setup OUT status phase\n");
1621 #endif
1622 do_setup_out_status_phase(pcd);
1623 }
1624 else {
1625 #ifdef DEBUG_EP0
1626 DWC_DEBUGPL(DBG_PCDV, "Do setup IN status phase\n");
1627 #endif
1628 do_setup_in_status_phase(pcd);
1629 }
1630 pcd->ep0_pending = 0;
1631 return 1;
1632 }
1633
1634 if (list_empty(&ep->queue)) {
1635 return 0;
1636 }
1637 req = list_entry(ep->queue.next, dwc_otg_pcd_request_t, queue);
1638
1639
1640 if (pcd->ep0state == EP0_OUT_STATUS_PHASE || pcd->ep0state == EP0_IN_STATUS_PHASE) {
1641 is_last = 1;
1642 }
1643 else if (ep->dwc_ep.is_in) {
1644 deptsiz.d32 = dwc_read_reg32(&in_ep_regs->dieptsiz);
1645 if(core_if->dma_desc_enable != 0)
1646 desc_sts.d32 = readl(dev_if->in_desc_addr);
1647 #ifdef DEBUG_EP0
1648 DWC_DEBUGPL(DBG_PCDV, "%s len=%d xfersize=%d pktcnt=%d\n",
1649 ep->ep.name, ep->dwc_ep.xfer_len,
1650 deptsiz.b.xfersize, deptsiz.b.pktcnt);
1651 #endif
1652
1653 if (((core_if->dma_desc_enable == 0) && (deptsiz.b.xfersize == 0)) ||
1654 ((core_if->dma_desc_enable != 0) && (desc_sts.b.bytes == 0))) {
1655 req->req.actual = ep->dwc_ep.xfer_count;
1656 /* Is a Zero Len Packet needed? */
1657 if (req->req.zero) {
1658 #ifdef DEBUG_EP0
1659 DWC_DEBUGPL(DBG_PCD, "Setup Rx ZLP\n");
1660 #endif
1661 req->req.zero = 0;
1662 }
1663 do_setup_out_status_phase(pcd);
1664 }
1665 }
1666 else {
1667 /* ep0-OUT */
1668 #ifdef DEBUG_EP0
1669 deptsiz.d32 = dwc_read_reg32(&out_ep_regs->doeptsiz);
1670 DWC_DEBUGPL(DBG_PCDV, "%s len=%d xsize=%d pktcnt=%d\n",
1671 ep->ep.name, ep->dwc_ep.xfer_len,
1672 deptsiz.b.xfersize,
1673 deptsiz.b.pktcnt);
1674 #endif
1675 req->req.actual = ep->dwc_ep.xfer_count;
1676 /* Is a Zero Len Packet needed? */
1677 if (req->req.zero) {
1678 #ifdef DEBUG_EP0
1679 DWC_DEBUGPL(DBG_PCDV, "Setup Tx ZLP\n");
1680 #endif
1681 req->req.zero = 0;
1682 }
1683 if(core_if->dma_desc_enable == 0)
1684 do_setup_in_status_phase(pcd);
1685 }
1686
1687 /* Complete the request */
1688 if (is_last) {
1689 dwc_otg_request_done(ep, req, 0);
1690 ep->dwc_ep.start_xfer_buff = 0;
1691 ep->dwc_ep.xfer_buff = 0;
1692 ep->dwc_ep.xfer_len = 0;
1693 return 1;
1694 }
1695 return 0;
1696 }
1697
1698 /**
1699 * This function completes the request for the EP. If there are
1700 * additional requests for the EP in the queue they will be started.
1701 */
1702 static void complete_ep(dwc_otg_pcd_ep_t *ep)
1703 {
1704 dwc_otg_core_if_t *core_if = GET_CORE_IF(ep->pcd);
1705 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
1706 dwc_otg_dev_in_ep_regs_t *in_ep_regs =
1707 dev_if->in_ep_regs[ep->dwc_ep.num];
1708 deptsiz_data_t deptsiz;
1709 desc_sts_data_t desc_sts;
1710 dwc_otg_pcd_request_t *req = 0;
1711 dwc_otg_dma_desc_t* dma_desc;
1712 uint32_t byte_count = 0;
1713 int is_last = 0;
1714 int i;
1715
1716 DWC_DEBUGPL(DBG_PCDV,"%s() %s-%s\n", __func__, ep->ep.name,
1717 (ep->dwc_ep.is_in?"IN":"OUT"));
1718
1719 /* Get any pending requests */
1720 if (!list_empty(&ep->queue)) {
1721 req = list_entry(ep->queue.next, dwc_otg_pcd_request_t,
1722 queue);
1723 if (!req) {
1724 printk("complete_ep 0x%p, req = NULL!\n", ep);
1725 return;
1726 }
1727 }
1728 else {
1729 printk("complete_ep 0x%p, ep->queue empty!\n", ep);
1730 return;
1731 }
1732 DWC_DEBUGPL(DBG_PCD, "Requests %d\n", ep->pcd->request_pending);
1733
1734 if (ep->dwc_ep.is_in) {
1735 deptsiz.d32 = dwc_read_reg32(&in_ep_regs->dieptsiz);
1736
1737 if (core_if->dma_enable) {
1738 if(core_if->dma_desc_enable == 0) {
1739 if (deptsiz.b.xfersize == 0 && deptsiz.b.pktcnt == 0) {
1740 byte_count = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
1741
1742 ep->dwc_ep.xfer_buff += byte_count;
1743 ep->dwc_ep.dma_addr += byte_count;
1744 ep->dwc_ep.xfer_count += byte_count;
1745
1746 DWC_DEBUGPL(DBG_PCDV, "%s len=%d xfersize=%d pktcnt=%d\n",
1747 ep->ep.name, ep->dwc_ep.xfer_len,
1748 deptsiz.b.xfersize, deptsiz.b.pktcnt);
1749
1750
1751 if(ep->dwc_ep.xfer_len < ep->dwc_ep.total_len) {
1752 dwc_otg_ep_start_transfer(core_if, &ep->dwc_ep);
1753 } else if(ep->dwc_ep.sent_zlp) {
1754 /*
1755 * This fragment of code should initiate 0
1756 * length trasfer in case if it is queued
1757 * a trasfer with size divisible to EPs max
1758 * packet size and with usb_request zero field
1759 * is set, which means that after data is transfered,
1760 * it is also should be transfered
1761 * a 0 length packet at the end. For Slave and
1762 * Buffer DMA modes in this case SW has
1763 * to initiate 2 transfers one with transfer size,
1764 * and the second with 0 size. For Desriptor
1765 * DMA mode SW is able to initiate a transfer,
1766 * which will handle all the packets including
1767 * the last 0 legth.
1768 */
1769 ep->dwc_ep.sent_zlp = 0;
1770 dwc_otg_ep_start_zl_transfer(core_if, &ep->dwc_ep);
1771 } else {
1772 is_last = 1;
1773 }
1774 } else {
1775 DWC_WARN("Incomplete transfer (%s-%s [siz=%d pkt=%d])\n",
1776 ep->ep.name, (ep->dwc_ep.is_in?"IN":"OUT"),
1777 deptsiz.b.xfersize, deptsiz.b.pktcnt);
1778 }
1779 } else {
1780 dma_desc = ep->dwc_ep.desc_addr;
1781 byte_count = 0;
1782 ep->dwc_ep.sent_zlp = 0;
1783
1784 for(i = 0; i < ep->dwc_ep.desc_cnt; ++i) {
1785 desc_sts.d32 = readl(dma_desc);
1786 byte_count += desc_sts.b.bytes;
1787 dma_desc++;
1788 }
1789
1790 if(byte_count == 0) {
1791 ep->dwc_ep.xfer_count = ep->dwc_ep.total_len;
1792 is_last = 1;
1793 } else {
1794 DWC_WARN("Incomplete transfer\n");
1795 }
1796 }
1797 } else {
1798 if (deptsiz.b.xfersize == 0 && deptsiz.b.pktcnt == 0) {
1799 /* Check if the whole transfer was completed,
1800 * if no, setup transfer for next portion of data
1801 */
1802 DWC_DEBUGPL(DBG_PCDV, "%s len=%d xfersize=%d pktcnt=%d\n",
1803 ep->ep.name, ep->dwc_ep.xfer_len,
1804 deptsiz.b.xfersize, deptsiz.b.pktcnt);
1805 if(ep->dwc_ep.xfer_len < ep->dwc_ep.total_len) {
1806 dwc_otg_ep_start_transfer(core_if, &ep->dwc_ep);
1807 } else if(ep->dwc_ep.sent_zlp) {
1808 /*
1809 * This fragment of code should initiate 0
1810 * length trasfer in case if it is queued
1811 * a trasfer with size divisible to EPs max
1812 * packet size and with usb_request zero field
1813 * is set, which means that after data is transfered,
1814 * it is also should be transfered
1815 * a 0 length packet at the end. For Slave and
1816 * Buffer DMA modes in this case SW has
1817 * to initiate 2 transfers one with transfer size,
1818 * and the second with 0 size. For Desriptor
1819 * DMA mode SW is able to initiate a transfer,
1820 * which will handle all the packets including
1821 * the last 0 legth.
1822 */
1823 ep->dwc_ep.sent_zlp = 0;
1824 dwc_otg_ep_start_zl_transfer(core_if, &ep->dwc_ep);
1825 } else {
1826 is_last = 1;
1827 }
1828 }
1829 else {
1830 DWC_WARN("Incomplete transfer (%s-%s [siz=%d pkt=%d])\n",
1831 ep->ep.name, (ep->dwc_ep.is_in?"IN":"OUT"),
1832 deptsiz.b.xfersize, deptsiz.b.pktcnt);
1833 }
1834 }
1835 } else {
1836 dwc_otg_dev_out_ep_regs_t *out_ep_regs =
1837 dev_if->out_ep_regs[ep->dwc_ep.num];
1838 desc_sts.d32 = 0;
1839 if(core_if->dma_enable) {
1840 if(core_if->dma_desc_enable) {
1841 dma_desc = ep->dwc_ep.desc_addr;
1842 byte_count = 0;
1843 ep->dwc_ep.sent_zlp = 0;
1844 for(i = 0; i < ep->dwc_ep.desc_cnt; ++i) {
1845 desc_sts.d32 = readl(dma_desc);
1846 byte_count += desc_sts.b.bytes;
1847 dma_desc++;
1848 }
1849
1850 ep->dwc_ep.xfer_count = ep->dwc_ep.total_len
1851 - byte_count + ((4 - (ep->dwc_ep.total_len & 0x3)) & 0x3);
1852 is_last = 1;
1853 } else {
1854 deptsiz.d32 = 0;
1855 deptsiz.d32 = dwc_read_reg32(&out_ep_regs->doeptsiz);
1856
1857 byte_count = (ep->dwc_ep.xfer_len -
1858 ep->dwc_ep.xfer_count - deptsiz.b.xfersize);
1859 ep->dwc_ep.xfer_buff += byte_count;
1860 ep->dwc_ep.dma_addr += byte_count;
1861 ep->dwc_ep.xfer_count += byte_count;
1862
1863 /* Check if the whole transfer was completed,
1864 * if no, setup transfer for next portion of data
1865 */
1866 if(ep->dwc_ep.xfer_len < ep->dwc_ep.total_len) {
1867 dwc_otg_ep_start_transfer(core_if, &ep->dwc_ep);
1868 }
1869 else if(ep->dwc_ep.sent_zlp) {
1870 /*
1871 * This fragment of code should initiate 0
1872 * length trasfer in case if it is queued
1873 * a trasfer with size divisible to EPs max
1874 * packet size and with usb_request zero field
1875 * is set, which means that after data is transfered,
1876 * it is also should be transfered
1877 * a 0 length packet at the end. For Slave and
1878 * Buffer DMA modes in this case SW has
1879 * to initiate 2 transfers one with transfer size,
1880 * and the second with 0 size. For Desriptor
1881 * DMA mode SW is able to initiate a transfer,
1882 * which will handle all the packets including
1883 * the last 0 legth.
1884 */
1885 ep->dwc_ep.sent_zlp = 0;
1886 dwc_otg_ep_start_zl_transfer(core_if, &ep->dwc_ep);
1887 } else {
1888 is_last = 1;
1889 }
1890 }
1891 } else {
1892 /* Check if the whole transfer was completed,
1893 * if no, setup transfer for next portion of data
1894 */
1895 if(ep->dwc_ep.xfer_len < ep->dwc_ep.total_len) {
1896 dwc_otg_ep_start_transfer(core_if, &ep->dwc_ep);
1897 }
1898 else if(ep->dwc_ep.sent_zlp) {
1899 /*
1900 * This fragment of code should initiate 0
1901 * length trasfer in case if it is queued
1902 * a trasfer with size divisible to EPs max
1903 * packet size and with usb_request zero field
1904 * is set, which means that after data is transfered,
1905 * it is also should be transfered
1906 * a 0 length packet at the end. For Slave and
1907 * Buffer DMA modes in this case SW has
1908 * to initiate 2 transfers one with transfer size,
1909 * and the second with 0 size. For Desriptor
1910 * DMA mode SW is able to initiate a transfer,
1911 * which will handle all the packets including
1912 * the last 0 legth.
1913 */
1914 ep->dwc_ep.sent_zlp = 0;
1915 dwc_otg_ep_start_zl_transfer(core_if, &ep->dwc_ep);
1916 } else {
1917 is_last = 1;
1918 }
1919 }
1920
1921 #ifdef DEBUG
1922
1923 DWC_DEBUGPL(DBG_PCDV, "addr %p, %s len=%d cnt=%d xsize=%d pktcnt=%d\n",
1924 &out_ep_regs->doeptsiz, ep->ep.name, ep->dwc_ep.xfer_len,
1925 ep->dwc_ep.xfer_count,
1926 deptsiz.b.xfersize,
1927 deptsiz.b.pktcnt);
1928 #endif
1929 }
1930
1931 /* Complete the request */
1932 if (is_last) {
1933 req->req.actual = ep->dwc_ep.xfer_count;
1934
1935 dwc_otg_request_done(ep, req, 0);
1936
1937 ep->dwc_ep.start_xfer_buff = 0;
1938 ep->dwc_ep.xfer_buff = 0;
1939 ep->dwc_ep.xfer_len = 0;
1940
1941 /* If there is a request in the queue start it.*/
1942 start_next_request(ep);
1943 }
1944 }
1945
1946
1947 #ifdef DWC_EN_ISOC
1948
1949 /**
1950 * This function BNA interrupt for Isochronous EPs
1951 *
1952 */
1953 static void dwc_otg_pcd_handle_iso_bna(dwc_otg_pcd_ep_t *ep)
1954 {
1955 dwc_ep_t *dwc_ep = &ep->dwc_ep;
1956 volatile uint32_t *addr;
1957 depctl_data_t depctl = {.d32 = 0};
1958 dwc_otg_pcd_t *pcd = ep->pcd;
1959 dwc_otg_dma_desc_t *dma_desc;
1960 int i;
1961
1962 dma_desc = dwc_ep->iso_desc_addr + dwc_ep->desc_cnt * (dwc_ep->proc_buf_num);
1963
1964 if(dwc_ep->is_in) {
1965 desc_sts_data_t sts = {.d32 = 0};
1966 for(i = 0;i < dwc_ep->desc_cnt; ++i, ++dma_desc)
1967 {
1968 sts.d32 = readl(&dma_desc->status);
1969 sts.b_iso_in.bs = BS_HOST_READY;
1970 writel(sts.d32,&dma_desc->status);
1971 }
1972 }
1973 else {
1974 desc_sts_data_t sts = {.d32 = 0};
1975 for(i = 0;i < dwc_ep->desc_cnt; ++i, ++dma_desc)
1976 {
1977 sts.d32 = readl(&dma_desc->status);
1978 sts.b_iso_out.bs = BS_HOST_READY;
1979 writel(sts.d32,&dma_desc->status);
1980 }
1981 }
1982
1983 if(dwc_ep->is_in == 0){
1984 addr = &GET_CORE_IF(pcd)->dev_if->out_ep_regs[dwc_ep->num]->doepctl;
1985 }
1986 else{
1987 addr = &GET_CORE_IF(pcd)->dev_if->in_ep_regs[dwc_ep->num]->diepctl;
1988 }
1989 depctl.b.epena = 1;
1990 dwc_modify_reg32(addr,depctl.d32,depctl.d32);
1991 }
1992
1993 /**
1994 * This function sets latest iso packet information(non-PTI mode)
1995 *
1996 * @param core_if Programming view of DWC_otg controller.
1997 * @param ep The EP to start the transfer on.
1998 *
1999 */
2000 void set_current_pkt_info(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
2001 {
2002 deptsiz_data_t deptsiz = { .d32 = 0 };
2003 dma_addr_t dma_addr;
2004 uint32_t offset;
2005
2006 if(ep->proc_buf_num)
2007 dma_addr = ep->dma_addr1;
2008 else
2009 dma_addr = ep->dma_addr0;
2010
2011
2012 if(ep->is_in) {
2013 deptsiz.d32 = dwc_read_reg32(&core_if->dev_if->in_ep_regs[ep->num]->dieptsiz);
2014 offset = ep->data_per_frame;
2015 } else {
2016 deptsiz.d32 = dwc_read_reg32(&core_if->dev_if->out_ep_regs[ep->num]->doeptsiz);
2017 offset = ep->data_per_frame + (0x4 & (0x4 - (ep->data_per_frame & 0x3)));
2018 }
2019
2020 if(!deptsiz.b.xfersize) {
2021 ep->pkt_info[ep->cur_pkt].length = ep->data_per_frame;
2022 ep->pkt_info[ep->cur_pkt].offset = ep->cur_pkt_dma_addr - dma_addr;
2023 ep->pkt_info[ep->cur_pkt].status = 0;
2024 } else {
2025 ep->pkt_info[ep->cur_pkt].length = ep->data_per_frame;
2026 ep->pkt_info[ep->cur_pkt].offset = ep->cur_pkt_dma_addr - dma_addr;
2027 ep->pkt_info[ep->cur_pkt].status = -ENODATA;
2028 }
2029 ep->cur_pkt_addr += offset;
2030 ep->cur_pkt_dma_addr += offset;
2031 ep->cur_pkt++;
2032 }
2033
2034 /**
2035 * This function sets latest iso packet information(DDMA mode)
2036 *
2037 * @param core_if Programming view of DWC_otg controller.
2038 * @param dwc_ep The EP to start the transfer on.
2039 *
2040 */
2041 static void set_ddma_iso_pkts_info(dwc_otg_core_if_t *core_if, dwc_ep_t *dwc_ep)
2042 {
2043 dwc_otg_dma_desc_t* dma_desc;
2044 desc_sts_data_t sts = {.d32 = 0};
2045 iso_pkt_info_t *iso_packet;
2046 uint32_t data_per_desc;
2047 uint32_t offset;
2048 int i, j;
2049
2050 iso_packet = dwc_ep->pkt_info;
2051
2052 /** Reinit closed DMA Descriptors*/
2053 /** ISO OUT EP */
2054 if(dwc_ep->is_in == 0) {
2055 dma_desc = dwc_ep->iso_desc_addr + dwc_ep->desc_cnt * dwc_ep->proc_buf_num;
2056 offset = 0;
2057
2058 for(i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm; i+= dwc_ep->pkt_per_frm)
2059 {
2060 for(j = 0; j < dwc_ep->pkt_per_frm; ++j)
2061 {
2062 data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
2063 dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
2064 data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
2065
2066 sts.d32 = readl(&dma_desc->status);
2067
2068 /* Write status in iso_packet_decsriptor */
2069 iso_packet->status = sts.b_iso_out.rxsts + (sts.b_iso_out.bs^BS_DMA_DONE);
2070 if(iso_packet->status) {
2071 iso_packet->status = -ENODATA;
2072 }
2073
2074 /* Received data length */
2075 if(!sts.b_iso_out.rxbytes){
2076 iso_packet->length = data_per_desc - sts.b_iso_out.rxbytes;
2077 } else {
2078 iso_packet->length = data_per_desc - sts.b_iso_out.rxbytes +
2079 (4 - dwc_ep->data_per_frame % 4);
2080 }
2081
2082 iso_packet->offset = offset;
2083
2084 offset += data_per_desc;
2085 dma_desc ++;
2086 iso_packet ++;
2087 }
2088 }
2089
2090 for(j = 0; j < dwc_ep->pkt_per_frm - 1; ++j)
2091 {
2092 data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
2093 dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
2094 data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
2095
2096 sts.d32 = readl(&dma_desc->status);
2097
2098 /* Write status in iso_packet_decsriptor */
2099 iso_packet->status = sts.b_iso_out.rxsts + (sts.b_iso_out.bs^BS_DMA_DONE);
2100 if(iso_packet->status) {
2101 iso_packet->status = -ENODATA;
2102 }
2103
2104 /* Received data length */
2105 iso_packet->length = dwc_ep->data_per_frame - sts.b_iso_out.rxbytes;
2106
2107 iso_packet->offset = offset;
2108
2109 offset += data_per_desc;
2110 iso_packet++;
2111 dma_desc++;
2112 }
2113
2114 sts.d32 = readl(&dma_desc->status);
2115
2116 /* Write status in iso_packet_decsriptor */
2117 iso_packet->status = sts.b_iso_out.rxsts + (sts.b_iso_out.bs^BS_DMA_DONE);
2118 if(iso_packet->status) {
2119 iso_packet->status = -ENODATA;
2120 }
2121 /* Received data length */
2122 if(!sts.b_iso_out.rxbytes){
2123 iso_packet->length = dwc_ep->data_per_frame - sts.b_iso_out.rxbytes;
2124 } else {
2125 iso_packet->length = dwc_ep->data_per_frame - sts.b_iso_out.rxbytes +
2126 (4 - dwc_ep->data_per_frame % 4);
2127 }
2128
2129 iso_packet->offset = offset;
2130 }
2131 else /** ISO IN EP */
2132 {
2133 dma_desc = dwc_ep->iso_desc_addr + dwc_ep->desc_cnt * dwc_ep->proc_buf_num;
2134
2135 for(i = 0; i < dwc_ep->desc_cnt - 1; i++)
2136 {
2137 sts.d32 = readl(&dma_desc->status);
2138
2139 /* Write status in iso packet descriptor */
2140 iso_packet->status = sts.b_iso_in.txsts + (sts.b_iso_in.bs^BS_DMA_DONE);
2141 if(iso_packet->status != 0) {
2142 iso_packet->status = -ENODATA;
2143
2144 }
2145 /* Bytes has been transfered */
2146 iso_packet->length = dwc_ep->data_per_frame - sts.b_iso_in.txbytes;
2147
2148 dma_desc ++;
2149 iso_packet++;
2150 }
2151
2152 sts.d32 = readl(&dma_desc->status);
2153 while(sts.b_iso_in.bs == BS_DMA_BUSY) {
2154 sts.d32 = readl(&dma_desc->status);
2155 }
2156
2157 /* Write status in iso packet descriptor ??? do be done with ERROR codes*/
2158 iso_packet->status = sts.b_iso_in.txsts + (sts.b_iso_in.bs^BS_DMA_DONE);
2159 if(iso_packet->status != 0) {
2160 iso_packet->status = -ENODATA;
2161 }
2162
2163 /* Bytes has been transfered */
2164 iso_packet->length = dwc_ep->data_per_frame - sts.b_iso_in.txbytes;
2165 }
2166 }
2167
2168 /**
2169 * This function reinitialize DMA Descriptors for Isochronous transfer
2170 *
2171 * @param core_if Programming view of DWC_otg controller.
2172 * @param dwc_ep The EP to start the transfer on.
2173 *
2174 */
2175 static void reinit_ddma_iso_xfer(dwc_otg_core_if_t *core_if, dwc_ep_t *dwc_ep)
2176 {
2177 int i, j;
2178 dwc_otg_dma_desc_t* dma_desc;
2179 dma_addr_t dma_ad;
2180 volatile uint32_t *addr;
2181 desc_sts_data_t sts = { .d32 =0 };
2182 uint32_t data_per_desc;
2183
2184 if(dwc_ep->is_in == 0) {
2185 addr = &core_if->dev_if->out_ep_regs[dwc_ep->num]->doepctl;
2186 }
2187 else {
2188 addr = &core_if->dev_if->in_ep_regs[dwc_ep->num]->diepctl;
2189 }
2190
2191
2192 if(dwc_ep->proc_buf_num == 0) {
2193 /** Buffer 0 descriptors setup */
2194 dma_ad = dwc_ep->dma_addr0;
2195 }
2196 else {
2197 /** Buffer 1 descriptors setup */
2198 dma_ad = dwc_ep->dma_addr1;
2199 }
2200
2201
2202 /** Reinit closed DMA Descriptors*/
2203 /** ISO OUT EP */
2204 if(dwc_ep->is_in == 0) {
2205 dma_desc = dwc_ep->iso_desc_addr + dwc_ep->desc_cnt * dwc_ep->proc_buf_num;
2206
2207 sts.b_iso_out.bs = BS_HOST_READY;
2208 sts.b_iso_out.rxsts = 0;
2209 sts.b_iso_out.l = 0;
2210 sts.b_iso_out.sp = 0;
2211 sts.b_iso_out.ioc = 0;
2212 sts.b_iso_out.pid = 0;
2213 sts.b_iso_out.framenum = 0;
2214
2215 for(i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm; i+= dwc_ep->pkt_per_frm)
2216 {
2217 for(j = 0; j < dwc_ep->pkt_per_frm; ++j)
2218 {
2219 data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
2220 dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
2221 data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
2222 sts.b_iso_out.rxbytes = data_per_desc;
2223 writel((uint32_t)dma_ad, &dma_desc->buf);
2224 writel(sts.d32, &dma_desc->status);
2225
2226 (uint32_t)dma_ad += data_per_desc;
2227 dma_desc ++;
2228 }
2229 }
2230
2231 for(j = 0; j < dwc_ep->pkt_per_frm - 1; ++j)
2232 {
2233
2234 data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
2235 dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
2236 data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
2237 sts.b_iso_out.rxbytes = data_per_desc;
2238
2239 writel((uint32_t)dma_ad, &dma_desc->buf);
2240 writel(sts.d32, &dma_desc->status);
2241
2242 dma_desc++;
2243 (uint32_t)dma_ad += data_per_desc;
2244 }
2245
2246 sts.b_iso_out.ioc = 1;
2247 sts.b_iso_out.l = dwc_ep->proc_buf_num;
2248
2249 data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
2250 dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
2251 data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
2252 sts.b_iso_out.rxbytes = data_per_desc;
2253
2254 writel((uint32_t)dma_ad, &dma_desc->buf);
2255 writel(sts.d32, &dma_desc->status);
2256 }
2257 else /** ISO IN EP */
2258 {
2259 dma_desc = dwc_ep->iso_desc_addr + dwc_ep->desc_cnt * dwc_ep->proc_buf_num;
2260
2261 sts.b_iso_in.bs = BS_HOST_READY;
2262 sts.b_iso_in.txsts = 0;
2263 sts.b_iso_in.sp = 0;
2264 sts.b_iso_in.ioc = 0;
2265 sts.b_iso_in.pid = dwc_ep->pkt_per_frm;
2266 sts.b_iso_in.framenum = dwc_ep->next_frame;
2267 sts.b_iso_in.txbytes = dwc_ep->data_per_frame;
2268 sts.b_iso_in.l = 0;
2269
2270 for(i = 0; i < dwc_ep->desc_cnt - 1; i++)
2271 {
2272 writel((uint32_t)dma_ad, &dma_desc->buf);
2273 writel(sts.d32, &dma_desc->status);
2274
2275 sts.b_iso_in.framenum += dwc_ep->bInterval;
2276 (uint32_t)dma_ad += dwc_ep->data_per_frame;
2277 dma_desc ++;
2278 }
2279
2280 sts.b_iso_in.ioc = 1;
2281 sts.b_iso_in.l = dwc_ep->proc_buf_num;
2282
2283 writel((uint32_t)dma_ad, &dma_desc->buf);
2284 writel(sts.d32, &dma_desc->status);
2285
2286 dwc_ep->next_frame = sts.b_iso_in.framenum + dwc_ep->bInterval * 1;
2287 }
2288 dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1;
2289 }
2290
2291
2292 /**
2293 * This function is to handle Iso EP transfer complete interrupt
2294 * in case Iso out packet was dropped
2295 *
2296 * @param core_if Programming view of DWC_otg controller.
2297 * @param dwc_ep The EP for wihich transfer complete was asserted
2298 *
2299 */
2300 static uint32_t handle_iso_out_pkt_dropped(dwc_otg_core_if_t *core_if, dwc_ep_t *dwc_ep)
2301 {
2302 uint32_t dma_addr;
2303 uint32_t drp_pkt;
2304 uint32_t drp_pkt_cnt;
2305 deptsiz_data_t deptsiz = { .d32 = 0 };
2306 depctl_data_t depctl = { .d32 = 0 };
2307 int i;
2308
2309 deptsiz.d32 = dwc_read_reg32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doeptsiz);
2310
2311 drp_pkt = dwc_ep->pkt_cnt - deptsiz.b.pktcnt;
2312 drp_pkt_cnt = dwc_ep->pkt_per_frm - (drp_pkt % dwc_ep->pkt_per_frm);
2313
2314 /* Setting dropped packets status */
2315 for(i = 0; i < drp_pkt_cnt; ++i) {
2316 dwc_ep->pkt_info[drp_pkt].status = -ENODATA;
2317 drp_pkt ++;
2318 deptsiz.b.pktcnt--;
2319 }
2320
2321
2322 if(deptsiz.b.pktcnt > 0) {
2323 deptsiz.b.xfersize = dwc_ep->xfer_len - (dwc_ep->pkt_cnt - deptsiz.b.pktcnt) * dwc_ep->maxpacket;
2324 } else {
2325 deptsiz.b.xfersize = 0;
2326 deptsiz.b.pktcnt = 0;
2327 }
2328
2329 dwc_write_reg32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doeptsiz, deptsiz.d32);
2330
2331 if(deptsiz.b.pktcnt > 0) {
2332 if(dwc_ep->proc_buf_num) {
2333 dma_addr = dwc_ep->dma_addr1 + dwc_ep->xfer_len - deptsiz.b.xfersize;
2334 } else {
2335 dma_addr = dwc_ep->dma_addr0 + dwc_ep->xfer_len - deptsiz.b.xfersize;;
2336 }
2337
2338 dwc_write_reg32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doepdma, dma_addr);
2339
2340 /** Re-enable endpoint, clear nak */
2341 depctl.d32 = 0;
2342 depctl.b.epena = 1;
2343 depctl.b.cnak = 1;
2344
2345 dwc_modify_reg32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doepctl,
2346 depctl.d32,depctl.d32);
2347 return 0;
2348 } else {
2349 return 1;
2350 }
2351 }
2352
2353 /**
2354 * This function sets iso packets information(PTI mode)
2355 *
2356 * @param core_if Programming view of DWC_otg controller.
2357 * @param ep The EP to start the transfer on.
2358 *
2359 */
2360 static uint32_t set_iso_pkts_info(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
2361 {
2362 int i, j;
2363 dma_addr_t dma_ad;
2364 iso_pkt_info_t *packet_info = ep->pkt_info;
2365 uint32_t offset;
2366 uint32_t frame_data;
2367 deptsiz_data_t deptsiz;
2368
2369 if(ep->proc_buf_num == 0) {
2370 /** Buffer 0 descriptors setup */
2371 dma_ad = ep->dma_addr0;
2372 }
2373 else {
2374 /** Buffer 1 descriptors setup */
2375 dma_ad = ep->dma_addr1;
2376 }
2377
2378
2379 if(ep->is_in) {
2380 deptsiz.d32 = dwc_read_reg32(&core_if->dev_if->in_ep_regs[ep->num]->dieptsiz);
2381 } else {
2382 deptsiz.d32 = dwc_read_reg32(&core_if->dev_if->out_ep_regs[ep->num]->doeptsiz);
2383 }
2384
2385 if(!deptsiz.b.xfersize) {
2386 offset = 0;
2387 for(i = 0; i < ep->pkt_cnt; i += ep->pkt_per_frm)
2388 {
2389 frame_data = ep->data_per_frame;
2390 for(j = 0; j < ep->pkt_per_frm; ++j) {
2391
2392 /* Packet status - is not set as initially
2393 * it is set to 0 and if packet was sent
2394 successfully, status field will remain 0*/
2395
2396
2397 /* Bytes has been transfered */
2398 packet_info->length = (ep->maxpacket < frame_data) ?
2399 ep->maxpacket : frame_data;
2400
2401 /* Received packet offset */
2402 packet_info->offset = offset;
2403 offset += packet_info->length;
2404 frame_data -= packet_info->length;
2405
2406 packet_info ++;
2407 }
2408 }
2409 return 1;
2410 } else {
2411 /* This is a workaround for in case of Transfer Complete with
2412 * PktDrpSts interrupts merging - in this case Transfer complete
2413 * interrupt for Isoc Out Endpoint is asserted without PktDrpSts
2414 * set and with DOEPTSIZ register non zero. Investigations showed,
2415 * that this happens when Out packet is dropped, but because of
2416 * interrupts merging during first interrupt handling PktDrpSts
2417 * bit is cleared and for next merged interrupts it is not reset.
2418 * In this case SW hadles the interrupt as if PktDrpSts bit is set.
2419 */
2420 if(ep->is_in) {
2421 return 1;
2422 } else {
2423 return handle_iso_out_pkt_dropped(core_if, ep);
2424 }
2425 }
2426 }
2427
2428 /**
2429 * This function is to handle Iso EP transfer complete interrupt
2430 *
2431 * @param ep The EP for which transfer complete was asserted
2432 *
2433 */
2434 static void complete_iso_ep(dwc_otg_pcd_ep_t *ep)
2435 {
2436 dwc_otg_core_if_t *core_if = GET_CORE_IF(ep->pcd);
2437 dwc_ep_t *dwc_ep = &ep->dwc_ep;
2438 uint8_t is_last = 0;
2439
2440 if(core_if->dma_enable) {
2441 if(core_if->dma_desc_enable) {
2442 set_ddma_iso_pkts_info(core_if, dwc_ep);
2443 reinit_ddma_iso_xfer(core_if, dwc_ep);
2444 is_last = 1;
2445 } else {
2446 if(core_if->pti_enh_enable) {
2447 if(set_iso_pkts_info(core_if, dwc_ep)) {
2448 dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1;
2449 dwc_otg_iso_ep_start_buf_transfer(core_if, dwc_ep);
2450 is_last = 1;
2451 }
2452 } else {
2453 set_current_pkt_info(core_if, dwc_ep);
2454 if(dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
2455 is_last = 1;
2456 dwc_ep->cur_pkt = 0;
2457 dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1;
2458 if(dwc_ep->proc_buf_num) {
2459 dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff1;
2460 dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr1;
2461 } else {
2462 dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff0;
2463 dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr0;
2464 }
2465
2466 }
2467 dwc_otg_iso_ep_start_frm_transfer(core_if, dwc_ep);
2468 }
2469 }
2470 } else {
2471 set_current_pkt_info(core_if, dwc_ep);
2472 if(dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
2473 is_last = 1;
2474 dwc_ep->cur_pkt = 0;
2475 dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1;
2476 if(dwc_ep->proc_buf_num) {
2477 dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff1;
2478 dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr1;
2479 } else {
2480 dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff0;
2481 dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr0;
2482 }
2483
2484 }
2485 dwc_otg_iso_ep_start_frm_transfer(core_if, dwc_ep);
2486 }
2487 if(is_last)
2488 dwc_otg_iso_buffer_done(ep, ep->iso_req);
2489 }
2490
2491 #endif //DWC_EN_ISOC
2492
2493
2494 /**
2495 * This function handles EP0 Control transfers.
2496 *
2497 * The state of the control tranfers are tracked in
2498 * <code>ep0state</code>.
2499 */
2500 static void handle_ep0(dwc_otg_pcd_t *pcd)
2501 {
2502 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
2503 dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
2504 desc_sts_data_t desc_sts;
2505 deptsiz0_data_t deptsiz;
2506 uint32_t byte_count;
2507
2508 #ifdef DEBUG_EP0
2509 DWC_DEBUGPL(DBG_PCDV, "%s()\n", __func__);
2510 print_ep0_state(pcd);
2511 #endif
2512
2513 switch (pcd->ep0state) {
2514 case EP0_DISCONNECT:
2515 break;
2516
2517 case EP0_IDLE:
2518 pcd->request_config = 0;
2519
2520 pcd_setup(pcd);
2521 break;
2522
2523 case EP0_IN_DATA_PHASE:
2524 #ifdef DEBUG_EP0
2525 DWC_DEBUGPL(DBG_PCD, "DATA_IN EP%d-%s: type=%d, mps=%d\n",
2526 ep0->dwc_ep.num, (ep0->dwc_ep.is_in ?"IN":"OUT"),
2527 ep0->dwc_ep.type, ep0->dwc_ep.maxpacket);
2528 #endif
2529
2530 if (core_if->dma_enable != 0) {
2531 /*
2532 * For EP0 we can only program 1 packet at a time so we
2533 * need to do the make calculations after each complete.
2534 * Call write_packet to make the calculations, as in
2535 * slave mode, and use those values to determine if we
2536 * can complete.
2537 */
2538 if(core_if->dma_desc_enable == 0) {
2539 deptsiz.d32 = dwc_read_reg32(&core_if->dev_if->in_ep_regs[0]->dieptsiz);
2540 byte_count = ep0->dwc_ep.xfer_len - deptsiz.b.xfersize;
2541 }
2542 else {
2543 desc_sts.d32 = readl(core_if->dev_if->in_desc_addr);
2544 byte_count = ep0->dwc_ep.xfer_len - desc_sts.b.bytes;
2545 }
2546 ep0->dwc_ep.xfer_count += byte_count;
2547 ep0->dwc_ep.xfer_buff += byte_count;
2548 ep0->dwc_ep.dma_addr += byte_count;
2549 }
2550 if (ep0->dwc_ep.xfer_count < ep0->dwc_ep.total_len) {
2551 dwc_otg_ep0_continue_transfer (GET_CORE_IF(pcd), &ep0->dwc_ep);
2552 DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");
2553 }
2554 else if(ep0->dwc_ep.sent_zlp) {
2555 dwc_otg_ep0_continue_transfer (GET_CORE_IF(pcd), &ep0->dwc_ep);
2556 ep0->dwc_ep.sent_zlp = 0;
2557 DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");
2558 }
2559 else {
2560 ep0_complete_request(ep0);
2561 DWC_DEBUGPL(DBG_PCD, "COMPLETE TRANSFER\n");
2562 }
2563 break;
2564 case EP0_OUT_DATA_PHASE:
2565 #ifdef DEBUG_EP0
2566 DWC_DEBUGPL(DBG_PCD, "DATA_OUT EP%d-%s: type=%d, mps=%d\n",
2567 ep0->dwc_ep.num, (ep0->dwc_ep.is_in ?"IN":"OUT"),
2568 ep0->dwc_ep.type, ep0->dwc_ep.maxpacket);
2569 #endif
2570 if (core_if->dma_enable != 0) {
2571 if(core_if->dma_desc_enable == 0) {
2572 deptsiz.d32 = dwc_read_reg32(&core_if->dev_if->out_ep_regs[0]->doeptsiz);
2573 byte_count = ep0->dwc_ep.maxpacket - deptsiz.b.xfersize;
2574 }
2575 else {
2576 desc_sts.d32 = readl(core_if->dev_if->out_desc_addr);
2577 byte_count = ep0->dwc_ep.maxpacket - desc_sts.b.bytes;
2578 }
2579 ep0->dwc_ep.xfer_count += byte_count;
2580 ep0->dwc_ep.xfer_buff += byte_count;
2581 ep0->dwc_ep.dma_addr += byte_count;
2582 }
2583 if (ep0->dwc_ep.xfer_count < ep0->dwc_ep.total_len) {
2584 dwc_otg_ep0_continue_transfer (GET_CORE_IF(pcd), &ep0->dwc_ep);
2585 DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");
2586 }
2587 else if(ep0->dwc_ep.sent_zlp) {
2588 dwc_otg_ep0_continue_transfer (GET_CORE_IF(pcd), &ep0->dwc_ep);
2589 ep0->dwc_ep.sent_zlp = 0;
2590 DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");
2591 }
2592 else {
2593 ep0_complete_request(ep0);
2594 DWC_DEBUGPL(DBG_PCD, "COMPLETE TRANSFER\n");
2595 }
2596 break;
2597
2598
2599 case EP0_IN_STATUS_PHASE:
2600 case EP0_OUT_STATUS_PHASE:
2601 DWC_DEBUGPL(DBG_PCD, "CASE: EP0_STATUS\n");
2602 ep0_complete_request(ep0);
2603 pcd->ep0state = EP0_IDLE;
2604 ep0->stopped = 1;
2605 ep0->dwc_ep.is_in = 0; /* OUT for next SETUP */
2606
2607 /* Prepare for more SETUP Packets */
2608 if(core_if->dma_enable) {
2609 ep0_out_start(core_if, pcd);
2610 }
2611 break;
2612
2613 case EP0_STALL:
2614 DWC_ERROR("EP0 STALLed, should not get here pcd_setup()\n");
2615 break;
2616 }
2617 #ifdef DEBUG_EP0
2618 print_ep0_state(pcd);
2619 #endif
2620 }
2621
2622
2623 /**
2624 * Restart transfer
2625 */
2626 static void restart_transfer(dwc_otg_pcd_t *pcd, const uint32_t epnum)
2627 {
2628 dwc_otg_core_if_t *core_if;
2629 dwc_otg_dev_if_t *dev_if;
2630 deptsiz_data_t dieptsiz = {.d32=0};
2631 dwc_otg_pcd_ep_t *ep;
2632
2633 ep = get_in_ep(pcd, epnum);
2634
2635 #ifdef DWC_EN_ISOC
2636 if(ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) {
2637 return;
2638 }
2639 #endif /* DWC_EN_ISOC */
2640
2641 core_if = GET_CORE_IF(pcd);
2642 dev_if = core_if->dev_if;
2643
2644 dieptsiz.d32 = dwc_read_reg32(&dev_if->in_ep_regs[epnum]->dieptsiz);
2645
2646 DWC_DEBUGPL(DBG_PCD,"xfer_buff=%p xfer_count=%0x xfer_len=%0x"
2647 " stopped=%d\n", ep->dwc_ep.xfer_buff,
2648 ep->dwc_ep.xfer_count, ep->dwc_ep.xfer_len ,
2649 ep->stopped);
2650 /*
2651 * If xfersize is 0 and pktcnt in not 0, resend the last packet.
2652 */
2653 if (dieptsiz.b.pktcnt && dieptsiz.b.xfersize == 0 &&
2654 ep->dwc_ep.start_xfer_buff != 0) {
2655 if (ep->dwc_ep.total_len <= ep->dwc_ep.maxpacket) {
2656 ep->dwc_ep.xfer_count = 0;
2657 ep->dwc_ep.xfer_buff = ep->dwc_ep.start_xfer_buff;
2658 ep->dwc_ep.xfer_len = ep->dwc_ep.xfer_count;
2659 }
2660 else {
2661 ep->dwc_ep.xfer_count -= ep->dwc_ep.maxpacket;
2662 /* convert packet size to dwords. */
2663 ep->dwc_ep.xfer_buff -= ep->dwc_ep.maxpacket;
2664 ep->dwc_ep.xfer_len = ep->dwc_ep.xfer_count;
2665 }
2666 ep->stopped = 0;
2667 DWC_DEBUGPL(DBG_PCD,"xfer_buff=%p xfer_count=%0x "
2668 "xfer_len=%0x stopped=%d\n",
2669 ep->dwc_ep.xfer_buff,
2670 ep->dwc_ep.xfer_count, ep->dwc_ep.xfer_len ,
2671 ep->stopped
2672 );
2673 if (epnum == 0) {
2674 dwc_otg_ep0_start_transfer(core_if, &ep->dwc_ep);
2675 }
2676 else {
2677 dwc_otg_ep_start_transfer(core_if, &ep->dwc_ep);
2678 }
2679 }
2680 }
2681
2682
2683 /**
2684 * handle the IN EP disable interrupt.
2685 */
2686 static inline void handle_in_ep_disable_intr(dwc_otg_pcd_t *pcd,
2687 const uint32_t epnum)
2688 {
2689 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
2690 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
2691 deptsiz_data_t dieptsiz = {.d32=0};
2692 dctl_data_t dctl = {.d32=0};
2693 dwc_otg_pcd_ep_t *ep;
2694 dwc_ep_t *dwc_ep;
2695
2696 ep = get_in_ep(pcd, epnum);
2697 dwc_ep = &ep->dwc_ep;
2698
2699 if(dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
2700 dwc_otg_flush_tx_fifo(core_if, dwc_ep->tx_fifo_num);
2701 return;
2702 }
2703
2704 DWC_DEBUGPL(DBG_PCD,"diepctl%d=%0x\n", epnum,
2705 dwc_read_reg32(&dev_if->in_ep_regs[epnum]->diepctl));
2706 dieptsiz.d32 = dwc_read_reg32(&dev_if->in_ep_regs[epnum]->dieptsiz);
2707
2708 DWC_DEBUGPL(DBG_ANY, "pktcnt=%d size=%d\n",
2709 dieptsiz.b.pktcnt,
2710 dieptsiz.b.xfersize);
2711
2712 if (ep->stopped) {
2713 /* Flush the Tx FIFO */
2714 dwc_otg_flush_tx_fifo(core_if, dwc_ep->tx_fifo_num);
2715 /* Clear the Global IN NP NAK */
2716 dctl.d32 = 0;
2717 dctl.b.cgnpinnak = 1;
2718 dwc_modify_reg32(&dev_if->dev_global_regs->dctl,
2719 dctl.d32, 0);
2720 /* Restart the transaction */
2721 if (dieptsiz.b.pktcnt != 0 ||
2722 dieptsiz.b.xfersize != 0) {
2723 restart_transfer(pcd, epnum);
2724 }
2725 }
2726 else {
2727 /* Restart the transaction */
2728 if (dieptsiz.b.pktcnt != 0 ||
2729 dieptsiz.b.xfersize != 0) {
2730 restart_transfer(pcd, epnum);
2731 }
2732 DWC_DEBUGPL(DBG_ANY, "STOPPED!!!\n");
2733 }
2734 }
2735
2736 /**
2737 * Handler for the IN EP timeout handshake interrupt.
2738 */
2739 static inline void handle_in_ep_timeout_intr(dwc_otg_pcd_t *pcd,
2740 const uint32_t epnum)
2741 {
2742 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
2743 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
2744
2745 #ifdef DEBUG
2746 deptsiz_data_t dieptsiz = {.d32=0};
2747 uint32_t num = 0;
2748 #endif
2749 dctl_data_t dctl = {.d32=0};
2750 dwc_otg_pcd_ep_t *ep;
2751
2752 gintmsk_data_t intr_mask = {.d32 = 0};
2753
2754 ep = get_in_ep(pcd, epnum);
2755
2756 /* Disable the NP Tx Fifo Empty Interrrupt */
2757 if (!core_if->dma_enable) {
2758 intr_mask.b.nptxfempty = 1;
2759 dwc_modify_reg32(&core_if->core_global_regs->gintmsk, intr_mask.d32, 0);
2760 }
2761 /** @todo NGS Check EP type.
2762 * Implement for Periodic EPs */
2763 /*
2764 * Non-periodic EP
2765 */
2766 /* Enable the Global IN NAK Effective Interrupt */
2767 intr_mask.b.ginnakeff = 1;
2768 dwc_modify_reg32(&core_if->core_global_regs->gintmsk,
2769 0, intr_mask.d32);
2770
2771 /* Set Global IN NAK */
2772 dctl.b.sgnpinnak = 1;
2773 dwc_modify_reg32(&dev_if->dev_global_regs->dctl,
2774 dctl.d32, dctl.d32);
2775
2776 ep->stopped = 1;
2777
2778 #ifdef DEBUG
2779 dieptsiz.d32 = dwc_read_reg32(&dev_if->in_ep_regs[num]->dieptsiz);
2780 DWC_DEBUGPL(DBG_ANY, "pktcnt=%d size=%d\n",
2781 dieptsiz.b.pktcnt,
2782 dieptsiz.b.xfersize);
2783 #endif
2784
2785 #ifdef DISABLE_PERIODIC_EP
2786 /*
2787 * Set the NAK bit for this EP to
2788 * start the disable process.
2789 */
2790 diepctl.d32 = 0;
2791 diepctl.b.snak = 1;
2792 dwc_modify_reg32(&dev_if->in_ep_regs[num]->diepctl, diepctl.d32, diepctl.d32);
2793 ep->disabling = 1;
2794 ep->stopped = 1;
2795 #endif
2796 }
2797
2798 /**
2799 * Handler for the IN EP NAK interrupt.
2800 */
2801 static inline int32_t handle_in_ep_nak_intr(dwc_otg_pcd_t *pcd,
2802 const uint32_t epnum)
2803 {
2804 /** @todo implement ISR */
2805 dwc_otg_core_if_t* core_if;
2806 diepmsk_data_t intr_mask = { .d32 = 0};
2807
2808 DWC_PRINT("INTERRUPT Handler not implemented for %s\n", "IN EP NAK");
2809 core_if = GET_CORE_IF(pcd);
2810 intr_mask.b.nak = 1;
2811
2812 if(core_if->multiproc_int_enable) {
2813 dwc_modify_reg32(&core_if->dev_if->dev_global_regs->diepeachintmsk[epnum],
2814 intr_mask.d32, 0);
2815 } else {
2816 dwc_modify_reg32(&core_if->dev_if->dev_global_regs->diepmsk,
2817 intr_mask.d32, 0);
2818 }
2819
2820 return 1;
2821 }
2822
2823 /**
2824 * Handler for the OUT EP Babble interrupt.
2825 */
2826 static inline int32_t handle_out_ep_babble_intr(dwc_otg_pcd_t *pcd,
2827 const uint32_t epnum)
2828 {
2829 /** @todo implement ISR */
2830 dwc_otg_core_if_t* core_if;
2831 doepmsk_data_t intr_mask = { .d32 = 0};
2832
2833 DWC_PRINT("INTERRUPT Handler not implemented for %s\n", "OUT EP Babble");
2834 core_if = GET_CORE_IF(pcd);
2835 intr_mask.b.babble = 1;
2836
2837 if(core_if->multiproc_int_enable) {
2838 dwc_modify_reg32(&core_if->dev_if->dev_global_regs->doepeachintmsk[epnum],
2839 intr_mask.d32, 0);
2840 } else {
2841 dwc_modify_reg32(&core_if->dev_if->dev_global_regs->doepmsk,
2842 intr_mask.d32, 0);
2843 }
2844
2845 return 1;
2846 }
2847
2848 /**
2849 * Handler for the OUT EP NAK interrupt.
2850 */
2851 static inline int32_t handle_out_ep_nak_intr(dwc_otg_pcd_t *pcd,
2852 const uint32_t epnum)
2853 {
2854 /** @todo implement ISR */
2855 dwc_otg_core_if_t* core_if;
2856 doepmsk_data_t intr_mask = { .d32 = 0};
2857
2858 DWC_PRINT("INTERRUPT Handler not implemented for %s\n", "OUT EP NAK");
2859 core_if = GET_CORE_IF(pcd);
2860 intr_mask.b.nak = 1;
2861
2862 if(core_if->multiproc_int_enable) {
2863 dwc_modify_reg32(&core_if->dev_if->dev_global_regs->doepeachintmsk[epnum],
2864 intr_mask.d32, 0);
2865 } else {
2866 dwc_modify_reg32(&core_if->dev_if->dev_global_regs->doepmsk,
2867 intr_mask.d32, 0);
2868 }
2869
2870 return 1;
2871 }
2872
2873 /**
2874 * Handler for the OUT EP NYET interrupt.
2875 */
2876 static inline int32_t handle_out_ep_nyet_intr(dwc_otg_pcd_t *pcd,
2877 const uint32_t epnum)
2878 {
2879 /** @todo implement ISR */
2880 dwc_otg_core_if_t* core_if;
2881 doepmsk_data_t intr_mask = { .d32 = 0};
2882
2883 DWC_PRINT("INTERRUPT Handler not implemented for %s\n", "OUT EP NYET");
2884 core_if = GET_CORE_IF(pcd);
2885 intr_mask.b.nyet = 1;
2886
2887 if(core_if->multiproc_int_enable) {
2888 dwc_modify_reg32(&core_if->dev_if->dev_global_regs->doepeachintmsk[epnum],
2889 intr_mask.d32, 0);
2890 } else {
2891 dwc_modify_reg32(&core_if->dev_if->dev_global_regs->doepmsk,
2892 intr_mask.d32, 0);
2893 }
2894
2895 return 1;
2896 }
2897
2898 /**
2899 * This interrupt indicates that an IN EP has a pending Interrupt.
2900 * The sequence for handling the IN EP interrupt is shown below:
2901 * -# Read the Device All Endpoint Interrupt register
2902 * -# Repeat the following for each IN EP interrupt bit set (from
2903 * LSB to MSB).
2904 * -# Read the Device Endpoint Interrupt (DIEPINTn) register
2905 * -# If "Transfer Complete" call the request complete function
2906 * -# If "Endpoint Disabled" complete the EP disable procedure.
2907 * -# If "AHB Error Interrupt" log error
2908 * -# If "Time-out Handshake" log error
2909 * -# If "IN Token Received when TxFIFO Empty" write packet to Tx
2910 * FIFO.
2911 * -# If "IN Token EP Mismatch" (disable, this is handled by EP
2912 * Mismatch Interrupt)
2913 */
2914 static int32_t dwc_otg_pcd_handle_in_ep_intr(dwc_otg_pcd_t *pcd)
2915 {
2916 #define CLEAR_IN_EP_INTR(__core_if,__epnum,__intr) \
2917 do { \
2918 diepint_data_t diepint = {.d32=0}; \
2919 diepint.b.__intr = 1; \
2920 dwc_write_reg32(&__core_if->dev_if->in_ep_regs[__epnum]->diepint, \
2921 diepint.d32); \
2922 } while (0)
2923
2924 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
2925 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
2926 diepint_data_t diepint = {.d32=0};
2927 dctl_data_t dctl = {.d32=0};
2928 depctl_data_t depctl = {.d32=0};
2929 uint32_t ep_intr;
2930 uint32_t epnum = 0;
2931 dwc_otg_pcd_ep_t *ep;
2932 dwc_ep_t *dwc_ep;
2933 gintmsk_data_t intr_mask = {.d32 = 0};
2934
2935
2936
2937 DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, pcd);
2938
2939 /* Read in the device interrupt bits */
2940 ep_intr = dwc_otg_read_dev_all_in_ep_intr(core_if);
2941
2942 /* Service the Device IN interrupts for each endpoint */
2943 while(ep_intr) {
2944 if (ep_intr&0x1) {
2945 uint32_t empty_msk;
2946 /* Get EP pointer */
2947 ep = get_in_ep(pcd, epnum);
2948 dwc_ep = &ep->dwc_ep;
2949
2950 depctl.d32 = dwc_read_reg32(&dev_if->in_ep_regs[epnum]->diepctl);
2951 empty_msk = dwc_read_reg32(&dev_if->dev_global_regs->dtknqr4_fifoemptymsk);
2952
2953 DWC_DEBUGPL(DBG_PCDV,
2954 "IN EP INTERRUPT - %d\nepmty_msk - %8x diepctl - %8x\n",
2955 epnum,
2956 empty_msk,
2957 depctl.d32);
2958
2959 DWC_DEBUGPL(DBG_PCD,
2960 "EP%d-%s: type=%d, mps=%d\n",
2961 dwc_ep->num, (dwc_ep->is_in ?"IN":"OUT"),
2962 dwc_ep->type, dwc_ep->maxpacket);
2963
2964 diepint.d32 = dwc_otg_read_dev_in_ep_intr(core_if, dwc_ep);
2965
2966 DWC_DEBUGPL(DBG_PCDV, "EP %d Interrupt Register - 0x%x\n", epnum, diepint.d32);
2967 /* Transfer complete */
2968 if (diepint.b.xfercompl) {
2969 /* Disable the NP Tx FIFO Empty
2970 * Interrrupt */
2971 if(core_if->en_multiple_tx_fifo == 0) {
2972 intr_mask.b.nptxfempty = 1;
2973 dwc_modify_reg32(&core_if->core_global_regs->gintmsk, intr_mask.d32, 0);
2974 }
2975 else {
2976 /* Disable the Tx FIFO Empty Interrupt for this EP */
2977 uint32_t fifoemptymsk = 0x1 << dwc_ep->num;
2978 dwc_modify_reg32(&core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
2979 fifoemptymsk, 0);
2980 }
2981 /* Clear the bit in DIEPINTn for this interrupt */
2982 CLEAR_IN_EP_INTR(core_if,epnum,xfercompl);
2983
2984 /* Complete the transfer */
2985 if (epnum == 0) {
2986 handle_ep0(pcd);
2987 }
2988 #ifdef DWC_EN_ISOC
2989 else if(dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
2990 if(!ep->stopped)
2991 complete_iso_ep(ep);
2992 }
2993 #endif //DWC_EN_ISOC
2994 else {
2995
2996 complete_ep(ep);
2997 }
2998 }
2999 /* Endpoint disable */
3000 if (diepint.b.epdisabled) {
3001 DWC_DEBUGPL(DBG_ANY,"EP%d IN disabled\n", epnum);
3002 handle_in_ep_disable_intr(pcd, epnum);
3003
3004 /* Clear the bit in DIEPINTn for this interrupt */
3005 CLEAR_IN_EP_INTR(core_if,epnum,epdisabled);
3006 }
3007 /* AHB Error */
3008 if (diepint.b.ahberr) {
3009 DWC_DEBUGPL(DBG_ANY,"EP%d IN AHB Error\n", epnum);
3010 /* Clear the bit in DIEPINTn for this interrupt */
3011 CLEAR_IN_EP_INTR(core_if,epnum,ahberr);
3012 }
3013 /* TimeOUT Handshake (non-ISOC IN EPs) */
3014 if (diepint.b.timeout) {
3015 DWC_DEBUGPL(DBG_ANY,"EP%d IN Time-out\n", epnum);
3016 handle_in_ep_timeout_intr(pcd, epnum);
3017
3018 CLEAR_IN_EP_INTR(core_if,epnum,timeout);
3019 }
3020 /** IN Token received with TxF Empty */
3021 if (diepint.b.intktxfemp) {
3022 DWC_DEBUGPL(DBG_ANY,"EP%d IN TKN TxFifo Empty\n",
3023 epnum);
3024 if (!ep->stopped && epnum != 0) {
3025
3026 diepmsk_data_t diepmsk = { .d32 = 0};
3027 diepmsk.b.intktxfemp = 1;
3028
3029 if(core_if->multiproc_int_enable) {
3030 dwc_modify_reg32(&dev_if->dev_global_regs->diepeachintmsk[epnum],
3031 diepmsk.d32, 0);
3032 } else {
3033 dwc_modify_reg32(&dev_if->dev_global_regs->diepmsk, diepmsk.d32, 0);
3034 }
3035 start_next_request(ep);
3036 }
3037 else if(core_if->dma_desc_enable && epnum == 0 &&
3038 pcd->ep0state == EP0_OUT_STATUS_PHASE) {
3039 // EP0 IN set STALL
3040 depctl.d32 = dwc_read_reg32(&dev_if->in_ep_regs[epnum]->diepctl);
3041
3042 /* set the disable and stall bits */
3043 if (depctl.b.epena) {
3044 depctl.b.epdis = 1;
3045 }
3046 depctl.b.stall = 1;
3047 dwc_write_reg32(&dev_if->in_ep_regs[epnum]->diepctl, depctl.d32);
3048 }
3049 CLEAR_IN_EP_INTR(core_if,epnum,intktxfemp);
3050 }
3051 /** IN Token Received with EP mismatch */
3052 if (diepint.b.intknepmis) {
3053 DWC_DEBUGPL(DBG_ANY,"EP%d IN TKN EP Mismatch\n", epnum);
3054 CLEAR_IN_EP_INTR(core_if,epnum,intknepmis);
3055 }
3056 /** IN Endpoint NAK Effective */
3057 if (diepint.b.inepnakeff) {
3058 DWC_DEBUGPL(DBG_ANY,"EP%d IN EP NAK Effective\n", epnum);
3059 /* Periodic EP */
3060 if (ep->disabling) {
3061 depctl.d32 = 0;
3062 depctl.b.snak = 1;
3063 depctl.b.epdis = 1;
3064 dwc_modify_reg32(&dev_if->in_ep_regs[epnum]->diepctl, depctl.d32, depctl.d32);
3065 }
3066 CLEAR_IN_EP_INTR(core_if,epnum,inepnakeff);
3067
3068 }
3069
3070 /** IN EP Tx FIFO Empty Intr */
3071 if (diepint.b.emptyintr) {
3072 DWC_DEBUGPL(DBG_ANY,"EP%d Tx FIFO Empty Intr \n", epnum);
3073 write_empty_tx_fifo(pcd, epnum);
3074
3075 CLEAR_IN_EP_INTR(core_if,epnum,emptyintr);
3076
3077 }
3078
3079 /** IN EP BNA Intr */
3080 if (diepint.b.bna) {
3081 CLEAR_IN_EP_INTR(core_if,epnum,bna);
3082 if(core_if->dma_desc_enable) {
3083 #ifdef DWC_EN_ISOC
3084 if(dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
3085 /*
3086 * This checking is performed to prevent first "false" BNA
3087 * handling occuring right after reconnect
3088 */
3089 if(dwc_ep->next_frame != 0xffffffff)
3090 dwc_otg_pcd_handle_iso_bna(ep);
3091 }
3092 else
3093 #endif //DWC_EN_ISOC
3094 {
3095 dctl.d32 = dwc_read_reg32(&dev_if->dev_global_regs->dctl);
3096
3097 /* If Global Continue on BNA is disabled - disable EP */
3098 if(!dctl.b.gcontbna) {
3099 depctl.d32 = 0;
3100 depctl.b.snak = 1;
3101 depctl.b.epdis = 1;
3102 dwc_modify_reg32(&dev_if->in_ep_regs[epnum]->diepctl, depctl.d32, depctl.d32);
3103 } else {
3104 start_next_request(ep);
3105 }
3106 }
3107 }
3108 }
3109 /* NAK Interrutp */
3110 if (diepint.b.nak) {
3111 DWC_DEBUGPL(DBG_ANY,"EP%d IN NAK Interrupt\n", epnum);
3112 handle_in_ep_nak_intr(pcd, epnum);
3113
3114 CLEAR_IN_EP_INTR(core_if,epnum,nak);
3115 }
3116 }
3117 epnum++;
3118 ep_intr >>=1;
3119 }
3120
3121 return 1;
3122 #undef CLEAR_IN_EP_INTR
3123 }
3124
3125 /**
3126 * This interrupt indicates that an OUT EP has a pending Interrupt.
3127 * The sequence for handling the OUT EP interrupt is shown below:
3128 * -# Read the Device All Endpoint Interrupt register
3129 * -# Repeat the following for each OUT EP interrupt bit set (from
3130 * LSB to MSB).
3131 * -# Read the Device Endpoint Interrupt (DOEPINTn) register
3132 * -# If "Transfer Complete" call the request complete function
3133 * -# If "Endpoint Disabled" complete the EP disable procedure.
3134 * -# If "AHB Error Interrupt" log error
3135 * -# If "Setup Phase Done" process Setup Packet (See Standard USB
3136 * Command Processing)
3137 */
3138 static int32_t dwc_otg_pcd_handle_out_ep_intr(dwc_otg_pcd_t *pcd)
3139 {
3140 #define CLEAR_OUT_EP_INTR(__core_if,__epnum,__intr) \
3141 do { \
3142 doepint_data_t doepint = {.d32=0}; \
3143 doepint.b.__intr = 1; \
3144 dwc_write_reg32(&__core_if->dev_if->out_ep_regs[__epnum]->doepint, \
3145 doepint.d32); \
3146 } while (0)
3147
3148 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
3149 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
3150 uint32_t ep_intr;
3151 doepint_data_t doepint = {.d32=0};
3152 dctl_data_t dctl = {.d32=0};
3153 depctl_data_t doepctl = {.d32=0};
3154 uint32_t epnum = 0;
3155 dwc_otg_pcd_ep_t *ep;
3156 dwc_ep_t *dwc_ep;
3157
3158 DWC_DEBUGPL(DBG_PCDV, "%s()\n", __func__);
3159
3160 /* Read in the device interrupt bits */
3161 ep_intr = dwc_otg_read_dev_all_out_ep_intr(core_if);
3162
3163 while(ep_intr) {
3164 if (ep_intr&0x1) {
3165 /* Get EP pointer */
3166 ep = get_out_ep(pcd, epnum);
3167 dwc_ep = &ep->dwc_ep;
3168
3169 #ifdef VERBOSE
3170 DWC_DEBUGPL(DBG_PCDV,
3171 "EP%d-%s: type=%d, mps=%d\n",
3172 dwc_ep->num, (dwc_ep->is_in ?"IN":"OUT"),
3173 dwc_ep->type, dwc_ep->maxpacket);
3174 #endif
3175 doepint.d32 = dwc_otg_read_dev_out_ep_intr(core_if, dwc_ep);
3176
3177 /* Transfer complete */
3178 if (doepint.b.xfercompl) {
3179
3180 if (epnum == 0) {
3181 /* Clear the bit in DOEPINTn for this interrupt */
3182 CLEAR_OUT_EP_INTR(core_if,epnum,xfercompl);
3183 if(core_if->dma_desc_enable == 0 || pcd->ep0state != EP0_IDLE)
3184 handle_ep0(pcd);
3185 #ifdef DWC_EN_ISOC
3186 } else if(dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
3187 if (doepint.b.pktdrpsts == 0) {
3188 /* Clear the bit in DOEPINTn for this interrupt */
3189 CLEAR_OUT_EP_INTR(core_if,epnum,xfercompl);
3190 complete_iso_ep(ep);
3191 } else {
3192
3193 doepint_data_t doepint = {.d32=0};
3194 doepint.b.xfercompl = 1;
3195 doepint.b.pktdrpsts = 1;
3196 dwc_write_reg32(&core_if->dev_if->out_ep_regs[epnum]->doepint,
3197 doepint.d32);
3198 if(handle_iso_out_pkt_dropped(core_if,dwc_ep)) {
3199 complete_iso_ep(ep);
3200 }
3201 }
3202 #endif //DWC_EN_ISOC
3203 } else {
3204 /* Clear the bit in DOEPINTn for this interrupt */
3205 CLEAR_OUT_EP_INTR(core_if,epnum,xfercompl);
3206 complete_ep(ep);
3207 }
3208
3209 }
3210
3211 /* Endpoint disable */
3212 if (doepint.b.epdisabled) {
3213
3214 /* Clear the bit in DOEPINTn for this interrupt */
3215 CLEAR_OUT_EP_INTR(core_if,epnum,epdisabled);
3216 }
3217 /* AHB Error */
3218 if (doepint.b.ahberr) {
3219 DWC_DEBUGPL(DBG_PCD,"EP%d OUT AHB Error\n", epnum);
3220 DWC_DEBUGPL(DBG_PCD,"EP DMA REG %d \n", core_if->dev_if->out_ep_regs[epnum]->doepdma);
3221 CLEAR_OUT_EP_INTR(core_if,epnum,ahberr);
3222 }
3223 /* Setup Phase Done (contorl EPs) */
3224 if (doepint.b.setup) {
3225 #ifdef DEBUG_EP0
3226 DWC_DEBUGPL(DBG_PCD,"EP%d SETUP Done\n",
3227 epnum);
3228 #endif
3229 CLEAR_OUT_EP_INTR(core_if,epnum,setup);
3230
3231 handle_ep0(pcd);
3232 }
3233
3234 /** OUT EP BNA Intr */
3235 if (doepint.b.bna) {
3236 CLEAR_OUT_EP_INTR(core_if,epnum,bna);
3237 if(core_if->dma_desc_enable) {
3238 #ifdef DWC_EN_ISOC
3239 if(dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
3240 /*
3241 * This checking is performed to prevent first "false" BNA
3242 * handling occuring right after reconnect
3243 */
3244 if(dwc_ep->next_frame != 0xffffffff)
3245 dwc_otg_pcd_handle_iso_bna(ep);
3246 }
3247 else
3248 #endif //DWC_EN_ISOC
3249 {
3250 dctl.d32 = dwc_read_reg32(&dev_if->dev_global_regs->dctl);
3251
3252 /* If Global Continue on BNA is disabled - disable EP*/
3253 if(!dctl.b.gcontbna) {
3254 doepctl.d32 = 0;
3255 doepctl.b.snak = 1;
3256 doepctl.b.epdis = 1;
3257 dwc_modify_reg32(&dev_if->out_ep_regs[epnum]->doepctl, doepctl.d32, doepctl.d32);
3258 } else {
3259 start_next_request(ep);
3260 }
3261 }
3262 }
3263 }
3264 if (doepint.b.stsphsercvd) {
3265 CLEAR_OUT_EP_INTR(core_if,epnum,stsphsercvd);
3266 if(core_if->dma_desc_enable) {
3267 do_setup_in_status_phase(pcd);
3268 }
3269 }
3270 /* Babble Interrutp */
3271 if (doepint.b.babble) {
3272 DWC_DEBUGPL(DBG_ANY,"EP%d OUT Babble\n", epnum);
3273 handle_out_ep_babble_intr(pcd, epnum);
3274
3275 CLEAR_OUT_EP_INTR(core_if,epnum,babble);
3276 }
3277 /* NAK Interrutp */
3278 if (doepint.b.nak) {
3279 DWC_DEBUGPL(DBG_ANY,"EP%d OUT NAK\n", epnum);
3280 handle_out_ep_nak_intr(pcd, epnum);
3281
3282 CLEAR_OUT_EP_INTR(core_if,epnum,nak);
3283 }
3284 /* NYET Interrutp */
3285 if (doepint.b.nyet) {
3286 DWC_DEBUGPL(DBG_ANY,"EP%d OUT NYET\n", epnum);
3287 handle_out_ep_nyet_intr(pcd, epnum);
3288
3289 CLEAR_OUT_EP_INTR(core_if,epnum,nyet);
3290 }
3291 }
3292
3293 epnum++;
3294 ep_intr >>=1;
3295 }
3296
3297 return 1;
3298
3299 #undef CLEAR_OUT_EP_INTR
3300 }
3301
3302
3303 /**
3304 * Incomplete ISO IN Transfer Interrupt.
3305 * This interrupt indicates one of the following conditions occurred
3306 * while transmitting an ISOC transaction.
3307 * - Corrupted IN Token for ISOC EP.
3308 * - Packet not complete in FIFO.
3309 * The follow actions will be taken:
3310 * -# Determine the EP
3311 * -# Set incomplete flag in dwc_ep structure
3312 * -# Disable EP; when "Endpoint Disabled" interrupt is received
3313 * Flush FIFO
3314 */
3315 int32_t dwc_otg_pcd_handle_incomplete_isoc_in_intr(dwc_otg_pcd_t *pcd)
3316 {
3317 gintsts_data_t gintsts;
3318
3319
3320 #ifdef DWC_EN_ISOC
3321 dwc_otg_dev_if_t *dev_if;
3322 deptsiz_data_t deptsiz = { .d32 = 0};
3323 depctl_data_t depctl = { .d32 = 0};
3324 dsts_data_t dsts = { .d32 = 0};
3325 dwc_ep_t *dwc_ep;
3326 int i;
3327
3328 dev_if = GET_CORE_IF(pcd)->dev_if;
3329
3330 for(i = 1; i <= dev_if->num_in_eps; ++i) {
3331 dwc_ep = &pcd->in_ep[i].dwc_ep;
3332 if(dwc_ep->active &&
3333 dwc_ep->type == USB_ENDPOINT_XFER_ISOC)
3334 {
3335 deptsiz.d32 = dwc_read_reg32(&dev_if->in_ep_regs[i]->dieptsiz);
3336 depctl.d32 = dwc_read_reg32(&dev_if->in_ep_regs[i]->diepctl);
3337
3338 if(depctl.b.epdis && deptsiz.d32) {
3339 set_current_pkt_info(GET_CORE_IF(pcd), dwc_ep);
3340 if(dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
3341 dwc_ep->cur_pkt = 0;
3342 dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1;
3343
3344 if(dwc_ep->proc_buf_num) {
3345 dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff1;
3346 dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr1;
3347 } else {
3348 dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff0;
3349 dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr0;
3350 }
3351
3352 }
3353
3354 dsts.d32 = dwc_read_reg32(&GET_CORE_IF(pcd)->dev_if->dev_global_regs->dsts);
3355 dwc_ep->next_frame = dsts.b.soffn;
3356
3357 dwc_otg_iso_ep_start_frm_transfer(GET_CORE_IF(pcd), dwc_ep);
3358 }
3359 }
3360 }
3361
3362 #else
3363 gintmsk_data_t intr_mask = { .d32 = 0};
3364 DWC_PRINT("INTERRUPT Handler not implemented for %s\n",
3365 "IN ISOC Incomplete");
3366
3367 intr_mask.b.incomplisoin = 1;
3368 dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
3369 intr_mask.d32, 0);
3370 #endif //DWC_EN_ISOC
3371
3372 /* Clear interrupt */
3373 gintsts.d32 = 0;
3374 gintsts.b.incomplisoin = 1;
3375 dwc_write_reg32 (&GET_CORE_IF(pcd)->core_global_regs->gintsts,
3376 gintsts.d32);
3377
3378 return 1;
3379 }
3380
3381 /**
3382 * Incomplete ISO OUT Transfer Interrupt.
3383 *
3384 * This interrupt indicates that the core has dropped an ISO OUT
3385 * packet. The following conditions can be the cause:
3386 * - FIFO Full, the entire packet would not fit in the FIFO.
3387 * - CRC Error
3388 * - Corrupted Token
3389 * The follow actions will be taken:
3390 * -# Determine the EP
3391 * -# Set incomplete flag in dwc_ep structure
3392 * -# Read any data from the FIFO
3393 * -# Disable EP. when "Endpoint Disabled" interrupt is received
3394 * re-enable EP.
3395 */
3396 int32_t dwc_otg_pcd_handle_incomplete_isoc_out_intr(dwc_otg_pcd_t *pcd)
3397 {
3398 /* @todo implement ISR */
3399 gintsts_data_t gintsts;
3400
3401 #ifdef DWC_EN_ISOC
3402 dwc_otg_dev_if_t *dev_if;
3403 deptsiz_data_t deptsiz = { .d32 = 0};
3404 depctl_data_t depctl = { .d32 = 0};
3405 dsts_data_t dsts = { .d32 = 0};
3406 dwc_ep_t *dwc_ep;
3407 int i;
3408
3409 dev_if = GET_CORE_IF(pcd)->dev_if;
3410
3411 for(i = 1; i <= dev_if->num_out_eps; ++i) {
3412 dwc_ep = &pcd->in_ep[i].dwc_ep;
3413 if(pcd->out_ep[i].dwc_ep.active &&
3414 pcd->out_ep[i].dwc_ep.type == USB_ENDPOINT_XFER_ISOC)
3415 {
3416 deptsiz.d32 = dwc_read_reg32(&dev_if->out_ep_regs[i]->doeptsiz);
3417 depctl.d32 = dwc_read_reg32(&dev_if->out_ep_regs[i]->doepctl);
3418
3419 if(depctl.b.epdis && deptsiz.d32) {
3420 set_current_pkt_info(GET_CORE_IF(pcd), &pcd->out_ep[i].dwc_ep);
3421 if(dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
3422 dwc_ep->cur_pkt = 0;
3423 dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1;
3424
3425 if(dwc_ep->proc_buf_num) {
3426 dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff1;
3427 dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr1;
3428 } else {
3429 dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff0;
3430 dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr0;
3431 }
3432
3433 }
3434
3435 dsts.d32 = dwc_read_reg32(&GET_CORE_IF(pcd)->dev_if->dev_global_regs->dsts);
3436 dwc_ep->next_frame = dsts.b.soffn;
3437
3438 dwc_otg_iso_ep_start_frm_transfer(GET_CORE_IF(pcd), dwc_ep);
3439 }
3440 }
3441 }
3442 #else
3443 /** @todo implement ISR */
3444 gintmsk_data_t intr_mask = { .d32 = 0};
3445
3446 DWC_PRINT("INTERRUPT Handler not implemented for %s\n",
3447 "OUT ISOC Incomplete");
3448
3449 intr_mask.b.incomplisoout = 1;
3450 dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
3451 intr_mask.d32, 0);
3452
3453 #endif // DWC_EN_ISOC
3454
3455 /* Clear interrupt */
3456 gintsts.d32 = 0;
3457 gintsts.b.incomplisoout = 1;
3458 dwc_write_reg32 (&GET_CORE_IF(pcd)->core_global_regs->gintsts,
3459 gintsts.d32);
3460
3461 return 1;
3462 }
3463
3464 /**
3465 * This function handles the Global IN NAK Effective interrupt.
3466 *
3467 */
3468 int32_t dwc_otg_pcd_handle_in_nak_effective(dwc_otg_pcd_t *pcd)
3469 {
3470 dwc_otg_dev_if_t *dev_if = GET_CORE_IF(pcd)->dev_if;
3471 depctl_data_t diepctl = { .d32 = 0};
3472 depctl_data_t diepctl_rd = { .d32 = 0};
3473 gintmsk_data_t intr_mask = { .d32 = 0};
3474 gintsts_data_t gintsts;
3475 int i;
3476
3477 DWC_DEBUGPL(DBG_PCD, "Global IN NAK Effective\n");
3478
3479 /* Disable all active IN EPs */
3480 diepctl.b.epdis = 1;
3481 diepctl.b.snak = 1;
3482
3483 for (i=0; i <= dev_if->num_in_eps; i++)
3484 {
3485 diepctl_rd.d32 = dwc_read_reg32(&dev_if->in_ep_regs[i]->diepctl);
3486 if (diepctl_rd.b.epena) {
3487 dwc_write_reg32(&dev_if->in_ep_regs[i]->diepctl,
3488 diepctl.d32);
3489 }
3490 }
3491 /* Disable the Global IN NAK Effective Interrupt */
3492 intr_mask.b.ginnakeff = 1;
3493 dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
3494 intr_mask.d32, 0);
3495
3496 /* Clear interrupt */
3497 gintsts.d32 = 0;
3498 gintsts.b.ginnakeff = 1;
3499 dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
3500 gintsts.d32);
3501
3502 return 1;
3503 }
3504
3505 /**
3506 * OUT NAK Effective.
3507 *
3508 */
3509 int32_t dwc_otg_pcd_handle_out_nak_effective(dwc_otg_pcd_t *pcd)
3510 {
3511 gintmsk_data_t intr_mask = { .d32 = 0};
3512 gintsts_data_t gintsts;
3513
3514 DWC_PRINT("INTERRUPT Handler not implemented for %s\n",
3515 "Global IN NAK Effective\n");
3516 /* Disable the Global IN NAK Effective Interrupt */
3517 intr_mask.b.goutnakeff = 1;
3518 dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
3519 intr_mask.d32, 0);
3520
3521 /* Clear interrupt */
3522 gintsts.d32 = 0;
3523 gintsts.b.goutnakeff = 1;
3524 dwc_write_reg32 (&GET_CORE_IF(pcd)->core_global_regs->gintsts,
3525 gintsts.d32);
3526
3527 return 1;
3528 }
3529
3530
3531 /**
3532 * PCD interrupt handler.
3533 *
3534 * The PCD handles the device interrupts. Many conditions can cause a
3535 * device interrupt. When an interrupt occurs, the device interrupt
3536 * service routine determines the cause of the interrupt and
3537 * dispatches handling to the appropriate function. These interrupt
3538 * handling functions are described below.
3539 *
3540 * All interrupt registers are processed from LSB to MSB.
3541 *
3542 */
3543 int32_t dwc_otg_pcd_handle_intr(dwc_otg_pcd_t *pcd)
3544 {
3545 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
3546 #ifdef VERBOSE
3547 dwc_otg_core_global_regs_t *global_regs =
3548 core_if->core_global_regs;
3549 #endif
3550 gintsts_data_t gintr_status;
3551 int32_t retval = 0;
3552
3553
3554 #ifdef VERBOSE
3555 DWC_DEBUGPL(DBG_ANY, "%s() gintsts=%08x gintmsk=%08x\n",
3556 __func__,
3557 dwc_read_reg32(&global_regs->gintsts),
3558 dwc_read_reg32(&global_regs->gintmsk));
3559 #endif
3560
3561 if (dwc_otg_is_device_mode(core_if)) {
3562 SPIN_LOCK(&pcd->lock);
3563 #ifdef VERBOSE
3564 DWC_DEBUGPL(DBG_PCDV, "%s() gintsts=%08x gintmsk=%08x\n",
3565 __func__,
3566 dwc_read_reg32(&global_regs->gintsts),
3567 dwc_read_reg32(&global_regs->gintmsk));
3568 #endif
3569
3570 gintr_status.d32 = dwc_otg_read_core_intr(core_if);
3571
3572 /*
3573 if (!gintr_status.d32) {
3574 SPIN_UNLOCK(&pcd->lock);
3575 return 0;
3576 }
3577 */
3578 DWC_DEBUGPL(DBG_PCDV, "%s: gintsts&gintmsk=%08x\n",
3579 __func__, gintr_status.d32);
3580
3581 if (gintr_status.b.sofintr) {
3582 retval |= dwc_otg_pcd_handle_sof_intr(pcd);
3583 }
3584 if (gintr_status.b.rxstsqlvl) {
3585 retval |= dwc_otg_pcd_handle_rx_status_q_level_intr(pcd);
3586 }
3587 if (gintr_status.b.nptxfempty) {
3588 retval |= dwc_otg_pcd_handle_np_tx_fifo_empty_intr(pcd);
3589 }
3590 if (gintr_status.b.ginnakeff) {
3591 retval |= dwc_otg_pcd_handle_in_nak_effective(pcd);
3592 }
3593 if (gintr_status.b.goutnakeff) {
3594 retval |= dwc_otg_pcd_handle_out_nak_effective(pcd);
3595 }
3596 if (gintr_status.b.i2cintr) {
3597 retval |= dwc_otg_pcd_handle_i2c_intr(pcd);
3598 }
3599 if (gintr_status.b.erlysuspend) {
3600 retval |= dwc_otg_pcd_handle_early_suspend_intr(pcd);
3601 }
3602 if (gintr_status.b.usbreset) {
3603 retval |= dwc_otg_pcd_handle_usb_reset_intr(pcd);
3604 }
3605 if (gintr_status.b.enumdone) {
3606 retval |= dwc_otg_pcd_handle_enum_done_intr(pcd);
3607 }
3608 if (gintr_status.b.isooutdrop) {
3609 retval |= dwc_otg_pcd_handle_isoc_out_packet_dropped_intr(pcd);
3610 }
3611 if (gintr_status.b.eopframe) {
3612 retval |= dwc_otg_pcd_handle_end_periodic_frame_intr(pcd);
3613 }
3614 if (gintr_status.b.epmismatch) {
3615 retval |= dwc_otg_pcd_handle_ep_mismatch_intr(core_if);
3616 }
3617 if (gintr_status.b.inepint) {
3618 if(!core_if->multiproc_int_enable) {
3619 retval |= dwc_otg_pcd_handle_in_ep_intr(pcd);
3620 }
3621 }
3622 if (gintr_status.b.outepintr) {
3623 if(!core_if->multiproc_int_enable) {
3624 retval |= dwc_otg_pcd_handle_out_ep_intr(pcd);
3625 }
3626 }
3627 if (gintr_status.b.incomplisoin) {
3628 retval |= dwc_otg_pcd_handle_incomplete_isoc_in_intr(pcd);
3629 }
3630 if (gintr_status.b.incomplisoout) {
3631 retval |= dwc_otg_pcd_handle_incomplete_isoc_out_intr(pcd);
3632 }
3633
3634 /* In MPI mode De vice Endpoints intterrupts are asserted
3635 * without setting outepintr and inepint bits set, so these
3636 * Interrupt handlers are called without checking these bit-fields
3637 */
3638 if(core_if->multiproc_int_enable) {
3639 retval |= dwc_otg_pcd_handle_in_ep_intr(pcd);
3640 retval |= dwc_otg_pcd_handle_out_ep_intr(pcd);
3641 }
3642 #ifdef VERBOSE
3643 DWC_DEBUGPL(DBG_PCDV, "%s() gintsts=%0x\n", __func__,
3644 dwc_read_reg32(&global_regs->gintsts));
3645 #endif
3646 SPIN_UNLOCK(&pcd->lock);
3647 }
3648
3649 S3C2410X_CLEAR_EINTPEND();
3650
3651 return retval;
3652 }
3653
3654 #endif /* DWC_HOST_ONLY */