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