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
00042
00043 #define DEBUG_EP0
00044
00048 static void dwc_otg_pcd_update_otg(dwc_otg_pcd_t * pcd, const unsigned reset)
00049 {
00050
00051 if (reset) {
00052 pcd->b_hnp_enable = 0;
00053 pcd->a_hnp_support = 0;
00054 pcd->a_alt_hnp_support = 0;
00055 }
00056
00057 if (pcd->fops->hnp_changed) {
00058 pcd->fops->hnp_changed(pcd);
00059 }
00060 }
00061
00076 static inline void print_ep0_state(dwc_otg_pcd_t * pcd)
00077 {
00078 #ifdef DEBUG
00079 char str[40];
00080
00081 switch (pcd->ep0state) {
00082 case EP0_DISCONNECT:
00083 dwc_strcpy(str, "EP0_DISCONNECT");
00084 break;
00085 case EP0_IDLE:
00086 dwc_strcpy(str, "EP0_IDLE");
00087 break;
00088 case EP0_IN_DATA_PHASE:
00089 dwc_strcpy(str, "EP0_IN_DATA_PHASE");
00090 break;
00091 case EP0_OUT_DATA_PHASE:
00092 dwc_strcpy(str, "EP0_OUT_DATA_PHASE");
00093 break;
00094 case EP0_IN_STATUS_PHASE:
00095 dwc_strcpy(str, "EP0_IN_STATUS_PHASE");
00096 break;
00097 case EP0_OUT_STATUS_PHASE:
00098 dwc_strcpy(str, "EP0_OUT_STATUS_PHASE");
00099 break;
00100 case EP0_STALL:
00101 dwc_strcpy(str, "EP0_STALL");
00102 break;
00103 default:
00104 dwc_strcpy(str, "EP0_INVALID");
00105 }
00106
00107 DWC_DEBUGPL(DBG_ANY, "%s(%d)\n", str, pcd->ep0state);
00108 #endif
00109 }
00110
00111 #ifdef DWC_UTE_CFI
00112 static inline void print_desc(struct dwc_otg_dma_desc *ddesc,
00113 const uint8_t * epname, int descnum)
00114 {
00115 CFI_INFO
00116 ("%s DMA_DESC(%d) buf=0x%08x bytes=0x%04x; sp=0x%x; l=0x%x; sts=0x%02x; bs=0x%02x\n",
00117 epname, descnum, ddesc->buf, ddesc->status.b.bytes,
00118 ddesc->status.b.sp, ddesc->status.b.l, ddesc->status.b.sts,
00119 ddesc->status.b.bs);
00120 }
00121 #endif
00122
00126 static inline dwc_otg_pcd_ep_t *get_in_ep(dwc_otg_pcd_t * pcd, uint32_t ep_num)
00127 {
00128 int i;
00129 int num_in_eps = GET_CORE_IF(pcd)->dev_if->num_in_eps;
00130 if (ep_num == 0) {
00131 return &pcd->ep0;
00132 } else {
00133 for (i = 0; i < num_in_eps; ++i) {
00134 if (pcd->in_ep[i].dwc_ep.num == ep_num)
00135 return &pcd->in_ep[i];
00136 }
00137 return 0;
00138 }
00139 }
00140
00144 static inline dwc_otg_pcd_ep_t *get_out_ep(dwc_otg_pcd_t * pcd, uint32_t ep_num)
00145 {
00146 int i;
00147 int num_out_eps = GET_CORE_IF(pcd)->dev_if->num_out_eps;
00148 if (ep_num == 0) {
00149 return &pcd->ep0;
00150 } else {
00151 for (i = 0; i < num_out_eps; ++i) {
00152 if (pcd->out_ep[i].dwc_ep.num == ep_num)
00153 return &pcd->out_ep[i];
00154 }
00155 return 0;
00156 }
00157 }
00158
00163 dwc_otg_pcd_ep_t *get_ep_by_addr(dwc_otg_pcd_t * pcd, u16 wIndex)
00164 {
00165 dwc_otg_pcd_ep_t *ep;
00166 uint32_t ep_num = UE_GET_ADDR(wIndex);
00167
00168 if (ep_num == 0) {
00169 ep = &pcd->ep0;
00170 } else if (UE_GET_DIR(wIndex) == UE_DIR_IN) {
00171 ep = &pcd->in_ep[ep_num - 1];
00172 } else {
00173 ep = &pcd->out_ep[ep_num - 1];
00174 }
00175
00176 return ep;
00177 }
00178
00183 void start_next_request(dwc_otg_pcd_ep_t * ep)
00184 {
00185 dwc_otg_pcd_request_t *req = 0;
00186 uint32_t max_transfer =
00187 GET_CORE_IF(ep->pcd)->core_params->max_transfer_size;
00188
00189 #ifdef DWC_UTE_CFI
00190 struct dwc_otg_pcd *pcd;
00191 pcd = ep->pcd;
00192 #endif
00193
00194 if (!DWC_CIRCLEQ_EMPTY(&ep->queue)) {
00195 req = DWC_CIRCLEQ_FIRST(&ep->queue);
00196
00197 #ifdef DWC_UTE_CFI
00198 if (ep->dwc_ep.buff_mode != BM_STANDARD) {
00199 ep->dwc_ep.cfi_req_len = req->length;
00200 pcd->cfi->ops.build_descriptors(pcd->cfi, pcd, ep, req);
00201 } else {
00202 #endif
00203
00204 ep->dwc_ep.dma_addr = req->dma;
00205 ep->dwc_ep.start_xfer_buff = req->buf;
00206 ep->dwc_ep.xfer_buff = req->buf;
00207 ep->dwc_ep.sent_zlp = 0;
00208 ep->dwc_ep.total_len = req->length;
00209 ep->dwc_ep.xfer_len = 0;
00210 ep->dwc_ep.xfer_count = 0;
00211
00212 ep->dwc_ep.maxxfer = max_transfer;
00213 if (GET_CORE_IF(ep->pcd)->dma_desc_enable) {
00214 uint32_t out_max_xfer = DDMA_MAX_TRANSFER_SIZE
00215 - (DDMA_MAX_TRANSFER_SIZE % 4);
00216 if (ep->dwc_ep.is_in) {
00217 if (ep->dwc_ep.maxxfer >
00218 DDMA_MAX_TRANSFER_SIZE) {
00219 ep->dwc_ep.maxxfer =
00220 DDMA_MAX_TRANSFER_SIZE;
00221 }
00222 } else {
00223 if (ep->dwc_ep.maxxfer > out_max_xfer) {
00224 ep->dwc_ep.maxxfer =
00225 out_max_xfer;
00226 }
00227 }
00228 }
00229 if (ep->dwc_ep.maxxfer < ep->dwc_ep.total_len) {
00230 ep->dwc_ep.maxxfer -=
00231 (ep->dwc_ep.maxxfer % ep->dwc_ep.maxpacket);
00232 }
00233 if (req->sent_zlp) {
00234 if ((ep->dwc_ep.total_len %
00235 ep->dwc_ep.maxpacket == 0)
00236 && (ep->dwc_ep.total_len != 0)) {
00237 ep->dwc_ep.sent_zlp = 1;
00238 }
00239
00240 }
00241 #ifdef DWC_UTE_CFI
00242 }
00243 #endif
00244 dwc_otg_ep_start_transfer(GET_CORE_IF(ep->pcd), &ep->dwc_ep);
00245 }
00246 }
00247
00252 int32_t dwc_otg_pcd_handle_sof_intr(dwc_otg_pcd_t * pcd)
00253 {
00254 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
00255
00256 gintsts_data_t gintsts;
00257
00258 DWC_DEBUGPL(DBG_PCD, "SOF\n");
00259
00260
00261 gintsts.d32 = 0;
00262 gintsts.b.sofintr = 1;
00263 dwc_write_reg32(&core_if->core_global_regs->gintsts, gintsts.d32);
00264
00265 return 1;
00266 }
00267
00285 int32_t dwc_otg_pcd_handle_rx_status_q_level_intr(dwc_otg_pcd_t * pcd)
00286 {
00287 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
00288 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
00289 gintmsk_data_t gintmask = {.d32 = 0 };
00290 device_grxsts_data_t status;
00291 dwc_otg_pcd_ep_t *ep;
00292 gintsts_data_t gintsts;
00293 #ifdef DEBUG
00294 static char *dpid_str[] = { "D0", "D2", "D1", "MDATA" };
00295 #endif
00296
00297
00298
00299 gintmask.b.rxstsqlvl = 1;
00300 dwc_modify_reg32(&global_regs->gintmsk, gintmask.d32, 0);
00301
00302
00303 status.d32 = dwc_read_reg32(&global_regs->grxstsp);
00304
00305 DWC_DEBUGPL(DBG_PCD, "EP:%d BCnt:%d DPID:%s "
00306 "pktsts:%x Frame:%d(0x%0x)\n",
00307 status.b.epnum, status.b.bcnt,
00308 dpid_str[status.b.dpid],
00309 status.b.pktsts, status.b.fn, status.b.fn);
00310
00311 ep = get_out_ep(pcd, status.b.epnum);
00312
00313 switch (status.b.pktsts) {
00314 case DWC_DSTS_GOUT_NAK:
00315 DWC_DEBUGPL(DBG_PCDV, "Global OUT NAK\n");
00316 break;
00317 case DWC_STS_DATA_UPDT:
00318 DWC_DEBUGPL(DBG_PCDV, "OUT Data Packet\n");
00319 if (status.b.bcnt && ep->dwc_ep.xfer_buff) {
00321 dwc_otg_read_packet(core_if,
00322 ep->dwc_ep.xfer_buff,
00323 status.b.bcnt);
00324 ep->dwc_ep.xfer_count += status.b.bcnt;
00325 ep->dwc_ep.xfer_buff += status.b.bcnt;
00326 }
00327 break;
00328 case DWC_STS_XFER_COMP:
00329 DWC_DEBUGPL(DBG_PCDV, "OUT Complete\n");
00330 break;
00331 case DWC_DSTS_SETUP_COMP:
00332 #ifdef DEBUG_EP0
00333 DWC_DEBUGPL(DBG_PCDV, "Setup Complete\n");
00334 #endif
00335 break;
00336 case DWC_DSTS_SETUP_UPDT:
00337 dwc_otg_read_setup_packet(core_if, pcd->setup_pkt->d32);
00338 #ifdef DEBUG_EP0
00339 DWC_DEBUGPL(DBG_PCD,
00340 "SETUP PKT: %02x.%02x v%04x i%04x l%04x\n",
00341 pcd->setup_pkt->req.bmRequestType,
00342 pcd->setup_pkt->req.bRequest,
00343 UGETW(pcd->setup_pkt->req.wValue),
00344 UGETW(pcd->setup_pkt->req.wIndex),
00345 UGETW(pcd->setup_pkt->req.wLength));
00346 #endif
00347 ep->dwc_ep.xfer_count += status.b.bcnt;
00348 break;
00349 default:
00350 DWC_DEBUGPL(DBG_PCDV, "Invalid Packet Status (0x%0x)\n",
00351 status.b.pktsts);
00352 break;
00353 }
00354
00355
00356 dwc_modify_reg32(&global_regs->gintmsk, 0, gintmask.d32);
00357
00358 gintsts.d32 = 0;
00359 gintsts.b.rxstsqlvl = 1;
00360 dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
00361
00362
00363 return 1;
00364 }
00365
00378 static inline int get_ep_of_last_in_token(dwc_otg_core_if_t * core_if)
00379 {
00380 dwc_otg_device_global_regs_t *dev_global_regs =
00381 core_if->dev_if->dev_global_regs;
00382 const uint32_t TOKEN_Q_DEPTH = core_if->hwcfg2.b.dev_token_q_depth;
00383
00384 const int DTKNQ_REG_CNT = (TOKEN_Q_DEPTH + 7) / 8;
00385 dtknq1_data_t dtknqr1;
00386 uint32_t in_tkn_epnums[4];
00387 int ndx = 0;
00388 int i = 0;
00389 volatile uint32_t *addr = &dev_global_regs->dtknqr1;
00390 int epnum = 0;
00391
00392
00393
00394
00395 for (i = 0; i < DTKNQ_REG_CNT; i++) {
00396 in_tkn_epnums[i] = dwc_read_reg32(addr);
00397 DWC_DEBUGPL(DBG_PCDV, "DTKNQR%d=0x%08x\n", i + 1,
00398 in_tkn_epnums[i]);
00399 if (addr == &dev_global_regs->dvbusdis) {
00400 addr = &dev_global_regs->dtknqr3_dthrctl;
00401 } else {
00402 ++addr;
00403 }
00404
00405 }
00406
00407
00408 dtknqr1.d32 = in_tkn_epnums[0];
00409
00410 in_tkn_epnums[0] = dtknqr1.b.epnums0_5;
00411 ndx = dtknqr1.b.intknwptr - 1;
00412
00413
00414 if (ndx == -1) {
00417 int cnt = TOKEN_Q_DEPTH;
00418 if (TOKEN_Q_DEPTH <= 6) {
00419 cnt = TOKEN_Q_DEPTH - 1;
00420 } else if (TOKEN_Q_DEPTH <= 14) {
00421 cnt = TOKEN_Q_DEPTH - 7;
00422 } else if (TOKEN_Q_DEPTH <= 22) {
00423 cnt = TOKEN_Q_DEPTH - 15;
00424 } else {
00425 cnt = TOKEN_Q_DEPTH - 23;
00426 }
00427 epnum = (in_tkn_epnums[DTKNQ_REG_CNT - 1] >> (cnt * 4)) & 0xF;
00428 } else {
00429 if (ndx <= 5) {
00430 epnum = (in_tkn_epnums[0] >> (ndx * 4)) & 0xF;
00431 } else if (ndx <= 13) {
00432 ndx -= 6;
00433 epnum = (in_tkn_epnums[1] >> (ndx * 4)) & 0xF;
00434 } else if (ndx <= 21) {
00435 ndx -= 14;
00436 epnum = (in_tkn_epnums[2] >> (ndx * 4)) & 0xF;
00437 } else if (ndx <= 29) {
00438 ndx -= 22;
00439 epnum = (in_tkn_epnums[3] >> (ndx * 4)) & 0xF;
00440 }
00441 }
00442
00443 return epnum;
00444 }
00445
00451 int32_t dwc_otg_pcd_handle_np_tx_fifo_empty_intr(dwc_otg_pcd_t * pcd)
00452 {
00453 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
00454 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
00455 dwc_otg_dev_in_ep_regs_t *ep_regs;
00456 gnptxsts_data_t txstatus = {.d32 = 0 };
00457 gintsts_data_t gintsts;
00458
00459 int epnum = 0;
00460 dwc_otg_pcd_ep_t *ep = 0;
00461 uint32_t len = 0;
00462 int dwords;
00463
00464
00465 epnum = get_ep_of_last_in_token(core_if);
00466 ep = get_in_ep(pcd, epnum);
00467
00468 DWC_DEBUGPL(DBG_PCD, "NP TxFifo Empty: %d \n", epnum);
00469
00470 ep_regs = core_if->dev_if->in_ep_regs[epnum];
00471
00472 len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
00473 if (len > ep->dwc_ep.maxpacket) {
00474 len = ep->dwc_ep.maxpacket;
00475 }
00476 dwords = (len + 3) / 4;
00477
00478
00479
00480 txstatus.d32 = dwc_read_reg32(&global_regs->gnptxsts);
00481 DWC_DEBUGPL(DBG_PCDV, "b4 GNPTXSTS=0x%08x\n", txstatus.d32);
00482
00483 while (txstatus.b.nptxqspcavail > 0 &&
00484 txstatus.b.nptxfspcavail > dwords &&
00485 ep->dwc_ep.xfer_count < ep->dwc_ep.xfer_len) {
00486
00487 dwc_otg_ep_write_packet(core_if, &ep->dwc_ep, 0);
00488 len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
00489
00490 if (len > ep->dwc_ep.maxpacket) {
00491 len = ep->dwc_ep.maxpacket;
00492 }
00493
00494 dwords = (len + 3) / 4;
00495 txstatus.d32 = dwc_read_reg32(&global_regs->gnptxsts);
00496 DWC_DEBUGPL(DBG_PCDV, "GNPTXSTS=0x%08x\n", txstatus.d32);
00497 }
00498
00499 DWC_DEBUGPL(DBG_PCDV, "GNPTXSTS=0x%08x\n",
00500 dwc_read_reg32(&global_regs->gnptxsts));
00501
00502
00503 gintsts.d32 = 0;
00504 gintsts.b.nptxfempty = 1;
00505 dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
00506
00507 return 1;
00508 }
00509
00515 static int32_t write_empty_tx_fifo(dwc_otg_pcd_t * pcd, uint32_t epnum)
00516 {
00517 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
00518 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
00519 dwc_otg_dev_in_ep_regs_t *ep_regs;
00520 dtxfsts_data_t txstatus = {.d32 = 0 };
00521 dwc_otg_pcd_ep_t *ep = 0;
00522 uint32_t len = 0;
00523 int dwords;
00524
00525 ep = get_in_ep(pcd, epnum);
00526
00527 DWC_DEBUGPL(DBG_PCD, "Dedicated TxFifo Empty: %d \n", epnum);
00528
00529 ep_regs = core_if->dev_if->in_ep_regs[epnum];
00530
00531 len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
00532
00533 if (len > ep->dwc_ep.maxpacket) {
00534 len = ep->dwc_ep.maxpacket;
00535 }
00536
00537 dwords = (len + 3) / 4;
00538
00539
00540
00541 txstatus.d32 = dwc_read_reg32(&dev_if->in_ep_regs[epnum]->dtxfsts);
00542 DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", epnum, txstatus.d32);
00543
00544 while (txstatus.b.txfspcavail > dwords &&
00545 ep->dwc_ep.xfer_count < ep->dwc_ep.xfer_len &&
00546 ep->dwc_ep.xfer_len != 0) {
00547
00548 dwc_otg_ep_write_packet(core_if, &ep->dwc_ep, 0);
00549
00550 len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
00551 if (len > ep->dwc_ep.maxpacket) {
00552 len = ep->dwc_ep.maxpacket;
00553 }
00554
00555 dwords = (len + 3) / 4;
00556 txstatus.d32 =
00557 dwc_read_reg32(&dev_if->in_ep_regs[epnum]->dtxfsts);
00558 DWC_DEBUGPL(DBG_PCDV, "dtxfsts[%d]=0x%08x\n", epnum,
00559 txstatus.d32);
00560 }
00561
00562 DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", epnum,
00563 dwc_read_reg32(&dev_if->in_ep_regs[epnum]->dtxfsts));
00564
00565 return 1;
00566 }
00567
00573 void dwc_otg_pcd_stop(dwc_otg_pcd_t * pcd)
00574 {
00575 int i, num_in_eps, num_out_eps;
00576 dwc_otg_pcd_ep_t *ep;
00577
00578 gintmsk_data_t intr_mask = {.d32 = 0 };
00579
00580 DWC_SPINLOCK(pcd->lock);
00581
00582 num_in_eps = GET_CORE_IF(pcd)->dev_if->num_in_eps;
00583 num_out_eps = GET_CORE_IF(pcd)->dev_if->num_out_eps;
00584
00585 DWC_DEBUGPL(DBG_PCDV, "%s() \n", __func__);
00586
00587 if (pcd->ep0state == EP0_DISCONNECT) {
00588 DWC_DEBUGPL(DBG_ANY, "%s() Already Disconnected\n", __func__);
00589 return;
00590 }
00591 pcd->ep0state = EP0_DISCONNECT;
00592
00593
00594 dwc_otg_pcd_update_otg(pcd, 1);
00595
00596
00597 intr_mask.b.nptxfempty = 1;
00598 dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
00599 intr_mask.d32, 0);
00600
00601
00603 dwc_otg_flush_tx_fifo(GET_CORE_IF(pcd), 0x10);
00604 dwc_otg_flush_rx_fifo(GET_CORE_IF(pcd));
00605
00606
00607 ep = &pcd->ep0;
00608 dwc_otg_request_nuke(ep);
00609
00610 for (i = 0; i < num_in_eps; i++) {
00611 dwc_otg_pcd_ep_t *ep = &pcd->in_ep[i];
00612 dwc_otg_request_nuke(ep);
00613 }
00614
00615 for (i = 0; i < num_out_eps; i++) {
00616 dwc_otg_pcd_ep_t *ep = &pcd->out_ep[i];
00617 dwc_otg_request_nuke(ep);
00618 }
00619
00620
00621 if (pcd->fops->disconnect) {
00622 DWC_SPINUNLOCK(pcd->lock);
00623 pcd->fops->disconnect(pcd);
00624 DWC_SPINLOCK(pcd->lock);
00625 }
00626 DWC_SPINUNLOCK(pcd->lock);
00627 }
00628
00632 int32_t dwc_otg_pcd_handle_i2c_intr(dwc_otg_pcd_t * pcd)
00633 {
00634 gintmsk_data_t intr_mask = {.d32 = 0 };
00635 gintsts_data_t gintsts;
00636
00637 DWC_PRINTF("INTERRUPT Handler not implemented for %s\n", "i2cintr");
00638 intr_mask.b.i2cintr = 1;
00639 dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
00640 intr_mask.d32, 0);
00641
00642
00643 gintsts.d32 = 0;
00644 gintsts.b.i2cintr = 1;
00645 dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
00646 gintsts.d32);
00647 return 1;
00648 }
00649
00653 int32_t dwc_otg_pcd_handle_early_suspend_intr(dwc_otg_pcd_t * pcd)
00654 {
00655 gintsts_data_t gintsts;
00656 #if defined(VERBOSE)
00657 DWC_PRINTF("Early Suspend Detected\n");
00658 #endif
00659
00660 gintsts.d32 = 0;
00661 gintsts.b.erlysuspend = 1;
00662 dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
00663 gintsts.d32);
00664 return 1;
00665 }
00666
00684 static inline void ep0_out_start(dwc_otg_core_if_t * core_if,
00685 dwc_otg_pcd_t * pcd)
00686 {
00687 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
00688 deptsiz0_data_t doeptsize0 = {.d32 = 0 };
00689 dwc_otg_dev_dma_desc_t *dma_desc;
00690 depctl_data_t doepctl = {.d32 = 0 };
00691
00692 #ifdef VERBOSE
00693 DWC_DEBUGPL(DBG_PCDV, "%s() doepctl0=%0x\n", __func__,
00694 dwc_read_reg32(&dev_if->out_ep_regs[0]->doepctl));
00695 #endif
00696
00697 doeptsize0.b.supcnt = 3;
00698 doeptsize0.b.pktcnt = 1;
00699 doeptsize0.b.xfersize = 8 * 3;
00700
00701 if (core_if->dma_enable) {
00702 if (!core_if->dma_desc_enable) {
00704 dwc_write_reg32(&dev_if->out_ep_regs[0]->doeptsiz,
00705 doeptsize0.d32);
00706
00708 dwc_write_reg32(&dev_if->out_ep_regs[0]->doepdma,
00709 pcd->setup_pkt_dma_handle);
00710 } else {
00711 dev_if->setup_desc_index =
00712 (dev_if->setup_desc_index + 1) & 1;
00713 dma_desc =
00714 dev_if->setup_desc_addr[dev_if->setup_desc_index];
00715
00717 dma_desc->status.b.bs = BS_HOST_BUSY;
00718 dma_desc->status.b.l = 1;
00719 dma_desc->status.b.ioc = 1;
00720 dma_desc->status.b.bytes = pcd->ep0.dwc_ep.maxpacket;
00721 dma_desc->buf = pcd->setup_pkt_dma_handle;
00722 dma_desc->status.b.bs = BS_HOST_READY;
00723
00725 dwc_write_reg32(&dev_if->out_ep_regs[0]->doepdma,
00726 dev_if->dma_setup_desc_addr[dev_if->
00727 setup_desc_index]);
00728 }
00729
00730 } else {
00732 dwc_write_reg32(&dev_if->out_ep_regs[0]->doeptsiz,
00733 doeptsize0.d32);
00734 }
00735
00737 doepctl.b.epena = 1;
00738 doepctl.b.cnak = 1;
00739 dwc_write_reg32(&dev_if->out_ep_regs[0]->doepctl, doepctl.d32);
00740
00741 #ifdef VERBOSE
00742 DWC_DEBUGPL(DBG_PCDV, "doepctl0=%0x\n",
00743 dwc_read_reg32(&dev_if->out_ep_regs[0]->doepctl));
00744 DWC_DEBUGPL(DBG_PCDV, "diepctl0=%0x\n",
00745 dwc_read_reg32(&dev_if->in_ep_regs[0]->diepctl));
00746 #endif
00747 }
00748
00772 int32_t dwc_otg_pcd_handle_usb_reset_intr(dwc_otg_pcd_t * pcd)
00773 {
00774 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
00775 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
00776 depctl_data_t doepctl = {.d32 = 0 };
00777 daint_data_t daintmsk = {.d32 = 0 };
00778 doepmsk_data_t doepmsk = {.d32 = 0 };
00779 diepmsk_data_t diepmsk = {.d32 = 0 };
00780 dcfg_data_t dcfg = {.d32 = 0 };
00781 grstctl_t resetctl = {.d32 = 0 };
00782 dctl_data_t dctl = {.d32 = 0 };
00783 int i = 0;
00784 gintsts_data_t gintsts;
00785 pcgcctl_data_t power = {.d32 = 0 };
00786
00787 power.d32 = dwc_read_reg32(core_if->pcgcctl);
00788 if (power.b.stoppclk) {
00789 power.d32 = 0;
00790 power.b.stoppclk = 1;
00791 dwc_modify_reg32(core_if->pcgcctl, power.d32, 0);
00792
00793 power.b.pwrclmp = 1;
00794 dwc_modify_reg32(core_if->pcgcctl, power.d32, 0);
00795
00796 power.b.rstpdwnmodule = 1;
00797 dwc_modify_reg32(core_if->pcgcctl, power.d32, 0);
00798 }
00799
00800 core_if->lx_state = DWC_OTG_L0;
00801
00802 DWC_PRINTF("USB RESET\n");
00803 #ifdef DWC_EN_ISOC
00804 for (i = 1; i < 16; ++i) {
00805 dwc_otg_pcd_ep_t *ep;
00806 dwc_ep_t *dwc_ep;
00807 ep = get_in_ep(pcd, i);
00808 if (ep != 0) {
00809 dwc_ep = &ep->dwc_ep;
00810 dwc_ep->next_frame = 0xffffffff;
00811 }
00812 }
00813 #endif
00814
00815
00816 dwc_otg_pcd_update_otg(pcd, 1);
00817
00818
00819 dctl.b.rmtwkupsig = 1;
00820 dwc_modify_reg32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32, 0);
00821
00822
00823 doepctl.b.snak = 1;
00824 for (i = 0; i <= dev_if->num_out_eps; i++) {
00825 dwc_write_reg32(&dev_if->out_ep_regs[i]->doepctl, doepctl.d32);
00826 }
00827
00828
00829 dwc_otg_flush_tx_fifo(core_if, 0x10);
00830
00831 resetctl.b.intknqflsh = 1;
00832 dwc_write_reg32(&core_if->core_global_regs->grstctl, resetctl.d32);
00833
00834 if (core_if->multiproc_int_enable) {
00835 daintmsk.b.inep0 = 1;
00836 daintmsk.b.outep0 = 1;
00837 dwc_write_reg32(&dev_if->dev_global_regs->deachintmsk,
00838 daintmsk.d32);
00839
00840 doepmsk.b.setup = 1;
00841 doepmsk.b.xfercompl = 1;
00842 doepmsk.b.ahberr = 1;
00843 doepmsk.b.epdisabled = 1;
00844
00845 if (core_if->dma_desc_enable) {
00846 doepmsk.b.stsphsercvd = 1;
00847 doepmsk.b.bna = 1;
00848 }
00849
00850
00851
00852
00853
00854
00855
00856
00857 dwc_write_reg32(&dev_if->dev_global_regs->doepeachintmsk[0],
00858 doepmsk.d32);
00859
00860 diepmsk.b.xfercompl = 1;
00861 diepmsk.b.timeout = 1;
00862 diepmsk.b.epdisabled = 1;
00863 diepmsk.b.ahberr = 1;
00864 diepmsk.b.intknepmis = 1;
00865
00866 if (core_if->dma_desc_enable) {
00867 diepmsk.b.bna = 1;
00868 }
00869
00870
00871
00872
00873
00874 dwc_write_reg32(&dev_if->dev_global_regs->diepeachintmsk[0],
00875 diepmsk.d32);
00876 } else {
00877 daintmsk.b.inep0 = 1;
00878 daintmsk.b.outep0 = 1;
00879 dwc_write_reg32(&dev_if->dev_global_regs->daintmsk,
00880 daintmsk.d32);
00881
00882 doepmsk.b.setup = 1;
00883 doepmsk.b.xfercompl = 1;
00884 doepmsk.b.ahberr = 1;
00885 doepmsk.b.epdisabled = 1;
00886
00887 if (core_if->dma_desc_enable) {
00888 doepmsk.b.stsphsercvd = 1;
00889 doepmsk.b.bna = 1;
00890 }
00891 dwc_write_reg32(&dev_if->dev_global_regs->doepmsk, doepmsk.d32);
00892
00893 diepmsk.b.xfercompl = 1;
00894 diepmsk.b.timeout = 1;
00895 diepmsk.b.epdisabled = 1;
00896 diepmsk.b.ahberr = 1;
00897 diepmsk.b.intknepmis = 1;
00898
00899 if (core_if->dma_desc_enable) {
00900 diepmsk.b.bna = 1;
00901 }
00902
00903 dwc_write_reg32(&dev_if->dev_global_regs->diepmsk, diepmsk.d32);
00904 }
00905
00906
00907 dcfg.d32 = dwc_read_reg32(&dev_if->dev_global_regs->dcfg);
00908 dcfg.b.devaddr = 0;
00909 dwc_write_reg32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
00910
00911
00912 ep0_out_start(core_if, pcd);
00913
00914
00915 gintsts.d32 = 0;
00916 gintsts.b.usbreset = 1;
00917 dwc_write_reg32(&core_if->core_global_regs->gintsts, gintsts.d32);
00918
00919 return 1;
00920 }
00921
00928 static int get_device_speed(dwc_otg_core_if_t * core_if)
00929 {
00930 dsts_data_t dsts;
00931 int speed = 0;
00932 dsts.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts);
00933
00934 switch (dsts.b.enumspd) {
00935 case DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
00936 speed = USB_SPEED_HIGH;
00937 break;
00938 case DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
00939 case DWC_DSTS_ENUMSPD_FS_PHY_48MHZ:
00940 speed = USB_SPEED_FULL;
00941 break;
00942
00943 case DWC_DSTS_ENUMSPD_LS_PHY_6MHZ:
00944 speed = USB_SPEED_LOW;
00945 break;
00946 }
00947
00948 return speed;
00949 }
00950
00956 int32_t dwc_otg_pcd_handle_enum_done_intr(dwc_otg_pcd_t * pcd)
00957 {
00958 dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
00959 gintsts_data_t gintsts;
00960 gusbcfg_data_t gusbcfg;
00961 dwc_otg_core_global_regs_t *global_regs =
00962 GET_CORE_IF(pcd)->core_global_regs;
00963 uint8_t utmi16b, utmi8b;
00964 int speed;
00965 DWC_DEBUGPL(DBG_PCD, "SPEED ENUM\n");
00966
00967 if (GET_CORE_IF(pcd)->snpsid >= OTG_CORE_REV_2_60a) {
00968 utmi16b = 6;
00969 utmi8b = 9;
00970 } else {
00971 utmi16b = 4;
00972 utmi8b = 8;
00973 }
00974 dwc_otg_ep0_activate(GET_CORE_IF(pcd), &ep0->dwc_ep);
00975
00976 #ifdef DEBUG_EP0
00977 print_ep0_state(pcd);
00978 #endif
00979
00980 if (pcd->ep0state == EP0_DISCONNECT) {
00981 pcd->ep0state = EP0_IDLE;
00982 } else if (pcd->ep0state == EP0_STALL) {
00983 pcd->ep0state = EP0_IDLE;
00984 }
00985
00986 pcd->ep0state = EP0_IDLE;
00987
00988 ep0->stopped = 0;
00989
00990 speed = get_device_speed(GET_CORE_IF(pcd));
00991 pcd->fops->connect(pcd, speed);
00992
00993
00994 gusbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
00995 if (speed == USB_SPEED_HIGH) {
00996 if (GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type ==
00997 DWC_HWCFG2_HS_PHY_TYPE_ULPI) {
00998
00999 gusbcfg.b.usbtrdtim = 9;
01000 }
01001 if (GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type ==
01002 DWC_HWCFG2_HS_PHY_TYPE_UTMI) {
01003
01004 if (GET_CORE_IF(pcd)->hwcfg4.b.utmi_phy_data_width == 0) {
01005 gusbcfg.b.usbtrdtim = utmi8b;
01006 } else if (GET_CORE_IF(pcd)->hwcfg4.b.
01007 utmi_phy_data_width == 1) {
01008 gusbcfg.b.usbtrdtim = utmi16b;
01009 } else if (GET_CORE_IF(pcd)->core_params->
01010 phy_utmi_width == 8) {
01011 gusbcfg.b.usbtrdtim = utmi8b;
01012 } else {
01013 gusbcfg.b.usbtrdtim = utmi16b;
01014 }
01015 }
01016 if (GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type ==
01017 DWC_HWCFG2_HS_PHY_TYPE_UTMI_ULPI) {
01018
01019 if (gusbcfg.b.ulpi_utmi_sel == 1) {
01020
01021 gusbcfg.b.usbtrdtim = 9;
01022 } else {
01023
01024 if (GET_CORE_IF(pcd)->core_params->
01025 phy_utmi_width == 16) {
01026 gusbcfg.b.usbtrdtim = utmi16b;
01027 } else {
01028 gusbcfg.b.usbtrdtim = utmi8b;
01029 }
01030 }
01031 }
01032 } else {
01033
01034 gusbcfg.b.usbtrdtim = 9;
01035 }
01036 dwc_write_reg32(&global_regs->gusbcfg, gusbcfg.d32);
01037
01038
01039 gintsts.d32 = 0;
01040 gintsts.b.enumdone = 1;
01041 dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
01042 gintsts.d32);
01043 return 1;
01044 }
01045
01051 int32_t dwc_otg_pcd_handle_isoc_out_packet_dropped_intr(dwc_otg_pcd_t * pcd)
01052 {
01053 gintmsk_data_t intr_mask = {.d32 = 0 };
01054 gintsts_data_t gintsts;
01055
01056 DWC_PRINTF("INTERRUPT Handler not implemented for %s\n",
01057 "ISOC Out Dropped");
01058
01059 intr_mask.b.isooutdrop = 1;
01060 dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
01061 intr_mask.d32, 0);
01062
01063
01064 gintsts.d32 = 0;
01065 gintsts.b.isooutdrop = 1;
01066 dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
01067 gintsts.d32);
01068
01069 return 1;
01070 }
01071
01077 int32_t dwc_otg_pcd_handle_end_periodic_frame_intr(dwc_otg_pcd_t * pcd)
01078 {
01079 gintmsk_data_t intr_mask = {.d32 = 0 };
01080 gintsts_data_t gintsts;
01081 DWC_PRINTF("INTERRUPT Handler not implemented for %s\n", "EOP");
01082
01083 intr_mask.b.eopframe = 1;
01084 dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
01085 intr_mask.d32, 0);
01086
01087
01088 gintsts.d32 = 0;
01089 gintsts.b.eopframe = 1;
01090 dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
01091 gintsts.d32);
01092
01093 return 1;
01094 }
01095
01105 int32_t dwc_otg_pcd_handle_ep_mismatch_intr(dwc_otg_core_if_t * core_if)
01106 {
01107 gintsts_data_t gintsts;
01108 DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, core_if);
01109
01110
01111 gintsts.d32 = 0;
01112 gintsts.b.epmismatch = 1;
01113 dwc_write_reg32(&core_if->core_global_regs->gintsts, gintsts.d32);
01114
01115 return 1;
01116 }
01117
01121 static inline void ep0_do_stall(dwc_otg_pcd_t * pcd, const int err_val)
01122 {
01123 dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
01124 usb_device_request_t *ctrl = &pcd->setup_pkt->req;
01125 DWC_WARN("req %02x.%02x protocol STALL; err %d\n",
01126 ctrl->bmRequestType, ctrl->bRequest, err_val);
01127
01128 ep0->dwc_ep.is_in = 1;
01129 dwc_otg_ep_set_stall(GET_CORE_IF(pcd), &ep0->dwc_ep);
01130 pcd->ep0.stopped = 1;
01131 pcd->ep0state = EP0_IDLE;
01132 ep0_out_start(GET_CORE_IF(pcd), pcd);
01133 }
01134
01138 static inline void do_gadget_setup(dwc_otg_pcd_t * pcd,
01139 usb_device_request_t * ctrl)
01140 {
01141 int ret = 0;
01142 DWC_SPINUNLOCK(pcd->lock);
01143 ret = pcd->fops->setup(pcd, (uint8_t *) ctrl);
01144 DWC_SPINLOCK(pcd->lock);
01145 if (ret < 0) {
01146 ep0_do_stall(pcd, ret);
01147 }
01148
01161 if (ret == 256 + 999) {
01162 pcd->request_config = 1;
01163 }
01164 }
01165
01166 #ifdef DWC_UTE_CFI
01167
01171 static inline int cfi_gadget_setup(dwc_otg_pcd_t * pcd,
01172 struct cfi_usb_ctrlrequest *ctrl_req)
01173 {
01174 int ret = 0;
01175
01176 if (pcd->fops && pcd->fops->cfi_setup) {
01177 DWC_SPINUNLOCK(pcd->lock);
01178 ret = pcd->fops->cfi_setup(pcd, ctrl_req);
01179 DWC_SPINLOCK(pcd->lock);
01180 if (ret < 0) {
01181 ep0_do_stall(pcd, ret);
01182 return ret;
01183 }
01184 }
01185
01186 return ret;
01187 }
01188 #endif
01189
01194 static inline void do_setup_in_status_phase(dwc_otg_pcd_t * pcd)
01195 {
01196 dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
01197 if (pcd->ep0state == EP0_STALL) {
01198 return;
01199 }
01200
01201 pcd->ep0state = EP0_IN_STATUS_PHASE;
01202
01203
01204 DWC_DEBUGPL(DBG_PCD, "EP0 IN ZLP\n");
01205 ep0->dwc_ep.xfer_len = 0;
01206 ep0->dwc_ep.xfer_count = 0;
01207 ep0->dwc_ep.is_in = 1;
01208 ep0->dwc_ep.dma_addr = pcd->setup_pkt_dma_handle;
01209 dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
01210
01211
01212
01213 }
01214
01219 static inline void do_setup_out_status_phase(dwc_otg_pcd_t * pcd)
01220 {
01221 dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
01222 if (pcd->ep0state == EP0_STALL) {
01223 DWC_DEBUGPL(DBG_PCD, "EP0 STALLED\n");
01224 return;
01225 }
01226 pcd->ep0state = EP0_OUT_STATUS_PHASE;
01227
01228 DWC_DEBUGPL(DBG_PCD, "EP0 OUT ZLP\n");
01229 ep0->dwc_ep.xfer_len = 0;
01230 ep0->dwc_ep.xfer_count = 0;
01231 ep0->dwc_ep.is_in = 0;
01232 ep0->dwc_ep.dma_addr = pcd->setup_pkt_dma_handle;
01233 dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
01234
01235
01236 if (GET_CORE_IF(pcd)->dma_enable == 0) {
01237 ep0_out_start(GET_CORE_IF(pcd), pcd);
01238 }
01239 }
01240
01245 static inline void pcd_clear_halt(dwc_otg_pcd_t * pcd, dwc_otg_pcd_ep_t * ep)
01246 {
01247 if (ep->dwc_ep.stall_clear_flag == 0)
01248 dwc_otg_ep_clear_stall(GET_CORE_IF(pcd), &ep->dwc_ep);
01249
01250
01251 dwc_otg_ep_activate(GET_CORE_IF(pcd), &ep->dwc_ep);
01252 if (ep->stopped) {
01253 ep->stopped = 0;
01254
01255
01259
01260
01261
01262
01263
01264
01265
01266 ep->queue_sof = 1;
01267 DWC_TASK_SCHEDULE(pcd->start_xfer_tasklet);
01268 }
01269
01270 do_setup_in_status_phase(pcd);
01271 }
01272
01284 void do_test_mode(void *data)
01285 {
01286 dctl_data_t dctl;
01287 dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *) data;
01288 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
01289 int test_mode = pcd->test_mode;
01290
01291
01292
01293 dctl.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dctl);
01294 switch (test_mode) {
01295 case 1:
01296 dctl.b.tstctl = 1;
01297 break;
01298
01299 case 2:
01300 dctl.b.tstctl = 2;
01301 break;
01302
01303 case 3:
01304 dctl.b.tstctl = 3;
01305 break;
01306
01307 case 4:
01308 dctl.b.tstctl = 4;
01309 break;
01310
01311 case 5:
01312 dctl.b.tstctl = 5;
01313 break;
01314 }
01315 dwc_write_reg32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32);
01316 }
01317
01321 static inline void do_get_status(dwc_otg_pcd_t * pcd)
01322 {
01323 usb_device_request_t ctrl = pcd->setup_pkt->req;
01324 dwc_otg_pcd_ep_t *ep;
01325 dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
01326 uint16_t *status = pcd->status_buf;
01327
01328 #ifdef DEBUG_EP0
01329 DWC_DEBUGPL(DBG_PCD,
01330 "GET_STATUS %02x.%02x v%04x i%04x l%04x\n",
01331 ctrl.bmRequestType, ctrl.bRequest,
01332 UGETW(ctrl.wValue), UGETW(ctrl.wIndex),
01333 UGETW(ctrl.wLength));
01334 #endif
01335
01336 switch (UT_GET_RECIPIENT(ctrl.bmRequestType)) {
01337 case UT_DEVICE:
01338 *status = 0x1;
01339 *status |= pcd->remote_wakeup_enable << 1;
01340 break;
01341
01342 case UT_INTERFACE:
01343 *status = 0;
01344 break;
01345
01346 case UT_ENDPOINT:
01347 ep = get_ep_by_addr(pcd, UGETW(ctrl.wIndex));
01348 if (ep == 0 || UGETW(ctrl.wLength) > 2) {
01349 ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
01350 return;
01351 }
01353 *status = ep->stopped;
01354 break;
01355 }
01356 pcd->ep0_pending = 1;
01357 ep0->dwc_ep.start_xfer_buff = (uint8_t *) status;
01358 ep0->dwc_ep.xfer_buff = (uint8_t *) status;
01359 ep0->dwc_ep.dma_addr = pcd->status_buf_dma_handle;
01360 ep0->dwc_ep.xfer_len = 2;
01361 ep0->dwc_ep.xfer_count = 0;
01362 ep0->dwc_ep.total_len = ep0->dwc_ep.xfer_len;
01363 dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
01364 }
01365
01369 static inline void do_set_feature(dwc_otg_pcd_t * pcd)
01370 {
01371 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
01372 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
01373 usb_device_request_t ctrl = pcd->setup_pkt->req;
01374 dwc_otg_pcd_ep_t *ep = 0;
01375 int32_t otg_cap_param = core_if->core_params->otg_cap;
01376 gotgctl_data_t gotgctl = {.d32 = 0 };
01377
01378 DWC_DEBUGPL(DBG_PCD, "SET_FEATURE:%02x.%02x v%04x i%04x l%04x\n",
01379 ctrl.bmRequestType, ctrl.bRequest,
01380 UGETW(ctrl.wValue), UGETW(ctrl.wIndex),
01381 UGETW(ctrl.wLength));
01382 DWC_DEBUGPL(DBG_PCD, "otg_cap=%d\n", otg_cap_param);
01383
01384 switch (UT_GET_RECIPIENT(ctrl.bmRequestType)) {
01385 case UT_DEVICE:
01386 switch (UGETW(ctrl.wValue)) {
01387 case UF_DEVICE_REMOTE_WAKEUP:
01388 pcd->remote_wakeup_enable = 1;
01389 break;
01390
01391 case UF_TEST_MODE:
01392
01393
01394
01395
01399 pcd->test_mode = UGETW(ctrl.wIndex) >> 8;
01400 DWC_TASK_SCHEDULE(pcd->test_mode_tasklet);
01401 break;
01402
01403 case UF_DEVICE_B_HNP_ENABLE:
01404 DWC_DEBUGPL(DBG_PCDV,
01405 "SET_FEATURE: USB_DEVICE_B_HNP_ENABLE\n");
01406
01407
01408 if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) {
01409 pcd->b_hnp_enable = 1;
01410 dwc_otg_pcd_update_otg(pcd, 0);
01411 DWC_DEBUGPL(DBG_PCD, "Request B HNP\n");
01414 gotgctl.b.devhnpen = 1;
01415 gotgctl.b.hnpreq = 1;
01416 dwc_write_reg32(&global_regs->gotgctl,
01417 gotgctl.d32);
01418 } else {
01419 ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
01420 }
01421 break;
01422
01423 case UF_DEVICE_A_HNP_SUPPORT:
01424
01425 DWC_DEBUGPL(DBG_PCDV,
01426 "SET_FEATURE: USB_DEVICE_A_HNP_SUPPORT\n");
01427 if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) {
01428 pcd->a_hnp_support = 1;
01429 dwc_otg_pcd_update_otg(pcd, 0);
01430 } else {
01431 ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
01432 }
01433 break;
01434
01435 case UF_DEVICE_A_ALT_HNP_SUPPORT:
01436
01437 DWC_DEBUGPL(DBG_PCDV,
01438 "SET_FEATURE: USB_DEVICE_A_ALT_HNP_SUPPORT\n");
01439 if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) {
01440 pcd->a_alt_hnp_support = 1;
01441 dwc_otg_pcd_update_otg(pcd, 0);
01442 } else {
01443 ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
01444 }
01445 break;
01446 }
01447 do_setup_in_status_phase(pcd);
01448 break;
01449
01450 case UT_INTERFACE:
01451 do_gadget_setup(pcd, &ctrl);
01452 break;
01453
01454 case UT_ENDPOINT:
01455 if (UGETW(ctrl.wValue) == UF_ENDPOINT_HALT) {
01456 ep = get_ep_by_addr(pcd, UGETW(ctrl.wIndex));
01457 if (ep == 0) {
01458 ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
01459 return;
01460 }
01461 ep->stopped = 1;
01462 dwc_otg_ep_set_stall(core_if, &ep->dwc_ep);
01463 }
01464 do_setup_in_status_phase(pcd);
01465 break;
01466 }
01467 }
01468
01472 static inline void do_clear_feature(dwc_otg_pcd_t * pcd)
01473 {
01474 usb_device_request_t ctrl = pcd->setup_pkt->req;
01475 dwc_otg_pcd_ep_t *ep = 0;
01476
01477 DWC_DEBUGPL(DBG_PCD,
01478 "CLEAR_FEATURE:%02x.%02x v%04x i%04x l%04x\n",
01479 ctrl.bmRequestType, ctrl.bRequest,
01480 UGETW(ctrl.wValue), UGETW(ctrl.wIndex),
01481 UGETW(ctrl.wLength));
01482
01483 switch (UT_GET_RECIPIENT(ctrl.bmRequestType)) {
01484 case UT_DEVICE:
01485 switch (UGETW(ctrl.wValue)) {
01486 case UF_DEVICE_REMOTE_WAKEUP:
01487 pcd->remote_wakeup_enable = 0;
01488 break;
01489
01490 case UF_TEST_MODE:
01492 break;
01493 }
01494 do_setup_in_status_phase(pcd);
01495 break;
01496
01497 case UT_ENDPOINT:
01498 ep = get_ep_by_addr(pcd, UGETW(ctrl.wIndex));
01499 if (ep == 0) {
01500 ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
01501 return;
01502 }
01503
01504 pcd_clear_halt(pcd, ep);
01505
01506 break;
01507 }
01508 }
01509
01513 static inline void do_set_address(dwc_otg_pcd_t * pcd)
01514 {
01515 dwc_otg_dev_if_t *dev_if = GET_CORE_IF(pcd)->dev_if;
01516 usb_device_request_t ctrl = pcd->setup_pkt->req;
01517
01518 if (ctrl.bmRequestType == UT_DEVICE) {
01519 dcfg_data_t dcfg = {.d32 = 0 };
01520
01521 #ifdef DEBUG_EP0
01522
01523 #endif
01524 dcfg.b.devaddr = UGETW(ctrl.wValue);
01525 dwc_modify_reg32(&dev_if->dev_global_regs->dcfg, 0, dcfg.d32);
01526 do_setup_in_status_phase(pcd);
01527 }
01528 }
01529
01580 static inline void pcd_setup(dwc_otg_pcd_t * pcd)
01581 {
01582 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
01583 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
01584 usb_device_request_t ctrl = pcd->setup_pkt->req;
01585 dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
01586
01587 deptsiz0_data_t doeptsize0 = {.d32 = 0 };
01588
01589 #ifdef DWC_UTE_CFI
01590 int retval = 0;
01591 struct cfi_usb_ctrlrequest cfi_req;
01592 #endif
01593
01594 #ifdef DEBUG_EP0
01595 DWC_DEBUGPL(DBG_PCD, "SETUP %02x.%02x v%04x i%04x l%04x\n",
01596 ctrl.bmRequestType, ctrl.bRequest,
01597 UGETW(ctrl.wValue), UGETW(ctrl.wIndex),
01598 UGETW(ctrl.wLength));
01599 #endif
01600
01601 doeptsize0.d32 = dwc_read_reg32(&dev_if->out_ep_regs[0]->doeptsiz);
01602
01605 if (core_if->dma_enable && core_if->dma_desc_enable == 0
01606 && (doeptsize0.b.supcnt < 2)) {
01607 DWC_ERROR
01608 ("\n\n----------- CANNOT handle > 1 setup packet in DMA mode\n\n");
01609 }
01610
01611
01612 dwc_otg_request_nuke(ep0);
01613 ep0->stopped = 0;
01614
01615 if (ctrl.bmRequestType & UE_DIR_IN) {
01616 ep0->dwc_ep.is_in = 1;
01617 pcd->ep0state = EP0_IN_DATA_PHASE;
01618 } else {
01619 ep0->dwc_ep.is_in = 0;
01620 pcd->ep0state = EP0_OUT_DATA_PHASE;
01621 }
01622
01623 if (UGETW(ctrl.wLength) == 0) {
01624 ep0->dwc_ep.is_in = 1;
01625 pcd->ep0state = EP0_IN_STATUS_PHASE;
01626 }
01627
01628 if (UT_GET_TYPE(ctrl.bmRequestType) != UT_STANDARD) {
01629
01630 #ifdef DWC_UTE_CFI
01631 DWC_MEMCPY(&cfi_req, &ctrl, sizeof(usb_device_request_t));
01632
01633
01634 if (UT_GET_TYPE(cfi_req.bRequestType) == UT_VENDOR) {
01635 if (cfi_req.bRequest > 0xB0 && cfi_req.bRequest < 0xBF) {
01636 retval = cfi_setup(pcd, &cfi_req);
01637 if (retval < 0) {
01638 ep0_do_stall(pcd, retval);
01639 pcd->ep0_pending = 0;
01640 return;
01641 }
01642
01643
01644 if (pcd->cfi->need_gadget_att) {
01645 retval =
01646 cfi_gadget_setup(pcd,
01647 &pcd->cfi->
01648 ctrl_req);
01649 if (retval < 0) {
01650 pcd->ep0_pending = 0;
01651 return;
01652 }
01653 }
01654
01655 if (pcd->cfi->need_status_in_complete) {
01656 do_setup_in_status_phase(pcd);
01657 }
01658 return;
01659 }
01660 }
01661 #endif
01662
01663
01664 do_gadget_setup(pcd, &ctrl);
01665 return;
01666 }
01667
01670
01671
01672
01673 switch (ctrl.bRequest) {
01674 case UR_GET_STATUS:
01675 do_get_status(pcd);
01676 break;
01677
01678 case UR_CLEAR_FEATURE:
01679 do_clear_feature(pcd);
01680 break;
01681
01682 case UR_SET_FEATURE:
01683 do_set_feature(pcd);
01684 break;
01685
01686 case UR_SET_ADDRESS:
01687 do_set_address(pcd);
01688 break;
01689
01690 case UR_SET_INTERFACE:
01691 case UR_SET_CONFIG:
01692
01693 do_gadget_setup(pcd, &ctrl);
01694 break;
01695
01696 case UR_SYNCH_FRAME:
01697 do_gadget_setup(pcd, &ctrl);
01698 break;
01699
01700 default:
01701
01702 do_gadget_setup(pcd, &ctrl);
01703 break;
01704 }
01705 }
01706
01710 static int32_t ep0_complete_request(dwc_otg_pcd_ep_t * ep)
01711 {
01712 dwc_otg_core_if_t *core_if = GET_CORE_IF(ep->pcd);
01713 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
01714 dwc_otg_dev_in_ep_regs_t *in_ep_regs =
01715 dev_if->in_ep_regs[ep->dwc_ep.num];
01716 #ifdef DEBUG_EP0
01717 dwc_otg_dev_out_ep_regs_t *out_ep_regs =
01718 dev_if->out_ep_regs[ep->dwc_ep.num];
01719 #endif
01720 deptsiz0_data_t deptsiz;
01721 dev_dma_desc_sts_t desc_sts;
01722 dwc_otg_pcd_request_t *req;
01723 int is_last = 0;
01724 dwc_otg_pcd_t *pcd = ep->pcd;
01725
01726 #ifdef DWC_UTE_CFI
01727 struct cfi_usb_ctrlrequest *ctrlreq;
01728 int retval = -DWC_E_NOT_SUPPORTED;
01729 #endif
01730
01731 if (pcd->ep0_pending && DWC_CIRCLEQ_EMPTY(&ep->queue)) {
01732 if (ep->dwc_ep.is_in) {
01733 #ifdef DEBUG_EP0
01734 DWC_DEBUGPL(DBG_PCDV, "Do setup OUT status phase\n");
01735 #endif
01736 do_setup_out_status_phase(pcd);
01737 } else {
01738 #ifdef DEBUG_EP0
01739 DWC_DEBUGPL(DBG_PCDV, "Do setup IN status phase\n");
01740 #endif
01741
01742 #ifdef DWC_UTE_CFI
01743 ctrlreq = &pcd->cfi->ctrl_req;
01744
01745 if (UT_GET_TYPE(ctrlreq->bRequestType) == UT_VENDOR) {
01746 if (ctrlreq->bRequest > 0xB0
01747 && ctrlreq->bRequest < 0xBF) {
01748
01749
01750 if ((retval =
01751 pcd->cfi->ops.
01752 ctrl_write_complete(pcd->cfi,
01753 pcd)) < 0) {
01754 CFI_INFO
01755 ("ERROR setting a new value in the PCD(%d)\n",
01756 retval);
01757 ep0_do_stall(pcd, retval);
01758 pcd->ep0_pending = 0;
01759 return 0;
01760 }
01761
01762
01763 if (pcd->cfi->need_gadget_att == 1) {
01764
01765 retval =
01766 cfi_gadget_setup(pcd,
01767 &pcd->cfi->
01768 ctrl_req);
01769
01770
01771
01772
01773 if (retval < 0) {
01774 CFI_INFO
01775 ("ERROR setting a new value in the gadget(%d)\n",
01776 retval);
01777 pcd->ep0_pending = 0;
01778 return 0;
01779 }
01780 }
01781
01782 CFI_INFO("%s: RETVAL=%d\n", __func__,
01783 retval);
01784
01785
01786
01787
01788
01789
01790 do_setup_in_status_phase(pcd);
01791 pcd->ep0_pending = 0;
01792 return 1;
01793 }
01794 }
01795 #endif
01796
01797 do_setup_in_status_phase(pcd);
01798 }
01799 pcd->ep0_pending = 0;
01800 return 1;
01801 }
01802
01803 if (DWC_CIRCLEQ_EMPTY(&ep->queue)) {
01804 return 0;
01805 }
01806 req = DWC_CIRCLEQ_FIRST(&ep->queue);
01807
01808 if (pcd->ep0state == EP0_OUT_STATUS_PHASE
01809 || pcd->ep0state == EP0_IN_STATUS_PHASE) {
01810 is_last = 1;
01811 } else if (ep->dwc_ep.is_in) {
01812 deptsiz.d32 = dwc_read_reg32(&in_ep_regs->dieptsiz);
01813 if (core_if->dma_desc_enable != 0)
01814 desc_sts = dev_if->in_desc_addr->status;
01815 #ifdef DEBUG_EP0
01816 DWC_DEBUGPL(DBG_PCDV, "%d len=%d xfersize=%d pktcnt=%d\n",
01817 ep->dwc_ep.num, ep->dwc_ep.xfer_len,
01818 deptsiz.b.xfersize, deptsiz.b.pktcnt);
01819 #endif
01820
01821 if (((core_if->dma_desc_enable == 0)
01822 && (deptsiz.b.xfersize == 0))
01823 || ((core_if->dma_desc_enable != 0)
01824 && (desc_sts.b.bytes == 0))) {
01825 req->actual = ep->dwc_ep.xfer_count;
01826
01827 if (req->sent_zlp) {
01828 #ifdef DEBUG_EP0
01829 DWC_DEBUGPL(DBG_PCD, "Setup Rx ZLP\n");
01830 #endif
01831 req->sent_zlp = 0;
01832 }
01833 do_setup_out_status_phase(pcd);
01834 }
01835 } else {
01836
01837 #ifdef DEBUG_EP0
01838 deptsiz.d32 = dwc_read_reg32(&out_ep_regs->doeptsiz);
01839 DWC_DEBUGPL(DBG_PCDV, "%d len=%d xsize=%d pktcnt=%d\n",
01840 ep->dwc_ep.num, ep->dwc_ep.xfer_len,
01841 deptsiz.b.xfersize, deptsiz.b.pktcnt);
01842 #endif
01843 req->actual = ep->dwc_ep.xfer_count;
01844
01845
01846 if (req->sent_zlp) {
01847 #ifdef DEBUG_EP0
01848 DWC_DEBUGPL(DBG_PCDV, "Setup Tx ZLP\n");
01849 #endif
01850 req->sent_zlp = 0;
01851 }
01852 if (core_if->dma_desc_enable == 0)
01853 do_setup_in_status_phase(pcd);
01854 }
01855
01856
01857 if (is_last) {
01858 dwc_otg_request_done(ep, req, 0);
01859 ep->dwc_ep.start_xfer_buff = 0;
01860 ep->dwc_ep.xfer_buff = 0;
01861 ep->dwc_ep.xfer_len = 0;
01862 return 1;
01863 }
01864 return 0;
01865 }
01866
01867 #ifdef DWC_UTE_CFI
01868
01874 static inline int cfi_calc_desc_residue(dwc_otg_pcd_ep_t * ep)
01875 {
01876 int32_t ret = 0;
01877 int i;
01878 struct dwc_otg_dma_desc *ddesc = NULL;
01879 struct cfi_ep *cfiep;
01880
01881
01882 cfiep = get_cfi_ep_by_pcd_ep(ep->pcd->cfi, ep);
01883 if (!cfiep) {
01884 CFI_INFO("%s: Failed to find ep\n", __func__);
01885 return -1;
01886 }
01887
01888 ddesc = ep->dwc_ep.descs;
01889
01890 for (i = 0; (i < cfiep->desc_count) && (i < MAX_DMA_DESCS_PER_EP); i++) {
01891
01892 #if defined(PRINT_CFI_DMA_DESCS)
01893 print_desc(ddesc, ep->ep.name, i);
01894 #endif
01895 ret += ddesc->status.b.bytes;
01896 ddesc++;
01897 }
01898
01899 if (ret)
01900 CFI_INFO("!!!!!!!!!! WARNING (%s) - residue=%d\n", __func__,
01901 ret);
01902
01903 return ret;
01904 }
01905 #endif
01906
01911 static void complete_ep(dwc_otg_pcd_ep_t * ep)
01912 {
01913 dwc_otg_core_if_t *core_if = GET_CORE_IF(ep->pcd);
01914 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
01915 dwc_otg_dev_in_ep_regs_t *in_ep_regs =
01916 dev_if->in_ep_regs[ep->dwc_ep.num];
01917 deptsiz_data_t deptsiz;
01918 dev_dma_desc_sts_t desc_sts;
01919 dwc_otg_pcd_request_t *req = 0;
01920 dwc_otg_dev_dma_desc_t *dma_desc;
01921 uint32_t byte_count = 0;
01922 int is_last = 0;
01923 int i;
01924
01925 DWC_DEBUGPL(DBG_PCDV, "%s() %d-%s\n", __func__, ep->dwc_ep.num,
01926 (ep->dwc_ep.is_in ? "IN" : "OUT"));
01927
01928
01929 if (!DWC_CIRCLEQ_EMPTY(&ep->queue)) {
01930 req = DWC_CIRCLEQ_FIRST(&ep->queue);
01931 if (!req) {
01932 DWC_PRINTF("complete_ep 0x%p, req = NULL!\n", ep);
01933 return;
01934 }
01935 } else {
01936 DWC_PRINTF("complete_ep 0x%p, ep->queue empty!\n", ep);
01937 return;
01938 }
01939
01940 DWC_DEBUGPL(DBG_PCD, "Requests %d\n", ep->pcd->request_pending);
01941
01942 if (ep->dwc_ep.is_in) {
01943 deptsiz.d32 = dwc_read_reg32(&in_ep_regs->dieptsiz);
01944
01945 if (core_if->dma_enable) {
01946 if (core_if->dma_desc_enable == 0) {
01947 if (deptsiz.b.xfersize == 0
01948 && deptsiz.b.pktcnt == 0) {
01949 byte_count =
01950 ep->dwc_ep.xfer_len -
01951 ep->dwc_ep.xfer_count;
01952
01953 ep->dwc_ep.xfer_buff += byte_count;
01954 ep->dwc_ep.dma_addr += byte_count;
01955 ep->dwc_ep.xfer_count += byte_count;
01956
01957 DWC_DEBUGPL(DBG_PCDV,
01958 "%d-%s len=%d xfersize=%d pktcnt=%d\n",
01959 ep->dwc_ep.num,
01960 (ep->dwc_ep.
01961 is_in ? "IN" : "OUT"),
01962 ep->dwc_ep.xfer_len,
01963 deptsiz.b.xfersize,
01964 deptsiz.b.pktcnt);
01965
01966 if (ep->dwc_ep.xfer_len <
01967 ep->dwc_ep.total_len) {
01968 dwc_otg_ep_start_transfer
01969 (core_if, &ep->dwc_ep);
01970 } else if (ep->dwc_ep.sent_zlp) {
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986 ep->dwc_ep.sent_zlp = 0;
01987 dwc_otg_ep_start_zl_transfer
01988 (core_if, &ep->dwc_ep);
01989 } else {
01990 is_last = 1;
01991 }
01992 } else {
01993 DWC_WARN
01994 ("Incomplete transfer (%d - %s [siz=%d pkt=%d])\n",
01995 ep->dwc_ep.num,
01996 (ep->dwc_ep.is_in ? "IN" : "OUT"),
01997 deptsiz.b.xfersize,
01998 deptsiz.b.pktcnt);
01999 }
02000 } else {
02001 dma_desc = ep->dwc_ep.desc_addr;
02002 byte_count = 0;
02003 ep->dwc_ep.sent_zlp = 0;
02004
02005 #ifdef DWC_UTE_CFI
02006 CFI_INFO("%s: BUFFER_MODE=%d\n", __func__,
02007 ep->dwc_ep.buff_mode);
02008 if (ep->dwc_ep.buff_mode != BM_STANDARD) {
02009 int residue;
02010
02011 residue = cfi_calc_desc_residue(ep);
02012 if (residue < 0)
02013 return;
02014
02015 byte_count = residue;
02016 } else {
02017 #endif
02018 for (i = 0; i < ep->dwc_ep.desc_cnt;
02019 ++i) {
02020 desc_sts = dma_desc->status;
02021 byte_count += desc_sts.b.bytes;
02022 dma_desc++;
02023 }
02024 #ifdef DWC_UTE_CFI
02025 }
02026 #endif
02027 if (byte_count == 0) {
02028 ep->dwc_ep.xfer_count =
02029 ep->dwc_ep.total_len;
02030 is_last = 1;
02031 } else {
02032 DWC_WARN("Incomplete transfer\n");
02033 }
02034 }
02035 } else {
02036 if (deptsiz.b.xfersize == 0 && deptsiz.b.pktcnt == 0) {
02037 DWC_DEBUGPL(DBG_PCDV,
02038 "%d-%s len=%d xfersize=%d pktcnt=%d\n",
02039 ep->dwc_ep.num,
02040 ep->dwc_ep.is_in ? "IN" : "OUT",
02041 ep->dwc_ep.xfer_len,
02042 deptsiz.b.xfersize,
02043 deptsiz.b.pktcnt);
02044
02045
02046
02047
02048 if (ep->dwc_ep.xfer_len < ep->dwc_ep.total_len) {
02049 dwc_otg_ep_start_transfer(core_if,
02050 &ep->dwc_ep);
02051 } else if (ep->dwc_ep.sent_zlp) {
02052
02053
02054
02055
02056
02057
02058
02059
02060
02061
02062
02063
02064
02065
02066
02067 ep->dwc_ep.sent_zlp = 0;
02068 dwc_otg_ep_start_zl_transfer(core_if,
02069 &ep->
02070 dwc_ep);
02071 } else {
02072 is_last = 1;
02073 }
02074 } else {
02075 DWC_WARN
02076 ("Incomplete transfer (%d-%s [siz=%d pkt=%d])\n",
02077 ep->dwc_ep.num,
02078 (ep->dwc_ep.is_in ? "IN" : "OUT"),
02079 deptsiz.b.xfersize, deptsiz.b.pktcnt);
02080 }
02081 }
02082 } else {
02083 dwc_otg_dev_out_ep_regs_t *out_ep_regs =
02084 dev_if->out_ep_regs[ep->dwc_ep.num];
02085 desc_sts.d32 = 0;
02086 if (core_if->dma_enable) {
02087 if (core_if->dma_desc_enable) {
02088 dma_desc = ep->dwc_ep.desc_addr;
02089 byte_count = 0;
02090 ep->dwc_ep.sent_zlp = 0;
02091
02092 #ifdef DWC_UTE_CFI
02093 CFI_INFO("%s: BUFFER_MODE=%d\n", __func__,
02094 ep->dwc_ep.buff_mode);
02095 if (ep->dwc_ep.buff_mode != BM_STANDARD) {
02096 int residue;
02097 residue = cfi_calc_desc_residue(ep);
02098 if (residue < 0)
02099 return;
02100 byte_count = residue;
02101 } else {
02102 #endif
02103
02104 for (i = 0; i < ep->dwc_ep.desc_cnt;
02105 ++i) {
02106 desc_sts = dma_desc->status;
02107 byte_count += desc_sts.b.bytes;
02108 dma_desc++;
02109 }
02110
02111 #ifdef DWC_UTE_CFI
02112 }
02113 #endif
02114 ep->dwc_ep.xfer_count = ep->dwc_ep.total_len
02115 - byte_count +
02116 ((4 - (ep->dwc_ep.total_len & 0x3)) & 0x3);
02117 is_last = 1;
02118 } else {
02119 deptsiz.d32 = 0;
02120 deptsiz.d32 =
02121 dwc_read_reg32(&out_ep_regs->doeptsiz);
02122
02123 byte_count = (ep->dwc_ep.xfer_len -
02124 ep->dwc_ep.xfer_count -
02125 deptsiz.b.xfersize);
02126 ep->dwc_ep.xfer_buff += byte_count;
02127 ep->dwc_ep.dma_addr += byte_count;
02128 ep->dwc_ep.xfer_count += byte_count;
02129
02130
02131
02132
02133 if (ep->dwc_ep.xfer_len < ep->dwc_ep.total_len) {
02134 dwc_otg_ep_start_transfer(core_if,
02135 &ep->dwc_ep);
02136 } else if (ep->dwc_ep.sent_zlp) {
02137
02138
02139
02140
02141
02142
02143
02144
02145
02146
02147
02148
02149
02150
02151
02152 ep->dwc_ep.sent_zlp = 0;
02153 dwc_otg_ep_start_zl_transfer(core_if,
02154 &ep->
02155 dwc_ep);
02156 } else {
02157 is_last = 1;
02158 }
02159 }
02160 } else {
02161
02162
02163
02164 if (ep->dwc_ep.xfer_len < ep->dwc_ep.total_len) {
02165 dwc_otg_ep_start_transfer(core_if, &ep->dwc_ep);
02166 } else if (ep->dwc_ep.sent_zlp) {
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182 ep->dwc_ep.sent_zlp = 0;
02183 dwc_otg_ep_start_zl_transfer(core_if,
02184 &ep->dwc_ep);
02185 } else {
02186 is_last = 1;
02187 }
02188 }
02189
02190 DWC_DEBUGPL(DBG_PCDV,
02191 "addr %p, %d-%s len=%d cnt=%d xsize=%d pktcnt=%d\n",
02192 &out_ep_regs->doeptsiz, ep->dwc_ep.num,
02193 ep->dwc_ep.is_in ? "IN" : "OUT",
02194 ep->dwc_ep.xfer_len, ep->dwc_ep.xfer_count,
02195 deptsiz.b.xfersize, deptsiz.b.pktcnt);
02196 }
02197
02198
02199 if (is_last) {
02200 #ifdef DWC_UTE_CFI
02201 if (ep->dwc_ep.buff_mode != BM_STANDARD) {
02202 req->actual = ep->dwc_ep.cfi_req_len - byte_count;
02203 } else {
02204 #endif
02205 req->actual = ep->dwc_ep.xfer_count;
02206 #ifdef DWC_UTE_CFI
02207 }
02208 #endif
02209
02210 dwc_otg_request_done(ep, req, 0);
02211
02212 ep->dwc_ep.start_xfer_buff = 0;
02213 ep->dwc_ep.xfer_buff = 0;
02214 ep->dwc_ep.xfer_len = 0;
02215
02216
02217 start_next_request(ep);
02218 }
02219 }
02220
02221 #ifdef DWC_EN_ISOC
02222
02227 static void dwc_otg_pcd_handle_iso_bna(dwc_otg_pcd_ep_t * ep)
02228 {
02229 dwc_ep_t *dwc_ep = &ep->dwc_ep;
02230 volatile uint32_t *addr;
02231 depctl_data_t depctl = {.d32 = 0 };
02232 dwc_otg_pcd_t *pcd = ep->pcd;
02233 dwc_otg_dev_dma_desc_t *dma_desc;
02234 int i;
02235
02236 dma_desc =
02237 dwc_ep->iso_desc_addr + dwc_ep->desc_cnt * (dwc_ep->proc_buf_num);
02238
02239 if (dwc_ep->is_in) {
02240 dev_dma_desc_sts_t sts = {.d32 = 0 };
02241 for (i = 0; i < dwc_ep->desc_cnt; ++i, ++dma_desc) {
02242 sts.d32 = dma_desc->status.d32;
02243 sts.b_iso_in.bs = BS_HOST_READY;
02244 dma_desc->status.d32 = sts.d32;
02245 }
02246 } else {
02247 dev_dma_desc_sts_t sts = {.d32 = 0 };
02248 for (i = 0; i < dwc_ep->desc_cnt; ++i, ++dma_desc) {
02249 sts.d32 = dma_desc->status.d32;
02250 sts.b_iso_out.bs = BS_HOST_READY;
02251 dma_desc->status.d32 = sts.d32;
02252 }
02253 }
02254
02255 if (dwc_ep->is_in == 0) {
02256 addr =
02257 &GET_CORE_IF(pcd)->dev_if->out_ep_regs[dwc_ep->num]->
02258 doepctl;
02259 } else {
02260 addr =
02261 &GET_CORE_IF(pcd)->dev_if->in_ep_regs[dwc_ep->num]->diepctl;
02262 }
02263 depctl.b.epena = 1;
02264 dwc_modify_reg32(addr, depctl.d32, depctl.d32);
02265 }
02266
02274 void set_current_pkt_info(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
02275 {
02276 deptsiz_data_t deptsiz = {.d32 = 0 };
02277 dma_addr_t dma_addr;
02278 uint32_t offset;
02279
02280 if (ep->proc_buf_num)
02281 dma_addr = ep->dma_addr1;
02282 else
02283 dma_addr = ep->dma_addr0;
02284
02285 if (ep->is_in) {
02286 deptsiz.d32 =
02287 dwc_read_reg32(&core_if->dev_if->in_ep_regs[ep->num]->
02288 dieptsiz);
02289 offset = ep->data_per_frame;
02290 } else {
02291 deptsiz.d32 =
02292 dwc_read_reg32(&core_if->dev_if->out_ep_regs[ep->num]->
02293 doeptsiz);
02294 offset =
02295 ep->data_per_frame +
02296 (0x4 & (0x4 - (ep->data_per_frame & 0x3)));
02297 }
02298
02299 if (!deptsiz.b.xfersize) {
02300 ep->pkt_info[ep->cur_pkt].length = ep->data_per_frame;
02301 ep->pkt_info[ep->cur_pkt].offset =
02302 ep->cur_pkt_dma_addr - dma_addr;
02303 ep->pkt_info[ep->cur_pkt].status = 0;
02304 } else {
02305 ep->pkt_info[ep->cur_pkt].length = ep->data_per_frame;
02306 ep->pkt_info[ep->cur_pkt].offset =
02307 ep->cur_pkt_dma_addr - dma_addr;
02308 ep->pkt_info[ep->cur_pkt].status = -DWC_E_NO_DATA;
02309 }
02310 ep->cur_pkt_addr += offset;
02311 ep->cur_pkt_dma_addr += offset;
02312 ep->cur_pkt++;
02313 }
02314
02322 static void set_ddma_iso_pkts_info(dwc_otg_core_if_t * core_if,
02323 dwc_ep_t * dwc_ep)
02324 {
02325 dwc_otg_dev_dma_desc_t *dma_desc;
02326 dev_dma_desc_sts_t sts = {.d32 = 0 };
02327 iso_pkt_info_t *iso_packet;
02328 uint32_t data_per_desc;
02329 uint32_t offset;
02330 int i, j;
02331
02332 iso_packet = dwc_ep->pkt_info;
02333
02336 if (dwc_ep->is_in == 0) {
02337 dma_desc =
02338 dwc_ep->iso_desc_addr +
02339 dwc_ep->desc_cnt * dwc_ep->proc_buf_num;
02340 offset = 0;
02341
02342 for (i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm;
02343 i += dwc_ep->pkt_per_frm) {
02344 for (j = 0; j < dwc_ep->pkt_per_frm; ++j) {
02345 data_per_desc =
02346 ((j + 1) * dwc_ep->maxpacket >
02347 dwc_ep->data_per_frame) ? dwc_ep->
02348 data_per_frame -
02349 j * dwc_ep->maxpacket : dwc_ep->maxpacket;
02350 data_per_desc +=
02351 (data_per_desc % 4) ? (4 -
02352 data_per_desc %
02353 4) : 0;
02354
02355 sts.d32 = dma_desc->status.d32;
02356
02357
02358 iso_packet->status =
02359 sts.b_iso_out.rxsts +
02360 (sts.b_iso_out.bs ^ BS_DMA_DONE);
02361 if (iso_packet->status) {
02362 iso_packet->status = -DWC_E_NO_DATA;
02363 }
02364
02365
02366 if (!sts.b_iso_out.rxbytes) {
02367 iso_packet->length =
02368 data_per_desc -
02369 sts.b_iso_out.rxbytes;
02370 } else {
02371 iso_packet->length =
02372 data_per_desc -
02373 sts.b_iso_out.rxbytes + (4 -
02374 dwc_ep->
02375 data_per_frame
02376 % 4);
02377 }
02378
02379 iso_packet->offset = offset;
02380
02381 offset += data_per_desc;
02382 dma_desc++;
02383 iso_packet++;
02384 }
02385 }
02386
02387 for (j = 0; j < dwc_ep->pkt_per_frm - 1; ++j) {
02388 data_per_desc =
02389 ((j + 1) * dwc_ep->maxpacket >
02390 dwc_ep->data_per_frame) ? dwc_ep->data_per_frame -
02391 j * dwc_ep->maxpacket : dwc_ep->maxpacket;
02392 data_per_desc +=
02393 (data_per_desc % 4) ? (4 - data_per_desc % 4) : 0;
02394
02395 sts.d32 = dma_desc->status.d32;
02396
02397
02398 iso_packet->status =
02399 sts.b_iso_out.rxsts +
02400 (sts.b_iso_out.bs ^ BS_DMA_DONE);
02401 if (iso_packet->status) {
02402 iso_packet->status = -DWC_E_NO_DATA;
02403 }
02404
02405
02406 iso_packet->length =
02407 dwc_ep->data_per_frame - sts.b_iso_out.rxbytes;
02408
02409 iso_packet->offset = offset;
02410
02411 offset += data_per_desc;
02412 iso_packet++;
02413 dma_desc++;
02414 }
02415
02416 sts.d32 = dma_desc->status.d32;
02417
02418
02419 iso_packet->status =
02420 sts.b_iso_out.rxsts + (sts.b_iso_out.bs ^ BS_DMA_DONE);
02421 if (iso_packet->status) {
02422 iso_packet->status = -DWC_E_NO_DATA;
02423 }
02424
02425 if (!sts.b_iso_out.rxbytes) {
02426 iso_packet->length =
02427 dwc_ep->data_per_frame - sts.b_iso_out.rxbytes;
02428 } else {
02429 iso_packet->length =
02430 dwc_ep->data_per_frame - sts.b_iso_out.rxbytes +
02431 (4 - dwc_ep->data_per_frame % 4);
02432 }
02433
02434 iso_packet->offset = offset;
02435 } else {
02438 dma_desc =
02439 dwc_ep->iso_desc_addr +
02440 dwc_ep->desc_cnt * dwc_ep->proc_buf_num;
02441
02442 for (i = 0; i < dwc_ep->desc_cnt - 1; i++) {
02443 sts.d32 = dma_desc->status.d32;
02444
02445
02446 iso_packet->status =
02447 sts.b_iso_in.txsts +
02448 (sts.b_iso_in.bs ^ BS_DMA_DONE);
02449 if (iso_packet->status != 0) {
02450 iso_packet->status = -DWC_E_NO_DATA;
02451
02452 }
02453
02454 iso_packet->length =
02455 dwc_ep->data_per_frame - sts.b_iso_in.txbytes;
02456
02457 dma_desc++;
02458 iso_packet++;
02459 }
02460
02461 sts.d32 = dma_desc->status.d32;
02462 while (sts.b_iso_in.bs == BS_DMA_BUSY) {
02463 sts.d32 = dma_desc->status.d32;
02464 }
02465
02466
02467 iso_packet->status =
02468 sts.b_iso_in.txsts + (sts.b_iso_in.bs ^ BS_DMA_DONE);
02469 if (iso_packet->status != 0) {
02470 iso_packet->status = -DWC_E_NO_DATA;
02471 }
02472
02473
02474 iso_packet->length =
02475 dwc_ep->data_per_frame - sts.b_iso_in.txbytes;
02476 }
02477 }
02478
02486 static void reinit_ddma_iso_xfer(dwc_otg_core_if_t * core_if, dwc_ep_t * dwc_ep)
02487 {
02488 int i, j;
02489 dwc_otg_dev_dma_desc_t *dma_desc;
02490 dma_addr_t dma_ad;
02491 volatile uint32_t *addr;
02492 dev_dma_desc_sts_t sts = {.d32 = 0 };
02493 uint32_t data_per_desc;
02494
02495 if (dwc_ep->is_in == 0) {
02496 addr = &core_if->dev_if->out_ep_regs[dwc_ep->num]->doepctl;
02497 } else {
02498 addr = &core_if->dev_if->in_ep_regs[dwc_ep->num]->diepctl;
02499 }
02500
02501 if (dwc_ep->proc_buf_num == 0) {
02503 dma_ad = dwc_ep->dma_addr0;
02504 } else {
02506 dma_ad = dwc_ep->dma_addr1;
02507 }
02508
02511 if (dwc_ep->is_in == 0) {
02512 dma_desc =
02513 dwc_ep->iso_desc_addr +
02514 dwc_ep->desc_cnt * dwc_ep->proc_buf_num;
02515
02516 sts.b_iso_out.bs = BS_HOST_READY;
02517 sts.b_iso_out.rxsts = 0;
02518 sts.b_iso_out.l = 0;
02519 sts.b_iso_out.sp = 0;
02520 sts.b_iso_out.ioc = 0;
02521 sts.b_iso_out.pid = 0;
02522 sts.b_iso_out.framenum = 0;
02523
02524 for (i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm;
02525 i += dwc_ep->pkt_per_frm) {
02526 for (j = 0; j < dwc_ep->pkt_per_frm; ++j) {
02527 data_per_desc =
02528 ((j + 1) * dwc_ep->maxpacket >
02529 dwc_ep->data_per_frame) ? dwc_ep->
02530 data_per_frame -
02531 j * dwc_ep->maxpacket : dwc_ep->maxpacket;
02532 data_per_desc +=
02533 (data_per_desc % 4) ? (4 -
02534 data_per_desc %
02535 4) : 0;
02536 sts.b_iso_out.rxbytes = data_per_desc;
02537 dma_desc->buf = dma_ad;
02538 dma_desc->status.d32 = sts.d32;
02539
02540 dma_ad += data_per_desc;
02541 dma_desc++;
02542 }
02543 }
02544
02545 for (j = 0; j < dwc_ep->pkt_per_frm - 1; ++j) {
02546
02547 data_per_desc =
02548 ((j + 1) * dwc_ep->maxpacket >
02549 dwc_ep->data_per_frame) ? dwc_ep->data_per_frame -
02550 j * dwc_ep->maxpacket : dwc_ep->maxpacket;
02551 data_per_desc +=
02552 (data_per_desc % 4) ? (4 - data_per_desc % 4) : 0;
02553 sts.b_iso_out.rxbytes = data_per_desc;
02554
02555 dma_desc->buf = dma_ad;
02556 dma_desc->status.d32 = sts.d32;
02557
02558 dma_desc++;
02559 dma_ad += data_per_desc;
02560 }
02561
02562 sts.b_iso_out.ioc = 1;
02563 sts.b_iso_out.l = dwc_ep->proc_buf_num;
02564
02565 data_per_desc =
02566 ((j + 1) * dwc_ep->maxpacket >
02567 dwc_ep->data_per_frame) ? dwc_ep->data_per_frame -
02568 j * dwc_ep->maxpacket : dwc_ep->maxpacket;
02569 data_per_desc +=
02570 (data_per_desc % 4) ? (4 - data_per_desc % 4) : 0;
02571 sts.b_iso_out.rxbytes = data_per_desc;
02572
02573 dma_desc->buf = dma_ad;
02574 dma_desc->status.d32 = sts.d32;
02575 } else {
02578 dma_desc =
02579 dwc_ep->iso_desc_addr +
02580 dwc_ep->desc_cnt * dwc_ep->proc_buf_num;
02581
02582 sts.b_iso_in.bs = BS_HOST_READY;
02583 sts.b_iso_in.txsts = 0;
02584 sts.b_iso_in.sp = 0;
02585 sts.b_iso_in.ioc = 0;
02586 sts.b_iso_in.pid = dwc_ep->pkt_per_frm;
02587 sts.b_iso_in.framenum = dwc_ep->next_frame;
02588 sts.b_iso_in.txbytes = dwc_ep->data_per_frame;
02589 sts.b_iso_in.l = 0;
02590
02591 for (i = 0; i < dwc_ep->desc_cnt - 1; i++) {
02592 dma_desc->buf = dma_ad;
02593 dma_desc->status.d32 = sts.d32;
02594
02595 sts.b_iso_in.framenum += dwc_ep->bInterval;
02596 dma_ad += dwc_ep->data_per_frame;
02597 dma_desc++;
02598 }
02599
02600 sts.b_iso_in.ioc = 1;
02601 sts.b_iso_in.l = dwc_ep->proc_buf_num;
02602
02603 dma_desc->buf = dma_ad;
02604 dma_desc->status.d32 = sts.d32;
02605
02606 dwc_ep->next_frame =
02607 sts.b_iso_in.framenum + dwc_ep->bInterval * 1;
02608 }
02609 dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1;
02610 }
02611
02620 static uint32_t handle_iso_out_pkt_dropped(dwc_otg_core_if_t * core_if,
02621 dwc_ep_t * dwc_ep)
02622 {
02623 uint32_t dma_addr;
02624 uint32_t drp_pkt;
02625 uint32_t drp_pkt_cnt;
02626 deptsiz_data_t deptsiz = {.d32 = 0 };
02627 depctl_data_t depctl = {.d32 = 0 };
02628 int i;
02629
02630 deptsiz.d32 =
02631 dwc_read_reg32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->
02632 doeptsiz);
02633
02634 drp_pkt = dwc_ep->pkt_cnt - deptsiz.b.pktcnt;
02635 drp_pkt_cnt = dwc_ep->pkt_per_frm - (drp_pkt % dwc_ep->pkt_per_frm);
02636
02637
02638 for (i = 0; i < drp_pkt_cnt; ++i) {
02639 dwc_ep->pkt_info[drp_pkt].status = -DWC_E_NO_DATA;
02640 drp_pkt++;
02641 deptsiz.b.pktcnt--;
02642 }
02643
02644 if (deptsiz.b.pktcnt > 0) {
02645 deptsiz.b.xfersize =
02646 dwc_ep->xfer_len - (dwc_ep->pkt_cnt -
02647 deptsiz.b.pktcnt) * dwc_ep->maxpacket;
02648 } else {
02649 deptsiz.b.xfersize = 0;
02650 deptsiz.b.pktcnt = 0;
02651 }
02652
02653 dwc_write_reg32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doeptsiz,
02654 deptsiz.d32);
02655
02656 if (deptsiz.b.pktcnt > 0) {
02657 if (dwc_ep->proc_buf_num) {
02658 dma_addr =
02659 dwc_ep->dma_addr1 + dwc_ep->xfer_len -
02660 deptsiz.b.xfersize;
02661 } else {
02662 dma_addr =
02663 dwc_ep->dma_addr0 + dwc_ep->xfer_len -
02664 deptsiz.b.xfersize;;
02665 }
02666
02667 dwc_write_reg32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->
02668 doepdma, dma_addr);
02669
02671 depctl.d32 = 0;
02672 depctl.b.epena = 1;
02673 depctl.b.cnak = 1;
02674
02675 dwc_modify_reg32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->
02676 doepctl, depctl.d32, depctl.d32);
02677 return 0;
02678 } else {
02679 return 1;
02680 }
02681 }
02682
02690 static uint32_t set_iso_pkts_info(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
02691 {
02692 int i, j;
02693 dma_addr_t dma_ad;
02694 iso_pkt_info_t *packet_info = ep->pkt_info;
02695 uint32_t offset;
02696 uint32_t frame_data;
02697 deptsiz_data_t deptsiz;
02698
02699 if (ep->proc_buf_num == 0) {
02701 dma_ad = ep->dma_addr0;
02702 } else {
02704 dma_ad = ep->dma_addr1;
02705 }
02706
02707 if (ep->is_in) {
02708 deptsiz.d32 =
02709 dwc_read_reg32(&core_if->dev_if->in_ep_regs[ep->num]->
02710 dieptsiz);
02711 } else {
02712 deptsiz.d32 =
02713 dwc_read_reg32(&core_if->dev_if->out_ep_regs[ep->num]->
02714 doeptsiz);
02715 }
02716
02717 if (!deptsiz.b.xfersize) {
02718 offset = 0;
02719 for (i = 0; i < ep->pkt_cnt; i += ep->pkt_per_frm) {
02720 frame_data = ep->data_per_frame;
02721 for (j = 0; j < ep->pkt_per_frm; ++j) {
02722
02723
02724
02725
02726
02727
02728 packet_info->length =
02729 (ep->maxpacket <
02730 frame_data) ? ep->maxpacket : frame_data;
02731
02732
02733 packet_info->offset = offset;
02734 offset += packet_info->length;
02735 frame_data -= packet_info->length;
02736
02737 packet_info++;
02738 }
02739 }
02740 return 1;
02741 } else {
02742
02743
02744
02745
02746
02747
02748
02749
02750
02751 if (ep->is_in) {
02752 return 1;
02753 } else {
02754 return handle_iso_out_pkt_dropped(core_if, ep);
02755 }
02756 }
02757 }
02758
02766 static void complete_iso_ep(dwc_otg_pcd_t * pcd, dwc_otg_pcd_ep_t * ep)
02767 {
02768 dwc_otg_core_if_t *core_if = GET_CORE_IF(ep->pcd);
02769 dwc_ep_t *dwc_ep = &ep->dwc_ep;
02770 uint8_t is_last = 0;
02771
02772 if(ep->dwc_ep.next_frame == 0xffffffff) {
02773 DWC_WARN("Next frame is not set!\n");
02774 return;
02775 }
02776
02777 if (core_if->dma_enable) {
02778 if (core_if->dma_desc_enable) {
02779 set_ddma_iso_pkts_info(core_if, dwc_ep);
02780 reinit_ddma_iso_xfer(core_if, dwc_ep);
02781 is_last = 1;
02782 } else {
02783 if (core_if->pti_enh_enable) {
02784 if (set_iso_pkts_info(core_if, dwc_ep)) {
02785 dwc_ep->proc_buf_num =
02786 (dwc_ep->proc_buf_num ^ 1) & 0x1;
02787 dwc_otg_iso_ep_start_buf_transfer
02788 (core_if, dwc_ep);
02789 is_last = 1;
02790 }
02791 } else {
02792 set_current_pkt_info(core_if, dwc_ep);
02793 if (dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
02794 is_last = 1;
02795 dwc_ep->cur_pkt = 0;
02796 dwc_ep->proc_buf_num =
02797 (dwc_ep->proc_buf_num ^ 1) & 0x1;
02798 if (dwc_ep->proc_buf_num) {
02799 dwc_ep->cur_pkt_addr =
02800 dwc_ep->xfer_buff1;
02801 dwc_ep->cur_pkt_dma_addr =
02802 dwc_ep->dma_addr1;
02803 } else {
02804 dwc_ep->cur_pkt_addr =
02805 dwc_ep->xfer_buff0;
02806 dwc_ep->cur_pkt_dma_addr =
02807 dwc_ep->dma_addr0;
02808 }
02809
02810 }
02811 dwc_otg_iso_ep_start_frm_transfer(core_if,
02812 dwc_ep);
02813 }
02814 }
02815 } else {
02816 set_current_pkt_info(core_if, dwc_ep);
02817 if (dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
02818 is_last = 1;
02819 dwc_ep->cur_pkt = 0;
02820 dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1;
02821 if (dwc_ep->proc_buf_num) {
02822 dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff1;
02823 dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr1;
02824 } else {
02825 dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff0;
02826 dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr0;
02827 }
02828
02829 }
02830 dwc_otg_iso_ep_start_frm_transfer(core_if, dwc_ep);
02831 }
02832 if (is_last)
02833 dwc_otg_iso_buffer_done(pcd, ep, ep->iso_req_handle);
02834 }
02835 #endif
02836
02843 static void handle_ep0(dwc_otg_pcd_t * pcd)
02844 {
02845 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
02846 dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
02847 dev_dma_desc_sts_t desc_sts;
02848 deptsiz0_data_t deptsiz;
02849 uint32_t byte_count;
02850
02851 #ifdef DEBUG_EP0
02852 DWC_DEBUGPL(DBG_PCDV, "%s()\n", __func__);
02853 print_ep0_state(pcd);
02854 #endif
02855
02856
02857
02858 switch (pcd->ep0state) {
02859 case EP0_DISCONNECT:
02860 break;
02861
02862 case EP0_IDLE:
02863 pcd->request_config = 0;
02864
02865 pcd_setup(pcd);
02866 break;
02867
02868 case EP0_IN_DATA_PHASE:
02869 #ifdef DEBUG_EP0
02870 DWC_DEBUGPL(DBG_PCD, "DATA_IN EP%d-%s: type=%d, mps=%d\n",
02871 ep0->dwc_ep.num, (ep0->dwc_ep.is_in ? "IN" : "OUT"),
02872 ep0->dwc_ep.type, ep0->dwc_ep.maxpacket);
02873 #endif
02874
02875 if (core_if->dma_enable != 0) {
02876
02877
02878
02879
02880
02881
02882
02883 if (core_if->dma_desc_enable == 0) {
02884 deptsiz.d32 =
02885 dwc_read_reg32(&core_if->dev_if->
02886 in_ep_regs[0]->dieptsiz);
02887 byte_count =
02888 ep0->dwc_ep.xfer_len - deptsiz.b.xfersize;
02889 } else {
02890 desc_sts =
02891 core_if->dev_if->in_desc_addr->status;
02892 byte_count =
02893 ep0->dwc_ep.xfer_len - desc_sts.b.bytes;
02894 }
02895 ep0->dwc_ep.xfer_count += byte_count;
02896 ep0->dwc_ep.xfer_buff += byte_count;
02897 ep0->dwc_ep.dma_addr += byte_count;
02898 }
02899 if (ep0->dwc_ep.xfer_count < ep0->dwc_ep.total_len) {
02900 dwc_otg_ep0_continue_transfer(GET_CORE_IF(pcd),
02901 &ep0->dwc_ep);
02902 DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");
02903 } else if (ep0->dwc_ep.sent_zlp) {
02904 dwc_otg_ep0_continue_transfer(GET_CORE_IF(pcd),
02905 &ep0->dwc_ep);
02906 ep0->dwc_ep.sent_zlp = 0;
02907 DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");
02908 } else {
02909 ep0_complete_request(ep0);
02910 DWC_DEBUGPL(DBG_PCD, "COMPLETE TRANSFER\n");
02911 }
02912 break;
02913 case EP0_OUT_DATA_PHASE:
02914 #ifdef DEBUG_EP0
02915 DWC_DEBUGPL(DBG_PCD, "DATA_OUT EP%d-%s: type=%d, mps=%d\n",
02916 ep0->dwc_ep.num, (ep0->dwc_ep.is_in ? "IN" : "OUT"),
02917 ep0->dwc_ep.type, ep0->dwc_ep.maxpacket);
02918 #endif
02919 if (core_if->dma_enable != 0) {
02920 if (core_if->dma_desc_enable == 0) {
02921 deptsiz.d32 =
02922 dwc_read_reg32(&core_if->dev_if->
02923 out_ep_regs[0]->doeptsiz);
02924 byte_count =
02925 ep0->dwc_ep.maxpacket - deptsiz.b.xfersize;
02926 } else {
02927 desc_sts =
02928 core_if->dev_if->out_desc_addr->status;
02929 byte_count =
02930 ep0->dwc_ep.maxpacket - desc_sts.b.bytes;
02931 }
02932 ep0->dwc_ep.xfer_count += byte_count;
02933 ep0->dwc_ep.xfer_buff += byte_count;
02934 ep0->dwc_ep.dma_addr += byte_count;
02935 }
02936 if (ep0->dwc_ep.xfer_count < ep0->dwc_ep.total_len) {
02937 dwc_otg_ep0_continue_transfer(GET_CORE_IF(pcd),
02938 &ep0->dwc_ep);
02939 DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");
02940 } else if (ep0->dwc_ep.sent_zlp) {
02941 dwc_otg_ep0_continue_transfer(GET_CORE_IF(pcd),
02942 &ep0->dwc_ep);
02943 ep0->dwc_ep.sent_zlp = 0;
02944 DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");
02945 } else {
02946 ep0_complete_request(ep0);
02947 DWC_DEBUGPL(DBG_PCD, "COMPLETE TRANSFER\n");
02948 }
02949 break;
02950
02951 case EP0_IN_STATUS_PHASE:
02952 case EP0_OUT_STATUS_PHASE:
02953 DWC_DEBUGPL(DBG_PCD, "CASE: EP0_STATUS\n");
02954 ep0_complete_request(ep0);
02955 pcd->ep0state = EP0_IDLE;
02956 ep0->stopped = 1;
02957 ep0->dwc_ep.is_in = 0;
02958
02959
02960 if (core_if->dma_enable) {
02961 ep0_out_start(core_if, pcd);
02962 }
02963 break;
02964
02965 case EP0_STALL:
02966 DWC_ERROR("EP0 STALLed, should not get here pcd_setup()\n");
02967 break;
02968 }
02969 #ifdef DEBUG_EP0
02970 print_ep0_state(pcd);
02971 #endif
02972 }
02973
02977 static void restart_transfer(dwc_otg_pcd_t * pcd, const uint32_t epnum)
02978 {
02979 dwc_otg_core_if_t *core_if;
02980 dwc_otg_dev_if_t *dev_if;
02981 deptsiz_data_t dieptsiz = {.d32 = 0 };
02982 dwc_otg_pcd_ep_t *ep;
02983
02984 ep = get_in_ep(pcd, epnum);
02985
02986 #ifdef DWC_EN_ISOC
02987 if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) {
02988 return;
02989 }
02990 #endif
02991
02992 core_if = GET_CORE_IF(pcd);
02993 dev_if = core_if->dev_if;
02994
02995 dieptsiz.d32 = dwc_read_reg32(&dev_if->in_ep_regs[epnum]->dieptsiz);
02996
02997 DWC_DEBUGPL(DBG_PCD, "xfer_buff=%p xfer_count=%0x xfer_len=%0x"
02998 " stopped=%d\n", ep->dwc_ep.xfer_buff,
02999 ep->dwc_ep.xfer_count, ep->dwc_ep.xfer_len, ep->stopped);
03000
03001
03002
03003 if (dieptsiz.b.pktcnt && dieptsiz.b.xfersize == 0 &&
03004 ep->dwc_ep.start_xfer_buff != 0) {
03005 if (ep->dwc_ep.total_len <= ep->dwc_ep.maxpacket) {
03006 ep->dwc_ep.xfer_count = 0;
03007 ep->dwc_ep.xfer_buff = ep->dwc_ep.start_xfer_buff;
03008 ep->dwc_ep.xfer_len = ep->dwc_ep.xfer_count;
03009 } else {
03010 ep->dwc_ep.xfer_count -= ep->dwc_ep.maxpacket;
03011
03012 ep->dwc_ep.xfer_buff -= ep->dwc_ep.maxpacket;
03013 ep->dwc_ep.xfer_len = ep->dwc_ep.xfer_count;
03014 }
03015 ep->stopped = 0;
03016 DWC_DEBUGPL(DBG_PCD, "xfer_buff=%p xfer_count=%0x "
03017 "xfer_len=%0x stopped=%d\n",
03018 ep->dwc_ep.xfer_buff,
03019 ep->dwc_ep.xfer_count, ep->dwc_ep.xfer_len,
03020 ep->stopped);
03021 if (epnum == 0) {
03022 dwc_otg_ep0_start_transfer(core_if, &ep->dwc_ep);
03023 } else {
03024 dwc_otg_ep_start_transfer(core_if, &ep->dwc_ep);
03025 }
03026 }
03027 }
03028
03032 static inline void handle_in_ep_disable_intr(dwc_otg_pcd_t * pcd,
03033 const uint32_t epnum)
03034 {
03035 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
03036 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
03037 deptsiz_data_t dieptsiz = {.d32 = 0 };
03038 dctl_data_t dctl = {.d32 = 0 };
03039 dwc_otg_pcd_ep_t *ep;
03040 dwc_ep_t *dwc_ep;
03041
03042 ep = get_in_ep(pcd, epnum);
03043 dwc_ep = &ep->dwc_ep;
03044
03045 if (dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
03046 dwc_otg_flush_tx_fifo(core_if, dwc_ep->tx_fifo_num);
03047 return;
03048 }
03049
03050 DWC_DEBUGPL(DBG_PCD, "diepctl%d=%0x\n", epnum,
03051 dwc_read_reg32(&dev_if->in_ep_regs[epnum]->diepctl));
03052 dieptsiz.d32 = dwc_read_reg32(&dev_if->in_ep_regs[epnum]->dieptsiz);
03053
03054 DWC_DEBUGPL(DBG_ANY, "pktcnt=%d size=%d\n",
03055 dieptsiz.b.pktcnt, dieptsiz.b.xfersize);
03056
03057 if (ep->stopped) {
03058
03059 dwc_otg_flush_tx_fifo(core_if, dwc_ep->tx_fifo_num);
03060
03061 dctl.d32 = 0;
03062 dctl.b.cgnpinnak = 1;
03063 dwc_modify_reg32(&dev_if->dev_global_regs->dctl, dctl.d32, 0);
03064
03065 if (dieptsiz.b.pktcnt != 0 || dieptsiz.b.xfersize != 0) {
03066 restart_transfer(pcd, epnum);
03067 }
03068 } else {
03069
03070 if (dieptsiz.b.pktcnt != 0 || dieptsiz.b.xfersize != 0) {
03071 restart_transfer(pcd, epnum);
03072 }
03073 DWC_DEBUGPL(DBG_ANY, "STOPPED!!!\n");
03074 }
03075 }
03076
03080 static inline void handle_in_ep_timeout_intr(dwc_otg_pcd_t * pcd,
03081 const uint32_t epnum)
03082 {
03083 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
03084 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
03085
03086 #ifdef DEBUG
03087 deptsiz_data_t dieptsiz = {.d32 = 0 };
03088 uint32_t num = 0;
03089 #endif
03090 dctl_data_t dctl = {.d32 = 0 };
03091 dwc_otg_pcd_ep_t *ep;
03092
03093 gintmsk_data_t intr_mask = {.d32 = 0 };
03094
03095 ep = get_in_ep(pcd, epnum);
03096
03097
03098 if (!core_if->dma_enable) {
03099 intr_mask.b.nptxfempty = 1;
03100 dwc_modify_reg32(&core_if->core_global_regs->gintmsk,
03101 intr_mask.d32, 0);
03102 }
03105
03106
03107
03108
03109 intr_mask.b.ginnakeff = 1;
03110 dwc_modify_reg32(&core_if->core_global_regs->gintmsk, 0, intr_mask.d32);
03111
03112
03113 dctl.b.sgnpinnak = 1;
03114 dwc_modify_reg32(&dev_if->dev_global_regs->dctl, dctl.d32, dctl.d32);
03115
03116 ep->stopped = 1;
03117
03118 #ifdef DEBUG
03119 dieptsiz.d32 = dwc_read_reg32(&dev_if->in_ep_regs[num]->dieptsiz);
03120 DWC_DEBUGPL(DBG_ANY, "pktcnt=%d size=%d\n",
03121 dieptsiz.b.pktcnt, dieptsiz.b.xfersize);
03122 #endif
03123
03124 #ifdef DISABLE_PERIODIC_EP
03125
03126
03127
03128
03129 diepctl.d32 = 0;
03130 diepctl.b.snak = 1;
03131 dwc_modify_reg32(&dev_if->in_ep_regs[num]->diepctl, diepctl.d32,
03132 diepctl.d32);
03133 ep->disabling = 1;
03134 ep->stopped = 1;
03135 #endif
03136 }
03137
03141 static inline int32_t handle_in_ep_nak_intr(dwc_otg_pcd_t * pcd,
03142 const uint32_t epnum)
03143 {
03145 dwc_otg_core_if_t *core_if;
03146 diepmsk_data_t intr_mask = {.d32 = 0 };
03147
03148 DWC_PRINTF("INTERRUPT Handler not implemented for %s\n", "IN EP NAK");
03149 core_if = GET_CORE_IF(pcd);
03150 intr_mask.b.nak = 1;
03151
03152 if (core_if->multiproc_int_enable) {
03153 dwc_modify_reg32(&core_if->dev_if->dev_global_regs->
03154 diepeachintmsk[epnum], intr_mask.d32, 0);
03155 } else {
03156 dwc_modify_reg32(&core_if->dev_if->dev_global_regs->diepmsk,
03157 intr_mask.d32, 0);
03158 }
03159
03160 return 1;
03161 }
03162
03166 static inline int32_t handle_out_ep_babble_intr(dwc_otg_pcd_t * pcd,
03167 const uint32_t epnum)
03168 {
03170 dwc_otg_core_if_t *core_if;
03171 doepmsk_data_t intr_mask = {.d32 = 0 };
03172
03173 DWC_PRINTF("INTERRUPT Handler not implemented for %s\n",
03174 "OUT EP Babble");
03175 core_if = GET_CORE_IF(pcd);
03176 intr_mask.b.babble = 1;
03177
03178 if (core_if->multiproc_int_enable) {
03179 dwc_modify_reg32(&core_if->dev_if->dev_global_regs->
03180 doepeachintmsk[epnum], intr_mask.d32, 0);
03181 } else {
03182 dwc_modify_reg32(&core_if->dev_if->dev_global_regs->doepmsk,
03183 intr_mask.d32, 0);
03184 }
03185
03186 return 1;
03187 }
03188
03192 static inline int32_t handle_out_ep_nak_intr(dwc_otg_pcd_t * pcd,
03193 const uint32_t epnum)
03194 {
03196 dwc_otg_core_if_t *core_if;
03197 doepmsk_data_t intr_mask = {.d32 = 0 };
03198
03199 DWC_PRINTF("INTERRUPT Handler not implemented for %s\n", "OUT EP NAK");
03200 core_if = GET_CORE_IF(pcd);
03201 intr_mask.b.nak = 1;
03202
03203 if (core_if->multiproc_int_enable) {
03204 dwc_modify_reg32(&core_if->dev_if->dev_global_regs->
03205 doepeachintmsk[epnum], intr_mask.d32, 0);
03206 } else {
03207 dwc_modify_reg32(&core_if->dev_if->dev_global_regs->doepmsk,
03208 intr_mask.d32, 0);
03209 }
03210
03211 return 1;
03212 }
03213
03217 static inline int32_t handle_out_ep_nyet_intr(dwc_otg_pcd_t * pcd,
03218 const uint32_t epnum)
03219 {
03221 dwc_otg_core_if_t *core_if;
03222 doepmsk_data_t intr_mask = {.d32 = 0 };
03223
03224 DWC_PRINTF("INTERRUPT Handler not implemented for %s\n", "OUT EP NYET");
03225 core_if = GET_CORE_IF(pcd);
03226 intr_mask.b.nyet = 1;
03227
03228 if (core_if->multiproc_int_enable) {
03229 dwc_modify_reg32(&core_if->dev_if->dev_global_regs->
03230 doepeachintmsk[epnum], intr_mask.d32, 0);
03231 } else {
03232 dwc_modify_reg32(&core_if->dev_if->dev_global_regs->doepmsk,
03233 intr_mask.d32, 0);
03234 }
03235
03236 return 1;
03237 }
03238
03255 static int32_t dwc_otg_pcd_handle_in_ep_intr(dwc_otg_pcd_t * pcd)
03256 {
03257 #define CLEAR_IN_EP_INTR(__core_if,__epnum,__intr) \
03258 do { \
03259 diepint_data_t diepint = {.d32=0}; \
03260 diepint.b.__intr = 1; \
03261 dwc_write_reg32(&__core_if->dev_if->in_ep_regs[__epnum]->diepint, \
03262 diepint.d32); \
03263 } while (0)
03264
03265 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
03266 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
03267 diepint_data_t diepint = {.d32 = 0 };
03268 dctl_data_t dctl = {.d32 = 0 };
03269 depctl_data_t depctl = {.d32 = 0 };
03270 uint32_t ep_intr;
03271 uint32_t epnum = 0;
03272 dwc_otg_pcd_ep_t *ep;
03273 dwc_ep_t *dwc_ep;
03274 gintmsk_data_t intr_mask = {.d32 = 0 };
03275
03276 DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, pcd);
03277
03278
03279 ep_intr = dwc_otg_read_dev_all_in_ep_intr(core_if);
03280
03281
03282 while (ep_intr) {
03283 if (ep_intr & 0x1) {
03284 uint32_t empty_msk;
03285
03286 ep = get_in_ep(pcd, epnum);
03287 dwc_ep = &ep->dwc_ep;
03288
03289 depctl.d32 =
03290 dwc_read_reg32(&dev_if->in_ep_regs[epnum]->diepctl);
03291 empty_msk =
03292 dwc_read_reg32(&dev_if->dev_global_regs->
03293 dtknqr4_fifoemptymsk);
03294
03295 DWC_DEBUGPL(DBG_PCDV,
03296 "IN EP INTERRUPT - %d\nepmty_msk - %8x diepctl - %8x\n",
03297 epnum, empty_msk, depctl.d32);
03298
03299 DWC_DEBUGPL(DBG_PCD,
03300 "EP%d-%s: type=%d, mps=%d\n",
03301 dwc_ep->num, (dwc_ep->is_in ? "IN" : "OUT"),
03302 dwc_ep->type, dwc_ep->maxpacket);
03303
03304 diepint.d32 =
03305 dwc_otg_read_dev_in_ep_intr(core_if, dwc_ep);
03306
03307 DWC_DEBUGPL(DBG_PCDV,
03308 "EP %d Interrupt Register - 0x%x\n", epnum,
03309 diepint.d32);
03310
03311 if (diepint.b.xfercompl) {
03312
03313
03314 if (core_if->en_multiple_tx_fifo == 0) {
03315 intr_mask.b.nptxfempty = 1;
03316 dwc_modify_reg32(&core_if->
03317 core_global_regs->
03318 gintmsk, intr_mask.d32,
03319 0);
03320 } else {
03321
03322 uint32_t fifoemptymsk =
03323 0x1 << dwc_ep->num;
03324 dwc_modify_reg32(&core_if->dev_if->
03325 dev_global_regs->
03326 dtknqr4_fifoemptymsk,
03327 fifoemptymsk, 0);
03328 }
03329
03330 CLEAR_IN_EP_INTR(core_if, epnum, xfercompl);
03331
03332
03333 if (epnum == 0) {
03334 handle_ep0(pcd);
03335 }
03336 #ifdef DWC_EN_ISOC
03337 else if (dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
03338 if (!ep->stopped)
03339 complete_iso_ep(pcd, ep);
03340 }
03341 #endif
03342 else {
03343
03344 complete_ep(ep);
03345 }
03346 }
03347
03348 if (diepint.b.epdisabled) {
03349 DWC_DEBUGPL(DBG_ANY, "EP%d IN disabled\n",
03350 epnum);
03351 handle_in_ep_disable_intr(pcd, epnum);
03352
03353
03354 CLEAR_IN_EP_INTR(core_if, epnum, epdisabled);
03355 }
03356
03357 if (diepint.b.ahberr) {
03358 DWC_DEBUGPL(DBG_ANY, "EP%d IN AHB Error\n",
03359 epnum);
03360
03361 CLEAR_IN_EP_INTR(core_if, epnum, ahberr);
03362 }
03363
03364 if (diepint.b.timeout) {
03365 DWC_DEBUGPL(DBG_ANY, "EP%d IN Time-out\n",
03366 epnum);
03367 handle_in_ep_timeout_intr(pcd, epnum);
03368
03369 CLEAR_IN_EP_INTR(core_if, epnum, timeout);
03370 }
03372 if (diepint.b.intktxfemp) {
03373 DWC_DEBUGPL(DBG_ANY,
03374 "EP%d IN TKN TxFifo Empty\n",
03375 epnum);
03376 if (!ep->stopped && epnum != 0) {
03377
03378 diepmsk_data_t diepmsk = {.d32 = 0 };
03379 diepmsk.b.intktxfemp = 1;
03380
03381 if (core_if->multiproc_int_enable) {
03382 dwc_modify_reg32(&dev_if->
03383 dev_global_regs->
03384 diepeachintmsk
03385 [epnum],
03386 diepmsk.d32,
03387 0);
03388 } else {
03389 dwc_modify_reg32(&dev_if->
03390 dev_global_regs->
03391 diepmsk,
03392 diepmsk.d32,
03393 0);
03394 }
03395 } else if (core_if->dma_desc_enable
03396 && epnum == 0
03397 && pcd->ep0state ==
03398 EP0_OUT_STATUS_PHASE) {
03399
03400 depctl.d32 =
03401 dwc_read_reg32(&dev_if->
03402 in_ep_regs[epnum]->
03403 diepctl);
03404
03405
03406 if (depctl.b.epena) {
03407 depctl.b.epdis = 1;
03408 }
03409 depctl.b.stall = 1;
03410 dwc_write_reg32(&dev_if->
03411 in_ep_regs[epnum]->
03412 diepctl, depctl.d32);
03413 }
03414 CLEAR_IN_EP_INTR(core_if, epnum, intktxfemp);
03415 }
03417 if (diepint.b.intknepmis) {
03418 DWC_DEBUGPL(DBG_ANY,
03419 "EP%d IN TKN EP Mismatch\n", epnum);
03420 CLEAR_IN_EP_INTR(core_if, epnum, intknepmis);
03421 }
03423 if (diepint.b.inepnakeff) {
03424 DWC_DEBUGPL(DBG_ANY,
03425 "EP%d IN EP NAK Effective\n",
03426 epnum);
03427
03428 if (ep->disabling) {
03429 depctl.d32 = 0;
03430 depctl.b.snak = 1;
03431 depctl.b.epdis = 1;
03432 dwc_modify_reg32(&dev_if->
03433 in_ep_regs[epnum]->
03434 diepctl, depctl.d32,
03435 depctl.d32);
03436 }
03437 CLEAR_IN_EP_INTR(core_if, epnum, inepnakeff);
03438
03439 }
03440
03442 if (diepint.b.emptyintr) {
03443 DWC_DEBUGPL(DBG_ANY,
03444 "EP%d Tx FIFO Empty Intr \n",
03445 epnum);
03446 write_empty_tx_fifo(pcd, epnum);
03447
03448 CLEAR_IN_EP_INTR(core_if, epnum, emptyintr);
03449
03450 }
03451
03453 if (diepint.b.bna) {
03454 CLEAR_IN_EP_INTR(core_if, epnum, bna);
03455 if (core_if->dma_desc_enable) {
03456 #ifdef DWC_EN_ISOC
03457 if (dwc_ep->type ==
03458 DWC_OTG_EP_TYPE_ISOC) {
03459
03460
03461
03462
03463 if (dwc_ep->next_frame !=
03464 0xffffffff)
03465 dwc_otg_pcd_handle_iso_bna
03466 (ep);
03467 } else
03468 #endif
03469 {
03470 dctl.d32 =
03471 dwc_read_reg32(&dev_if->
03472 dev_global_regs->
03473 dctl);
03474
03475
03476 if (!dctl.b.gcontbna) {
03477 depctl.d32 = 0;
03478 depctl.b.snak = 1;
03479 depctl.b.epdis = 1;
03480 dwc_modify_reg32
03481 (&dev_if->
03482 in_ep_regs[epnum]->
03483 diepctl,
03484 depctl.d32,
03485 depctl.d32);
03486 } else {
03487 start_next_request(ep);
03488 }
03489 }
03490 }
03491 }
03492
03493 if (diepint.b.nak) {
03494 DWC_DEBUGPL(DBG_ANY, "EP%d IN NAK Interrupt\n",
03495 epnum);
03496 handle_in_ep_nak_intr(pcd, epnum);
03497
03498 CLEAR_IN_EP_INTR(core_if, epnum, nak);
03499 }
03500 }
03501 epnum++;
03502 ep_intr >>= 1;
03503 }
03504
03505 return 1;
03506 #undef CLEAR_IN_EP_INTR
03507 }
03508
03522 static int32_t dwc_otg_pcd_handle_out_ep_intr(dwc_otg_pcd_t * pcd)
03523 {
03524 #define CLEAR_OUT_EP_INTR(__core_if,__epnum,__intr) \
03525 do { \
03526 doepint_data_t doepint = {.d32=0}; \
03527 doepint.b.__intr = 1; \
03528 dwc_write_reg32(&__core_if->dev_if->out_ep_regs[__epnum]->doepint, \
03529 doepint.d32); \
03530 } while (0)
03531
03532 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
03533 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
03534 uint32_t ep_intr;
03535 doepint_data_t doepint = {.d32 = 0 };
03536 dctl_data_t dctl = {.d32 = 0 };
03537 depctl_data_t doepctl = {.d32 = 0 };
03538 uint32_t epnum = 0;
03539 dwc_otg_pcd_ep_t *ep;
03540 dwc_ep_t *dwc_ep;
03541
03542 DWC_DEBUGPL(DBG_PCDV, "%s()\n", __func__);
03543
03544
03545 ep_intr = dwc_otg_read_dev_all_out_ep_intr(core_if);
03546
03547 while (ep_intr) {
03548 if (ep_intr & 0x1) {
03549
03550 ep = get_out_ep(pcd, epnum);
03551 dwc_ep = &ep->dwc_ep;
03552
03553 #ifdef VERBOSE
03554 DWC_DEBUGPL(DBG_PCDV,
03555 "EP%d-%s: type=%d, mps=%d\n",
03556 dwc_ep->num, (dwc_ep->is_in ? "IN" : "OUT"),
03557 dwc_ep->type, dwc_ep->maxpacket);
03558 #endif
03559 doepint.d32 =
03560 dwc_otg_read_dev_out_ep_intr(core_if, dwc_ep);
03561
03562
03563 if (doepint.b.xfercompl) {
03564
03565 if (epnum == 0) {
03566
03567 CLEAR_OUT_EP_INTR(core_if, epnum,
03568 xfercompl);
03569 if (core_if->dma_desc_enable == 0
03570 || pcd->ep0state != EP0_IDLE)
03571 handle_ep0(pcd);
03572 #ifdef DWC_EN_ISOC
03573 } else if (dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
03574 if (doepint.b.pktdrpsts == 0) {
03575
03576 CLEAR_OUT_EP_INTR(core_if,
03577 epnum,
03578 xfercompl);
03579 complete_iso_ep(pcd, ep);
03580 } else {
03581
03582 doepint_data_t doepint = {.d32 =
03583 0 };
03584 doepint.b.xfercompl = 1;
03585 doepint.b.pktdrpsts = 1;
03586 dwc_write_reg32(&core_if->
03587 dev_if->
03588 out_ep_regs
03589 [epnum]->
03590 doepint,
03591 doepint.d32);
03592 if (handle_iso_out_pkt_dropped
03593 (core_if, dwc_ep)) {
03594 complete_iso_ep(pcd,
03595 ep);
03596 }
03597 }
03598 #endif
03599 } else {
03600
03601 CLEAR_OUT_EP_INTR(core_if, epnum,
03602 xfercompl);
03603 complete_ep(ep);
03604 }
03605
03606 }
03607
03608
03609 if (doepint.b.epdisabled) {
03610
03611
03612 CLEAR_OUT_EP_INTR(core_if, epnum, epdisabled);
03613 }
03614
03615 if (doepint.b.ahberr) {
03616 DWC_DEBUGPL(DBG_PCD, "EP%d OUT AHB Error\n",
03617 epnum);
03618 DWC_DEBUGPL(DBG_PCD, "EP DMA REG %d \n",
03619 core_if->dev_if->
03620 out_ep_regs[epnum]->doepdma);
03621 CLEAR_OUT_EP_INTR(core_if, epnum, ahberr);
03622 }
03623
03624 if (doepint.b.setup) {
03625 #ifdef DEBUG_EP0
03626 DWC_DEBUGPL(DBG_PCD, "EP%d SETUP Done\n",
03627 epnum);
03628 #endif
03629 CLEAR_OUT_EP_INTR(core_if, epnum, setup);
03630
03631 handle_ep0(pcd);
03632 }
03633
03635 if (doepint.b.bna) {
03636 CLEAR_OUT_EP_INTR(core_if, epnum, bna);
03637 if (core_if->dma_desc_enable) {
03638 #ifdef DWC_EN_ISOC
03639 if (dwc_ep->type ==
03640 DWC_OTG_EP_TYPE_ISOC) {
03641
03642
03643
03644
03645 if (dwc_ep->next_frame !=
03646 0xffffffff)
03647 dwc_otg_pcd_handle_iso_bna
03648 (ep);
03649 } else
03650 #endif
03651 {
03652 dctl.d32 =
03653 dwc_read_reg32(&dev_if->
03654 dev_global_regs->
03655 dctl);
03656
03657
03658 if (!dctl.b.gcontbna) {
03659 doepctl.d32 = 0;
03660 doepctl.b.snak = 1;
03661 doepctl.b.epdis = 1;
03662 dwc_modify_reg32
03663 (&dev_if->
03664 out_ep_regs
03665 [epnum]->doepctl,
03666 doepctl.d32,
03667 doepctl.d32);
03668 } else {
03669 start_next_request(ep);
03670 }
03671 }
03672 }
03673 }
03674 if (doepint.b.stsphsercvd) {
03675 CLEAR_OUT_EP_INTR(core_if, epnum, stsphsercvd);
03676 if (core_if->dma_desc_enable) {
03677 do_setup_in_status_phase(pcd);
03678 }
03679 }
03680
03681 if (doepint.b.babble) {
03682 DWC_DEBUGPL(DBG_ANY, "EP%d OUT Babble\n",
03683 epnum);
03684 handle_out_ep_babble_intr(pcd, epnum);
03685
03686 CLEAR_OUT_EP_INTR(core_if, epnum, babble);
03687 }
03688
03689 if (doepint.b.nak) {
03690 DWC_DEBUGPL(DBG_ANY, "EP%d OUT NAK\n", epnum);
03691 handle_out_ep_nak_intr(pcd, epnum);
03692
03693 CLEAR_OUT_EP_INTR(core_if, epnum, nak);
03694 }
03695
03696 if (doepint.b.nyet) {
03697 DWC_DEBUGPL(DBG_ANY, "EP%d OUT NYET\n", epnum);
03698 handle_out_ep_nyet_intr(pcd, epnum);
03699
03700 CLEAR_OUT_EP_INTR(core_if, epnum, nyet);
03701 }
03702 }
03703
03704 epnum++;
03705 ep_intr >>= 1;
03706 }
03707
03708 return 1;
03709
03710 #undef CLEAR_OUT_EP_INTR
03711 }
03712
03725 int32_t dwc_otg_pcd_handle_incomplete_isoc_in_intr(dwc_otg_pcd_t * pcd)
03726 {
03727 gintsts_data_t gintsts;
03728
03729 #ifdef DWC_EN_ISOC
03730 dwc_otg_dev_if_t *dev_if;
03731 deptsiz_data_t deptsiz = {.d32 = 0 };
03732 depctl_data_t depctl = {.d32 = 0 };
03733 dsts_data_t dsts = {.d32 = 0 };
03734 dwc_ep_t *dwc_ep;
03735 int i;
03736
03737 dev_if = GET_CORE_IF(pcd)->dev_if;
03738
03739 for (i = 1; i <= dev_if->num_in_eps; ++i) {
03740 dwc_ep = &pcd->in_ep[i].dwc_ep;
03741 if (dwc_ep->active && dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
03742 deptsiz.d32 =
03743 dwc_read_reg32(&dev_if->in_ep_regs[i]->dieptsiz);
03744 depctl.d32 =
03745 dwc_read_reg32(&dev_if->in_ep_regs[i]->diepctl);
03746
03747 if (depctl.b.epdis && deptsiz.d32) {
03748 set_current_pkt_info(GET_CORE_IF(pcd), dwc_ep);
03749 if (dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
03750 dwc_ep->cur_pkt = 0;
03751 dwc_ep->proc_buf_num =
03752 (dwc_ep->proc_buf_num ^ 1) & 0x1;
03753
03754 if (dwc_ep->proc_buf_num) {
03755 dwc_ep->cur_pkt_addr =
03756 dwc_ep->xfer_buff1;
03757 dwc_ep->cur_pkt_dma_addr =
03758 dwc_ep->dma_addr1;
03759 } else {
03760 dwc_ep->cur_pkt_addr =
03761 dwc_ep->xfer_buff0;
03762 dwc_ep->cur_pkt_dma_addr =
03763 dwc_ep->dma_addr0;
03764 }
03765
03766 }
03767
03768 dsts.d32 =
03769 dwc_read_reg32(&GET_CORE_IF(pcd)->dev_if->
03770 dev_global_regs->dsts);
03771 dwc_ep->next_frame = dsts.b.soffn;
03772
03773 dwc_otg_iso_ep_start_frm_transfer(GET_CORE_IF
03774 (pcd),
03775 dwc_ep);
03776 }
03777 }
03778 }
03779
03780 #else
03781 gintmsk_data_t intr_mask = {.d32 = 0 };
03782 DWC_PRINTF("INTERRUPT Handler not implemented for %s\n",
03783 "IN ISOC Incomplete");
03784
03785 intr_mask.b.incomplisoin = 1;
03786 dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
03787 intr_mask.d32, 0);
03788 #endif //DWC_EN_ISOC
03789
03790
03791 gintsts.d32 = 0;
03792 gintsts.b.incomplisoin = 1;
03793 dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
03794 gintsts.d32);
03795
03796 return 1;
03797 }
03798
03814 int32_t dwc_otg_pcd_handle_incomplete_isoc_out_intr(dwc_otg_pcd_t * pcd)
03815 {
03816
03817 gintsts_data_t gintsts;
03818
03819 #ifdef DWC_EN_ISOC
03820 dwc_otg_dev_if_t *dev_if;
03821 deptsiz_data_t deptsiz = {.d32 = 0 };
03822 depctl_data_t depctl = {.d32 = 0 };
03823 dsts_data_t dsts = {.d32 = 0 };
03824 dwc_ep_t *dwc_ep;
03825 int i;
03826
03827 dev_if = GET_CORE_IF(pcd)->dev_if;
03828
03829 for (i = 1; i <= dev_if->num_out_eps; ++i) {
03830 dwc_ep = &pcd->in_ep[i].dwc_ep;
03831 if (pcd->out_ep[i].dwc_ep.active &&
03832 pcd->out_ep[i].dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) {
03833 deptsiz.d32 =
03834 dwc_read_reg32(&dev_if->out_ep_regs[i]->doeptsiz);
03835 depctl.d32 =
03836 dwc_read_reg32(&dev_if->out_ep_regs[i]->doepctl);
03837
03838 if (depctl.b.epdis && deptsiz.d32) {
03839 set_current_pkt_info(GET_CORE_IF(pcd),
03840 &pcd->out_ep[i].dwc_ep);
03841 if (dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
03842 dwc_ep->cur_pkt = 0;
03843 dwc_ep->proc_buf_num =
03844 (dwc_ep->proc_buf_num ^ 1) & 0x1;
03845
03846 if (dwc_ep->proc_buf_num) {
03847 dwc_ep->cur_pkt_addr =
03848 dwc_ep->xfer_buff1;
03849 dwc_ep->cur_pkt_dma_addr =
03850 dwc_ep->dma_addr1;
03851 } else {
03852 dwc_ep->cur_pkt_addr =
03853 dwc_ep->xfer_buff0;
03854 dwc_ep->cur_pkt_dma_addr =
03855 dwc_ep->dma_addr0;
03856 }
03857
03858 }
03859
03860 dsts.d32 =
03861 dwc_read_reg32(&GET_CORE_IF(pcd)->dev_if->
03862 dev_global_regs->dsts);
03863 dwc_ep->next_frame = dsts.b.soffn;
03864
03865 dwc_otg_iso_ep_start_frm_transfer(GET_CORE_IF
03866 (pcd),
03867 dwc_ep);
03868 }
03869 }
03870 }
03871 #else
03872
03873 gintmsk_data_t intr_mask = {.d32 = 0 };
03874
03875 DWC_PRINTF("INTERRUPT Handler not implemented for %s\n",
03876 "OUT ISOC Incomplete");
03877
03878 intr_mask.b.incomplisoout = 1;
03879 dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
03880 intr_mask.d32, 0);
03881
03882 #endif
03883
03884
03885 gintsts.d32 = 0;
03886 gintsts.b.incomplisoout = 1;
03887 dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
03888 gintsts.d32);
03889
03890 return 1;
03891 }
03892
03897 int32_t dwc_otg_pcd_handle_in_nak_effective(dwc_otg_pcd_t * pcd)
03898 {
03899 dwc_otg_dev_if_t *dev_if = GET_CORE_IF(pcd)->dev_if;
03900 depctl_data_t diepctl = {.d32 = 0 };
03901 depctl_data_t diepctl_rd = {.d32 = 0 };
03902 gintmsk_data_t intr_mask = {.d32 = 0 };
03903 gintsts_data_t gintsts;
03904 int i;
03905
03906 DWC_DEBUGPL(DBG_PCD, "Global IN NAK Effective\n");
03907
03908
03909 diepctl.b.epdis = 1;
03910 diepctl.b.snak = 1;
03911
03912 for (i = 0; i <= dev_if->num_in_eps; i++) {
03913 diepctl_rd.d32 =
03914 dwc_read_reg32(&dev_if->in_ep_regs[i]->diepctl);
03915 if (diepctl_rd.b.epena) {
03916 dwc_write_reg32(&dev_if->in_ep_regs[i]->diepctl,
03917 diepctl.d32);
03918 }
03919 }
03920
03921 intr_mask.b.ginnakeff = 1;
03922 dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
03923 intr_mask.d32, 0);
03924
03925
03926 gintsts.d32 = 0;
03927 gintsts.b.ginnakeff = 1;
03928 dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
03929 gintsts.d32);
03930
03931 return 1;
03932 }
03933
03938 int32_t dwc_otg_pcd_handle_out_nak_effective(dwc_otg_pcd_t * pcd)
03939 {
03940 gintmsk_data_t intr_mask = {.d32 = 0 };
03941 gintsts_data_t gintsts;
03942
03943 DWC_PRINTF("INTERRUPT Handler not implemented for %s\n",
03944 "Global IN NAK Effective\n");
03945
03946 intr_mask.b.goutnakeff = 1;
03947 dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
03948 intr_mask.d32, 0);
03949
03950
03951 gintsts.d32 = 0;
03952 gintsts.b.goutnakeff = 1;
03953 dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
03954 gintsts.d32);
03955
03956 return 1;
03957 }
03958
03971 int32_t dwc_otg_pcd_handle_intr(dwc_otg_pcd_t * pcd)
03972 {
03973 dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
03974 #ifdef VERBOSE
03975 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
03976 #endif
03977 gintsts_data_t gintr_status;
03978 int32_t retval = 0;
03979
03980 #ifdef VERBOSE
03981 DWC_DEBUGPL(DBG_ANY, "%s() gintsts=%08x gintmsk=%08x\n",
03982 __func__,
03983 dwc_read_reg32(&global_regs->gintsts),
03984 dwc_read_reg32(&global_regs->gintmsk));
03985 #endif
03986
03987 if (dwc_otg_is_device_mode(core_if)) {
03988 DWC_SPINLOCK(pcd->lock);
03989 #ifdef VERBOSE
03990 DWC_DEBUGPL(DBG_PCDV, "%s() gintsts=%08x gintmsk=%08x\n",
03991 __func__,
03992 dwc_read_reg32(&global_regs->gintsts),
03993 dwc_read_reg32(&global_regs->gintmsk));
03994 #endif
03995
03996 gintr_status.d32 = dwc_otg_read_core_intr(core_if);
03997
03998 DWC_DEBUGPL(DBG_PCDV, "%s: gintsts&gintmsk=%08x\n",
03999 __func__, gintr_status.d32);
04000
04001 if (gintr_status.b.sofintr) {
04002 retval |= dwc_otg_pcd_handle_sof_intr(pcd);
04003 }
04004 if (gintr_status.b.rxstsqlvl) {
04005 retval |=
04006 dwc_otg_pcd_handle_rx_status_q_level_intr(pcd);
04007 }
04008 if (gintr_status.b.nptxfempty) {
04009 retval |= dwc_otg_pcd_handle_np_tx_fifo_empty_intr(pcd);
04010 }
04011 if (gintr_status.b.ginnakeff) {
04012 retval |= dwc_otg_pcd_handle_in_nak_effective(pcd);
04013 }
04014 if (gintr_status.b.goutnakeff) {
04015 retval |= dwc_otg_pcd_handle_out_nak_effective(pcd);
04016 }
04017 if (gintr_status.b.i2cintr) {
04018 retval |= dwc_otg_pcd_handle_i2c_intr(pcd);
04019 }
04020 if (gintr_status.b.erlysuspend) {
04021 retval |= dwc_otg_pcd_handle_early_suspend_intr(pcd);
04022 }
04023 if (gintr_status.b.usbreset) {
04024 retval |= dwc_otg_pcd_handle_usb_reset_intr(pcd);
04025 }
04026 if (gintr_status.b.enumdone) {
04027 retval |= dwc_otg_pcd_handle_enum_done_intr(pcd);
04028 }
04029 if (gintr_status.b.isooutdrop) {
04030 retval |=
04031 dwc_otg_pcd_handle_isoc_out_packet_dropped_intr
04032 (pcd);
04033 }
04034 if (gintr_status.b.eopframe) {
04035 retval |=
04036 dwc_otg_pcd_handle_end_periodic_frame_intr(pcd);
04037 }
04038 if (gintr_status.b.epmismatch) {
04039 retval |= dwc_otg_pcd_handle_ep_mismatch_intr(core_if);
04040 }
04041 if (gintr_status.b.inepint) {
04042 if (!core_if->multiproc_int_enable) {
04043 retval |= dwc_otg_pcd_handle_in_ep_intr(pcd);
04044 }
04045 }
04046 if (gintr_status.b.outepintr) {
04047 if (!core_if->multiproc_int_enable) {
04048 retval |= dwc_otg_pcd_handle_out_ep_intr(pcd);
04049 }
04050 }
04051 if (gintr_status.b.incomplisoin) {
04052 retval |=
04053 dwc_otg_pcd_handle_incomplete_isoc_in_intr(pcd);
04054 }
04055 if (gintr_status.b.incomplisoout) {
04056 retval |=
04057 dwc_otg_pcd_handle_incomplete_isoc_out_intr(pcd);
04058 }
04059
04060
04061
04062
04063
04064 if (core_if->multiproc_int_enable) {
04065 retval |= dwc_otg_pcd_handle_in_ep_intr(pcd);
04066 retval |= dwc_otg_pcd_handle_out_ep_intr(pcd);
04067 }
04068 #ifdef VERBOSE
04069 DWC_DEBUGPL(DBG_PCDV, "%s() gintsts=%0x\n", __func__,
04070 dwc_read_reg32(&global_regs->gintsts));
04071 #endif
04072 DWC_SPINUNLOCK(pcd->lock);
04073 }
04074 return retval;
04075 }
04076
04077 #endif