00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef DWC_HOST_ONLY
00034
00035 #include "dwc_otg_pcd.h"
00036
00037 #ifdef DWC_UTE_CFI
00038 #include "dwc_otg_cfi.h"
00039 #endif
00040
00041 #ifdef DWC_UTE_PER_IO
00042 extern void complete_xiso_ep(dwc_otg_pcd_ep_t * ep);
00043 #endif
00044
00045
00046 #define DEBUG_EP0
00047
00051 static void dwc_otg_pcd_update_otg(dwc_otg_pcd_t * pcd, const unsigned reset)
00052 {
00053
00054 if (reset) {
00055 pcd->b_hnp_enable = 0;
00056 pcd->a_hnp_support = 0;
00057 pcd->a_alt_hnp_support = 0;
00058 }
00059
00060 if (pcd->fops->hnp_changed) {
00061 pcd->fops->hnp_changed(pcd);
00062 }
00063 }
00064
00079 static inline void print_ep0_state(dwc_otg_pcd_t * pcd)
00080 {
00081 #ifdef DEBUG
00082 char str[40];
00083
00084 switch (pcd->ep0state) {
00085 case EP0_DISCONNECT:
00086 dwc_strcpy(str, "EP0_DISCONNECT");
00087 break;
00088 case EP0_IDLE:
00089 dwc_strcpy(str, "EP0_IDLE");
00090 break;
00091 case EP0_IN_DATA_PHASE:
00092 dwc_strcpy(str, "EP0_IN_DATA_PHASE");
00093 break;
00094 case EP0_OUT_DATA_PHASE:
00095 dwc_strcpy(str, "EP0_OUT_DATA_PHASE");
00096 break;
00097 case EP0_IN_STATUS_PHASE:
00098 dwc_strcpy(str, "EP0_IN_STATUS_PHASE");
00099 break;
00100 case EP0_OUT_STATUS_PHASE:
00101 dwc_strcpy(str, "EP0_OUT_STATUS_PHASE");
00102 break;
00103 case EP0_STALL:
00104 dwc_strcpy(str, "EP0_STALL");
00105 break;
00106 default:
00107 dwc_strcpy(str, "EP0_INVALID");
00108 }
00109
00110 DWC_DEBUGPL(DBG_ANY, "%s(%d)\n", str, pcd->ep0state);
00111 #endif
00112 }
00113
00119 static inline void print_memory_payload(dwc_otg_pcd_t * pcd, dwc_ep_t * ep)
00120 {
00121 #ifdef DEBUG
00122 deptsiz_data_t deptsiz_init = {.d32 = 0 };
00123 deptsiz_data_t deptsiz_updt = {.d32 = 0 };
00124 int pack_num;
00125 unsigned payload;
00126
00127 deptsiz_init.d32 = pcd->core_if->start_doeptsiz_val[ep->num];
00128 deptsiz_updt.d32 =
00129 DWC_READ_REG32(&pcd->core_if->dev_if->
00130 out_ep_regs[ep->num]->doeptsiz);
00131
00132 payload = deptsiz_init.b.xfersize - deptsiz_updt.b.xfersize;
00133
00134
00135
00136 pack_num = (!payload) ? 0 : (deptsiz_init.b.pktcnt - deptsiz_updt.b.pktcnt);
00137 DWC_DEBUGPL(DBG_PCDV,
00138 "Payload for EP%d-%s\n",
00139 ep->num, (ep->is_in ? "IN" : "OUT"));
00140 DWC_DEBUGPL(DBG_PCDV,
00141 "Number of transfered bytes = 0x%08x\n", payload);
00142 DWC_DEBUGPL(DBG_PCDV,
00143 "Number of transfered packets = %d\n", pack_num);
00144 #endif
00145 }
00146
00147
00148 #ifdef DWC_UTE_CFI
00149 static inline void print_desc(struct dwc_otg_dma_desc *ddesc,
00150 const uint8_t * epname, int descnum)
00151 {
00152 CFI_INFO
00153 ("%s DMA_DESC(%d) buf=0x%08x bytes=0x%04x; sp=0x%x; l=0x%x; sts=0x%02x; bs=0x%02x\n",
00154 epname, descnum, ddesc->buf, ddesc->status.b.bytes,
00155 ddesc->status.b.sp, ddesc->status.b.l, ddesc->status.b.sts,
00156 ddesc->status.b.bs);
00157 }
00158 #endif
00159
00163 static inline dwc_otg_pcd_ep_t *get_in_ep(dwc_otg_pcd_t * pcd, uint32_t ep_num)
00164 {
00165 int i;
00166 int num_in_eps = GET_CORE_IF(pcd)->dev_if->num_in_eps;
00167 if (ep_num == 0) {
00168 return &pcd->ep0;
00169 } else {
00170 for (i = 0; i < num_in_eps; ++i) {
00171 if (pcd->in_ep[i].dwc_ep.num == ep_num)
00172 return &pcd->in_ep[i];
00173 }
00174 return 0;
00175 }
00176 }
00177
00181 static inline dwc_otg_pcd_ep_t *get_out_ep(dwc_otg_pcd_t * pcd, uint32_t ep_num)
00182 {
00183 int i;
00184 int num_out_eps = GET_CORE_IF(pcd)->dev_if->num_out_eps;
00185 if (ep_num == 0) {
00186 return &pcd->ep0;
00187 } else {
00188 for (i = 0; i < num_out_eps; ++i) {
00189 if (pcd->out_ep[i].dwc_ep.num == ep_num)
00190 return &pcd->out_ep[i];
00191 }
00192 return 0;
00193 }
00194 }
00195
00200 dwc_otg_pcd_ep_t *get_ep_by_addr(dwc_otg_pcd_t * pcd, u16 wIndex)
00201 {
00202 dwc_otg_pcd_ep_t *ep;
00203 uint32_t ep_num = UE_GET_ADDR(wIndex);
00204
00205 if (ep_num == 0) {
00206 ep = &pcd->ep0;
00207 } else if (UE_GET_DIR(wIndex) == UE_DIR_IN) {
00208 ep = &pcd->in_ep[ep_num - 1];
00209 } else {
00210 ep = &pcd->out_ep[ep_num - 1];
00211 }
00212
00213 return ep;
00214 }
00215
00220 void start_next_request(dwc_otg_pcd_ep_t * ep)
00221 {
00222 dwc_otg_pcd_request_t *req = 0;
00223 uint32_t max_transfer =
00224 GET_CORE_IF(ep->pcd)->core_params->max_transfer_size;
00225
00226 #ifdef DWC_UTE_CFI
00227 struct dwc_otg_pcd *pcd;
00228 pcd = ep->pcd;
00229 #endif
00230
00231 if (!DWC_CIRCLEQ_EMPTY(&ep->queue)) {
00232 req = DWC_CIRCLEQ_FIRST(&ep->queue);
00233
00234 #ifdef DWC_UTE_CFI
00235 if (ep->dwc_ep.buff_mode != BM_STANDARD) {
00236 ep->dwc_ep.cfi_req_len = req->length;
00237 pcd->cfi->ops.build_descriptors(pcd->cfi, pcd, ep, req);
00238 } else {
00239 #endif
00240
00241 if (req->dw_align_buf) {
00242 ep->dwc_ep.dma_addr = req->dw_align_buf_dma;
00243 ep->dwc_ep.start_xfer_buff = req->dw_align_buf;
00244 ep->dwc_ep.xfer_buff = req->dw_align_buf;
00245 } else {
00246 ep->dwc_ep.dma_addr = req->dma;
00247 ep->dwc_ep.start_xfer_buff = req->buf;
00248 ep->dwc_ep.xfer_buff = req->buf;
00249 }
00250 ep->dwc_ep.sent_zlp = 0;
00251 ep->dwc_ep.total_len = req->length;
00252 ep->dwc_ep.xfer_len = 0;
00253 ep->dwc_ep.xfer_count = 0;
00254
00255 ep->dwc_ep.maxxfer = max_transfer;
00256 if (GET_CORE_IF(ep->pcd)->dma_desc_enable) {
00257 uint32_t out_max_xfer = DDMA_MAX_TRANSFER_SIZE
00258 - (DDMA_MAX_TRANSFER_SIZE % 4);
00259 if (ep->dwc_ep.is_in) {
00260 if (ep->dwc_ep.maxxfer >
00261 DDMA_MAX_TRANSFER_SIZE) {
00262 ep->dwc_ep.maxxfer =
00263 DDMA_MAX_TRANSFER_SIZE;
00264 }
00265 } else {
00266 if (ep->dwc_ep.maxxfer > out_max_xfer) {
00267 ep->dwc_ep.maxxfer =
00268 out_max_xfer;
00269 }
00270 }
00271 }
00272 if (ep->dwc_ep.maxxfer < ep->dwc_ep.total_len) {
00273 ep->dwc_ep.maxxfer -=
00274 (ep->dwc_ep.maxxfer % ep->dwc_ep.maxpacket);
00275 }
00276 if (req->sent_zlp) {
00277 if ((ep->dwc_ep.total_len %
00278 ep->dwc_ep.maxpacket == 0)
00279 && (ep->dwc_ep.total_len != 0)) {
00280 ep->dwc_ep.sent_zlp = 1;
00281 }
00282
00283 }
00284 #ifdef DWC_UTE_CFI
00285 }
00286 #endif
00287 dwc_otg_ep_start_transfer(GET_CORE_IF(ep->pcd), &ep->dwc_ep);
00288 } else if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) {
00289 DWC_PRINTF("There are no more ISOC requests \n");
00290 ep->dwc_ep.frame_num = 0xFFFFFFFF;
00291 }
00292 }
00293
00298 int32_t dwc_otg_pcd_handle_sof_intr(dwc_otg_pcd_t * pcd)
00299 {
00300 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
00301
00302 gintsts_data_t gintsts;
00303
00304 DWC_DEBUGPL(DBG_PCD, "SOF\n");
00305
00306
00307 gintsts.d32 = 0;
00308 gintsts.b.sofintr = 1;
00309 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
00310
00311 return 1;
00312 }
00313
00331 int32_t dwc_otg_pcd_handle_rx_status_q_level_intr(dwc_otg_pcd_t * pcd)
00332 {
00333 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
00334 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
00335 gintmsk_data_t gintmask = {.d32 = 0 };
00336 device_grxsts_data_t status;
00337 dwc_otg_pcd_ep_t *ep;
00338 gintsts_data_t gintsts;
00339 #ifdef DEBUG
00340 static char *dpid_str[] = { "D0", "D2", "D1", "MDATA" };
00341 #endif
00342
00343
00344
00345 gintmask.b.rxstsqlvl = 1;
00346 DWC_MODIFY_REG32(&global_regs->gintmsk, gintmask.d32, 0);
00347
00348
00349 status.d32 = DWC_READ_REG32(&global_regs->grxstsp);
00350
00351 DWC_DEBUGPL(DBG_PCD, "EP:%d BCnt:%d DPID:%s "
00352 "pktsts:%x Frame:%d(0x%0x)\n",
00353 status.b.epnum, status.b.bcnt,
00354 dpid_str[status.b.dpid],
00355 status.b.pktsts, status.b.fn, status.b.fn);
00356
00357 ep = get_out_ep(pcd, status.b.epnum);
00358
00359 switch (status.b.pktsts) {
00360 case DWC_DSTS_GOUT_NAK:
00361 DWC_DEBUGPL(DBG_PCDV, "Global OUT NAK\n");
00362 break;
00363 case DWC_STS_DATA_UPDT:
00364 DWC_DEBUGPL(DBG_PCDV, "OUT Data Packet\n");
00365 if (status.b.bcnt && ep->dwc_ep.xfer_buff) {
00367 dwc_otg_read_packet(core_if,
00368 ep->dwc_ep.xfer_buff,
00369 status.b.bcnt);
00370 ep->dwc_ep.xfer_count += status.b.bcnt;
00371 ep->dwc_ep.xfer_buff += status.b.bcnt;
00372 }
00373 break;
00374 case DWC_STS_XFER_COMP:
00375 DWC_DEBUGPL(DBG_PCDV, "OUT Complete\n");
00376 break;
00377 case DWC_DSTS_SETUP_COMP:
00378 #ifdef DEBUG_EP0
00379 DWC_DEBUGPL(DBG_PCDV, "Setup Complete\n");
00380 #endif
00381 break;
00382 case DWC_DSTS_SETUP_UPDT:
00383 dwc_otg_read_setup_packet(core_if, pcd->setup_pkt->d32);
00384 #ifdef DEBUG_EP0
00385 DWC_DEBUGPL(DBG_PCD,
00386 "SETUP PKT: %02x.%02x v%04x i%04x l%04x\n",
00387 pcd->setup_pkt->req.bmRequestType,
00388 pcd->setup_pkt->req.bRequest,
00389 UGETW(pcd->setup_pkt->req.wValue),
00390 UGETW(pcd->setup_pkt->req.wIndex),
00391 UGETW(pcd->setup_pkt->req.wLength));
00392 #endif
00393 ep->dwc_ep.xfer_count += status.b.bcnt;
00394 break;
00395 default:
00396 DWC_DEBUGPL(DBG_PCDV, "Invalid Packet Status (0x%0x)\n",
00397 status.b.pktsts);
00398 break;
00399 }
00400
00401
00402 DWC_MODIFY_REG32(&global_regs->gintmsk, 0, gintmask.d32);
00403
00404 gintsts.d32 = 0;
00405 gintsts.b.rxstsqlvl = 1;
00406 DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
00407
00408
00409 return 1;
00410 }
00411
00424 static inline int get_ep_of_last_in_token(dwc_otg_core_if_t * core_if)
00425 {
00426 dwc_otg_device_global_regs_t *dev_global_regs =
00427 core_if->dev_if->dev_global_regs;
00428 const uint32_t TOKEN_Q_DEPTH = core_if->hwcfg2.b.dev_token_q_depth;
00429
00430 const int DTKNQ_REG_CNT = (TOKEN_Q_DEPTH + 7) / 8;
00431 dtknq1_data_t dtknqr1;
00432 uint32_t in_tkn_epnums[4];
00433 int ndx = 0;
00434 int i = 0;
00435 volatile uint32_t *addr = &dev_global_regs->dtknqr1;
00436 int epnum = 0;
00437
00438
00439
00440
00441 for (i = 0; i < DTKNQ_REG_CNT; i++) {
00442 in_tkn_epnums[i] = DWC_READ_REG32(addr);
00443 DWC_DEBUGPL(DBG_PCDV, "DTKNQR%d=0x%08x\n", i + 1,
00444 in_tkn_epnums[i]);
00445 if (addr == &dev_global_regs->dvbusdis) {
00446 addr = &dev_global_regs->dtknqr3_dthrctl;
00447 } else {
00448 ++addr;
00449 }
00450
00451 }
00452
00453
00454 dtknqr1.d32 = in_tkn_epnums[0];
00455
00456 in_tkn_epnums[0] = dtknqr1.b.epnums0_5;
00457 ndx = dtknqr1.b.intknwptr - 1;
00458
00459
00460 if (ndx == -1) {
00463 int cnt = TOKEN_Q_DEPTH;
00464 if (TOKEN_Q_DEPTH <= 6) {
00465 cnt = TOKEN_Q_DEPTH - 1;
00466 } else if (TOKEN_Q_DEPTH <= 14) {
00467 cnt = TOKEN_Q_DEPTH - 7;
00468 } else if (TOKEN_Q_DEPTH <= 22) {
00469 cnt = TOKEN_Q_DEPTH - 15;
00470 } else {
00471 cnt = TOKEN_Q_DEPTH - 23;
00472 }
00473 epnum = (in_tkn_epnums[DTKNQ_REG_CNT - 1] >> (cnt * 4)) & 0xF;
00474 } else {
00475 if (ndx <= 5) {
00476 epnum = (in_tkn_epnums[0] >> (ndx * 4)) & 0xF;
00477 } else if (ndx <= 13) {
00478 ndx -= 6;
00479 epnum = (in_tkn_epnums[1] >> (ndx * 4)) & 0xF;
00480 } else if (ndx <= 21) {
00481 ndx -= 14;
00482 epnum = (in_tkn_epnums[2] >> (ndx * 4)) & 0xF;
00483 } else if (ndx <= 29) {
00484 ndx -= 22;
00485 epnum = (in_tkn_epnums[3] >> (ndx * 4)) & 0xF;
00486 }
00487 }
00488
00489 return epnum;
00490 }
00491
00497 int32_t dwc_otg_pcd_handle_np_tx_fifo_empty_intr(dwc_otg_pcd_t * pcd)
00498 {
00499 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
00500 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
00501 dwc_otg_dev_in_ep_regs_t *ep_regs;
00502 gnptxsts_data_t txstatus = {.d32 = 0 };
00503 gintsts_data_t gintsts;
00504
00505 int epnum = 0;
00506 dwc_otg_pcd_ep_t *ep = 0;
00507 uint32_t len = 0;
00508 int dwords;
00509
00510
00511 epnum = get_ep_of_last_in_token(core_if);
00512 ep = get_in_ep(pcd, epnum);
00513
00514 DWC_DEBUGPL(DBG_PCD, "NP TxFifo Empty: %d \n", epnum);
00515
00516 ep_regs = core_if->dev_if->in_ep_regs[epnum];
00517
00518 len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
00519 if (len > ep->dwc_ep.maxpacket) {
00520 len = ep->dwc_ep.maxpacket;
00521 }
00522 dwords = (len + 3) / 4;
00523
00524
00525
00526 txstatus.d32 = DWC_READ_REG32(&global_regs->gnptxsts);
00527 DWC_DEBUGPL(DBG_PCDV, "b4 GNPTXSTS=0x%08x\n", txstatus.d32);
00528
00529 while (txstatus.b.nptxqspcavail > 0 &&
00530 txstatus.b.nptxfspcavail > dwords &&
00531 ep->dwc_ep.xfer_count < ep->dwc_ep.xfer_len) {
00532
00533 dwc_otg_ep_write_packet(core_if, &ep->dwc_ep, 0);
00534 len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
00535
00536 if (len > ep->dwc_ep.maxpacket) {
00537 len = ep->dwc_ep.maxpacket;
00538 }
00539
00540 dwords = (len + 3) / 4;
00541 txstatus.d32 = DWC_READ_REG32(&global_regs->gnptxsts);
00542 DWC_DEBUGPL(DBG_PCDV, "GNPTXSTS=0x%08x\n", txstatus.d32);
00543 }
00544
00545 DWC_DEBUGPL(DBG_PCDV, "GNPTXSTS=0x%08x\n",
00546 DWC_READ_REG32(&global_regs->gnptxsts));
00547
00548
00549 gintsts.d32 = 0;
00550 gintsts.b.nptxfempty = 1;
00551 DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
00552
00553 return 1;
00554 }
00555
00561 static int32_t write_empty_tx_fifo(dwc_otg_pcd_t * pcd, uint32_t epnum)
00562 {
00563 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
00564 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
00565 dwc_otg_dev_in_ep_regs_t *ep_regs;
00566 dtxfsts_data_t txstatus = {.d32 = 0 };
00567 dwc_otg_pcd_ep_t *ep = 0;
00568 uint32_t len = 0;
00569 int dwords;
00570
00571 ep = get_in_ep(pcd, epnum);
00572
00573 DWC_DEBUGPL(DBG_PCD, "Dedicated TxFifo Empty: %d \n", epnum);
00574
00575 ep_regs = core_if->dev_if->in_ep_regs[epnum];
00576
00577 len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
00578
00579 if (len > ep->dwc_ep.maxpacket) {
00580 len = ep->dwc_ep.maxpacket;
00581 }
00582
00583 dwords = (len + 3) / 4;
00584
00585
00586
00587 txstatus.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts);
00588 DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", epnum, txstatus.d32);
00589
00590 while (txstatus.b.txfspcavail > dwords &&
00591 ep->dwc_ep.xfer_count < ep->dwc_ep.xfer_len &&
00592 ep->dwc_ep.xfer_len != 0) {
00593
00594 dwc_otg_ep_write_packet(core_if, &ep->dwc_ep, 0);
00595
00596 len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
00597 if (len > ep->dwc_ep.maxpacket) {
00598 len = ep->dwc_ep.maxpacket;
00599 }
00600
00601 dwords = (len + 3) / 4;
00602 txstatus.d32 =
00603 DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts);
00604 DWC_DEBUGPL(DBG_PCDV, "dtxfsts[%d]=0x%08x\n", epnum,
00605 txstatus.d32);
00606 }
00607
00608 DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", epnum,
00609 DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts));
00610
00611 return 1;
00612 }
00613
00619 void dwc_otg_pcd_stop(dwc_otg_pcd_t * pcd)
00620 {
00621 int i, num_in_eps, num_out_eps;
00622 dwc_otg_pcd_ep_t *ep;
00623
00624 gintmsk_data_t intr_mask = {.d32 = 0 };
00625
00626 DWC_SPINLOCK(pcd->lock);
00627
00628 num_in_eps = GET_CORE_IF(pcd)->dev_if->num_in_eps;
00629 num_out_eps = GET_CORE_IF(pcd)->dev_if->num_out_eps;
00630
00631 DWC_DEBUGPL(DBG_PCDV, "%s() \n", __func__);
00632
00633 if (pcd->ep0state == EP0_DISCONNECT) {
00634 DWC_DEBUGPL(DBG_ANY, "%s() Already Disconnected\n", __func__);
00635 DWC_SPINUNLOCK(pcd->lock);
00636 return;
00637 }
00638 pcd->ep0state = EP0_DISCONNECT;
00639
00640
00641 dwc_otg_pcd_update_otg(pcd, 1);
00642
00643
00644 intr_mask.b.nptxfempty = 1;
00645 DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
00646 intr_mask.d32, 0);
00647
00648
00650 dwc_otg_flush_tx_fifo(GET_CORE_IF(pcd), 0x10);
00651 dwc_otg_flush_rx_fifo(GET_CORE_IF(pcd));
00652
00653
00654 ep = &pcd->ep0;
00655 dwc_otg_request_nuke(ep);
00656
00657 for (i = 0; i < num_in_eps; i++) {
00658 dwc_otg_pcd_ep_t *ep = &pcd->in_ep[i];
00659 dwc_otg_request_nuke(ep);
00660 }
00661
00662 for (i = 0; i < num_out_eps; i++) {
00663 dwc_otg_pcd_ep_t *ep = &pcd->out_ep[i];
00664 dwc_otg_request_nuke(ep);
00665 }
00666
00667
00668 if (pcd->fops->disconnect) {
00669 DWC_SPINUNLOCK(pcd->lock);
00670 pcd->fops->disconnect(pcd);
00671 DWC_SPINLOCK(pcd->lock);
00672 }
00673 DWC_SPINUNLOCK(pcd->lock);
00674 }
00675
00679 int32_t dwc_otg_pcd_handle_i2c_intr(dwc_otg_pcd_t * pcd)
00680 {
00681 gintmsk_data_t intr_mask = {.d32 = 0 };
00682 gintsts_data_t gintsts;
00683
00684 DWC_PRINTF("INTERRUPT Handler not implemented for %s\n", "i2cintr");
00685 intr_mask.b.i2cintr = 1;
00686 DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
00687 intr_mask.d32, 0);
00688
00689
00690 gintsts.d32 = 0;
00691 gintsts.b.i2cintr = 1;
00692 DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
00693 gintsts.d32);
00694 return 1;
00695 }
00696
00700 int32_t dwc_otg_pcd_handle_early_suspend_intr(dwc_otg_pcd_t * pcd)
00701 {
00702 gintsts_data_t gintsts;
00703 #if defined(VERBOSE)
00704 DWC_PRINTF("Early Suspend Detected\n");
00705 #endif
00706
00707
00708 gintsts.d32 = 0;
00709 gintsts.b.erlysuspend = 1;
00710 DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
00711 gintsts.d32);
00712 return 1;
00713 }
00714
00732 static inline void ep0_out_start(dwc_otg_core_if_t * core_if,
00733 dwc_otg_pcd_t * pcd)
00734 {
00735 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
00736 deptsiz0_data_t doeptsize0 = {.d32 = 0 };
00737 dwc_otg_dev_dma_desc_t *dma_desc;
00738 depctl_data_t doepctl = {.d32 = 0 };
00739
00740 #ifdef VERBOSE
00741 DWC_DEBUGPL(DBG_PCDV, "%s() doepctl0=%0x\n", __func__,
00742 DWC_READ_REG32(&dev_if->out_ep_regs[0]->doepctl));
00743 #endif
00744
00745 doeptsize0.b.supcnt = 3;
00746 doeptsize0.b.pktcnt = 1;
00747 doeptsize0.b.xfersize = 8 * 3;
00748
00749 if (core_if->dma_enable) {
00750 if (!core_if->dma_desc_enable) {
00752 DWC_WRITE_REG32(&dev_if->out_ep_regs[0]->doeptsiz,
00753 doeptsize0.d32);
00754
00756 DWC_WRITE_REG32(&dev_if->out_ep_regs[0]->doepdma,
00757 pcd->setup_pkt_dma_handle);
00758 } else {
00759 dev_if->setup_desc_index =
00760 (dev_if->setup_desc_index + 1) & 1;
00761 dma_desc =
00762 dev_if->setup_desc_addr[dev_if->setup_desc_index];
00763
00765 dma_desc->status.b.bs = BS_HOST_BUSY;
00766 dma_desc->status.b.l = 1;
00767 dma_desc->status.b.ioc = 1;
00768 dma_desc->status.b.bytes = pcd->ep0.dwc_ep.maxpacket;
00769 dma_desc->buf = pcd->setup_pkt_dma_handle;
00770 dma_desc->status.b.sts = 0;
00771 dma_desc->status.b.bs = BS_HOST_READY;
00772
00774 DWC_WRITE_REG32(&dev_if->out_ep_regs[0]->doepdma,
00775 dev_if->
00776 dma_setup_desc_addr
00777 [dev_if->setup_desc_index]);
00778 }
00779
00780 } else {
00782 DWC_WRITE_REG32(&dev_if->out_ep_regs[0]->doeptsiz,
00783 doeptsize0.d32);
00784 }
00785
00787 doepctl.b.epena = 1;
00788 doepctl.b.cnak = 1;
00789 DWC_WRITE_REG32(&dev_if->out_ep_regs[0]->doepctl, doepctl.d32);
00790
00791 #ifdef VERBOSE
00792 DWC_DEBUGPL(DBG_PCDV, "doepctl0=%0x\n",
00793 DWC_READ_REG32(&dev_if->out_ep_regs[0]->doepctl));
00794 DWC_DEBUGPL(DBG_PCDV, "diepctl0=%0x\n",
00795 DWC_READ_REG32(&dev_if->in_ep_regs[0]->diepctl));
00796 #endif
00797 }
00798
00822 int32_t dwc_otg_pcd_handle_usb_reset_intr(dwc_otg_pcd_t * pcd)
00823 {
00824 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
00825 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
00826 depctl_data_t doepctl = {.d32 = 0 };
00827 depctl_data_t diepctl = {.d32 = 0 };
00828 daint_data_t daintmsk = {.d32 = 0 };
00829 doepmsk_data_t doepmsk = {.d32 = 0 };
00830 diepmsk_data_t diepmsk = {.d32 = 0 };
00831 dcfg_data_t dcfg = {.d32 = 0 };
00832 grstctl_t resetctl = {.d32 = 0 };
00833 dctl_data_t dctl = {.d32 = 0 };
00834 int i = 0;
00835 gintsts_data_t gintsts;
00836 pcgcctl_data_t power = {.d32 = 0 };
00837
00838 power.d32 = DWC_READ_REG32(core_if->pcgcctl);
00839 if (power.b.stoppclk) {
00840 power.d32 = 0;
00841 power.b.stoppclk = 1;
00842 DWC_MODIFY_REG32(core_if->pcgcctl, power.d32, 0);
00843
00844 power.b.pwrclmp = 1;
00845 DWC_MODIFY_REG32(core_if->pcgcctl, power.d32, 0);
00846
00847 power.b.rstpdwnmodule = 1;
00848 DWC_MODIFY_REG32(core_if->pcgcctl, power.d32, 0);
00849 }
00850
00851 core_if->lx_state = DWC_OTG_L0;
00852
00853 DWC_PRINTF("USB RESET\n");
00854 #ifdef DWC_EN_ISOC
00855 for (i = 1; i < 16; ++i) {
00856 dwc_otg_pcd_ep_t *ep;
00857 dwc_ep_t *dwc_ep;
00858 ep = get_in_ep(pcd, i);
00859 if (ep != 0) {
00860 dwc_ep = &ep->dwc_ep;
00861 dwc_ep->next_frame = 0xffffffff;
00862 }
00863 }
00864 #endif
00865
00866
00867 dwc_otg_pcd_update_otg(pcd, 1);
00868
00869
00870 dctl.b.rmtwkupsig = 1;
00871 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32, 0);
00872
00873
00874 doepctl.b.snak = 1;
00875 for (i = 0; i <= dev_if->num_out_eps; i++) {
00876 DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepctl, doepctl.d32);
00877 }
00878
00879
00880 dwc_otg_flush_tx_fifo(core_if, 0x10);
00881
00882 resetctl.b.intknqflsh = 1;
00883 DWC_WRITE_REG32(&core_if->core_global_regs->grstctl, resetctl.d32);
00884
00885 if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable) {
00886 core_if->start_predict = 0;
00887 for (i = 0; i<= core_if->dev_if->num_in_eps; ++i) {
00888 core_if->nextep_seq[i] = 0xff;
00889 }
00890 core_if->nextep_seq[0] = 0;
00891 core_if->first_in_nextep_seq = 0;
00892 diepctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[0]->diepctl);
00893 diepctl.b.nextep = 0;
00894 DWC_WRITE_REG32(&dev_if->in_ep_regs[0]->diepctl, diepctl.d32);
00895
00896
00897 dcfg.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dcfg);
00898 dcfg.b.epmscnt = 2;
00899 DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
00900
00901 DWC_DEBUGPL(DBG_PCDV,"%s first_in_nextep_seq= %2d; nextep_seq[]:\n",
00902 __func__, core_if->first_in_nextep_seq);
00903 for (i=0; i <= core_if->dev_if->num_in_eps; i++) {
00904 DWC_DEBUGPL(DBG_PCDV, "%2d\n", core_if->nextep_seq[i]);
00905 }
00906 }
00907
00908 if (core_if->multiproc_int_enable) {
00909 daintmsk.b.inep0 = 1;
00910 daintmsk.b.outep0 = 1;
00911 DWC_WRITE_REG32(&dev_if->dev_global_regs->deachintmsk,
00912 daintmsk.d32);
00913
00914 doepmsk.b.setup = 1;
00915 doepmsk.b.xfercompl = 1;
00916 doepmsk.b.ahberr = 1;
00917 doepmsk.b.epdisabled = 1;
00918
00919 if (core_if->dma_desc_enable) {
00920 doepmsk.b.stsphsercvd = 1;
00921 doepmsk.b.bna = 1;
00922 }
00923
00924
00925
00926
00927
00928
00929
00930
00931 DWC_WRITE_REG32(&dev_if->dev_global_regs->doepeachintmsk[0],
00932 doepmsk.d32);
00933
00934 diepmsk.b.xfercompl = 1;
00935 diepmsk.b.timeout = 1;
00936 diepmsk.b.epdisabled = 1;
00937 diepmsk.b.ahberr = 1;
00938 diepmsk.b.intknepmis = 1;
00939 if (!core_if->en_multiple_tx_fifo && core_if->dma_enable)
00940 diepmsk.b.intknepmis = 0;
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951 DWC_WRITE_REG32(&dev_if->dev_global_regs->diepeachintmsk[0],
00952 diepmsk.d32);
00953 } else {
00954 daintmsk.b.inep0 = 1;
00955 daintmsk.b.outep0 = 1;
00956 DWC_WRITE_REG32(&dev_if->dev_global_regs->daintmsk,
00957 daintmsk.d32);
00958
00959 doepmsk.b.setup = 1;
00960 doepmsk.b.xfercompl = 1;
00961 doepmsk.b.ahberr = 1;
00962 doepmsk.b.epdisabled = 1;
00963
00964 if (core_if->dma_desc_enable) {
00965 doepmsk.b.stsphsercvd = 1;
00966 doepmsk.b.bna = 1;
00967 }
00968 DWC_WRITE_REG32(&dev_if->dev_global_regs->doepmsk, doepmsk.d32);
00969
00970 diepmsk.b.xfercompl = 1;
00971 diepmsk.b.timeout = 1;
00972 diepmsk.b.epdisabled = 1;
00973 diepmsk.b.ahberr = 1;
00974 if (!core_if->en_multiple_tx_fifo && core_if->dma_enable)
00975 diepmsk.b.intknepmis = 0;
00976
00977
00978
00979
00980
00981
00982 DWC_WRITE_REG32(&dev_if->dev_global_regs->diepmsk, diepmsk.d32);
00983 }
00984
00985
00986 dcfg.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dcfg);
00987 dcfg.b.devaddr = 0;
00988 DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
00989
00990
00991 ep0_out_start(core_if, pcd);
00992
00993
00994 gintsts.d32 = 0;
00995 gintsts.b.usbreset = 1;
00996 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
00997
00998 return 1;
00999 }
01000
01007 static int get_device_speed(dwc_otg_core_if_t * core_if)
01008 {
01009 dsts_data_t dsts;
01010 int speed = 0;
01011 dsts.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);
01012
01013 switch (dsts.b.enumspd) {
01014 case DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
01015 speed = USB_SPEED_HIGH;
01016 break;
01017 case DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
01018 case DWC_DSTS_ENUMSPD_FS_PHY_48MHZ:
01019 speed = USB_SPEED_FULL;
01020 break;
01021
01022 case DWC_DSTS_ENUMSPD_LS_PHY_6MHZ:
01023 speed = USB_SPEED_LOW;
01024 break;
01025 }
01026
01027 return speed;
01028 }
01029
01035 int32_t dwc_otg_pcd_handle_enum_done_intr(dwc_otg_pcd_t * pcd)
01036 {
01037 dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
01038 gintsts_data_t gintsts;
01039 gusbcfg_data_t gusbcfg;
01040 dwc_otg_core_global_regs_t *global_regs =
01041 GET_CORE_IF(pcd)->core_global_regs;
01042 uint8_t utmi16b, utmi8b;
01043 int speed;
01044 DWC_DEBUGPL(DBG_PCD, "SPEED ENUM\n");
01045
01046 if (GET_CORE_IF(pcd)->snpsid >= OTG_CORE_REV_2_60a) {
01047 utmi16b = 6;
01048 utmi8b = 9;
01049 } else {
01050 utmi16b = 4;
01051 utmi8b = 8;
01052 }
01053 dwc_otg_ep0_activate(GET_CORE_IF(pcd), &ep0->dwc_ep);
01054
01055 #ifdef DEBUG_EP0
01056 print_ep0_state(pcd);
01057 #endif
01058
01059 if (pcd->ep0state == EP0_DISCONNECT) {
01060 pcd->ep0state = EP0_IDLE;
01061 } else if (pcd->ep0state == EP0_STALL) {
01062 pcd->ep0state = EP0_IDLE;
01063 }
01064
01065 pcd->ep0state = EP0_IDLE;
01066
01067 ep0->stopped = 0;
01068
01069 speed = get_device_speed(GET_CORE_IF(pcd));
01070 pcd->fops->connect(pcd, speed);
01071
01072
01073 gusbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
01074 if (speed == USB_SPEED_HIGH) {
01075 if (GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type ==
01076 DWC_HWCFG2_HS_PHY_TYPE_ULPI) {
01077
01078 gusbcfg.b.usbtrdtim = 9;
01079 }
01080 if (GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type ==
01081 DWC_HWCFG2_HS_PHY_TYPE_UTMI) {
01082
01083 if (GET_CORE_IF(pcd)->hwcfg4.b.utmi_phy_data_width == 0) {
01084 gusbcfg.b.usbtrdtim = utmi8b;
01085 } else if (GET_CORE_IF(pcd)->hwcfg4.
01086 b.utmi_phy_data_width == 1) {
01087 gusbcfg.b.usbtrdtim = utmi16b;
01088 } else if (GET_CORE_IF(pcd)->
01089 core_params->phy_utmi_width == 8) {
01090 gusbcfg.b.usbtrdtim = utmi8b;
01091 } else {
01092 gusbcfg.b.usbtrdtim = utmi16b;
01093 }
01094 }
01095 if (GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type ==
01096 DWC_HWCFG2_HS_PHY_TYPE_UTMI_ULPI) {
01097
01098 if (gusbcfg.b.ulpi_utmi_sel == 1) {
01099
01100 gusbcfg.b.usbtrdtim = 9;
01101 } else {
01102
01103 if (GET_CORE_IF(pcd)->
01104 core_params->phy_utmi_width == 16) {
01105 gusbcfg.b.usbtrdtim = utmi16b;
01106 } else {
01107 gusbcfg.b.usbtrdtim = utmi8b;
01108 }
01109 }
01110 }
01111 } else {
01112
01113 gusbcfg.b.usbtrdtim = 9;
01114 }
01115 DWC_WRITE_REG32(&global_regs->gusbcfg, gusbcfg.d32);
01116
01117
01118 gintsts.d32 = 0;
01119 gintsts.b.enumdone = 1;
01120 DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
01121 gintsts.d32);
01122 return 1;
01123 }
01124
01130 int32_t dwc_otg_pcd_handle_isoc_out_packet_dropped_intr(dwc_otg_pcd_t * pcd)
01131 {
01132 gintmsk_data_t intr_mask = {.d32 = 0 };
01133 gintsts_data_t gintsts;
01134
01135 DWC_WARN("INTERRUPT Handler not implemented for %s\n",
01136 "ISOC Out Dropped");
01137
01138 intr_mask.b.isooutdrop = 1;
01139 DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
01140 intr_mask.d32, 0);
01141
01142
01143 gintsts.d32 = 0;
01144 gintsts.b.isooutdrop = 1;
01145 DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
01146 gintsts.d32);
01147
01148 return 1;
01149 }
01150
01156 int32_t dwc_otg_pcd_handle_end_periodic_frame_intr(dwc_otg_pcd_t * pcd)
01157 {
01158 gintmsk_data_t intr_mask = {.d32 = 0 };
01159 gintsts_data_t gintsts;
01160 DWC_PRINTF("INTERRUPT Handler not implemented for %s\n", "EOP");
01161
01162 intr_mask.b.eopframe = 1;
01163 DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
01164 intr_mask.d32, 0);
01165
01166
01167 gintsts.d32 = 0;
01168 gintsts.b.eopframe = 1;
01169 DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
01170 gintsts.d32);
01171
01172 return 1;
01173 }
01174
01184 int32_t dwc_otg_pcd_handle_ep_mismatch_intr(dwc_otg_pcd_t * pcd)
01185 {
01186 gintsts_data_t gintsts;
01187 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
01188 dctl_data_t dctl;
01189 gintmsk_data_t intr_mask = {.d32 = 0 };
01190
01191 if (!core_if->en_multiple_tx_fifo && core_if->dma_enable) {
01192 core_if->start_predict = 1;
01193
01194 DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, core_if);
01195
01196 gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
01197 if (!gintsts.b.ginnakeff) {
01198
01199 intr_mask.d32 = 0;
01200 intr_mask.b.epmismatch = 1;
01201 DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, intr_mask.d32, 0);
01202
01203 intr_mask.d32 = 0;
01204 intr_mask.b.ginnakeff = 1;
01205 DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, 0, intr_mask.d32);
01206
01207 dctl.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl);
01208 dctl.b.sgnpinnak = 1;
01209 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32);
01210 } else {
01211 DWC_PRINTF("gintsts.b.ginnakeff = 1! dctl.b.sgnpinnak not set\n");
01212 }
01213
01214
01215 }
01216
01217 gintsts.d32 = 0;
01218 gintsts.b.epmismatch = 1;
01219 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
01220
01221 return 1;
01222 }
01223
01232 int32_t dwc_otg_pcd_handle_ep_fetsusp_intr(dwc_otg_pcd_t * pcd)
01233 {
01234 gintsts_data_t gintsts;
01235 gintmsk_data_t gintmsk_data;
01236 dctl_data_t dctl;
01237 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
01238 DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, core_if);
01239
01240
01241 dctl.d32 = 0;
01242 dctl.b.cgnpinnak = 1;
01243 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32, dctl.d32);
01244
01245
01246 gintmsk_data.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintmsk);
01247 gintmsk_data.b.fetsusp = 0;
01248 DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, gintmsk_data.d32);
01249
01250
01251 gintsts.d32 = 0;
01252 gintsts.b.fetsusp = 1;
01253 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
01254
01255 return 1;
01256 }
01260 static inline void ep0_do_stall(dwc_otg_pcd_t * pcd, const int err_val)
01261 {
01262 dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
01263 usb_device_request_t *ctrl = &pcd->setup_pkt->req;
01264 DWC_WARN("req %02x.%02x protocol STALL; err %d\n",
01265 ctrl->bmRequestType, ctrl->bRequest, err_val);
01266
01267 ep0->dwc_ep.is_in = 1;
01268 dwc_otg_ep_set_stall(GET_CORE_IF(pcd), &ep0->dwc_ep);
01269 pcd->ep0.stopped = 1;
01270 pcd->ep0state = EP0_IDLE;
01271 ep0_out_start(GET_CORE_IF(pcd), pcd);
01272 }
01273
01277 static inline void do_gadget_setup(dwc_otg_pcd_t * pcd,
01278 usb_device_request_t * ctrl)
01279 {
01280 int ret = 0;
01281 DWC_SPINUNLOCK(pcd->lock);
01282 ret = pcd->fops->setup(pcd, (uint8_t *) ctrl);
01283 DWC_SPINLOCK(pcd->lock);
01284 if (ret < 0) {
01285 ep0_do_stall(pcd, ret);
01286 }
01287
01300 if (ret == 256 + 999) {
01301 pcd->request_config = 1;
01302 }
01303 }
01304
01305 #ifdef DWC_UTE_CFI
01306
01310 static inline int cfi_gadget_setup(dwc_otg_pcd_t * pcd,
01311 struct cfi_usb_ctrlrequest *ctrl_req)
01312 {
01313 int ret = 0;
01314
01315 if (pcd->fops && pcd->fops->cfi_setup) {
01316 DWC_SPINUNLOCK(pcd->lock);
01317 ret = pcd->fops->cfi_setup(pcd, ctrl_req);
01318 DWC_SPINLOCK(pcd->lock);
01319 if (ret < 0) {
01320 ep0_do_stall(pcd, ret);
01321 return ret;
01322 }
01323 }
01324
01325 return ret;
01326 }
01327 #endif
01328
01333 static inline void do_setup_in_status_phase(dwc_otg_pcd_t * pcd)
01334 {
01335 dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
01336 if (pcd->ep0state == EP0_STALL) {
01337 return;
01338 }
01339
01340 pcd->ep0state = EP0_IN_STATUS_PHASE;
01341
01342
01343 DWC_DEBUGPL(DBG_PCD, "EP0 IN ZLP\n");
01344 ep0->dwc_ep.xfer_len = 0;
01345 ep0->dwc_ep.xfer_count = 0;
01346 ep0->dwc_ep.is_in = 1;
01347 ep0->dwc_ep.dma_addr = pcd->setup_pkt_dma_handle;
01348 dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
01349
01350
01351
01352 }
01353
01358 static inline void do_setup_out_status_phase(dwc_otg_pcd_t * pcd)
01359 {
01360 dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
01361 if (pcd->ep0state == EP0_STALL) {
01362 DWC_DEBUGPL(DBG_PCD, "EP0 STALLED\n");
01363 return;
01364 }
01365 pcd->ep0state = EP0_OUT_STATUS_PHASE;
01366
01367 DWC_DEBUGPL(DBG_PCD, "EP0 OUT ZLP\n");
01368 ep0->dwc_ep.xfer_len = 0;
01369 ep0->dwc_ep.xfer_count = 0;
01370 ep0->dwc_ep.is_in = 0;
01371 ep0->dwc_ep.dma_addr = pcd->setup_pkt_dma_handle;
01372 dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
01373
01374
01375 if (GET_CORE_IF(pcd)->dma_enable == 0) {
01376 ep0_out_start(GET_CORE_IF(pcd), pcd);
01377 }
01378 }
01379
01384 static inline void pcd_clear_halt(dwc_otg_pcd_t * pcd, dwc_otg_pcd_ep_t * ep)
01385 {
01386 if (ep->dwc_ep.stall_clear_flag == 0)
01387 dwc_otg_ep_clear_stall(GET_CORE_IF(pcd), &ep->dwc_ep);
01388
01389
01390 dwc_otg_ep_activate(GET_CORE_IF(pcd), &ep->dwc_ep);
01391 if (ep->stopped) {
01392 ep->stopped = 0;
01393
01394
01398
01399
01400
01401
01402
01403
01404
01405 ep->queue_sof = 1;
01406 DWC_TASK_SCHEDULE(pcd->start_xfer_tasklet);
01407 }
01408
01409 do_setup_in_status_phase(pcd);
01410 }
01411
01423 void do_test_mode(void *data)
01424 {
01425 dctl_data_t dctl;
01426 dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *) data;
01427 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
01428 int test_mode = pcd->test_mode;
01429
01430
01431
01432 dctl.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl);
01433 switch (test_mode) {
01434 case 1:
01435 dctl.b.tstctl = 1;
01436 break;
01437
01438 case 2:
01439 dctl.b.tstctl = 2;
01440 break;
01441
01442 case 3:
01443 dctl.b.tstctl = 3;
01444 break;
01445
01446 case 4:
01447 dctl.b.tstctl = 4;
01448 break;
01449
01450 case 5:
01451 dctl.b.tstctl = 5;
01452 break;
01453 }
01454 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32);
01455 }
01456
01460 static inline void do_get_status(dwc_otg_pcd_t * pcd)
01461 {
01462 usb_device_request_t ctrl = pcd->setup_pkt->req;
01463 dwc_otg_pcd_ep_t *ep;
01464 dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
01465 uint16_t *status = pcd->status_buf;
01466 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
01467
01468 #ifdef DEBUG_EP0
01469 DWC_DEBUGPL(DBG_PCD,
01470 "GET_STATUS %02x.%02x v%04x i%04x l%04x\n",
01471 ctrl.bmRequestType, ctrl.bRequest,
01472 UGETW(ctrl.wValue), UGETW(ctrl.wIndex),
01473 UGETW(ctrl.wLength));
01474 #endif
01475
01476 switch (UT_GET_RECIPIENT(ctrl.bmRequestType)) {
01477 case UT_DEVICE:
01478 if(UGETW(ctrl.wIndex) == 0xF000) {
01479 DWC_PRINTF("wIndex - %d\n", UGETW(ctrl.wIndex));
01480 DWC_PRINTF("OTG VERSION - %d\n", core_if->otg_ver);
01481 DWC_PRINTF("OTG CAP - %d, %d\n", core_if->core_params->otg_cap,
01482 DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE);
01483 if(core_if->otg_ver == 1 &&
01484 core_if->core_params->otg_cap == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) {
01485 uint8_t *otgsts = (uint8_t*)pcd->status_buf;
01486 *otgsts = (core_if->otg_sts & 0x1);
01487 pcd->ep0_pending = 1;
01488 ep0->dwc_ep.start_xfer_buff = (uint8_t *) otgsts;
01489 ep0->dwc_ep.xfer_buff = (uint8_t *) otgsts;
01490 ep0->dwc_ep.dma_addr = pcd->status_buf_dma_handle;
01491 ep0->dwc_ep.xfer_len = 1;
01492 ep0->dwc_ep.xfer_count = 0;
01493 ep0->dwc_ep.total_len = ep0->dwc_ep.xfer_len;
01494 dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
01495 return;
01496 } else {
01497 ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
01498 return;
01499 }
01500 break;
01501 } else {
01502 *status = 0x1;
01503 *status |= pcd->remote_wakeup_enable << 1;
01504 break;
01505 }
01506 case UT_INTERFACE:
01507 *status = 0;
01508 break;
01509
01510 case UT_ENDPOINT:
01511 ep = get_ep_by_addr(pcd, UGETW(ctrl.wIndex));
01512 if (ep == 0 || UGETW(ctrl.wLength) > 2) {
01513 ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
01514 return;
01515 }
01517 *status = ep->stopped;
01518 break;
01519 }
01520 pcd->ep0_pending = 1;
01521 ep0->dwc_ep.start_xfer_buff = (uint8_t *) status;
01522 ep0->dwc_ep.xfer_buff = (uint8_t *) status;
01523 ep0->dwc_ep.dma_addr = pcd->status_buf_dma_handle;
01524 ep0->dwc_ep.xfer_len = 2;
01525 ep0->dwc_ep.xfer_count = 0;
01526 ep0->dwc_ep.total_len = ep0->dwc_ep.xfer_len;
01527 dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
01528 }
01529
01533 static inline void do_set_feature(dwc_otg_pcd_t * pcd)
01534 {
01535 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
01536 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
01537 usb_device_request_t ctrl = pcd->setup_pkt->req;
01538 dwc_otg_pcd_ep_t *ep = 0;
01539 int32_t otg_cap_param = core_if->core_params->otg_cap;
01540 gotgctl_data_t gotgctl = {.d32 = 0 };
01541
01542 DWC_DEBUGPL(DBG_PCD, "SET_FEATURE:%02x.%02x v%04x i%04x l%04x\n",
01543 ctrl.bmRequestType, ctrl.bRequest,
01544 UGETW(ctrl.wValue), UGETW(ctrl.wIndex),
01545 UGETW(ctrl.wLength));
01546 DWC_DEBUGPL(DBG_PCD, "otg_cap=%d\n", otg_cap_param);
01547
01548 switch (UT_GET_RECIPIENT(ctrl.bmRequestType)) {
01549 case UT_DEVICE:
01550 switch (UGETW(ctrl.wValue)) {
01551 case UF_DEVICE_REMOTE_WAKEUP:
01552 pcd->remote_wakeup_enable = 1;
01553 break;
01554
01555 case UF_TEST_MODE:
01556
01557
01558
01559
01563 pcd->test_mode = UGETW(ctrl.wIndex) >> 8;
01564 DWC_TASK_SCHEDULE(pcd->test_mode_tasklet);
01565 break;
01566
01567 case UF_DEVICE_B_HNP_ENABLE:
01568 DWC_DEBUGPL(DBG_PCDV,
01569 "SET_FEATURE: USB_DEVICE_B_HNP_ENABLE\n");
01570
01571
01572 if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) {
01573 pcd->b_hnp_enable = 1;
01574 dwc_otg_pcd_update_otg(pcd, 0);
01575 DWC_DEBUGPL(DBG_PCD, "Request B HNP\n");
01578 gotgctl.b.devhnpen = 1;
01579 gotgctl.b.hnpreq = 1;
01580 DWC_WRITE_REG32(&global_regs->gotgctl,
01581 gotgctl.d32);
01582 } else {
01583 ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
01584 return;
01585 }
01586 break;
01587
01588 case UF_DEVICE_A_HNP_SUPPORT:
01589
01590 DWC_DEBUGPL(DBG_PCDV,
01591 "SET_FEATURE: USB_DEVICE_A_HNP_SUPPORT\n");
01592 if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) {
01593 pcd->a_hnp_support = 1;
01594 dwc_otg_pcd_update_otg(pcd, 0);
01595 } else {
01596 ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
01597 return;
01598 }
01599 break;
01600
01601 case UF_DEVICE_A_ALT_HNP_SUPPORT:
01602
01603 DWC_DEBUGPL(DBG_PCDV,
01604 "SET_FEATURE: USB_DEVICE_A_ALT_HNP_SUPPORT\n");
01605 if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) {
01606 pcd->a_alt_hnp_support = 1;
01607 dwc_otg_pcd_update_otg(pcd, 0);
01608 } else {
01609 ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
01610 return;
01611 }
01612 break;
01613
01614 default:
01615 ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
01616 return;
01617
01618 }
01619 do_setup_in_status_phase(pcd);
01620 break;
01621
01622 case UT_INTERFACE:
01623 do_gadget_setup(pcd, &ctrl);
01624 break;
01625
01626 case UT_ENDPOINT:
01627 if (UGETW(ctrl.wValue) == UF_ENDPOINT_HALT) {
01628 ep = get_ep_by_addr(pcd, UGETW(ctrl.wIndex));
01629 if (ep == 0) {
01630 ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
01631 return;
01632 }
01633 ep->stopped = 1;
01634 dwc_otg_ep_set_stall(core_if, &ep->dwc_ep);
01635 }
01636 do_setup_in_status_phase(pcd);
01637 break;
01638 }
01639 }
01640
01644 static inline void do_clear_feature(dwc_otg_pcd_t * pcd)
01645 {
01646 usb_device_request_t ctrl = pcd->setup_pkt->req;
01647 dwc_otg_pcd_ep_t *ep = 0;
01648
01649 DWC_DEBUGPL(DBG_PCD,
01650 "CLEAR_FEATURE:%02x.%02x v%04x i%04x l%04x\n",
01651 ctrl.bmRequestType, ctrl.bRequest,
01652 UGETW(ctrl.wValue), UGETW(ctrl.wIndex),
01653 UGETW(ctrl.wLength));
01654
01655 switch (UT_GET_RECIPIENT(ctrl.bmRequestType)) {
01656 case UT_DEVICE:
01657 switch (UGETW(ctrl.wValue)) {
01658 case UF_DEVICE_REMOTE_WAKEUP:
01659 pcd->remote_wakeup_enable = 0;
01660 break;
01661
01662 case UF_TEST_MODE:
01664 break;
01665
01666 default:
01667 ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
01668 return;
01669 }
01670 do_setup_in_status_phase(pcd);
01671 break;
01672
01673 case UT_ENDPOINT:
01674 ep = get_ep_by_addr(pcd, UGETW(ctrl.wIndex));
01675 if (ep == 0) {
01676 ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
01677 return;
01678 }
01679
01680 pcd_clear_halt(pcd, ep);
01681
01682 break;
01683 }
01684 }
01685
01689 static inline void do_set_address(dwc_otg_pcd_t * pcd)
01690 {
01691 dwc_otg_dev_if_t *dev_if = GET_CORE_IF(pcd)->dev_if;
01692 usb_device_request_t ctrl = pcd->setup_pkt->req;
01693
01694 if (ctrl.bmRequestType == UT_DEVICE) {
01695 dcfg_data_t dcfg = {.d32 = 0 };
01696
01697 #ifdef DEBUG_EP0
01698
01699 #endif
01700 dcfg.b.devaddr = UGETW(ctrl.wValue);
01701 DWC_MODIFY_REG32(&dev_if->dev_global_regs->dcfg, 0, dcfg.d32);
01702 do_setup_in_status_phase(pcd);
01703 }
01704 }
01705
01756 static inline void pcd_setup(dwc_otg_pcd_t * pcd)
01757 {
01758 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
01759 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
01760 usb_device_request_t ctrl = pcd->setup_pkt->req;
01761 dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
01762
01763 deptsiz0_data_t doeptsize0 = {.d32 = 0 };
01764
01765 #ifdef DWC_UTE_CFI
01766 int retval = 0;
01767 struct cfi_usb_ctrlrequest cfi_req;
01768 #endif
01769
01770 #ifdef DEBUG_EP0
01771 DWC_DEBUGPL(DBG_PCD, "SETUP %02x.%02x v%04x i%04x l%04x\n",
01772 ctrl.bmRequestType, ctrl.bRequest,
01773 UGETW(ctrl.wValue), UGETW(ctrl.wIndex),
01774 UGETW(ctrl.wLength));
01775 #endif
01776
01777 doeptsize0.d32 = DWC_READ_REG32(&dev_if->out_ep_regs[0]->doeptsiz);
01778
01781 if (core_if->dma_enable && core_if->dma_desc_enable == 0
01782 && (doeptsize0.b.supcnt < 2)) {
01783 DWC_ERROR
01784 ("\n\n----------- CANNOT handle > 1 setup packet in DMA mode\n\n");
01785 }
01786
01787
01788 dwc_otg_request_nuke(ep0);
01789 ep0->stopped = 0;
01790
01791 if (ctrl.bmRequestType & UE_DIR_IN) {
01792 ep0->dwc_ep.is_in = 1;
01793 pcd->ep0state = EP0_IN_DATA_PHASE;
01794 } else {
01795 ep0->dwc_ep.is_in = 0;
01796 pcd->ep0state = EP0_OUT_DATA_PHASE;
01797 }
01798
01799 if (UGETW(ctrl.wLength) == 0) {
01800 ep0->dwc_ep.is_in = 1;
01801 pcd->ep0state = EP0_IN_STATUS_PHASE;
01802 }
01803
01804 if (UT_GET_TYPE(ctrl.bmRequestType) != UT_STANDARD) {
01805
01806 #ifdef DWC_UTE_CFI
01807 DWC_MEMCPY(&cfi_req, &ctrl, sizeof(usb_device_request_t));
01808
01809
01810 ctrl.bRequestType, ctrl.bRequest);
01811 if (UT_GET_TYPE(cfi_req.bRequestType) == UT_VENDOR) {
01812 if (cfi_req.bRequest > 0xB0 && cfi_req.bRequest < 0xBF) {
01813 retval = cfi_setup(pcd, &cfi_req);
01814 if (retval < 0) {
01815 ep0_do_stall(pcd, retval);
01816 pcd->ep0_pending = 0;
01817 return;
01818 }
01819
01820
01821 if (pcd->cfi->need_gadget_att) {
01822 retval =
01823 cfi_gadget_setup(pcd,
01824 &pcd->
01825 cfi->ctrl_req);
01826 if (retval < 0) {
01827 pcd->ep0_pending = 0;
01828 return;
01829 }
01830 }
01831
01832 if (pcd->cfi->need_status_in_complete) {
01833 do_setup_in_status_phase(pcd);
01834 }
01835 return;
01836 }
01837 }
01838 #endif
01839
01840
01841 do_gadget_setup(pcd, &ctrl);
01842 return;
01843 }
01844
01847
01848
01849
01850 switch (ctrl.bRequest) {
01851 case UR_GET_STATUS:
01852 do_get_status(pcd);
01853 break;
01854
01855 case UR_CLEAR_FEATURE:
01856 do_clear_feature(pcd);
01857 break;
01858
01859 case UR_SET_FEATURE:
01860 do_set_feature(pcd);
01861 break;
01862
01863 case UR_SET_ADDRESS:
01864 do_set_address(pcd);
01865 break;
01866
01867 case UR_SET_INTERFACE:
01868 case UR_SET_CONFIG:
01869
01870 do_gadget_setup(pcd, &ctrl);
01871 break;
01872
01873 case UR_SYNCH_FRAME:
01874 do_gadget_setup(pcd, &ctrl);
01875 break;
01876
01877 default:
01878
01879 do_gadget_setup(pcd, &ctrl);
01880 break;
01881 }
01882 }
01883
01887 static int32_t ep0_complete_request(dwc_otg_pcd_ep_t * ep)
01888 {
01889 dwc_otg_core_if_t *core_if = GET_CORE_IF(ep->pcd);
01890 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
01891 dwc_otg_dev_in_ep_regs_t *in_ep_regs =
01892 dev_if->in_ep_regs[ep->dwc_ep.num];
01893 #ifdef DEBUG_EP0
01894 dwc_otg_dev_out_ep_regs_t *out_ep_regs =
01895 dev_if->out_ep_regs[ep->dwc_ep.num];
01896 #endif
01897 deptsiz0_data_t deptsiz;
01898 dev_dma_desc_sts_t desc_sts;
01899 dwc_otg_pcd_request_t *req;
01900 int is_last = 0;
01901 dwc_otg_pcd_t *pcd = ep->pcd;
01902
01903 #ifdef DWC_UTE_CFI
01904 struct cfi_usb_ctrlrequest *ctrlreq;
01905 int retval = -DWC_E_NOT_SUPPORTED;
01906 #endif
01907
01908 if (pcd->ep0_pending && DWC_CIRCLEQ_EMPTY(&ep->queue)) {
01909 if (ep->dwc_ep.is_in) {
01910 #ifdef DEBUG_EP0
01911 DWC_DEBUGPL(DBG_PCDV, "Do setup OUT status phase\n");
01912 #endif
01913 do_setup_out_status_phase(pcd);
01914 } else {
01915 #ifdef DEBUG_EP0
01916 DWC_DEBUGPL(DBG_PCDV, "Do setup IN status phase\n");
01917 #endif
01918
01919 #ifdef DWC_UTE_CFI
01920 ctrlreq = &pcd->cfi->ctrl_req;
01921
01922 if (UT_GET_TYPE(ctrlreq->bRequestType) == UT_VENDOR) {
01923 if (ctrlreq->bRequest > 0xB0
01924 && ctrlreq->bRequest < 0xBF) {
01925
01926
01927 if ((retval =
01928 pcd->cfi->ops.
01929 ctrl_write_complete(pcd->cfi,
01930 pcd)) < 0) {
01931 CFI_INFO
01932 ("ERROR setting a new value in the PCD(%d)\n",
01933 retval);
01934 ep0_do_stall(pcd, retval);
01935 pcd->ep0_pending = 0;
01936 return 0;
01937 }
01938
01939
01940 if (pcd->cfi->need_gadget_att == 1) {
01941
01942 retval =
01943 cfi_gadget_setup(pcd,
01944 &pcd->cfi->
01945 ctrl_req);
01946
01947
01948
01949
01950 if (retval < 0) {
01951 CFI_INFO
01952 ("ERROR setting a new value in the gadget(%d)\n",
01953 retval);
01954 pcd->ep0_pending = 0;
01955 return 0;
01956 }
01957 }
01958
01959 CFI_INFO("%s: RETVAL=%d\n", __func__,
01960 retval);
01961
01962
01963
01964
01965
01966
01967 do_setup_in_status_phase(pcd);
01968 pcd->ep0_pending = 0;
01969 return 1;
01970 }
01971 }
01972 #endif
01973
01974 do_setup_in_status_phase(pcd);
01975 }
01976 pcd->ep0_pending = 0;
01977 return 1;
01978 }
01979
01980 if (DWC_CIRCLEQ_EMPTY(&ep->queue)) {
01981 return 0;
01982 }
01983 req = DWC_CIRCLEQ_FIRST(&ep->queue);
01984
01985 if (pcd->ep0state == EP0_OUT_STATUS_PHASE
01986 || pcd->ep0state == EP0_IN_STATUS_PHASE) {
01987 is_last = 1;
01988 } else if (ep->dwc_ep.is_in) {
01989 deptsiz.d32 = DWC_READ_REG32(&in_ep_regs->dieptsiz);
01990 if (core_if->dma_desc_enable != 0)
01991 desc_sts = dev_if->in_desc_addr->status;
01992 #ifdef DEBUG_EP0
01993 DWC_DEBUGPL(DBG_PCDV, "%d len=%d xfersize=%d pktcnt=%d\n",
01994 ep->dwc_ep.num, ep->dwc_ep.xfer_len,
01995 deptsiz.b.xfersize, deptsiz.b.pktcnt);
01996 #endif
01997
01998 if (((core_if->dma_desc_enable == 0)
01999 && (deptsiz.b.xfersize == 0))
02000 || ((core_if->dma_desc_enable != 0)
02001 && (desc_sts.b.bytes == 0))) {
02002 req->actual = ep->dwc_ep.xfer_count;
02003
02004 if (req->sent_zlp) {
02005 #ifdef DEBUG_EP0
02006 DWC_DEBUGPL(DBG_PCD, "Setup Rx ZLP\n");
02007 #endif
02008 req->sent_zlp = 0;
02009 }
02010 do_setup_out_status_phase(pcd);
02011 }
02012 } else {
02013
02014 #ifdef DEBUG_EP0
02015 deptsiz.d32 = DWC_READ_REG32(&out_ep_regs->doeptsiz);
02016 DWC_DEBUGPL(DBG_PCDV, "%d len=%d xsize=%d pktcnt=%d\n",
02017 ep->dwc_ep.num, ep->dwc_ep.xfer_len,
02018 deptsiz.b.xfersize, deptsiz.b.pktcnt);
02019 #endif
02020 req->actual = ep->dwc_ep.xfer_count;
02021
02022
02023 if (req->sent_zlp) {
02024 #ifdef DEBUG_EP0
02025 DWC_DEBUGPL(DBG_PCDV, "Setup Tx ZLP\n");
02026 #endif
02027 req->sent_zlp = 0;
02028 }
02029 if (core_if->dma_desc_enable == 0)
02030 do_setup_in_status_phase(pcd);
02031 }
02032
02033
02034 if (is_last) {
02035 dwc_otg_request_done(ep, req, 0);
02036 ep->dwc_ep.start_xfer_buff = 0;
02037 ep->dwc_ep.xfer_buff = 0;
02038 ep->dwc_ep.xfer_len = 0;
02039 return 1;
02040 }
02041 return 0;
02042 }
02043
02044 #ifdef DWC_UTE_CFI
02045
02051 static inline int cfi_calc_desc_residue(dwc_otg_pcd_ep_t * ep)
02052 {
02053 int32_t ret = 0;
02054 int i;
02055 struct dwc_otg_dma_desc *ddesc = NULL;
02056 struct cfi_ep *cfiep;
02057
02058
02059 cfiep = get_cfi_ep_by_pcd_ep(ep->pcd->cfi, ep);
02060 if (!cfiep) {
02061 CFI_INFO("%s: Failed to find ep\n", __func__);
02062 return -1;
02063 }
02064
02065 ddesc = ep->dwc_ep.descs;
02066
02067 for (i = 0; (i < cfiep->desc_count) && (i < MAX_DMA_DESCS_PER_EP); i++) {
02068
02069 #if defined(PRINT_CFI_DMA_DESCS)
02070 print_desc(ddesc, ep->ep.name, i);
02071 #endif
02072 ret += ddesc->status.b.bytes;
02073 ddesc++;
02074 }
02075
02076 if (ret)
02077 CFI_INFO("!!!!!!!!!! WARNING (%s) - residue=%d\n", __func__,
02078 ret);
02079
02080 return ret;
02081 }
02082 #endif
02083
02088 static void complete_ep(dwc_otg_pcd_ep_t * ep)
02089 {
02090 dwc_otg_core_if_t *core_if = GET_CORE_IF(ep->pcd);
02091 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
02092 dwc_otg_dev_in_ep_regs_t *in_ep_regs =
02093 dev_if->in_ep_regs[ep->dwc_ep.num];
02094 deptsiz_data_t deptsiz;
02095 dev_dma_desc_sts_t desc_sts;
02096 dwc_otg_pcd_request_t *req = 0;
02097 dwc_otg_dev_dma_desc_t *dma_desc;
02098 uint32_t byte_count = 0;
02099 int is_last = 0;
02100 int i;
02101
02102 DWC_DEBUGPL(DBG_PCDV, "%s() %d-%s\n", __func__, ep->dwc_ep.num,
02103 (ep->dwc_ep.is_in ? "IN" : "OUT"));
02104
02105
02106 if (!DWC_CIRCLEQ_EMPTY(&ep->queue)) {
02107 req = DWC_CIRCLEQ_FIRST(&ep->queue);
02108 if (!req) {
02109 DWC_PRINTF("complete_ep 0x%p, req = NULL!\n", ep);
02110 return;
02111 }
02112 } else {
02113 DWC_PRINTF("complete_ep 0x%p, ep->queue empty!\n", ep);
02114 return;
02115 }
02116
02117 DWC_DEBUGPL(DBG_PCD, "Requests %d\n", ep->pcd->request_pending);
02118
02119 if (ep->dwc_ep.is_in) {
02120 deptsiz.d32 = DWC_READ_REG32(&in_ep_regs->dieptsiz);
02121
02122 if (core_if->dma_enable) {
02123 if (core_if->dma_desc_enable == 0) {
02124 if (deptsiz.b.xfersize == 0
02125 && deptsiz.b.pktcnt == 0) {
02126 byte_count =
02127 ep->dwc_ep.xfer_len -
02128 ep->dwc_ep.xfer_count;
02129
02130 ep->dwc_ep.xfer_buff += byte_count;
02131 ep->dwc_ep.dma_addr += byte_count;
02132 ep->dwc_ep.xfer_count += byte_count;
02133
02134 DWC_DEBUGPL(DBG_PCDV,
02135 "%d-%s len=%d xfersize=%d pktcnt=%d\n",
02136 ep->dwc_ep.num,
02137 (ep->dwc_ep.
02138 is_in ? "IN" : "OUT"),
02139 ep->dwc_ep.xfer_len,
02140 deptsiz.b.xfersize,
02141 deptsiz.b.pktcnt);
02142
02143 if (ep->dwc_ep.xfer_len <
02144 ep->dwc_ep.total_len) {
02145 dwc_otg_ep_start_transfer
02146 (core_if, &ep->dwc_ep);
02147 } else if (ep->dwc_ep.sent_zlp) {
02148
02149
02150
02151
02152
02153
02154
02155
02156
02157
02158
02159
02160
02161
02162
02163 ep->dwc_ep.sent_zlp = 0;
02164 dwc_otg_ep_start_zl_transfer
02165 (core_if, &ep->dwc_ep);
02166 } else {
02167 is_last = 1;
02168 }
02169 } else {
02170 if(ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC)
02171 {
02172 req->actual = 0;
02173 dwc_otg_request_done(ep, req, 0);
02174
02175 ep->dwc_ep.start_xfer_buff = 0;
02176 ep->dwc_ep.xfer_buff = 0;
02177 ep->dwc_ep.xfer_len = 0;
02178
02179
02180 start_next_request(ep);
02181 } else
02182 DWC_WARN
02183 ("Incomplete transfer (%d - %s [siz=%d pkt=%d])\n",
02184 ep->dwc_ep.num,
02185 (ep->dwc_ep.is_in ? "IN" : "OUT"),
02186 deptsiz.b.xfersize,
02187 deptsiz.b.pktcnt);
02188 }
02189 } else {
02190 dma_desc = ep->dwc_ep.desc_addr;
02191 byte_count = 0;
02192 ep->dwc_ep.sent_zlp = 0;
02193
02194 #ifdef DWC_UTE_CFI
02195 CFI_INFO("%s: BUFFER_MODE=%d\n", __func__,
02196 ep->dwc_ep.buff_mode);
02197 if (ep->dwc_ep.buff_mode != BM_STANDARD) {
02198 int residue;
02199
02200 residue = cfi_calc_desc_residue(ep);
02201 if (residue < 0)
02202 return;
02203
02204 byte_count = residue;
02205 } else {
02206 #endif
02207 for (i = 0; i < ep->dwc_ep.desc_cnt;
02208 ++i) {
02209 desc_sts = dma_desc->status;
02210 byte_count += desc_sts.b.bytes;
02211 dma_desc++;
02212 }
02213 #ifdef DWC_UTE_CFI
02214 }
02215 #endif
02216 if (byte_count == 0) {
02217 ep->dwc_ep.xfer_count =
02218 ep->dwc_ep.total_len;
02219 is_last = 1;
02220 } else {
02221 DWC_WARN("Incomplete transfer\n");
02222 }
02223 }
02224 } else {
02225 if (deptsiz.b.xfersize == 0 && deptsiz.b.pktcnt == 0) {
02226 DWC_DEBUGPL(DBG_PCDV,
02227 "%d-%s len=%d xfersize=%d pktcnt=%d\n",
02228 ep->dwc_ep.num,
02229 ep->dwc_ep.is_in ? "IN" : "OUT",
02230 ep->dwc_ep.xfer_len,
02231 deptsiz.b.xfersize,
02232 deptsiz.b.pktcnt);
02233
02234
02235
02236
02237 if (ep->dwc_ep.xfer_len < ep->dwc_ep.total_len) {
02238 dwc_otg_ep_start_transfer(core_if,
02239 &ep->dwc_ep);
02240 } else if (ep->dwc_ep.sent_zlp) {
02241
02242
02243
02244
02245
02246
02247
02248
02249
02250
02251
02252
02253
02254
02255
02256 ep->dwc_ep.sent_zlp = 0;
02257 dwc_otg_ep_start_zl_transfer(core_if,
02258 &ep->dwc_ep);
02259 } else {
02260 is_last = 1;
02261 }
02262 } else {
02263 DWC_WARN
02264 ("Incomplete transfer (%d-%s [siz=%d pkt=%d])\n",
02265 ep->dwc_ep.num,
02266 (ep->dwc_ep.is_in ? "IN" : "OUT"),
02267 deptsiz.b.xfersize, deptsiz.b.pktcnt);
02268 }
02269 }
02270 } else {
02271 dwc_otg_dev_out_ep_regs_t *out_ep_regs =
02272 dev_if->out_ep_regs[ep->dwc_ep.num];
02273 desc_sts.d32 = 0;
02274 if (core_if->dma_enable) {
02275 if (core_if->dma_desc_enable) {
02276 dma_desc = ep->dwc_ep.desc_addr;
02277 byte_count = 0;
02278 ep->dwc_ep.sent_zlp = 0;
02279
02280 #ifdef DWC_UTE_CFI
02281 CFI_INFO("%s: BUFFER_MODE=%d\n", __func__,
02282 ep->dwc_ep.buff_mode);
02283 if (ep->dwc_ep.buff_mode != BM_STANDARD) {
02284 int residue;
02285 residue = cfi_calc_desc_residue(ep);
02286 if (residue < 0)
02287 return;
02288 byte_count = residue;
02289 } else {
02290 #endif
02291
02292 for (i = 0; i < ep->dwc_ep.desc_cnt;
02293 ++i) {
02294 desc_sts = dma_desc->status;
02295 byte_count += desc_sts.b.bytes;
02296 dma_desc++;
02297 }
02298
02299 #ifdef DWC_UTE_CFI
02300 }
02301 #endif
02302
02303
02304
02305 if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_INTR &&
02306 (ep->dwc_ep.maxpacket%4)) {
02307 ep->dwc_ep.xfer_count = ep->dwc_ep.total_len - byte_count;
02308 if ((ep->dwc_ep.xfer_len % ep->dwc_ep.maxpacket) &&
02309 (ep->dwc_ep.xfer_len/ep->dwc_ep.maxpacket < MAX_DMA_DESC_CNT))
02310 ep->dwc_ep.xfer_len -=
02311 (ep->dwc_ep.desc_cnt - 1) * ep->dwc_ep.maxpacket +
02312 ep->dwc_ep.xfer_len % ep->dwc_ep.maxpacket;
02313 else
02314 ep->dwc_ep.xfer_len -=
02315 ep->dwc_ep.desc_cnt * ep->dwc_ep.maxpacket;
02316 if (ep->dwc_ep.xfer_len > 0) {
02317 dwc_otg_ep_start_transfer(core_if,
02318 &ep->dwc_ep);
02319 } else {
02320 is_last = 1;
02321 }
02322 } else {
02323 ep->dwc_ep.xfer_count = ep->dwc_ep.total_len
02324 - byte_count +
02325 ((4 - (ep->dwc_ep.total_len & 0x3)) & 0x3);
02326 is_last = 1;
02327 }
02328 } else {
02329 deptsiz.d32 = 0;
02330 deptsiz.d32 =
02331 DWC_READ_REG32(&out_ep_regs->doeptsiz);
02332
02333 byte_count = (ep->dwc_ep.xfer_len -
02334 ep->dwc_ep.xfer_count -
02335 deptsiz.b.xfersize);
02336 ep->dwc_ep.xfer_buff += byte_count;
02337 ep->dwc_ep.dma_addr += byte_count;
02338 ep->dwc_ep.xfer_count += byte_count;
02339
02340
02341
02342
02343 if (ep->dwc_ep.xfer_len < ep->dwc_ep.total_len) {
02344 dwc_otg_ep_start_transfer(core_if,
02345 &ep->dwc_ep);
02346 } else if (ep->dwc_ep.sent_zlp) {
02347
02348
02349
02350
02351
02352
02353
02354
02355
02356
02357
02358
02359
02360
02361
02362 ep->dwc_ep.sent_zlp = 0;
02363 dwc_otg_ep_start_zl_transfer(core_if,
02364 &ep->dwc_ep);
02365 } else {
02366 is_last = 1;
02367 }
02368 }
02369 } else {
02370
02371
02372
02373 if (ep->dwc_ep.xfer_len < ep->dwc_ep.total_len) {
02374 dwc_otg_ep_start_transfer(core_if, &ep->dwc_ep);
02375 } else if (ep->dwc_ep.sent_zlp) {
02376
02377
02378
02379
02380
02381
02382
02383
02384
02385
02386
02387
02388
02389
02390
02391 ep->dwc_ep.sent_zlp = 0;
02392 dwc_otg_ep_start_zl_transfer(core_if,
02393 &ep->dwc_ep);
02394 } else {
02395 is_last = 1;
02396 }
02397 }
02398
02399 DWC_DEBUGPL(DBG_PCDV,
02400 "addr %p, %d-%s len=%d cnt=%d xsize=%d pktcnt=%d\n",
02401 &out_ep_regs->doeptsiz, ep->dwc_ep.num,
02402 ep->dwc_ep.is_in ? "IN" : "OUT",
02403 ep->dwc_ep.xfer_len, ep->dwc_ep.xfer_count,
02404 deptsiz.b.xfersize, deptsiz.b.pktcnt);
02405 }
02406
02407
02408 if (is_last) {
02409 #ifdef DWC_UTE_CFI
02410 if (ep->dwc_ep.buff_mode != BM_STANDARD) {
02411 req->actual = ep->dwc_ep.cfi_req_len - byte_count;
02412 } else {
02413 #endif
02414 req->actual = ep->dwc_ep.xfer_count;
02415 #ifdef DWC_UTE_CFI
02416 }
02417 #endif
02418 if (req->dw_align_buf) {
02419 if (!ep->dwc_ep.is_in) {
02420 dwc_memcpy(req->buf, req->dw_align_buf, req->length);
02421 }
02422 DWC_DMA_FREE(req->length, req->dw_align_buf,
02423 req->dw_align_buf_dma);
02424 }
02425
02426 dwc_otg_request_done(ep, req, 0);
02427
02428 ep->dwc_ep.start_xfer_buff = 0;
02429 ep->dwc_ep.xfer_buff = 0;
02430 ep->dwc_ep.xfer_len = 0;
02431
02432
02433 start_next_request(ep);
02434 }
02435 }
02436
02437 #ifdef DWC_EN_ISOC
02438
02443 static void dwc_otg_pcd_handle_iso_bna(dwc_otg_pcd_ep_t * ep)
02444 {
02445 dwc_ep_t *dwc_ep = &ep->dwc_ep;
02446 volatile uint32_t *addr;
02447 depctl_data_t depctl = {.d32 = 0 };
02448 dwc_otg_pcd_t *pcd = ep->pcd;
02449 dwc_otg_dev_dma_desc_t *dma_desc;
02450 int i;
02451
02452 dma_desc =
02453 dwc_ep->iso_desc_addr + dwc_ep->desc_cnt * (dwc_ep->proc_buf_num);
02454
02455 if (dwc_ep->is_in) {
02456 dev_dma_desc_sts_t sts = {.d32 = 0 };
02457 for (i = 0; i < dwc_ep->desc_cnt; ++i, ++dma_desc) {
02458 sts.d32 = dma_desc->status.d32;
02459 sts.b_iso_in.bs = BS_HOST_READY;
02460 dma_desc->status.d32 = sts.d32;
02461 }
02462 } else {
02463 dev_dma_desc_sts_t sts = {.d32 = 0 };
02464 for (i = 0; i < dwc_ep->desc_cnt; ++i, ++dma_desc) {
02465 sts.d32 = dma_desc->status.d32;
02466 sts.b_iso_out.bs = BS_HOST_READY;
02467 dma_desc->status.d32 = sts.d32;
02468 }
02469 }
02470
02471 if (dwc_ep->is_in == 0) {
02472 addr =
02473 &GET_CORE_IF(pcd)->dev_if->out_ep_regs[dwc_ep->
02474 num]->doepctl;
02475 } else {
02476 addr =
02477 &GET_CORE_IF(pcd)->dev_if->in_ep_regs[dwc_ep->num]->diepctl;
02478 }
02479 depctl.b.epena = 1;
02480 DWC_MODIFY_REG32(addr, depctl.d32, depctl.d32);
02481 }
02482
02490 void set_current_pkt_info(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
02491 {
02492 deptsiz_data_t deptsiz = {.d32 = 0 };
02493 dma_addr_t dma_addr;
02494 uint32_t offset;
02495
02496 if (ep->proc_buf_num)
02497 dma_addr = ep->dma_addr1;
02498 else
02499 dma_addr = ep->dma_addr0;
02500
02501 if (ep->is_in) {
02502 deptsiz.d32 =
02503 DWC_READ_REG32(&core_if->dev_if->
02504 in_ep_regs[ep->num]->dieptsiz);
02505 offset = ep->data_per_frame;
02506 } else {
02507 deptsiz.d32 =
02508 DWC_READ_REG32(&core_if->dev_if->
02509 out_ep_regs[ep->num]->doeptsiz);
02510 offset =
02511 ep->data_per_frame +
02512 (0x4 & (0x4 - (ep->data_per_frame & 0x3)));
02513 }
02514
02515 if (!deptsiz.b.xfersize) {
02516 ep->pkt_info[ep->cur_pkt].length = ep->data_per_frame;
02517 ep->pkt_info[ep->cur_pkt].offset =
02518 ep->cur_pkt_dma_addr - dma_addr;
02519 ep->pkt_info[ep->cur_pkt].status = 0;
02520 } else {
02521 ep->pkt_info[ep->cur_pkt].length = ep->data_per_frame;
02522 ep->pkt_info[ep->cur_pkt].offset =
02523 ep->cur_pkt_dma_addr - dma_addr;
02524 ep->pkt_info[ep->cur_pkt].status = -DWC_E_NO_DATA;
02525 }
02526 ep->cur_pkt_addr += offset;
02527 ep->cur_pkt_dma_addr += offset;
02528 ep->cur_pkt++;
02529 }
02530
02538 static void set_ddma_iso_pkts_info(dwc_otg_core_if_t * core_if,
02539 dwc_ep_t * dwc_ep)
02540 {
02541 dwc_otg_dev_dma_desc_t *dma_desc;
02542 dev_dma_desc_sts_t sts = {.d32 = 0 };
02543 iso_pkt_info_t *iso_packet;
02544 uint32_t data_per_desc;
02545 uint32_t offset;
02546 int i, j;
02547
02548 iso_packet = dwc_ep->pkt_info;
02549
02552 if (dwc_ep->is_in == 0) {
02553 dma_desc =
02554 dwc_ep->iso_desc_addr +
02555 dwc_ep->desc_cnt * dwc_ep->proc_buf_num;
02556 offset = 0;
02557
02558 for (i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm;
02559 i += dwc_ep->pkt_per_frm) {
02560 for (j = 0; j < dwc_ep->pkt_per_frm; ++j) {
02561 data_per_desc =
02562 ((j + 1) * dwc_ep->maxpacket >
02563 dwc_ep->
02564 data_per_frame) ? dwc_ep->data_per_frame -
02565 j * dwc_ep->maxpacket : dwc_ep->maxpacket;
02566 data_per_desc +=
02567 (data_per_desc % 4) ? (4 -
02568 data_per_desc %
02569 4) : 0;
02570
02571 sts.d32 = dma_desc->status.d32;
02572
02573
02574 iso_packet->status =
02575 sts.b_iso_out.rxsts +
02576 (sts.b_iso_out.bs ^ BS_DMA_DONE);
02577 if (iso_packet->status) {
02578 iso_packet->status = -DWC_E_NO_DATA;
02579 }
02580
02581
02582 if (!sts.b_iso_out.rxbytes) {
02583 iso_packet->length =
02584 data_per_desc -
02585 sts.b_iso_out.rxbytes;
02586 } else {
02587 iso_packet->length =
02588 data_per_desc -
02589 sts.b_iso_out.rxbytes + (4 -
02590 dwc_ep->data_per_frame
02591 % 4);
02592 }
02593
02594 iso_packet->offset = offset;
02595
02596 offset += data_per_desc;
02597 dma_desc++;
02598 iso_packet++;
02599 }
02600 }
02601
02602 for (j = 0; j < dwc_ep->pkt_per_frm - 1; ++j) {
02603 data_per_desc =
02604 ((j + 1) * dwc_ep->maxpacket >
02605 dwc_ep->data_per_frame) ? dwc_ep->data_per_frame -
02606 j * dwc_ep->maxpacket : dwc_ep->maxpacket;
02607 data_per_desc +=
02608 (data_per_desc % 4) ? (4 - data_per_desc % 4) : 0;
02609
02610 sts.d32 = dma_desc->status.d32;
02611
02612
02613 iso_packet->status =
02614 sts.b_iso_out.rxsts +
02615 (sts.b_iso_out.bs ^ BS_DMA_DONE);
02616 if (iso_packet->status) {
02617 iso_packet->status = -DWC_E_NO_DATA;
02618 }
02619
02620
02621 iso_packet->length =
02622 dwc_ep->data_per_frame - sts.b_iso_out.rxbytes;
02623
02624 iso_packet->offset = offset;
02625
02626 offset += data_per_desc;
02627 iso_packet++;
02628 dma_desc++;
02629 }
02630
02631 sts.d32 = dma_desc->status.d32;
02632
02633
02634 iso_packet->status =
02635 sts.b_iso_out.rxsts + (sts.b_iso_out.bs ^ BS_DMA_DONE);
02636 if (iso_packet->status) {
02637 iso_packet->status = -DWC_E_NO_DATA;
02638 }
02639
02640 if (!sts.b_iso_out.rxbytes) {
02641 iso_packet->length =
02642 dwc_ep->data_per_frame - sts.b_iso_out.rxbytes;
02643 } else {
02644 iso_packet->length =
02645 dwc_ep->data_per_frame - sts.b_iso_out.rxbytes +
02646 (4 - dwc_ep->data_per_frame % 4);
02647 }
02648
02649 iso_packet->offset = offset;
02650 } else {
02653 dma_desc =
02654 dwc_ep->iso_desc_addr +
02655 dwc_ep->desc_cnt * dwc_ep->proc_buf_num;
02656
02657 for (i = 0; i < dwc_ep->desc_cnt - 1; i++) {
02658 sts.d32 = dma_desc->status.d32;
02659
02660
02661 iso_packet->status =
02662 sts.b_iso_in.txsts +
02663 (sts.b_iso_in.bs ^ BS_DMA_DONE);
02664 if (iso_packet->status != 0) {
02665 iso_packet->status = -DWC_E_NO_DATA;
02666
02667 }
02668
02669 iso_packet->length =
02670 dwc_ep->data_per_frame - sts.b_iso_in.txbytes;
02671
02672 dma_desc++;
02673 iso_packet++;
02674 }
02675
02676 sts.d32 = dma_desc->status.d32;
02677 while (sts.b_iso_in.bs == BS_DMA_BUSY) {
02678 sts.d32 = dma_desc->status.d32;
02679 }
02680
02681
02682 iso_packet->status =
02683 sts.b_iso_in.txsts + (sts.b_iso_in.bs ^ BS_DMA_DONE);
02684 if (iso_packet->status != 0) {
02685 iso_packet->status = -DWC_E_NO_DATA;
02686 }
02687
02688
02689 iso_packet->length =
02690 dwc_ep->data_per_frame - sts.b_iso_in.txbytes;
02691 }
02692 }
02693
02701 static void reinit_ddma_iso_xfer(dwc_otg_core_if_t * core_if, dwc_ep_t * dwc_ep)
02702 {
02703 int i, j;
02704 dwc_otg_dev_dma_desc_t *dma_desc;
02705 dma_addr_t dma_ad;
02706 volatile uint32_t *addr;
02707 dev_dma_desc_sts_t sts = {.d32 = 0 };
02708 uint32_t data_per_desc;
02709
02710 if (dwc_ep->is_in == 0) {
02711 addr = &core_if->dev_if->out_ep_regs[dwc_ep->num]->doepctl;
02712 } else {
02713 addr = &core_if->dev_if->in_ep_regs[dwc_ep->num]->diepctl;
02714 }
02715
02716 if (dwc_ep->proc_buf_num == 0) {
02718 dma_ad = dwc_ep->dma_addr0;
02719 } else {
02721 dma_ad = dwc_ep->dma_addr1;
02722 }
02723
02726 if (dwc_ep->is_in == 0) {
02727 dma_desc =
02728 dwc_ep->iso_desc_addr +
02729 dwc_ep->desc_cnt * dwc_ep->proc_buf_num;
02730
02731 sts.b_iso_out.bs = BS_HOST_READY;
02732 sts.b_iso_out.rxsts = 0;
02733 sts.b_iso_out.l = 0;
02734 sts.b_iso_out.sp = 0;
02735 sts.b_iso_out.ioc = 0;
02736 sts.b_iso_out.pid = 0;
02737 sts.b_iso_out.framenum = 0;
02738
02739 for (i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm;
02740 i += dwc_ep->pkt_per_frm) {
02741 for (j = 0; j < dwc_ep->pkt_per_frm; ++j) {
02742 data_per_desc =
02743 ((j + 1) * dwc_ep->maxpacket >
02744 dwc_ep->
02745 data_per_frame) ? dwc_ep->data_per_frame -
02746 j * dwc_ep->maxpacket : dwc_ep->maxpacket;
02747 data_per_desc +=
02748 (data_per_desc % 4) ? (4 -
02749 data_per_desc %
02750 4) : 0;
02751 sts.b_iso_out.rxbytes = data_per_desc;
02752 dma_desc->buf = dma_ad;
02753 dma_desc->status.d32 = sts.d32;
02754
02755 dma_ad += data_per_desc;
02756 dma_desc++;
02757 }
02758 }
02759
02760 for (j = 0; j < dwc_ep->pkt_per_frm - 1; ++j) {
02761
02762 data_per_desc =
02763 ((j + 1) * dwc_ep->maxpacket >
02764 dwc_ep->data_per_frame) ? dwc_ep->data_per_frame -
02765 j * dwc_ep->maxpacket : dwc_ep->maxpacket;
02766 data_per_desc +=
02767 (data_per_desc % 4) ? (4 - data_per_desc % 4) : 0;
02768 sts.b_iso_out.rxbytes = data_per_desc;
02769
02770 dma_desc->buf = dma_ad;
02771 dma_desc->status.d32 = sts.d32;
02772
02773 dma_desc++;
02774 dma_ad += data_per_desc;
02775 }
02776
02777 sts.b_iso_out.ioc = 1;
02778 sts.b_iso_out.l = dwc_ep->proc_buf_num;
02779
02780 data_per_desc =
02781 ((j + 1) * dwc_ep->maxpacket >
02782 dwc_ep->data_per_frame) ? dwc_ep->data_per_frame -
02783 j * dwc_ep->maxpacket : dwc_ep->maxpacket;
02784 data_per_desc +=
02785 (data_per_desc % 4) ? (4 - data_per_desc % 4) : 0;
02786 sts.b_iso_out.rxbytes = data_per_desc;
02787
02788 dma_desc->buf = dma_ad;
02789 dma_desc->status.d32 = sts.d32;
02790 } else {
02793 dma_desc =
02794 dwc_ep->iso_desc_addr +
02795 dwc_ep->desc_cnt * dwc_ep->proc_buf_num;
02796
02797 sts.b_iso_in.bs = BS_HOST_READY;
02798 sts.b_iso_in.txsts = 0;
02799 sts.b_iso_in.sp = 0;
02800 sts.b_iso_in.ioc = 0;
02801 sts.b_iso_in.pid = dwc_ep->pkt_per_frm;
02802 sts.b_iso_in.framenum = dwc_ep->next_frame;
02803 sts.b_iso_in.txbytes = dwc_ep->data_per_frame;
02804 sts.b_iso_in.l = 0;
02805
02806 for (i = 0; i < dwc_ep->desc_cnt - 1; i++) {
02807 dma_desc->buf = dma_ad;
02808 dma_desc->status.d32 = sts.d32;
02809
02810 sts.b_iso_in.framenum += dwc_ep->bInterval;
02811 dma_ad += dwc_ep->data_per_frame;
02812 dma_desc++;
02813 }
02814
02815 sts.b_iso_in.ioc = 1;
02816 sts.b_iso_in.l = dwc_ep->proc_buf_num;
02817
02818 dma_desc->buf = dma_ad;
02819 dma_desc->status.d32 = sts.d32;
02820
02821 dwc_ep->next_frame =
02822 sts.b_iso_in.framenum + dwc_ep->bInterval * 1;
02823 }
02824 dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1;
02825 }
02826
02835 static uint32_t handle_iso_out_pkt_dropped(dwc_otg_core_if_t * core_if,
02836 dwc_ep_t * dwc_ep)
02837 {
02838 uint32_t dma_addr;
02839 uint32_t drp_pkt;
02840 uint32_t drp_pkt_cnt;
02841 deptsiz_data_t deptsiz = {.d32 = 0 };
02842 depctl_data_t depctl = {.d32 = 0 };
02843 int i;
02844
02845 deptsiz.d32 =
02846 DWC_READ_REG32(&core_if->dev_if->
02847 out_ep_regs[dwc_ep->num]->doeptsiz);
02848
02849 drp_pkt = dwc_ep->pkt_cnt - deptsiz.b.pktcnt;
02850 drp_pkt_cnt = dwc_ep->pkt_per_frm - (drp_pkt % dwc_ep->pkt_per_frm);
02851
02852
02853 for (i = 0; i < drp_pkt_cnt; ++i) {
02854 dwc_ep->pkt_info[drp_pkt].status = -DWC_E_NO_DATA;
02855 drp_pkt++;
02856 deptsiz.b.pktcnt--;
02857 }
02858
02859 if (deptsiz.b.pktcnt > 0) {
02860 deptsiz.b.xfersize =
02861 dwc_ep->xfer_len - (dwc_ep->pkt_cnt -
02862 deptsiz.b.pktcnt) * dwc_ep->maxpacket;
02863 } else {
02864 deptsiz.b.xfersize = 0;
02865 deptsiz.b.pktcnt = 0;
02866 }
02867
02868 DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doeptsiz,
02869 deptsiz.d32);
02870
02871 if (deptsiz.b.pktcnt > 0) {
02872 if (dwc_ep->proc_buf_num) {
02873 dma_addr =
02874 dwc_ep->dma_addr1 + dwc_ep->xfer_len -
02875 deptsiz.b.xfersize;
02876 } else {
02877 dma_addr =
02878 dwc_ep->dma_addr0 + dwc_ep->xfer_len -
02879 deptsiz.b.xfersize;;
02880 }
02881
02882 DWC_WRITE_REG32(&core_if->dev_if->
02883 out_ep_regs[dwc_ep->num]->doepdma, dma_addr);
02884
02886 depctl.d32 = 0;
02887 depctl.b.epena = 1;
02888 depctl.b.cnak = 1;
02889
02890 DWC_MODIFY_REG32(&core_if->dev_if->
02891 out_ep_regs[dwc_ep->num]->doepctl, depctl.d32,
02892 depctl.d32);
02893 return 0;
02894 } else {
02895 return 1;
02896 }
02897 }
02898
02906 static uint32_t set_iso_pkts_info(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
02907 {
02908 int i, j;
02909 dma_addr_t dma_ad;
02910 iso_pkt_info_t *packet_info = ep->pkt_info;
02911 uint32_t offset;
02912 uint32_t frame_data;
02913 deptsiz_data_t deptsiz;
02914
02915 if (ep->proc_buf_num == 0) {
02917 dma_ad = ep->dma_addr0;
02918 } else {
02920 dma_ad = ep->dma_addr1;
02921 }
02922
02923 if (ep->is_in) {
02924 deptsiz.d32 =
02925 DWC_READ_REG32(&core_if->dev_if->
02926 in_ep_regs[ep->num]->dieptsiz);
02927 } else {
02928 deptsiz.d32 =
02929 DWC_READ_REG32(&core_if->dev_if->
02930 out_ep_regs[ep->num]->doeptsiz);
02931 }
02932
02933 if (!deptsiz.b.xfersize) {
02934 offset = 0;
02935 for (i = 0; i < ep->pkt_cnt; i += ep->pkt_per_frm) {
02936 frame_data = ep->data_per_frame;
02937 for (j = 0; j < ep->pkt_per_frm; ++j) {
02938
02939
02940
02941
02942
02943
02944 packet_info->length =
02945 (ep->maxpacket <
02946 frame_data) ? ep->maxpacket : frame_data;
02947
02948
02949 packet_info->offset = offset;
02950 offset += packet_info->length;
02951 frame_data -= packet_info->length;
02952
02953 packet_info++;
02954 }
02955 }
02956 return 1;
02957 } else {
02958
02959
02960
02961
02962
02963
02964
02965
02966
02967 if (ep->is_in) {
02968 return 1;
02969 } else {
02970 return handle_iso_out_pkt_dropped(core_if, ep);
02971 }
02972 }
02973 }
02974
02982 static void complete_iso_ep(dwc_otg_pcd_t * pcd, dwc_otg_pcd_ep_t * ep)
02983 {
02984 dwc_otg_core_if_t *core_if = GET_CORE_IF(ep->pcd);
02985 dwc_ep_t *dwc_ep = &ep->dwc_ep;
02986 uint8_t is_last = 0;
02987
02988 if (ep->dwc_ep.next_frame == 0xffffffff) {
02989 DWC_WARN("Next frame is not set!\n");
02990 return;
02991 }
02992
02993 if (core_if->dma_enable) {
02994 if (core_if->dma_desc_enable) {
02995 set_ddma_iso_pkts_info(core_if, dwc_ep);
02996 reinit_ddma_iso_xfer(core_if, dwc_ep);
02997 is_last = 1;
02998 } else {
02999 if (core_if->pti_enh_enable) {
03000 if (set_iso_pkts_info(core_if, dwc_ep)) {
03001 dwc_ep->proc_buf_num =
03002 (dwc_ep->proc_buf_num ^ 1) & 0x1;
03003 dwc_otg_iso_ep_start_buf_transfer
03004 (core_if, dwc_ep);
03005 is_last = 1;
03006 }
03007 } else {
03008 set_current_pkt_info(core_if, dwc_ep);
03009 if (dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
03010 is_last = 1;
03011 dwc_ep->cur_pkt = 0;
03012 dwc_ep->proc_buf_num =
03013 (dwc_ep->proc_buf_num ^ 1) & 0x1;
03014 if (dwc_ep->proc_buf_num) {
03015 dwc_ep->cur_pkt_addr =
03016 dwc_ep->xfer_buff1;
03017 dwc_ep->cur_pkt_dma_addr =
03018 dwc_ep->dma_addr1;
03019 } else {
03020 dwc_ep->cur_pkt_addr =
03021 dwc_ep->xfer_buff0;
03022 dwc_ep->cur_pkt_dma_addr =
03023 dwc_ep->dma_addr0;
03024 }
03025
03026 }
03027 dwc_otg_iso_ep_start_frm_transfer(core_if,
03028 dwc_ep);
03029 }
03030 }
03031 } else {
03032 set_current_pkt_info(core_if, dwc_ep);
03033 if (dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
03034 is_last = 1;
03035 dwc_ep->cur_pkt = 0;
03036 dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1;
03037 if (dwc_ep->proc_buf_num) {
03038 dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff1;
03039 dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr1;
03040 } else {
03041 dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff0;
03042 dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr0;
03043 }
03044
03045 }
03046 dwc_otg_iso_ep_start_frm_transfer(core_if, dwc_ep);
03047 }
03048 if (is_last)
03049 dwc_otg_iso_buffer_done(pcd, ep, ep->iso_req_handle);
03050 }
03051 #endif
03052
03057 static void dwc_otg_pcd_handle_noniso_bna(dwc_otg_pcd_ep_t * ep)
03058 {
03059 dwc_ep_t *dwc_ep = &ep->dwc_ep;
03060 volatile uint32_t *addr;
03061 depctl_data_t depctl = {.d32 = 0 };
03062 dwc_otg_pcd_t *pcd = ep->pcd;
03063 dwc_otg_dev_dma_desc_t *dma_desc;
03064 dev_dma_desc_sts_t sts = {.d32 = 0 };
03065 dwc_otg_core_if_t *core_if = ep->pcd->core_if;
03066 int i, start;
03067
03068 if (!dwc_ep->desc_cnt)
03069 DWC_WARN("Descriptor count = %d\n", dwc_ep->desc_cnt);
03070
03071 if (core_if->core_params->cont_on_bna && !dwc_ep->is_in
03072 && dwc_ep->type != DWC_OTG_EP_TYPE_CONTROL) {
03073 uint32_t doepdma;
03074 dwc_otg_dev_out_ep_regs_t *out_regs =
03075 core_if->dev_if->out_ep_regs[dwc_ep->num];
03076 doepdma = DWC_READ_REG32(&(out_regs->doepdma));
03077 start = (doepdma - dwc_ep->dma_desc_addr)/sizeof(dwc_otg_dev_dma_desc_t);
03078 dma_desc = &(dwc_ep->desc_addr[start]);
03079 } else {
03080 start = 0;
03081 dma_desc = dwc_ep->desc_addr;
03082 }
03083
03084
03085 for (i = start; i < dwc_ep->desc_cnt; ++i, ++dma_desc) {
03086 sts.d32 = dma_desc->status.d32;
03087 sts.b.bs = BS_HOST_READY;
03088 dma_desc->status.d32 = sts.d32;
03089 }
03090
03091 if (dwc_ep->is_in == 0) {
03092 addr =
03093 &GET_CORE_IF(pcd)->dev_if->out_ep_regs[dwc_ep->
03094 num]->doepctl;
03095 } else {
03096 addr =
03097 &GET_CORE_IF(pcd)->dev_if->in_ep_regs[dwc_ep->num]->diepctl;
03098 }
03099 depctl.b.epena = 1;
03100 depctl.b.cnak = 1;
03101 DWC_MODIFY_REG32(addr, 0, depctl.d32);
03102 }
03103
03110 static void handle_ep0(dwc_otg_pcd_t * pcd)
03111 {
03112 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
03113 dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
03114 dev_dma_desc_sts_t desc_sts;
03115 deptsiz0_data_t deptsiz;
03116 uint32_t byte_count;
03117
03118 #ifdef DEBUG_EP0
03119 DWC_DEBUGPL(DBG_PCDV, "%s()\n", __func__);
03120 print_ep0_state(pcd);
03121 #endif
03122
03123
03124
03125 switch (pcd->ep0state) {
03126 case EP0_DISCONNECT:
03127 break;
03128
03129 case EP0_IDLE:
03130 pcd->request_config = 0;
03131
03132 pcd_setup(pcd);
03133 break;
03134
03135 case EP0_IN_DATA_PHASE:
03136 #ifdef DEBUG_EP0
03137 DWC_DEBUGPL(DBG_PCD, "DATA_IN EP%d-%s: type=%d, mps=%d\n",
03138 ep0->dwc_ep.num, (ep0->dwc_ep.is_in ? "IN" : "OUT"),
03139 ep0->dwc_ep.type, ep0->dwc_ep.maxpacket);
03140 #endif
03141
03142 if (core_if->dma_enable != 0) {
03143
03144
03145
03146
03147
03148
03149
03150 if (core_if->dma_desc_enable == 0) {
03151 deptsiz.d32 =
03152 DWC_READ_REG32(&core_if->
03153 dev_if->in_ep_regs[0]->
03154 dieptsiz);
03155 byte_count =
03156 ep0->dwc_ep.xfer_len - deptsiz.b.xfersize;
03157 } else {
03158 desc_sts =
03159 core_if->dev_if->in_desc_addr->status;
03160 byte_count =
03161 ep0->dwc_ep.xfer_len - desc_sts.b.bytes;
03162 }
03163 ep0->dwc_ep.xfer_count += byte_count;
03164 ep0->dwc_ep.xfer_buff += byte_count;
03165 ep0->dwc_ep.dma_addr += byte_count;
03166 }
03167 if (ep0->dwc_ep.xfer_count < ep0->dwc_ep.total_len) {
03168 dwc_otg_ep0_continue_transfer(GET_CORE_IF(pcd),
03169 &ep0->dwc_ep);
03170 DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");
03171 } else if (ep0->dwc_ep.sent_zlp) {
03172 dwc_otg_ep0_continue_transfer(GET_CORE_IF(pcd),
03173 &ep0->dwc_ep);
03174 ep0->dwc_ep.sent_zlp = 0;
03175 DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");
03176 } else {
03177 ep0_complete_request(ep0);
03178 DWC_DEBUGPL(DBG_PCD, "COMPLETE TRANSFER\n");
03179 }
03180 break;
03181 case EP0_OUT_DATA_PHASE:
03182 #ifdef DEBUG_EP0
03183 DWC_DEBUGPL(DBG_PCD, "DATA_OUT EP%d-%s: type=%d, mps=%d\n",
03184 ep0->dwc_ep.num, (ep0->dwc_ep.is_in ? "IN" : "OUT"),
03185 ep0->dwc_ep.type, ep0->dwc_ep.maxpacket);
03186 #endif
03187 if (core_if->dma_enable != 0) {
03188 if (core_if->dma_desc_enable == 0) {
03189 deptsiz.d32 =
03190 DWC_READ_REG32(&core_if->
03191 dev_if->out_ep_regs[0]->
03192 doeptsiz);
03193 byte_count =
03194 ep0->dwc_ep.maxpacket - deptsiz.b.xfersize;
03195 } else {
03196 desc_sts =
03197 core_if->dev_if->out_desc_addr->status;
03198 byte_count =
03199 ep0->dwc_ep.maxpacket - desc_sts.b.bytes;
03200 }
03201 ep0->dwc_ep.xfer_count += byte_count;
03202 ep0->dwc_ep.xfer_buff += byte_count;
03203 ep0->dwc_ep.dma_addr += byte_count;
03204 }
03205 if (ep0->dwc_ep.xfer_count < ep0->dwc_ep.total_len) {
03206 dwc_otg_ep0_continue_transfer(GET_CORE_IF(pcd),
03207 &ep0->dwc_ep);
03208 DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");
03209 } else if (ep0->dwc_ep.sent_zlp) {
03210 dwc_otg_ep0_continue_transfer(GET_CORE_IF(pcd),
03211 &ep0->dwc_ep);
03212 ep0->dwc_ep.sent_zlp = 0;
03213 DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");
03214 } else {
03215 ep0_complete_request(ep0);
03216 DWC_DEBUGPL(DBG_PCD, "COMPLETE TRANSFER\n");
03217 }
03218 break;
03219
03220 case EP0_IN_STATUS_PHASE:
03221 case EP0_OUT_STATUS_PHASE:
03222 DWC_DEBUGPL(DBG_PCD, "CASE: EP0_STATUS\n");
03223 ep0_complete_request(ep0);
03224 pcd->ep0state = EP0_IDLE;
03225 ep0->stopped = 1;
03226 ep0->dwc_ep.is_in = 0;
03227
03228
03229 if (core_if->dma_enable) {
03230 ep0_out_start(core_if, pcd);
03231 }
03232 break;
03233
03234 case EP0_STALL:
03235 DWC_ERROR("EP0 STALLed, should not get here pcd_setup()\n");
03236 break;
03237 }
03238 #ifdef DEBUG_EP0
03239 print_ep0_state(pcd);
03240 #endif
03241 }
03242
03246 static void restart_transfer(dwc_otg_pcd_t * pcd, const uint32_t epnum)
03247 {
03248 dwc_otg_core_if_t *core_if;
03249 dwc_otg_dev_if_t *dev_if;
03250 deptsiz_data_t dieptsiz = {.d32 = 0 };
03251 dwc_otg_pcd_ep_t *ep;
03252
03253 ep = get_in_ep(pcd, epnum);
03254
03255 #ifdef DWC_EN_ISOC
03256 if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) {
03257 return;
03258 }
03259 #endif
03260
03261 core_if = GET_CORE_IF(pcd);
03262 dev_if = core_if->dev_if;
03263
03264 dieptsiz.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dieptsiz);
03265
03266 DWC_DEBUGPL(DBG_PCD, "xfer_buff=%p xfer_count=%0x xfer_len=%0x"
03267 " stopped=%d\n", ep->dwc_ep.xfer_buff,
03268 ep->dwc_ep.xfer_count, ep->dwc_ep.xfer_len, ep->stopped);
03269
03270
03271
03272 if (dieptsiz.b.pktcnt && dieptsiz.b.xfersize == 0 &&
03273 ep->dwc_ep.start_xfer_buff != 0) {
03274 if (ep->dwc_ep.total_len <= ep->dwc_ep.maxpacket) {
03275 ep->dwc_ep.xfer_count = 0;
03276 ep->dwc_ep.xfer_buff = ep->dwc_ep.start_xfer_buff;
03277 ep->dwc_ep.xfer_len = ep->dwc_ep.xfer_count;
03278 } else {
03279 ep->dwc_ep.xfer_count -= ep->dwc_ep.maxpacket;
03280
03281 ep->dwc_ep.xfer_buff -= ep->dwc_ep.maxpacket;
03282 ep->dwc_ep.xfer_len = ep->dwc_ep.xfer_count;
03283 }
03284 ep->stopped = 0;
03285 DWC_DEBUGPL(DBG_PCD, "xfer_buff=%p xfer_count=%0x "
03286 "xfer_len=%0x stopped=%d\n",
03287 ep->dwc_ep.xfer_buff,
03288 ep->dwc_ep.xfer_count, ep->dwc_ep.xfer_len,
03289 ep->stopped);
03290 if (epnum == 0) {
03291 dwc_otg_ep0_start_transfer(core_if, &ep->dwc_ep);
03292 } else {
03293 dwc_otg_ep_start_transfer(core_if, &ep->dwc_ep);
03294 }
03295 }
03296 }
03297
03298
03299
03300
03301
03302
03303 void predict_nextep_seq( dwc_otg_core_if_t * core_if)
03304 {
03305 dwc_otg_device_global_regs_t *dev_global_regs =
03306 core_if->dev_if->dev_global_regs;
03307 const uint32_t TOKEN_Q_DEPTH = core_if->hwcfg2.b.dev_token_q_depth;
03308
03309 const int DTKNQ_REG_CNT = (TOKEN_Q_DEPTH + 7) / 8;
03310 dtknq1_data_t dtknqr1;
03311 uint32_t in_tkn_epnums[4];
03312 uint8_t seqnum[MAX_EPS_CHANNELS];
03313 uint8_t intkn_seq[TOKEN_Q_DEPTH];
03314 grstctl_t resetctl = {.d32 = 0 };
03315 uint8_t temp;
03316 int ndx = 0;
03317 int start = 0;
03318 int end = 0;
03319 int sort_done = 0;
03320 int i = 0;
03321 volatile uint32_t *addr = &dev_global_regs->dtknqr1;
03322
03323
03324 DWC_DEBUGPL(DBG_PCD,"dev_token_q_depth=%d\n",TOKEN_Q_DEPTH);
03325
03326
03327 for (i = 0; i < DTKNQ_REG_CNT; i++) {
03328 in_tkn_epnums[i] = DWC_READ_REG32(addr);
03329 DWC_DEBUGPL(DBG_PCDV, "DTKNQR%d=0x%08x\n", i + 1,
03330 in_tkn_epnums[i]);
03331 if (addr == &dev_global_regs->dvbusdis) {
03332 addr = &dev_global_regs->dtknqr3_dthrctl;
03333 } else {
03334 ++addr;
03335 }
03336
03337 }
03338
03339
03340 dtknqr1.d32 = in_tkn_epnums[0];
03341 if (dtknqr1.b.wrap_bit) {
03342 ndx = dtknqr1.b.intknwptr;
03343 end = ndx -1;
03344 if (end < 0)
03345 end = TOKEN_Q_DEPTH -1;
03346 } else {
03347 ndx = 0;
03348 end = dtknqr1.b.intknwptr -1;
03349 if (end < 0)
03350 end = 0;
03351 }
03352 start = ndx;
03353
03354
03355 for (i=0; i <= core_if->dev_if->num_in_eps; i++) {
03356 seqnum[i] = i +31;
03357 }
03358
03359
03360 for (i=0; i < 6; i++)
03361 intkn_seq[i] = (in_tkn_epnums[0] >> ((7-i) * 4)) & 0xf;
03362
03363 if (TOKEN_Q_DEPTH > 6) {
03364
03365 for (i=6; i < 14; i++)
03366 intkn_seq[i] = (in_tkn_epnums[1] >> ((7-(i-6)) * 4)) & 0xf;
03367 }
03368
03369 if (TOKEN_Q_DEPTH > 14) {
03370
03371 for (i=14; i < 22; i++)
03372 intkn_seq[i] = (in_tkn_epnums[2] >> ((7-(i-14)) * 4)) & 0xf;
03373 }
03374
03375 if (TOKEN_Q_DEPTH > 22) {
03376
03377 for (i=22; i < 30; i++)
03378 intkn_seq[i] = (in_tkn_epnums[3] >> ((7-(i-22)) * 4)) & 0xf;
03379 }
03380
03381 DWC_DEBUGPL(DBG_PCDV,"%s start=%d end=%d intkn_seq[]:\n", __func__, start, end);
03382 for (i=0; i<TOKEN_Q_DEPTH; i++)
03383 DWC_DEBUGPL(DBG_PCDV,"%d\n", intkn_seq[i]);
03384
03385
03386 i = 0;
03387 do {
03388 seqnum[intkn_seq[ndx]] = i;
03389 ndx++;
03390 i++;
03391 if (ndx == TOKEN_Q_DEPTH)
03392 ndx = 0;
03393 } while ( i < TOKEN_Q_DEPTH );
03394
03395
03396 for (i=0; i<=core_if->dev_if->num_in_eps; i++) {
03397 if (core_if->nextep_seq[i] == 0xff )
03398 seqnum[i] = 0xff;
03399 }
03400
03401
03402 sort_done = 0;
03403 while (!sort_done) {
03404 sort_done = 1;
03405 for (i=0; i<core_if->dev_if->num_in_eps; i++) {
03406 if (seqnum[i] > seqnum[i+1]) {
03407 temp = seqnum[i];
03408 seqnum[i] = seqnum[i+1];
03409 seqnum[i+1] = temp;
03410 sort_done = 0;
03411 }
03412 }
03413 }
03414
03415 ndx = start + seqnum[0];
03416 if (ndx >= TOKEN_Q_DEPTH)
03417 ndx = ndx % TOKEN_Q_DEPTH;
03418 core_if->first_in_nextep_seq = intkn_seq[ndx];
03419
03420
03421 for (i=0; i<=core_if->dev_if->num_in_eps; i++) {
03422 ndx = start + i;
03423 if (seqnum[i] < 31) {
03424 ndx = start + seqnum[i];
03425 if (ndx >= TOKEN_Q_DEPTH)
03426 ndx = ndx % TOKEN_Q_DEPTH;
03427 seqnum[i] = intkn_seq[ndx];
03428 } else {
03429 if (seqnum[i] < 0xff) {
03430 seqnum[i] = seqnum[i] - 31;
03431 } else {
03432 break;
03433 }
03434 }
03435 }
03436
03437
03438 for (i=0; i<core_if->dev_if->num_in_eps; i++) {
03439 if (seqnum[i] != 0xff) {
03440 if (seqnum[i+1] != 0xff) {
03441 core_if->nextep_seq[seqnum[i]] = seqnum[i+1];
03442 } else {
03443 core_if->nextep_seq[seqnum[i]] = core_if->first_in_nextep_seq;
03444 break;
03445 }
03446 } else {
03447 break;
03448 }
03449 }
03450
03451 DWC_DEBUGPL(DBG_PCDV, "%s first_in_nextep_seq= %2d; nextep_seq[]:\n",
03452 __func__, core_if->first_in_nextep_seq);
03453 for (i=0; i <= core_if->dev_if->num_in_eps; i++) {
03454 DWC_DEBUGPL(DBG_PCDV,"%2d\n", core_if->nextep_seq[i]);
03455 }
03456
03457
03458 resetctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->grstctl);
03459 resetctl.b.intknqflsh = 1;
03460 DWC_WRITE_REG32(&core_if->core_global_regs->grstctl, resetctl.d32);
03461
03462
03463 }
03464
03468 static inline void handle_in_ep_disable_intr(dwc_otg_pcd_t * pcd,
03469 const uint32_t epnum)
03470 {
03471 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
03472 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
03473 deptsiz_data_t dieptsiz = {.d32 = 0 };
03474 dctl_data_t dctl = {.d32 = 0 };
03475 dwc_otg_pcd_ep_t *ep;
03476 dwc_ep_t *dwc_ep;
03477 gintmsk_data_t gintmsk_data;
03478 depctl_data_t depctl;
03479 uint32_t diepdma;
03480 uint32_t remain_to_transfer = 0;
03481 uint8_t i;
03482 uint32_t xfer_size;
03483
03484 ep = get_in_ep(pcd, epnum);
03485 dwc_ep = &ep->dwc_ep;
03486
03487 if (dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
03488 dwc_otg_flush_tx_fifo(core_if, dwc_ep->tx_fifo_num);
03489 complete_ep(ep);
03490 return;
03491 }
03492
03493 DWC_DEBUGPL(DBG_PCD, "diepctl%d=%0x\n", epnum,
03494 DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->diepctl));
03495 dieptsiz.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dieptsiz);
03496 depctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->diepctl);
03497
03498 DWC_DEBUGPL(DBG_ANY, "pktcnt=%d size=%d\n",
03499 dieptsiz.b.pktcnt, dieptsiz.b.xfersize);
03500
03501 if ((core_if->start_predict == 0) || (depctl.b.eptype & 1)) {
03502 if (ep->stopped) {
03503 if (core_if->en_multiple_tx_fifo)
03504
03505 dwc_otg_flush_tx_fifo(core_if, dwc_ep->tx_fifo_num);
03506
03507 dctl.d32 = 0;
03508 dctl.b.cgnpinnak = 1;
03509 DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl, dctl.d32, dctl.d32);
03510
03511 if (dieptsiz.b.pktcnt != 0 || dieptsiz.b.xfersize != 0) {
03512 restart_transfer(pcd, epnum);
03513 }
03514 } else {
03515
03516 if (dieptsiz.b.pktcnt != 0 || dieptsiz.b.xfersize != 0) {
03517 restart_transfer(pcd, epnum);
03518 }
03519 DWC_DEBUGPL(DBG_ANY, "STOPPED!!!\n");
03520 }
03521 return;
03522 }
03523
03524 if (core_if->start_predict > 2) {
03525 core_if->start_predict--;
03526 return;
03527 }
03528
03529 core_if->start_predict--;
03530
03531 if (core_if->start_predict == 1) {
03532
03533 predict_nextep_seq(core_if);
03534
03535
03536 for ( i = 0; i <= core_if->dev_if->num_in_eps; i++) {
03537 depctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl);
03538 if (core_if->nextep_seq[i] != 0xff) {
03539 depctl.b.nextep = core_if->nextep_seq[i];
03540 DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepctl, depctl.d32);
03541 }
03542 }
03543
03544 dwc_otg_flush_tx_fifo(core_if, 0);
03545
03546 if (!core_if->dma_desc_enable) {
03547 i = core_if->first_in_nextep_seq;
03548 do {
03549 ep = get_in_ep(pcd, i);
03550 dieptsiz.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[i]->dieptsiz);
03551 xfer_size = ep->dwc_ep.total_len - ep->dwc_ep.xfer_count;
03552 if (xfer_size > ep->dwc_ep.maxxfer)
03553 xfer_size = ep->dwc_ep.maxxfer;
03554 depctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl);
03555 if (dieptsiz.b.pktcnt != 0) {
03556 if (xfer_size == 0) {
03557 remain_to_transfer = 0;
03558 } else {
03559 if ((xfer_size % ep->dwc_ep.maxpacket) == 0) {
03560 remain_to_transfer =
03561 dieptsiz.b.pktcnt * ep->dwc_ep.maxpacket;
03562 } else {
03563 remain_to_transfer = ((dieptsiz.b.pktcnt -1) * ep->dwc_ep.maxpacket)
03564 + (xfer_size % ep->dwc_ep.maxpacket);
03565 }
03566 }
03567 diepdma = DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepdma);
03568 dieptsiz.b.xfersize = remain_to_transfer;
03569 DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->dieptsiz, dieptsiz.d32);
03570 diepdma = ep->dwc_ep.dma_addr + (xfer_size - remain_to_transfer);
03571 DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepdma, diepdma);
03572 }
03573 i = core_if->nextep_seq[i];
03574 } while (i != core_if->first_in_nextep_seq);
03575 } else {
03576 DWC_PRINTF("%s Learning Queue not supported in DDMA\n", __func__);
03577 }
03578
03579
03580 i = core_if->first_in_nextep_seq;
03581 do {
03582 dieptsiz.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[i]->dieptsiz);
03583 depctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl);
03584 if (dieptsiz.b.pktcnt != 0) {
03585 depctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl);
03586 depctl.b.epena = 1;
03587 depctl.b.cnak = 1;
03588 DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepctl, depctl.d32);
03589 }
03590 i = core_if->nextep_seq[i];
03591 } while (i != core_if->first_in_nextep_seq);
03592
03593
03594 dctl.d32 = 0;
03595 dctl.b.cgnpinnak = 1;
03596 DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl, dctl.d32, dctl.d32);
03597
03598
03599 gintmsk_data.d32 = 0;
03600 gintmsk_data.b.epmismatch = 1;
03601 DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, 0, gintmsk_data.d32);
03602
03603 core_if->start_predict = 0;
03604
03605 }
03606 }
03607
03611 static inline void handle_in_ep_timeout_intr(dwc_otg_pcd_t * pcd,
03612 const uint32_t epnum)
03613 {
03614 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
03615 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
03616
03617 #ifdef DEBUG
03618 deptsiz_data_t dieptsiz = {.d32 = 0 };
03619 uint32_t num = 0;
03620 #endif
03621 dctl_data_t dctl = {.d32 = 0 };
03622 dwc_otg_pcd_ep_t *ep;
03623
03624 gintmsk_data_t intr_mask = {.d32 = 0 };
03625
03626 ep = get_in_ep(pcd, epnum);
03627
03628
03629 if (!core_if->dma_enable) {
03630 intr_mask.b.nptxfempty = 1;
03631 DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk,
03632 intr_mask.d32, 0);
03633 }
03636
03637
03638
03639
03640 intr_mask.b.ginnakeff = 1;
03641 DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, 0, intr_mask.d32);
03642
03643
03644 dctl.b.sgnpinnak = 1;
03645 DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl, dctl.d32, dctl.d32);
03646
03647 ep->stopped = 1;
03648
03649 #ifdef DEBUG
03650 dieptsiz.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[num]->dieptsiz);
03651 DWC_DEBUGPL(DBG_ANY, "pktcnt=%d size=%d\n",
03652 dieptsiz.b.pktcnt, dieptsiz.b.xfersize);
03653 #endif
03654
03655 #ifdef DISABLE_PERIODIC_EP
03656
03657
03658
03659
03660 diepctl.d32 = 0;
03661 diepctl.b.snak = 1;
03662 DWC_MODIFY_REG32(&dev_if->in_ep_regs[num]->diepctl, diepctl.d32,
03663 diepctl.d32);
03664 ep->disabling = 1;
03665 ep->stopped = 1;
03666 #endif
03667 }
03668
03672 static inline int32_t handle_in_ep_nak_intr(dwc_otg_pcd_t * pcd,
03673 const uint32_t epnum)
03674 {
03676 dwc_otg_core_if_t *core_if;
03677 diepmsk_data_t intr_mask = {.d32 = 0 };
03678
03679 DWC_PRINTF("INTERRUPT Handler not implemented for %s\n", "IN EP NAK");
03680 core_if = GET_CORE_IF(pcd);
03681 intr_mask.b.nak = 1;
03682
03683 if (core_if->multiproc_int_enable) {
03684 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->
03685 diepeachintmsk[epnum], intr_mask.d32, 0);
03686 } else {
03687 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->diepmsk,
03688 intr_mask.d32, 0);
03689 }
03690
03691 return 1;
03692 }
03693
03697 static inline int32_t handle_out_ep_babble_intr(dwc_otg_pcd_t * pcd,
03698 const uint32_t epnum)
03699 {
03701 dwc_otg_core_if_t *core_if;
03702 doepmsk_data_t intr_mask = {.d32 = 0 };
03703
03704 DWC_PRINTF("INTERRUPT Handler not implemented for %s\n",
03705 "OUT EP Babble");
03706 core_if = GET_CORE_IF(pcd);
03707 intr_mask.b.babble = 1;
03708
03709 if (core_if->multiproc_int_enable) {
03710 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->
03711 doepeachintmsk[epnum], intr_mask.d32, 0);
03712 } else {
03713 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->doepmsk,
03714 intr_mask.d32, 0);
03715 }
03716
03717 return 1;
03718 }
03719
03723 static inline int32_t handle_out_ep_nak_intr(dwc_otg_pcd_t * pcd,
03724 const uint32_t epnum)
03725 {
03727 dwc_otg_core_if_t *core_if;
03728 doepmsk_data_t intr_mask = {.d32 = 0 };
03729
03730 DWC_PRINTF("INTERRUPT Handler not implemented for %s\n", "OUT EP NAK");
03731 core_if = GET_CORE_IF(pcd);
03732 intr_mask.b.nak = 1;
03733
03734 if (core_if->multiproc_int_enable) {
03735 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->
03736 doepeachintmsk[epnum], intr_mask.d32, 0);
03737 } else {
03738 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->doepmsk,
03739 intr_mask.d32, 0);
03740 }
03741
03742 return 1;
03743 }
03744
03748 static inline int32_t handle_out_ep_nyet_intr(dwc_otg_pcd_t * pcd,
03749 const uint32_t epnum)
03750 {
03752 dwc_otg_core_if_t *core_if;
03753 doepmsk_data_t intr_mask = {.d32 = 0 };
03754
03755 DWC_PRINTF("INTERRUPT Handler not implemented for %s\n", "OUT EP NYET");
03756 core_if = GET_CORE_IF(pcd);
03757 intr_mask.b.nyet = 1;
03758
03759 if (core_if->multiproc_int_enable) {
03760 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->
03761 doepeachintmsk[epnum], intr_mask.d32, 0);
03762 } else {
03763 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->doepmsk,
03764 intr_mask.d32, 0);
03765 }
03766
03767 return 1;
03768 }
03769
03786 static int32_t dwc_otg_pcd_handle_in_ep_intr(dwc_otg_pcd_t * pcd)
03787 {
03788 #define CLEAR_IN_EP_INTR(__core_if,__epnum,__intr) \
03789 do { \
03790 diepint_data_t diepint = {.d32=0}; \
03791 diepint.b.__intr = 1; \
03792 DWC_WRITE_REG32(&__core_if->dev_if->in_ep_regs[__epnum]->diepint, \
03793 diepint.d32); \
03794 } while (0)
03795
03796 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
03797 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
03798 diepint_data_t diepint = {.d32 = 0 };
03799 depctl_data_t depctl = {.d32 = 0 };
03800 uint32_t ep_intr;
03801 uint32_t epnum = 0;
03802 dwc_otg_pcd_ep_t *ep;
03803 dwc_ep_t *dwc_ep;
03804 gintmsk_data_t intr_mask = {.d32 = 0 };
03805
03806 DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, pcd);
03807
03808
03809 ep_intr = dwc_otg_read_dev_all_in_ep_intr(core_if);
03810
03811
03812 while (ep_intr) {
03813 if (ep_intr & 0x1) {
03814 uint32_t empty_msk;
03815
03816 ep = get_in_ep(pcd, epnum);
03817 dwc_ep = &ep->dwc_ep;
03818
03819 depctl.d32 =
03820 DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->diepctl);
03821 empty_msk =
03822 DWC_READ_REG32(&dev_if->
03823 dev_global_regs->dtknqr4_fifoemptymsk);
03824
03825 DWC_DEBUGPL(DBG_PCDV,
03826 "IN EP INTERRUPT - %d\nepmty_msk - %8x diepctl - %8x\n",
03827 epnum, empty_msk, depctl.d32);
03828
03829 DWC_DEBUGPL(DBG_PCD,
03830 "EP%d-%s: type=%d, mps=%d\n",
03831 dwc_ep->num, (dwc_ep->is_in ? "IN" : "OUT"),
03832 dwc_ep->type, dwc_ep->maxpacket);
03833
03834 diepint.d32 =
03835 dwc_otg_read_dev_in_ep_intr(core_if, dwc_ep);
03836
03837 DWC_DEBUGPL(DBG_PCDV,
03838 "EP %d Interrupt Register - 0x%x\n", epnum,
03839 diepint.d32);
03840
03841 if (diepint.b.xfercompl) {
03842
03843
03844 if (core_if->en_multiple_tx_fifo == 0) {
03845 intr_mask.b.nptxfempty = 1;
03846 DWC_MODIFY_REG32
03847 (&core_if->core_global_regs->gintmsk,
03848 intr_mask.d32, 0);
03849 } else {
03850
03851 uint32_t fifoemptymsk =
03852 0x1 << dwc_ep->num;
03853 DWC_MODIFY_REG32(&core_if->
03854 dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
03855 fifoemptymsk, 0);
03856 }
03857
03858 CLEAR_IN_EP_INTR(core_if, epnum, xfercompl);
03859
03860
03861 if (epnum == 0) {
03862 handle_ep0(pcd);
03863 }
03864 #ifdef DWC_EN_ISOC
03865 else if (dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
03866 if (!ep->stopped)
03867 complete_iso_ep(pcd, ep);
03868 }
03869 #endif
03870 #ifdef DWC_UTE_PER_IO
03871 else if (dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
03872 if (!ep->stopped)
03873 complete_xiso_ep(ep);
03874 }
03875 #endif
03876 else {
03877 if (dwc_ep->type == DWC_OTG_EP_TYPE_ISOC &&
03878 dwc_ep->bInterval > 1) {
03879 dwc_ep->frame_num += dwc_ep->bInterval;
03880 if (dwc_ep->frame_num > 0x3FFF)
03881 {
03882 dwc_ep->frm_overrun = 1;
03883 dwc_ep->frame_num &= 0x3FFF;
03884 } else
03885 dwc_ep->frm_overrun = 0;
03886 }
03887 complete_ep(ep);
03888 if(diepint.b.nak)
03889 CLEAR_IN_EP_INTR(core_if, epnum, nak);
03890 }
03891 }
03892
03893 if (diepint.b.epdisabled) {
03894 DWC_DEBUGPL(DBG_ANY, "EP%d IN disabled\n",
03895 epnum);
03896 handle_in_ep_disable_intr(pcd, epnum);
03897
03898
03899 CLEAR_IN_EP_INTR(core_if, epnum, epdisabled);
03900 }
03901
03902 if (diepint.b.ahberr) {
03903 DWC_ERROR("EP%d IN AHB Error\n", epnum);
03904
03905 CLEAR_IN_EP_INTR(core_if, epnum, ahberr);
03906 }
03907
03908 if (diepint.b.timeout) {
03909 DWC_ERROR("EP%d IN Time-out\n", epnum);
03910 handle_in_ep_timeout_intr(pcd, epnum);
03911
03912 CLEAR_IN_EP_INTR(core_if, epnum, timeout);
03913 }
03915 if (diepint.b.intktxfemp) {
03916 DWC_DEBUGPL(DBG_ANY,
03917 "EP%d IN TKN TxFifo Empty\n",
03918 epnum);
03919 if (!ep->stopped && epnum != 0) {
03920
03921 diepmsk_data_t diepmsk = {.d32 = 0 };
03922 diepmsk.b.intktxfemp = 1;
03923
03924 if (core_if->multiproc_int_enable) {
03925 DWC_MODIFY_REG32
03926 (&dev_if->dev_global_regs->diepeachintmsk
03927 [epnum], diepmsk.d32, 0);
03928 } else {
03929 DWC_MODIFY_REG32
03930 (&dev_if->dev_global_regs->diepmsk,
03931 diepmsk.d32, 0);
03932 }
03933 } else if (core_if->dma_desc_enable
03934 && epnum == 0
03935 && pcd->ep0state ==
03936 EP0_OUT_STATUS_PHASE) {
03937
03938 depctl.d32 =
03939 DWC_READ_REG32(&dev_if->in_ep_regs
03940 [epnum]->diepctl);
03941
03942
03943 if (depctl.b.epena) {
03944 depctl.b.epdis = 1;
03945 }
03946 depctl.b.stall = 1;
03947 DWC_WRITE_REG32(&dev_if->in_ep_regs
03948 [epnum]->diepctl,
03949 depctl.d32);
03950 }
03951 CLEAR_IN_EP_INTR(core_if, epnum, intktxfemp);
03952 }
03954 if (diepint.b.intknepmis) {
03955 DWC_DEBUGPL(DBG_ANY,
03956 "EP%d IN TKN EP Mismatch\n", epnum);
03957 CLEAR_IN_EP_INTR(core_if, epnum, intknepmis);
03958 }
03960 if (diepint.b.inepnakeff) {
03961 DWC_DEBUGPL(DBG_ANY,
03962 "EP%d IN EP NAK Effective\n",
03963 epnum);
03964
03965 if (ep->disabling) {
03966 depctl.d32 = 0;
03967 depctl.b.snak = 1;
03968 depctl.b.epdis = 1;
03969 DWC_MODIFY_REG32(&dev_if->in_ep_regs
03970 [epnum]->diepctl,
03971 depctl.d32,
03972 depctl.d32);
03973 }
03974 CLEAR_IN_EP_INTR(core_if, epnum, inepnakeff);
03975
03976 }
03977
03979 if (diepint.b.emptyintr) {
03980 DWC_DEBUGPL(DBG_ANY,
03981 "EP%d Tx FIFO Empty Intr \n",
03982 epnum);
03983 write_empty_tx_fifo(pcd, epnum);
03984
03985 CLEAR_IN_EP_INTR(core_if, epnum, emptyintr);
03986
03987 }
03988
03990 if (diepint.b.bna) {
03991 CLEAR_IN_EP_INTR(core_if, epnum, bna);
03992 if (core_if->dma_desc_enable) {
03993 #ifdef DWC_EN_ISOC
03994 if (dwc_ep->type ==
03995 DWC_OTG_EP_TYPE_ISOC) {
03996
03997
03998
03999
04000 if (dwc_ep->next_frame !=
04001 0xffffffff)
04002 dwc_otg_pcd_handle_iso_bna(ep);
04003 } else
04004 #endif
04005 {
04006 dwc_otg_pcd_handle_noniso_bna(ep);
04007 }
04008 }
04009 }
04010
04011 if (diepint.b.nak) {
04012 DWC_DEBUGPL(DBG_ANY, "EP%d IN NAK Interrupt\n",
04013 epnum);
04014 if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC)
04015 {
04016 depctl_data_t depctl;
04017 if (ep->dwc_ep.frame_num == 0xFFFFFFFF)
04018 {
04019 ep->dwc_ep.frame_num = core_if->frame_num;
04020 if (ep->dwc_ep.bInterval > 1)
04021 {
04022 depctl.d32 = 0;
04023 depctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->diepctl);
04024 if (ep->dwc_ep.frame_num & 0x1) {
04025 depctl.b.setd1pid = 1;
04026 depctl.b.setd0pid = 0;
04027 } else {
04028 depctl.b.setd0pid = 1;
04029 depctl.b.setd1pid = 0;
04030 }
04031 DWC_WRITE_REG32(&dev_if->in_ep_regs[epnum]->diepctl, depctl.d32);
04032 }
04033 start_next_request(ep);
04034 }
04035 ep->dwc_ep.frame_num += ep->dwc_ep.bInterval;
04036 if (dwc_ep->frame_num > 0x3FFF)
04037 {
04038 dwc_ep->frm_overrun = 1;
04039 dwc_ep->frame_num &= 0x3FFF;
04040 } else
04041 dwc_ep->frm_overrun = 0;
04042 }
04043
04044 CLEAR_IN_EP_INTR(core_if, epnum, nak);
04045 }
04046 }
04047 epnum++;
04048 ep_intr >>= 1;
04049 }
04050
04051 return 1;
04052 #undef CLEAR_IN_EP_INTR
04053 }
04054
04068 static int32_t dwc_otg_pcd_handle_out_ep_intr(dwc_otg_pcd_t * pcd)
04069 {
04070 #define CLEAR_OUT_EP_INTR(__core_if,__epnum,__intr) \
04071 do { \
04072 doepint_data_t doepint = {.d32=0}; \
04073 doepint.b.__intr = 1; \
04074 DWC_WRITE_REG32(&__core_if->dev_if->out_ep_regs[__epnum]->doepint, \
04075 doepint.d32); \
04076 } while (0)
04077
04078 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
04079 uint32_t ep_intr;
04080 doepint_data_t doepint = {.d32 = 0 };
04081 uint32_t epnum = 0;
04082 dwc_otg_pcd_ep_t *ep;
04083 dwc_ep_t *dwc_ep;
04084 dctl_data_t dctl = {.d32 = 0 };
04085 gintmsk_data_t gintmsk = {.d32 = 0 };
04086
04087
04088 DWC_DEBUGPL(DBG_PCDV, "%s()\n", __func__);
04089
04090
04091 ep_intr = dwc_otg_read_dev_all_out_ep_intr(core_if);
04092
04093 while (ep_intr) {
04094 if (ep_intr & 0x1) {
04095
04096 ep = get_out_ep(pcd, epnum);
04097 dwc_ep = &ep->dwc_ep;
04098
04099 #ifdef VERBOSE
04100 DWC_DEBUGPL(DBG_PCDV,
04101 "EP%d-%s: type=%d, mps=%d\n",
04102 dwc_ep->num, (dwc_ep->is_in ? "IN" : "OUT"),
04103 dwc_ep->type, dwc_ep->maxpacket);
04104 #endif
04105 doepint.d32 =
04106 dwc_otg_read_dev_out_ep_intr(core_if, dwc_ep);
04107
04108
04109 if (doepint.b.xfercompl) {
04110
04111 if (epnum == 0) {
04112
04113 CLEAR_OUT_EP_INTR(core_if, epnum,
04114 xfercompl);
04115 if (core_if->dma_desc_enable == 0
04116 || pcd->ep0state != EP0_IDLE)
04117 handle_ep0(pcd);
04118 #ifdef DWC_EN_ISOC
04119 } else if (dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
04120 if (doepint.b.pktdrpsts == 0) {
04121
04122 CLEAR_OUT_EP_INTR(core_if,
04123 epnum,
04124 xfercompl);
04125 complete_iso_ep(pcd, ep);
04126 } else {
04127
04128 doepint_data_t doepint = {.d32 = 0 };
04129 doepint.b.xfercompl = 1;
04130 doepint.b.pktdrpsts = 1;
04131 DWC_WRITE_REG32
04132 (&core_if->dev_if->out_ep_regs
04133 [epnum]->doepint,
04134 doepint.d32);
04135 if (handle_iso_out_pkt_dropped
04136 (core_if, dwc_ep)) {
04137 complete_iso_ep(pcd,
04138 ep);
04139 }
04140 }
04141 #endif
04142 #ifdef DWC_UTE_PER_IO
04143 } else if (dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
04144 CLEAR_OUT_EP_INTR(core_if, epnum, xfercompl);
04145 if (!ep->stopped)
04146 complete_xiso_ep(ep);
04147 #endif
04148 } else {
04149
04150 CLEAR_OUT_EP_INTR(core_if, epnum,
04151 xfercompl);
04152
04153 if (core_if->core_params->dev_out_nak) {
04154 DWC_TIMER_CANCEL(pcd->core_if->ep_xfer_timer[epnum]);
04155 pcd->core_if->ep_xfer_info[epnum].state = 0;
04156 #ifdef DEBUG
04157 print_memory_payload(pcd, dwc_ep);
04158 #endif
04159 }
04160 complete_ep(ep);
04161 }
04162
04163 }
04164
04165
04166 if (doepint.b.epdisabled) {
04167
04168
04169 CLEAR_OUT_EP_INTR(core_if, epnum, epdisabled);
04170 if (core_if->core_params->dev_out_nak) {
04171 #ifdef DEBUG
04172 print_memory_payload(pcd, dwc_ep);
04173 #endif
04174
04175 if (core_if->ep_xfer_info[epnum].state == 2) {
04176 dctl.d32 = DWC_READ_REG32(&core_if->dev_if->
04177 dev_global_regs->dctl);
04178 dctl.b.cgoutnak = 1;
04179 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl,
04180 dctl.d32);
04181
04182
04183 gintmsk.b.goutnakeff = 1;
04184 DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk,
04185 0, gintmsk.d32);
04186
04187 complete_ep(ep);
04188 }
04189 }
04190 if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC)
04191 {
04192 dctl_data_t dctl;
04193 gintmsk_data_t intr_mask = {.d32 = 0};
04194 dwc_otg_pcd_request_t *req = 0;
04195
04196 dctl.d32 = DWC_READ_REG32(&core_if->dev_if->
04197 dev_global_regs->dctl);
04198 dctl.b.cgoutnak = 1;
04199 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl,
04200 dctl.d32);
04201
04202 intr_mask.d32 = 0;
04203 intr_mask.b.incomplisoout = 1;
04204
04205
04206 if (!DWC_CIRCLEQ_EMPTY(&ep->queue)) {
04207 req = DWC_CIRCLEQ_FIRST(&ep->queue);
04208 if (!req) {
04209 DWC_PRINTF("complete_ep 0x%p, req = NULL!\n", ep);
04210 } else {
04211 dwc_otg_request_done(ep, req, 0);
04212 start_next_request(ep);
04213 }
04214 } else {
04215 DWC_PRINTF("complete_ep 0x%p, ep->queue empty!\n", ep);
04216 }
04217 }
04218 }
04219
04220 if (doepint.b.ahberr) {
04221 DWC_ERROR("EP%d OUT AHB Error\n", epnum);
04222 DWC_ERROR("EP%d DEPDMA=0x%08x \n",
04223 epnum, core_if->dev_if->out_ep_regs[epnum]->doepdma);
04224 CLEAR_OUT_EP_INTR(core_if, epnum, ahberr);
04225 }
04226
04227 if (doepint.b.setup) {
04228 #ifdef DEBUG_EP0
04229 DWC_DEBUGPL(DBG_PCD, "EP%d SETUP Done\n",
04230 epnum);
04231 #endif
04232 CLEAR_OUT_EP_INTR(core_if, epnum, setup);
04233
04234 handle_ep0(pcd);
04235 }
04236
04238 if (doepint.b.bna) {
04239 CLEAR_OUT_EP_INTR(core_if, epnum, bna);
04240 if (core_if->dma_desc_enable) {
04241 #ifdef DWC_EN_ISOC
04242 if (dwc_ep->type ==
04243 DWC_OTG_EP_TYPE_ISOC) {
04244
04245
04246
04247
04248 if (dwc_ep->next_frame !=
04249 0xffffffff)
04250 dwc_otg_pcd_handle_iso_bna(ep);
04251 } else
04252 #endif
04253 {
04254 dwc_otg_pcd_handle_noniso_bna(ep);
04255 }
04256 }
04257 }
04258 if (doepint.b.stsphsercvd) {
04259 CLEAR_OUT_EP_INTR(core_if, epnum, stsphsercvd);
04260 if (core_if->dma_desc_enable) {
04261 do_setup_in_status_phase(pcd);
04262 }
04263 }
04264
04265 if (doepint.b.babble) {
04266 DWC_DEBUGPL(DBG_ANY, "EP%d OUT Babble\n",
04267 epnum);
04268 handle_out_ep_babble_intr(pcd, epnum);
04269
04270 CLEAR_OUT_EP_INTR(core_if, epnum, babble);
04271 }
04272 if (doepint.b.outtknepdis)
04273 {
04274 DWC_DEBUGPL(DBG_ANY, "EP%d OUT Token received when EP is \
04275 disabled\n",epnum);
04276 if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC)
04277 {
04278 doepmsk_data_t doepmsk = {.d32 = 0};
04279 ep->dwc_ep.frame_num = core_if->frame_num;
04280 if (ep->dwc_ep.bInterval > 1)
04281 {
04282 depctl_data_t depctl;
04283 depctl.d32 = DWC_READ_REG32(&core_if->dev_if->
04284 out_ep_regs[epnum]->doepctl);
04285 if (ep->dwc_ep.frame_num & 0x1) {
04286 depctl.b.setd1pid = 1;
04287 depctl.b.setd0pid = 0;
04288 } else {
04289 depctl.b.setd0pid = 1;
04290 depctl.b.setd1pid = 0;
04291 }
04292 DWC_WRITE_REG32(&core_if->dev_if->
04293 out_ep_regs[epnum]->doepctl, depctl.d32);
04294 }
04295 start_next_request(ep);
04296 doepmsk.b.outtknepdis = 1;
04297 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->doepmsk,
04298 doepmsk.d32, 0);
04299 }
04300 CLEAR_OUT_EP_INTR(core_if, epnum, outtknepdis);
04301 }
04302
04303
04304 if (doepint.b.nak) {
04305 DWC_DEBUGPL(DBG_ANY, "EP%d OUT NAK\n", epnum);
04306 handle_out_ep_nak_intr(pcd, epnum);
04307
04308 CLEAR_OUT_EP_INTR(core_if, epnum, nak);
04309 }
04310
04311 if (doepint.b.nyet) {
04312 DWC_DEBUGPL(DBG_ANY, "EP%d OUT NYET\n", epnum);
04313 handle_out_ep_nyet_intr(pcd, epnum);
04314
04315 CLEAR_OUT_EP_INTR(core_if, epnum, nyet);
04316 }
04317 }
04318
04319 epnum++;
04320 ep_intr >>= 1;
04321 }
04322
04323 return 1;
04324
04325 #undef CLEAR_OUT_EP_INTR
04326 }
04327 static int drop_transfer(uint32_t trgt_fr, uint32_t curr_fr, uint8_t frm_overrun)
04328 {
04329 int retval = 0;
04330 if(!frm_overrun && curr_fr >= trgt_fr)
04331 retval = 1;
04332 else if (frm_overrun && (curr_fr >= trgt_fr && ((curr_fr - trgt_fr) < 0x3FFF/2)))
04333 retval = 1;
04334 return retval;
04335 }
04348 int32_t dwc_otg_pcd_handle_incomplete_isoc_in_intr(dwc_otg_pcd_t * pcd)
04349 {
04350 gintsts_data_t gintsts;
04351
04352 #ifdef DWC_EN_ISOC
04353 dwc_otg_dev_if_t *dev_if;
04354 deptsiz_data_t deptsiz = {.d32 = 0 };
04355 depctl_data_t depctl = {.d32 = 0 };
04356 dsts_data_t dsts = {.d32 = 0 };
04357 dwc_ep_t *dwc_ep;
04358 int i;
04359
04360 dev_if = GET_CORE_IF(pcd)->dev_if;
04361
04362 for (i = 1; i <= dev_if->num_in_eps; ++i) {
04363 dwc_ep = &pcd->in_ep[i].dwc_ep;
04364 if (dwc_ep->active && dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
04365 deptsiz.d32 =
04366 DWC_READ_REG32(&dev_if->in_ep_regs[i]->dieptsiz);
04367 depctl.d32 =
04368 DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl);
04369
04370 if (depctl.b.epdis && deptsiz.d32) {
04371 set_current_pkt_info(GET_CORE_IF(pcd), dwc_ep);
04372 if (dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
04373 dwc_ep->cur_pkt = 0;
04374 dwc_ep->proc_buf_num =
04375 (dwc_ep->proc_buf_num ^ 1) & 0x1;
04376
04377 if (dwc_ep->proc_buf_num) {
04378 dwc_ep->cur_pkt_addr =
04379 dwc_ep->xfer_buff1;
04380 dwc_ep->cur_pkt_dma_addr =
04381 dwc_ep->dma_addr1;
04382 } else {
04383 dwc_ep->cur_pkt_addr =
04384 dwc_ep->xfer_buff0;
04385 dwc_ep->cur_pkt_dma_addr =
04386 dwc_ep->dma_addr0;
04387 }
04388
04389 }
04390
04391 dsts.d32 =
04392 DWC_READ_REG32(&GET_CORE_IF(pcd)->dev_if->
04393 dev_global_regs->dsts);
04394 dwc_ep->next_frame = dsts.b.soffn;
04395
04396 dwc_otg_iso_ep_start_frm_transfer(GET_CORE_IF
04397 (pcd),
04398 dwc_ep);
04399 }
04400 }
04401 }
04402
04403 #else
04404 depctl_data_t depctl = {.d32 = 0 };
04405 dwc_ep_t *dwc_ep;
04406 dwc_otg_dev_if_t *dev_if;
04407 int i;
04408 dev_if = GET_CORE_IF(pcd)->dev_if;
04409
04410 DWC_DEBUGPL(DBG_PCD,"Incomplete ISO IN \n");
04411
04412 for (i = 1; i <= dev_if->num_in_eps; ++i) {
04413 dwc_ep = &pcd->in_ep[i-1].dwc_ep;
04414 depctl.d32 =
04415 DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl);
04416 if (depctl.b.epena && dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
04417 if (drop_transfer(dwc_ep->frame_num, GET_CORE_IF(pcd)->frame_num,
04418 dwc_ep->frm_overrun))
04419 {
04420 depctl.d32 =
04421 DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl);
04422 depctl.b.snak = 1;
04423 depctl.b.epdis = 1;
04424 DWC_MODIFY_REG32(&dev_if->in_ep_regs[i]->diepctl, depctl.d32, depctl.d32);
04425 }
04426 }
04427 }
04428
04429
04430
04431
04432 #endif //DWC_EN_ISOC
04433
04434
04435 gintsts.d32 = 0;
04436 gintsts.b.incomplisoin = 1;
04437 DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
04438 gintsts.d32);
04439
04440 return 1;
04441 }
04442
04458 int32_t dwc_otg_pcd_handle_incomplete_isoc_out_intr(dwc_otg_pcd_t * pcd)
04459 {
04460
04461 gintsts_data_t gintsts;
04462
04463 #ifdef DWC_EN_ISOC
04464 dwc_otg_dev_if_t *dev_if;
04465 deptsiz_data_t deptsiz = {.d32 = 0 };
04466 depctl_data_t depctl = {.d32 = 0 };
04467 dsts_data_t dsts = {.d32 = 0 };
04468 dwc_ep_t *dwc_ep;
04469 int i;
04470
04471 dev_if = GET_CORE_IF(pcd)->dev_if;
04472
04473 for (i = 1; i <= dev_if->num_out_eps; ++i) {
04474 dwc_ep = &pcd->in_ep[i].dwc_ep;
04475 if (pcd->out_ep[i].dwc_ep.active &&
04476 pcd->out_ep[i].dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) {
04477 deptsiz.d32 =
04478 DWC_READ_REG32(&dev_if->out_ep_regs[i]->doeptsiz);
04479 depctl.d32 =
04480 DWC_READ_REG32(&dev_if->out_ep_regs[i]->doepctl);
04481
04482 if (depctl.b.epdis && deptsiz.d32) {
04483 set_current_pkt_info(GET_CORE_IF(pcd),
04484 &pcd->out_ep[i].dwc_ep);
04485 if (dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
04486 dwc_ep->cur_pkt = 0;
04487 dwc_ep->proc_buf_num =
04488 (dwc_ep->proc_buf_num ^ 1) & 0x1;
04489
04490 if (dwc_ep->proc_buf_num) {
04491 dwc_ep->cur_pkt_addr =
04492 dwc_ep->xfer_buff1;
04493 dwc_ep->cur_pkt_dma_addr =
04494 dwc_ep->dma_addr1;
04495 } else {
04496 dwc_ep->cur_pkt_addr =
04497 dwc_ep->xfer_buff0;
04498 dwc_ep->cur_pkt_dma_addr =
04499 dwc_ep->dma_addr0;
04500 }
04501
04502 }
04503
04504 dsts.d32 =
04505 DWC_READ_REG32(&GET_CORE_IF(pcd)->dev_if->
04506 dev_global_regs->dsts);
04507 dwc_ep->next_frame = dsts.b.soffn;
04508
04509 dwc_otg_iso_ep_start_frm_transfer(GET_CORE_IF
04510 (pcd),
04511 dwc_ep);
04512 }
04513 }
04514 }
04515 #else
04516
04517 gintmsk_data_t intr_mask = {.d32 = 0 };
04518 dwc_otg_core_if_t *core_if;
04519 deptsiz_data_t deptsiz = {.d32 = 0 };
04520 depctl_data_t depctl = {.d32 = 0 };
04521 dctl_data_t dctl = {.d32 = 0 };
04522 dwc_ep_t *dwc_ep = NULL;
04523 int i;
04524 core_if = GET_CORE_IF(pcd);
04525
04526 for (i = 0; i < core_if->dev_if->num_out_eps; ++i) {
04527 dwc_ep = &pcd->out_ep[i].dwc_ep;
04528 depctl.d32 =
04529 DWC_READ_REG32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doepctl);
04530 if (depctl.b.epena && depctl.b.dpid == (core_if->frame_num & 0x1)) {
04531 core_if->dev_if->isoc_ep = dwc_ep;
04532 deptsiz.d32 =
04533 DWC_READ_REG32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doeptsiz);
04534 break;
04535 }
04536 }
04537 dctl.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl);
04538 gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
04539 intr_mask.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintmsk);
04540
04541 if (!intr_mask.b.goutnakeff) {
04542
04543 intr_mask.b.goutnakeff = 1;
04544 DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, intr_mask.d32);
04545 }
04546 if (!gintsts.b.goutnakeff) {
04547 dctl.b.sgoutnak = 1;
04548 }
04549 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32);
04550
04551 depctl.d32 = DWC_READ_REG32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doepctl);
04552 if (depctl.b.epena) {
04553 depctl.b.epdis = 1;
04554 depctl.b.snak = 1;
04555 }
04556 DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doepctl, depctl.d32);
04557
04558 intr_mask.d32 = 0;
04559 intr_mask.b.incomplisoout = 1;
04560
04561 #endif
04562
04563
04564 gintsts.d32 = 0;
04565 gintsts.b.incomplisoout = 1;
04566 DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
04567 gintsts.d32);
04568
04569 return 1;
04570 }
04571
04576 int32_t dwc_otg_pcd_handle_in_nak_effective(dwc_otg_pcd_t * pcd)
04577 {
04578 dwc_otg_dev_if_t *dev_if = GET_CORE_IF(pcd)->dev_if;
04579 depctl_data_t diepctl = {.d32 = 0 };
04580 gintmsk_data_t intr_mask = {.d32 = 0 };
04581 gintsts_data_t gintsts;
04582 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
04583 int i;
04584
04585 DWC_DEBUGPL(DBG_PCD, "Global IN NAK Effective\n");
04586
04587
04588 for (i = 0; i <= dev_if->num_in_eps; i++) {
04589 diepctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl);
04590 if (!(diepctl.b.eptype & 1) && diepctl.b.epena) {
04591 if (core_if->start_predict > 0)
04592 core_if->start_predict++;
04593 diepctl.b.epdis = 1;
04594 diepctl.b.snak = 1;
04595 DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepctl, diepctl.d32);
04596 }
04597 }
04598
04599
04600
04601 intr_mask.b.ginnakeff = 1;
04602 DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
04603 intr_mask.d32, 0);
04604
04605
04606 gintsts.d32 = 0;
04607 gintsts.b.ginnakeff = 1;
04608 DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
04609 gintsts.d32);
04610
04611 return 1;
04612 }
04613
04618 int32_t dwc_otg_pcd_handle_out_nak_effective(dwc_otg_pcd_t * pcd)
04619 {
04620 dwc_otg_dev_if_t *dev_if = GET_CORE_IF(pcd)->dev_if;
04621 gintmsk_data_t intr_mask = {.d32 = 0 };
04622 gintsts_data_t gintsts;
04623 depctl_data_t doepctl;
04624 int i;
04625
04626
04627 intr_mask.b.goutnakeff = 1;
04628 DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
04629 intr_mask.d32, 0);
04630
04631
04632 if (pcd->core_if->core_params->dev_out_nak) {
04633
04634
04635
04636 for (i = 0; i <= dev_if->num_out_eps; i++) {
04637 if ( pcd->core_if->ep_xfer_info[i].state == 2 )
04638 break;
04639 }
04640 if (i > dev_if->num_out_eps) {
04641 dctl_data_t dctl;
04642 dctl.d32 = DWC_READ_REG32(&dev_if->
04643 dev_global_regs->dctl);
04644 dctl.b.cgoutnak = 1;
04645 DWC_WRITE_REG32(&dev_if->dev_global_regs->dctl,
04646 dctl.d32);
04647 goto out;
04648 }
04649
04650
04651 doepctl.d32 = DWC_READ_REG32(&dev_if->
04652 out_ep_regs[i]->doepctl);
04653 if (doepctl.b.epena) {
04654 doepctl.b.epdis = 1;
04655 doepctl.b.snak = 1;
04656 }
04657 DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepctl, doepctl.d32);
04658 return 1;
04659 }
04660
04661 if(dev_if->isoc_ep)
04662 {
04663 dwc_ep_t *dwc_ep = (dwc_ep_t *)dev_if->isoc_ep;
04664 uint32_t epnum = dwc_ep->num;
04665 doepint_data_t doepint;
04666 doepint.d32 = DWC_READ_REG32(&dev_if->out_ep_regs[dwc_ep->num]->doepint);
04667 dev_if->isoc_ep = NULL;
04668 doepctl.d32 = DWC_READ_REG32(&dev_if->out_ep_regs[epnum]->doepctl);
04669 DWC_PRINTF("Before disable DOEPCTL = %08x\n", doepctl.d32);
04670 if (doepctl.b.epena) {
04671 doepctl.b.epdis = 1;
04672 doepctl.b.snak = 1;
04673 }
04674 DWC_WRITE_REG32(&dev_if->out_ep_regs[epnum]->doepctl, doepctl.d32);
04675 return 1;
04676 } else
04677 DWC_PRINTF("INTERRUPT Handler not implemented for %s\n",
04678 "Global OUT NAK Effective\n");
04679
04680 out:
04681
04682 gintsts.d32 = 0;
04683 gintsts.b.goutnakeff = 1;
04684 DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
04685 gintsts.d32);
04686
04687 return 1;
04688 }
04689
04702 int32_t dwc_otg_pcd_handle_intr(dwc_otg_pcd_t * pcd)
04703 {
04704 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
04705 #ifdef VERBOSE
04706 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
04707 #endif
04708 gintsts_data_t gintr_status;
04709 int32_t retval = 0;
04710
04711
04712 if (core_if->hibernation_suspend == 1) {
04713 return retval;
04714 }
04715 #ifdef VERBOSE
04716 DWC_DEBUGPL(DBG_ANY, "%s() gintsts=%08x gintmsk=%08x\n",
04717 __func__,
04718 DWC_READ_REG32(&global_regs->gintsts),
04719 DWC_READ_REG32(&global_regs->gintmsk));
04720 #endif
04721
04722 if (dwc_otg_is_device_mode(core_if)) {
04723 DWC_SPINLOCK(pcd->lock);
04724 #ifdef VERBOSE
04725 DWC_DEBUGPL(DBG_PCDV, "%s() gintsts=%08x gintmsk=%08x\n",
04726 __func__,
04727 DWC_READ_REG32(&global_regs->gintsts),
04728 DWC_READ_REG32(&global_regs->gintmsk));
04729 #endif
04730
04731 gintr_status.d32 = dwc_otg_read_core_intr(core_if);
04732
04733 DWC_DEBUGPL(DBG_PCDV, "%s: gintsts&gintmsk=%08x\n",
04734 __func__, gintr_status.d32);
04735
04736 if (gintr_status.b.sofintr) {
04737 retval |= dwc_otg_pcd_handle_sof_intr(pcd);
04738 }
04739 if (gintr_status.b.rxstsqlvl) {
04740 retval |=
04741 dwc_otg_pcd_handle_rx_status_q_level_intr(pcd);
04742 }
04743 if (gintr_status.b.nptxfempty) {
04744 retval |= dwc_otg_pcd_handle_np_tx_fifo_empty_intr(pcd);
04745 }
04746 if (gintr_status.b.goutnakeff) {
04747 retval |= dwc_otg_pcd_handle_out_nak_effective(pcd);
04748 }
04749 if (gintr_status.b.i2cintr) {
04750 retval |= dwc_otg_pcd_handle_i2c_intr(pcd);
04751 }
04752 if (gintr_status.b.erlysuspend) {
04753 retval |= dwc_otg_pcd_handle_early_suspend_intr(pcd);
04754 }
04755 if (gintr_status.b.usbreset) {
04756 retval |= dwc_otg_pcd_handle_usb_reset_intr(pcd);
04757 }
04758 if (gintr_status.b.enumdone) {
04759 retval |= dwc_otg_pcd_handle_enum_done_intr(pcd);
04760 }
04761 if (gintr_status.b.isooutdrop) {
04762 retval |=
04763 dwc_otg_pcd_handle_isoc_out_packet_dropped_intr
04764 (pcd);
04765 }
04766 if (gintr_status.b.eopframe) {
04767 retval |=
04768 dwc_otg_pcd_handle_end_periodic_frame_intr(pcd);
04769 }
04770 if (gintr_status.b.inepint) {
04771 if (!core_if->multiproc_int_enable) {
04772 retval |= dwc_otg_pcd_handle_in_ep_intr(pcd);
04773 }
04774 }
04775 if (gintr_status.b.outepintr) {
04776 if (!core_if->multiproc_int_enable) {
04777 retval |= dwc_otg_pcd_handle_out_ep_intr(pcd);
04778 }
04779 }
04780 if (gintr_status.b.epmismatch) {
04781 retval |= dwc_otg_pcd_handle_ep_mismatch_intr(pcd);
04782 }
04783 if (gintr_status.b.fetsusp) {
04784 retval |= dwc_otg_pcd_handle_ep_fetsusp_intr(pcd);
04785 }
04786 if (gintr_status.b.ginnakeff) {
04787 retval |= dwc_otg_pcd_handle_in_nak_effective(pcd);
04788 }
04789 if (gintr_status.b.incomplisoin) {
04790 retval |=
04791 dwc_otg_pcd_handle_incomplete_isoc_in_intr(pcd);
04792 }
04793 if (gintr_status.b.incomplisoout) {
04794 retval |=
04795 dwc_otg_pcd_handle_incomplete_isoc_out_intr(pcd);
04796 }
04797
04798
04799
04800
04801
04802 if (core_if->multiproc_int_enable) {
04803 retval |= dwc_otg_pcd_handle_in_ep_intr(pcd);
04804 retval |= dwc_otg_pcd_handle_out_ep_intr(pcd);
04805 }
04806 #ifdef VERBOSE
04807 DWC_DEBUGPL(DBG_PCDV, "%s() gintsts=%0x\n", __func__,
04808 DWC_READ_REG32(&global_regs->gintsts));
04809 #endif
04810 DWC_SPINUNLOCK(pcd->lock);
04811 }
04812 return retval;
04813 }
04814
04815 #endif