00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef DWC_DEVICE_ONLY
00034
00042 #include "dwc_otg_hcd.h"
00043 #include "dwc_otg_regs.h"
00044
00045 dwc_otg_hcd_t *dwc_otg_hcd_alloc_hcd(void)
00046 {
00047 return DWC_ALLOC(sizeof(dwc_otg_hcd_t));
00048 }
00049
00054 void dwc_otg_hcd_connect_timeout(void *ptr)
00055 {
00056 DWC_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, ptr);
00057 DWC_PRINTF("Connect Timeout\n");
00058 __DWC_ERROR("Device Not Connected/Responding\n");
00059 }
00060
00061 #ifdef DEBUG
00062 static void dump_channel_info(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh)
00063 {
00064 if (qh->channel != NULL) {
00065 dwc_hc_t *hc = qh->channel;
00066 dwc_list_link_t *item;
00067 dwc_otg_qh_t *qh_item;
00068 int num_channels = hcd->core_if->core_params->host_channels;
00069 int i;
00070
00071 dwc_otg_hc_regs_t *hc_regs;
00072 hcchar_data_t hcchar;
00073 hcsplt_data_t hcsplt;
00074 hctsiz_data_t hctsiz;
00075 uint32_t hcdma;
00076
00077 hc_regs = hcd->core_if->host_if->hc_regs[hc->hc_num];
00078 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
00079 hcsplt.d32 = DWC_READ_REG32(&hc_regs->hcsplt);
00080 hctsiz.d32 = DWC_READ_REG32(&hc_regs->hctsiz);
00081 hcdma = DWC_READ_REG32(&hc_regs->hcdma);
00082
00083 DWC_PRINTF(" Assigned to channel %p:\n", hc);
00084 DWC_PRINTF(" hcchar 0x%08x, hcsplt 0x%08x\n", hcchar.d32,
00085 hcsplt.d32);
00086 DWC_PRINTF(" hctsiz 0x%08x, hcdma 0x%08x\n", hctsiz.d32,
00087 hcdma);
00088 DWC_PRINTF(" dev_addr: %d, ep_num: %d, ep_is_in: %d\n",
00089 hc->dev_addr, hc->ep_num, hc->ep_is_in);
00090 DWC_PRINTF(" ep_type: %d\n", hc->ep_type);
00091 DWC_PRINTF(" max_packet: %d\n", hc->max_packet);
00092 DWC_PRINTF(" data_pid_start: %d\n", hc->data_pid_start);
00093 DWC_PRINTF(" xfer_started: %d\n", hc->xfer_started);
00094 DWC_PRINTF(" halt_status: %d\n", hc->halt_status);
00095 DWC_PRINTF(" xfer_buff: %p\n", hc->xfer_buff);
00096 DWC_PRINTF(" xfer_len: %d\n", hc->xfer_len);
00097 DWC_PRINTF(" qh: %p\n", hc->qh);
00098 DWC_PRINTF(" NP inactive sched:\n");
00099 DWC_LIST_FOREACH(item, &hcd->non_periodic_sched_inactive) {
00100 qh_item =
00101 DWC_LIST_ENTRY(item, dwc_otg_qh_t, qh_list_entry);
00102 DWC_PRINTF(" %p\n", qh_item);
00103 }
00104 DWC_PRINTF(" NP active sched:\n");
00105 DWC_LIST_FOREACH(item, &hcd->non_periodic_sched_active) {
00106 qh_item =
00107 DWC_LIST_ENTRY(item, dwc_otg_qh_t, qh_list_entry);
00108 DWC_PRINTF(" %p\n", qh_item);
00109 }
00110 DWC_PRINTF(" Channels: \n");
00111 for (i = 0; i < num_channels; i++) {
00112 dwc_hc_t *hc = hcd->hc_ptr_array[i];
00113 DWC_PRINTF(" %2d: %p\n", i, hc);
00114 }
00115 }
00116 }
00117 #endif
00118
00123 static void hcd_start_func(void *_vp)
00124 {
00125 dwc_otg_hcd_t *hcd = (dwc_otg_hcd_t *) _vp;
00126
00127 DWC_DEBUGPL(DBG_HCDV, "%s() %p\n", __func__, hcd);
00128 if (hcd) {
00129 hcd->fops->start(hcd);
00130 }
00131 }
00132
00133 static void del_xfer_timers(dwc_otg_hcd_t * hcd)
00134 {
00135 #ifdef DEBUG
00136 int i;
00137 int num_channels = hcd->core_if->core_params->host_channels;
00138 for (i = 0; i < num_channels; i++) {
00139 DWC_TIMER_CANCEL(hcd->core_if->hc_xfer_timer[i]);
00140 }
00141 #endif
00142 }
00143
00144 static void del_timers(dwc_otg_hcd_t * hcd)
00145 {
00146 del_xfer_timers(hcd);
00147 DWC_TIMER_CANCEL(hcd->conn_timer);
00148 }
00149
00154 static void kill_urbs_in_qh_list(dwc_otg_hcd_t * hcd, dwc_list_link_t * qh_list)
00155 {
00156 dwc_list_link_t *qh_item;
00157 dwc_otg_qh_t *qh;
00158 dwc_otg_qtd_t *qtd, *qtd_tmp;
00159
00160 DWC_LIST_FOREACH(qh_item, qh_list) {
00161 qh = DWC_LIST_ENTRY(qh_item, dwc_otg_qh_t, qh_list_entry);
00162 DWC_CIRCLEQ_FOREACH_SAFE(qtd, qtd_tmp,
00163 &qh->qtd_list, qtd_list_entry) {
00164 qtd = DWC_CIRCLEQ_FIRST(&qh->qtd_list);
00165 if (qtd->urb != NULL) {
00166 hcd->fops->complete(hcd, qtd->urb->priv,
00167 qtd->urb, -DWC_E_TIMEOUT);
00168 dwc_otg_hcd_qtd_remove_and_free(hcd, qtd, qh);
00169 }
00170
00171 }
00172 }
00173 }
00174
00181 static void kill_all_urbs(dwc_otg_hcd_t * hcd)
00182 {
00183 kill_urbs_in_qh_list(hcd, &hcd->non_periodic_sched_inactive);
00184 kill_urbs_in_qh_list(hcd, &hcd->non_periodic_sched_active);
00185 kill_urbs_in_qh_list(hcd, &hcd->periodic_sched_inactive);
00186 kill_urbs_in_qh_list(hcd, &hcd->periodic_sched_ready);
00187 kill_urbs_in_qh_list(hcd, &hcd->periodic_sched_assigned);
00188 kill_urbs_in_qh_list(hcd, &hcd->periodic_sched_queued);
00189 }
00190
00197 static void dwc_otg_hcd_start_connect_timer(dwc_otg_hcd_t * hcd)
00198 {
00199 DWC_TIMER_SCHEDULE(hcd->conn_timer, 10000 );
00200 }
00201
00207 static int32_t dwc_otg_hcd_session_start_cb(void *p)
00208 {
00209 dwc_otg_hcd_t *dwc_otg_hcd;
00210 DWC_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, p);
00211 dwc_otg_hcd = p;
00212 dwc_otg_hcd_start_connect_timer(dwc_otg_hcd);
00213 return 1;
00214 }
00215
00222 static int32_t dwc_otg_hcd_start_cb(void *p)
00223 {
00224 dwc_otg_hcd_t *dwc_otg_hcd = p;
00225 dwc_otg_core_if_t *core_if;
00226 hprt0_data_t hprt0;
00227
00228 core_if = dwc_otg_hcd->core_if;
00229
00230 if (core_if->op_state == B_HOST) {
00231
00232
00233
00234
00235
00236 hprt0.d32 = dwc_otg_read_hprt0(core_if);
00237 hprt0.b.prtrst = 1;
00238 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
00239 }
00240 DWC_WORKQ_SCHEDULE_DELAYED(core_if->wq_otg,
00241 hcd_start_func, dwc_otg_hcd, 50,
00242 "start hcd");
00243
00244 return 1;
00245 }
00246
00252 static int32_t dwc_otg_hcd_disconnect_cb(void *p)
00253 {
00254 gintsts_data_t intr;
00255 dwc_otg_hcd_t *dwc_otg_hcd = p;
00256
00257
00258
00259
00260 dwc_otg_hcd->flags.b.port_connect_status_change = 1;
00261 dwc_otg_hcd->flags.b.port_connect_status = 0;
00262
00263
00264
00265
00266
00267
00268 intr.d32 = 0;
00269 intr.b.nptxfempty = 1;
00270 intr.b.ptxfempty = 1;
00271 intr.b.hcintr = 1;
00272 DWC_MODIFY_REG32(&dwc_otg_hcd->core_if->core_global_regs->gintmsk,
00273 intr.d32, 0);
00274 DWC_MODIFY_REG32(&dwc_otg_hcd->core_if->core_global_regs->gintsts,
00275 intr.d32, 0);
00276
00277 del_timers(dwc_otg_hcd);
00278
00279
00280
00281
00282
00283
00284 if (dwc_otg_is_device_mode(dwc_otg_hcd->core_if)) {
00285 if (dwc_otg_hcd->core_if->op_state != A_SUSPEND) {
00286 hprt0_data_t hprt0 = {.d32 = 0 };
00287 DWC_PRINTF("Disconnect: PortPower off\n");
00288 hprt0.b.prtpwr = 0;
00289 DWC_WRITE_REG32(dwc_otg_hcd->core_if->host_if->hprt0,
00290 hprt0.d32);
00291 }
00292
00293 dwc_otg_disable_host_interrupts(dwc_otg_hcd->core_if);
00294 }
00295
00296
00297 kill_all_urbs(dwc_otg_hcd);
00298
00299 if (dwc_otg_is_host_mode(dwc_otg_hcd->core_if)) {
00300
00301 int num_channels;
00302 int i;
00303 dwc_hc_t *channel;
00304 dwc_otg_hc_regs_t *hc_regs;
00305 hcchar_data_t hcchar;
00306
00307 num_channels = dwc_otg_hcd->core_if->core_params->host_channels;
00308
00309 if (!dwc_otg_hcd->core_if->dma_enable) {
00310
00311 for (i = 0; i < num_channels; i++) {
00312 channel = dwc_otg_hcd->hc_ptr_array[i];
00313 if (DWC_CIRCLEQ_EMPTY_ENTRY
00314 (channel, hc_list_entry)) {
00315 hc_regs =
00316 dwc_otg_hcd->core_if->
00317 host_if->hc_regs[i];
00318 hcchar.d32 =
00319 DWC_READ_REG32(&hc_regs->hcchar);
00320 if (hcchar.b.chen) {
00321 hcchar.b.chen = 0;
00322 hcchar.b.chdis = 1;
00323 hcchar.b.epdir = 0;
00324 DWC_WRITE_REG32
00325 (&hc_regs->hcchar,
00326 hcchar.d32);
00327 }
00328 }
00329 }
00330 }
00331
00332 for (i = 0; i < num_channels; i++) {
00333 channel = dwc_otg_hcd->hc_ptr_array[i];
00334 if (DWC_CIRCLEQ_EMPTY_ENTRY(channel, hc_list_entry)) {
00335 hc_regs =
00336 dwc_otg_hcd->core_if->host_if->hc_regs[i];
00337 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
00338 if (hcchar.b.chen) {
00339
00340 hcchar.b.chdis = 1;
00341 DWC_WRITE_REG32(&hc_regs->hcchar,
00342 hcchar.d32);
00343 }
00344
00345 dwc_otg_hc_cleanup(dwc_otg_hcd->core_if,
00346 channel);
00347 DWC_CIRCLEQ_INSERT_TAIL
00348 (&dwc_otg_hcd->free_hc_list, channel,
00349 hc_list_entry);
00350
00351
00352
00353
00354
00355 channel->qh = NULL;
00356 }
00357 }
00358 }
00359
00360 if (dwc_otg_hcd->fops->disconnect) {
00361 dwc_otg_hcd->fops->disconnect(dwc_otg_hcd);
00362 }
00363
00364 return 1;
00365 }
00366
00372 static int32_t dwc_otg_hcd_stop_cb(void *p)
00373 {
00374 dwc_otg_hcd_t *dwc_otg_hcd = p;
00375
00376 DWC_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, p);
00377 dwc_otg_hcd_stop(dwc_otg_hcd);
00378 return 1;
00379 }
00380
00381 #ifdef CONFIG_USB_DWC_OTG_LPM
00382
00387 static int dwc_otg_hcd_sleep_cb(void *p)
00388 {
00389 dwc_otg_hcd_t *hcd = p;
00390
00391 dwc_otg_hcd_free_hc_from_lpm(hcd);
00392
00393 return 0;
00394 }
00395 #endif
00396
00402 static int dwc_otg_hcd_rem_wakeup_cb(void *p)
00403 {
00404 dwc_otg_hcd_t *hcd = p;
00405
00406 if (hcd->core_if->lx_state == DWC_OTG_L2) {
00407 hcd->flags.b.port_suspend_change = 1;
00408 }
00409 #ifdef CONFIG_USB_DWC_OTG_LPM
00410 else {
00411 hcd->flags.b.port_l1_change = 1;
00412 }
00413 #endif
00414 return 0;
00415 }
00416
00421 void dwc_otg_hcd_stop(dwc_otg_hcd_t * hcd)
00422 {
00423 hprt0_data_t hprt0 = {.d32 = 0 };
00424
00425 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD STOP\n");
00426
00427
00428
00429
00430
00431
00432
00433
00434 dwc_otg_disable_host_interrupts(hcd->core_if);
00435
00436
00437 DWC_PRINTF("PortPower off\n");
00438 hprt0.b.prtpwr = 0;
00439 DWC_WRITE_REG32(hcd->core_if->host_if->hprt0, hprt0.d32);
00440 dwc_mdelay(1);
00441 }
00442
00443 int dwc_otg_hcd_urb_enqueue(dwc_otg_hcd_t * hcd,
00444 dwc_otg_hcd_urb_t * dwc_otg_urb, void **ep_handle,
00445 int atomic_alloc)
00446 {
00447 dwc_irqflags_t flags;
00448 int retval = 0;
00449 dwc_otg_qtd_t *qtd;
00450 gintmsk_data_t intr_mask = {.d32 = 0 };
00451
00452 if (!hcd->flags.b.port_connect_status) {
00453
00454 DWC_ERROR("Not connected\n");
00455 return -DWC_E_NO_DEVICE;
00456 }
00457
00458 qtd = dwc_otg_hcd_qtd_create(dwc_otg_urb, atomic_alloc);
00459 if (qtd == NULL) {
00460 DWC_ERROR("DWC OTG HCD URB Enqueue failed creating QTD\n");
00461 return -DWC_E_NO_MEMORY;
00462 }
00463
00464 retval =
00465 dwc_otg_hcd_qtd_add(qtd, hcd, (dwc_otg_qh_t **) ep_handle, atomic_alloc);
00466 if (retval < 0) {
00467 DWC_ERROR("DWC OTG HCD URB Enqueue failed adding QTD. "
00468 "Error status %d\n", retval);
00469 dwc_otg_hcd_qtd_free(qtd);
00470 } else {
00471 qtd->qh = *ep_handle;
00472 }
00473 intr_mask.d32 = DWC_READ_REG32(&hcd->core_if->core_global_regs->gintmsk);
00474 if (!intr_mask.b.sofintr && retval == 0) {
00475 dwc_otg_transaction_type_e tr_type;
00476 if ((qtd->qh->ep_type == UE_BULK)
00477 && !(qtd->urb->flags & URB_GIVEBACK_ASAP)) {
00478
00479 return 0;
00480 }
00481 DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags);
00482 tr_type = dwc_otg_hcd_select_transactions(hcd);
00483 if (tr_type != DWC_OTG_TRANSACTION_NONE) {
00484 dwc_otg_hcd_queue_transactions(hcd, tr_type);
00485 }
00486 DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags);
00487 }
00488
00489 return retval;
00490 }
00491
00492 int dwc_otg_hcd_urb_dequeue(dwc_otg_hcd_t * hcd,
00493 dwc_otg_hcd_urb_t * dwc_otg_urb)
00494 {
00495 dwc_otg_qh_t *qh;
00496 dwc_otg_qtd_t *urb_qtd;
00497
00498 urb_qtd = dwc_otg_urb->qtd;
00499 qh = urb_qtd->qh;
00500 #ifdef DEBUG
00501 if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
00502 if (urb_qtd->in_process) {
00503 dump_channel_info(hcd, qh);
00504 }
00505 }
00506 #endif
00507 if (urb_qtd->in_process && qh->channel) {
00508
00509 if (hcd->flags.b.port_connect_status) {
00510
00511
00512
00513
00514
00515
00516
00517 dwc_otg_hc_halt(hcd->core_if, qh->channel,
00518 DWC_OTG_HC_XFER_URB_DEQUEUE);
00519 }
00520 }
00521
00522
00523
00524
00525
00526
00527 if (!hcd->core_if->dma_desc_enable) {
00528 uint8_t b = urb_qtd->in_process;
00529 dwc_otg_hcd_qtd_remove_and_free(hcd, urb_qtd, qh);
00530 if (b) {
00531 dwc_otg_hcd_qh_deactivate(hcd, qh, 0);
00532 qh->channel = NULL;
00533 } else if (DWC_CIRCLEQ_EMPTY(&qh->qtd_list)) {
00534 dwc_otg_hcd_qh_remove(hcd, qh);
00535 }
00536 } else {
00537 dwc_otg_hcd_qtd_remove_and_free(hcd, urb_qtd, qh);
00538 }
00539 return 0;
00540 }
00541
00542 int dwc_otg_hcd_endpoint_disable(dwc_otg_hcd_t * hcd, void *ep_handle,
00543 int retry)
00544 {
00545 dwc_otg_qh_t *qh = (dwc_otg_qh_t *) ep_handle;
00546 int retval = 0;
00547 dwc_irqflags_t flags;
00548
00549 if (retry < 0) {
00550 retval = -DWC_E_INVALID;
00551 goto done;
00552 }
00553
00554 if (!qh) {
00555 retval = -DWC_E_INVALID;
00556 goto done;
00557 }
00558
00559 DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags);
00560
00561 while (!DWC_CIRCLEQ_EMPTY(&qh->qtd_list) && retry) {
00562 DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags);
00563 retry--;
00564 dwc_msleep(5);
00565 DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags);
00566 }
00567
00568 dwc_otg_hcd_qh_remove(hcd, qh);
00569
00570 DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags);
00571
00572
00573
00574
00575
00576
00577 dwc_otg_hcd_qh_free(hcd, qh);
00578
00579 done:
00580 return retval;
00581 }
00582
00583 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)
00584 int dwc_otg_hcd_endpoint_reset(dwc_otg_hcd_t * hcd, void *ep_handle)
00585 {
00586 int retval = 0;
00587 dwc_otg_qh_t *qh = (dwc_otg_qh_t *) ep_handle;
00588 if (!qh)
00589 return -DWC_E_INVALID;
00590
00591 qh->data_toggle = DWC_OTG_HC_PID_DATA0;
00592 return retval;
00593 }
00594 #endif
00595
00599 static dwc_otg_cil_callbacks_t hcd_cil_callbacks = {
00600 .start = dwc_otg_hcd_start_cb,
00601 .stop = dwc_otg_hcd_stop_cb,
00602 .disconnect = dwc_otg_hcd_disconnect_cb,
00603 .session_start = dwc_otg_hcd_session_start_cb,
00604 .resume_wakeup = dwc_otg_hcd_rem_wakeup_cb,
00605 #ifdef CONFIG_USB_DWC_OTG_LPM
00606 .sleep = dwc_otg_hcd_sleep_cb,
00607 #endif
00608 .p = 0,
00609 };
00610
00614 static void reset_tasklet_func(void *data)
00615 {
00616 dwc_otg_hcd_t *dwc_otg_hcd = (dwc_otg_hcd_t *) data;
00617 dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
00618 hprt0_data_t hprt0;
00619
00620 DWC_DEBUGPL(DBG_HCDV, "USB RESET tasklet called\n");
00621
00622 hprt0.d32 = dwc_otg_read_hprt0(core_if);
00623 hprt0.b.prtrst = 1;
00624 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
00625 dwc_mdelay(60);
00626
00627 hprt0.b.prtrst = 0;
00628 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
00629 dwc_otg_hcd->flags.b.port_reset_change = 1;
00630 }
00631
00632 static void qh_list_free(dwc_otg_hcd_t * hcd, dwc_list_link_t * qh_list)
00633 {
00634 dwc_list_link_t *item;
00635 dwc_otg_qh_t *qh;
00636 dwc_irqflags_t flags;
00637
00638 if (!qh_list->next) {
00639
00640 return;
00641 }
00642
00643
00644
00645
00646 DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags);
00647
00648 kill_urbs_in_qh_list(hcd, qh_list);
00649 DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags);
00650
00651 DWC_LIST_FOREACH(item, qh_list) {
00652 qh = DWC_LIST_ENTRY(item, dwc_otg_qh_t, qh_list_entry);
00653 dwc_otg_hcd_qh_remove_and_free(hcd, qh);
00654 }
00655 }
00656
00661 void dwc_otg_hcd_power_up(void *ptr)
00662 {
00663 gpwrdn_data_t gpwrdn = {.d32 = 0 };
00664 dwc_otg_core_if_t *core_if = (dwc_otg_core_if_t *) ptr;
00665
00666 DWC_PRINTF("%s called\n", __FUNCTION__);
00667
00668 if (!core_if->hibernation_suspend) {
00669 DWC_PRINTF("Already exited from Hibernation\n");
00670 return;
00671 }
00672
00673
00674 gpwrdn.b.pwrdnswtch = 1;
00675 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00676 dwc_udelay(10);
00677
00678
00679 gpwrdn.d32 = 0;
00680 gpwrdn.b.pwrdnrstn = 1;
00681 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00682 dwc_udelay(10);
00683
00684
00685 gpwrdn.d32 = 0;
00686 gpwrdn.b.pwrdnclmp = 1;
00687 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00688
00689
00690 gpwrdn.d32 = 0;
00691 gpwrdn.b.pwrdnrstn = 1;
00692 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
00693 dwc_udelay(10);
00694
00695
00696 gpwrdn.d32 = 0;
00697 gpwrdn.b.pmuintsel = 1;
00698 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00699
00700 core_if->hibernation_suspend = 0;
00701
00702
00703 gpwrdn.d32 = 0;
00704 gpwrdn.b.pmuactv = 1;
00705 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00706 dwc_udelay(10);
00707
00708
00709 gpwrdn.d32 = 0;
00710 gpwrdn.b.dis_vbus = 1;
00711 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00712
00713 core_if->op_state = A_HOST;
00714 dwc_otg_core_init(core_if);
00715 dwc_otg_enable_global_interrupts(core_if);
00716 cil_hcd_start(core_if);
00717 }
00718
00723 static void dwc_otg_hcd_free(dwc_otg_hcd_t * dwc_otg_hcd)
00724 {
00725 int i;
00726
00727 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD FREE\n");
00728
00729 del_timers(dwc_otg_hcd);
00730
00731
00732 qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->non_periodic_sched_inactive);
00733 qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->non_periodic_sched_active);
00734 qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_inactive);
00735 qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_ready);
00736 qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_assigned);
00737 qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_queued);
00738
00739
00740 for (i = 0; i < MAX_EPS_CHANNELS; i++) {
00741 dwc_hc_t *hc = dwc_otg_hcd->hc_ptr_array[i];
00742
00743 #ifdef DEBUG
00744 if (dwc_otg_hcd->core_if->hc_xfer_timer[i]) {
00745 DWC_TIMER_FREE(dwc_otg_hcd->core_if->hc_xfer_timer[i]);
00746 }
00747 #endif
00748 if (hc != NULL) {
00749 DWC_DEBUGPL(DBG_HCDV, "HCD Free channel #%i, hc=%p\n",
00750 i, hc);
00751 DWC_FREE(hc);
00752 }
00753 }
00754
00755 if (dwc_otg_hcd->core_if->dma_enable) {
00756 if (dwc_otg_hcd->status_buf_dma) {
00757 DWC_DMA_FREE(DWC_OTG_HCD_STATUS_BUF_SIZE,
00758 dwc_otg_hcd->status_buf,
00759 dwc_otg_hcd->status_buf_dma);
00760 }
00761 } else if (dwc_otg_hcd->status_buf != NULL) {
00762 DWC_FREE(dwc_otg_hcd->status_buf);
00763 }
00764 DWC_SPINLOCK_FREE(dwc_otg_hcd->lock);
00765
00766 dwc_otg_hcd->core_if->lock = NULL;
00767
00768 DWC_TIMER_FREE(dwc_otg_hcd->conn_timer);
00769 DWC_TASK_FREE(dwc_otg_hcd->reset_tasklet);
00770
00771 #ifdef DWC_DEV_SRPCAP
00772 if (dwc_otg_hcd->core_if->power_down == 2 &&
00773 dwc_otg_hcd->core_if->pwron_timer) {
00774 DWC_TIMER_FREE(dwc_otg_hcd->core_if->pwron_timer);
00775 }
00776 #endif
00777 DWC_FREE(dwc_otg_hcd);
00778 }
00779
00780 int dwc_otg_hcd_init(dwc_otg_hcd_t * hcd, dwc_otg_core_if_t * core_if)
00781 {
00782 int retval = 0;
00783 int num_channels;
00784 int i;
00785 dwc_hc_t *channel;
00786
00787 hcd->lock = DWC_SPINLOCK_ALLOC();
00788 if (!hcd->lock) {
00789 DWC_ERROR("Could not allocate lock for pcd");
00790 DWC_FREE(hcd);
00791 retval = -DWC_E_NO_MEMORY;
00792 goto out;
00793 }
00794 hcd->core_if = core_if;
00795
00796
00797 dwc_otg_cil_register_hcd_callbacks(hcd->core_if,
00798 &hcd_cil_callbacks, hcd);
00799
00800
00801 DWC_LIST_INIT(&hcd->non_periodic_sched_inactive);
00802 DWC_LIST_INIT(&hcd->non_periodic_sched_active);
00803
00804
00805 DWC_LIST_INIT(&hcd->periodic_sched_inactive);
00806 DWC_LIST_INIT(&hcd->periodic_sched_ready);
00807 DWC_LIST_INIT(&hcd->periodic_sched_assigned);
00808 DWC_LIST_INIT(&hcd->periodic_sched_queued);
00809
00810
00811
00812
00813
00814 DWC_CIRCLEQ_INIT(&hcd->free_hc_list);
00815 num_channels = hcd->core_if->core_params->host_channels;
00816 DWC_MEMSET(hcd->hc_ptr_array, 0, sizeof(hcd->hc_ptr_array));
00817 for (i = 0; i < num_channels; i++) {
00818 channel = DWC_ALLOC(sizeof(dwc_hc_t));
00819 if (channel == NULL) {
00820 retval = -DWC_E_NO_MEMORY;
00821 DWC_ERROR("%s: host channel allocation failed\n",
00822 __func__);
00823 dwc_otg_hcd_free(hcd);
00824 goto out;
00825 }
00826 channel->hc_num = i;
00827 hcd->hc_ptr_array[i] = channel;
00828 #ifdef DEBUG
00829 hcd->core_if->hc_xfer_timer[i] =
00830 DWC_TIMER_ALLOC("hc timer", hc_xfer_timeout,
00831 &hcd->core_if->hc_xfer_info[i]);
00832 #endif
00833 DWC_DEBUGPL(DBG_HCDV, "HCD Added channel #%d, hc=%p\n", i,
00834 channel);
00835 }
00836
00837
00838 hcd->conn_timer = DWC_TIMER_ALLOC("Connection timer",
00839 dwc_otg_hcd_connect_timeout, 0);
00840
00841
00842 hcd->reset_tasklet = DWC_TASK_ALLOC("reset_tasklet", reset_tasklet_func, hcd);
00843 #ifdef DWC_DEV_SRPCAP
00844 if (hcd->core_if->power_down == 2) {
00845
00846 hcd->core_if->pwron_timer = DWC_TIMER_ALLOC("PWRON TIMER",
00847 dwc_otg_hcd_power_up, core_if);
00848 }
00849 #endif
00850
00851
00852
00853
00854
00855
00856
00857 if (hcd->core_if->dma_enable) {
00858 hcd->status_buf =
00859 DWC_DMA_ALLOC(DWC_OTG_HCD_STATUS_BUF_SIZE,
00860 &hcd->status_buf_dma);
00861 } else {
00862 hcd->status_buf = DWC_ALLOC(DWC_OTG_HCD_STATUS_BUF_SIZE);
00863 }
00864 if (!hcd->status_buf) {
00865 retval = -DWC_E_NO_MEMORY;
00866 DWC_ERROR("%s: status_buf allocation failed\n", __func__);
00867 dwc_otg_hcd_free(hcd);
00868 goto out;
00869 }
00870
00871 hcd->otg_port = 1;
00872 hcd->frame_list = NULL;
00873 hcd->frame_list_dma = 0;
00874 hcd->periodic_qh_count = 0;
00875 out:
00876 return retval;
00877 }
00878
00879 void dwc_otg_hcd_remove(dwc_otg_hcd_t * hcd)
00880 {
00881
00882 dwc_otg_disable_host_interrupts(hcd->core_if);
00883
00884 dwc_otg_hcd_free(hcd);
00885 }
00886
00890 static void dwc_otg_hcd_reinit(dwc_otg_hcd_t * hcd)
00891 {
00892 int num_channels;
00893 int i;
00894 dwc_hc_t *channel;
00895 dwc_hc_t *channel_tmp;
00896
00897 hcd->flags.d32 = 0;
00898
00899 hcd->non_periodic_qh_ptr = &hcd->non_periodic_sched_active;
00900 hcd->non_periodic_channels = 0;
00901 hcd->periodic_channels = 0;
00902
00903
00904
00905
00906
00907 DWC_CIRCLEQ_FOREACH_SAFE(channel, channel_tmp,
00908 &hcd->free_hc_list, hc_list_entry) {
00909 DWC_CIRCLEQ_REMOVE(&hcd->free_hc_list, channel, hc_list_entry);
00910 }
00911
00912 num_channels = hcd->core_if->core_params->host_channels;
00913 for (i = 0; i < num_channels; i++) {
00914 channel = hcd->hc_ptr_array[i];
00915 DWC_CIRCLEQ_INSERT_TAIL(&hcd->free_hc_list, channel,
00916 hc_list_entry);
00917 dwc_otg_hc_cleanup(hcd->core_if, channel);
00918 }
00919
00920
00921 dwc_otg_core_host_init(hcd->core_if);
00922
00923
00924 hcd->core_if->lock = hcd->lock;
00925 }
00926
00936 static void assign_and_init_hc(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh)
00937 {
00938 dwc_hc_t *hc;
00939 dwc_otg_qtd_t *qtd;
00940 dwc_otg_hcd_urb_t *urb;
00941 void* ptr = NULL;
00942
00943 DWC_DEBUGPL(DBG_HCDV, "%s(%p,%p)\n", __func__, hcd, qh);
00944
00945 hc = DWC_CIRCLEQ_FIRST(&hcd->free_hc_list);
00946
00947
00948 DWC_CIRCLEQ_REMOVE_INIT(&hcd->free_hc_list, hc, hc_list_entry);
00949
00950 qtd = DWC_CIRCLEQ_FIRST(&qh->qtd_list);
00951
00952 urb = qtd->urb;
00953 qh->channel = hc;
00954
00955 qtd->in_process = 1;
00956
00957
00958
00959
00960
00961 hc->dev_addr = dwc_otg_hcd_get_dev_addr(&urb->pipe_info);
00962 hc->ep_num = dwc_otg_hcd_get_ep_num(&urb->pipe_info);
00963 hc->speed = qh->dev_speed;
00964 hc->max_packet = dwc_max_packet(qh->maxp);
00965
00966 hc->xfer_started = 0;
00967 hc->halt_status = DWC_OTG_HC_XFER_NO_HALT_STATUS;
00968 hc->error_state = (qtd->error_count > 0);
00969 hc->halt_on_queue = 0;
00970 hc->halt_pending = 0;
00971 hc->requests = 0;
00972
00973
00974
00975
00976
00977
00978
00979
00980 hc->ep_is_in = (dwc_otg_hcd_is_pipe_in(&urb->pipe_info) != 0);
00981 if (hc->ep_is_in) {
00982 hc->do_ping = 0;
00983 } else {
00984 hc->do_ping = qh->ping_state;
00985 }
00986
00987 hc->data_pid_start = qh->data_toggle;
00988 hc->multi_count = 1;
00989
00990 if (hcd->core_if->dma_enable) {
00991 hc->xfer_buff = (uint8_t *) urb->dma + urb->actual_length;
00992
00993
00994 if (((unsigned long)hc->xfer_buff & 0x3)
00995 && !hcd->core_if->dma_desc_enable) {
00996 ptr = (uint8_t *) urb->buf + urb->actual_length;
00997 }
00998 } else {
00999 hc->xfer_buff = (uint8_t *) urb->buf + urb->actual_length;
01000 }
01001 hc->xfer_len = urb->length - urb->actual_length;
01002 hc->xfer_count = 0;
01003
01004
01005
01006
01007 hc->do_split = 0;
01008 if (qh->do_split) {
01009 uint32_t hub_addr, port_addr;
01010 hc->do_split = 1;
01011 hc->xact_pos = qtd->isoc_split_pos;
01012 hc->complete_split = qtd->complete_split;
01013 hcd->fops->hub_info(hcd, urb->priv, &hub_addr, &port_addr);
01014 hc->hub_addr = (uint8_t) hub_addr;
01015 hc->port_addr = (uint8_t) port_addr;
01016 }
01017
01018 switch (dwc_otg_hcd_get_pipe_type(&urb->pipe_info)) {
01019 case UE_CONTROL:
01020 hc->ep_type = DWC_OTG_EP_TYPE_CONTROL;
01021 switch (qtd->control_phase) {
01022 case DWC_OTG_CONTROL_SETUP:
01023 DWC_DEBUGPL(DBG_HCDV, " Control setup transaction\n");
01024 hc->do_ping = 0;
01025 hc->ep_is_in = 0;
01026 hc->data_pid_start = DWC_OTG_HC_PID_SETUP;
01027 if (hcd->core_if->dma_enable) {
01028 hc->xfer_buff = (uint8_t *) urb->setup_dma;
01029 } else {
01030 hc->xfer_buff = (uint8_t *) urb->setup_packet;
01031 }
01032 hc->xfer_len = 8;
01033 ptr = NULL;
01034 break;
01035 case DWC_OTG_CONTROL_DATA:
01036 DWC_DEBUGPL(DBG_HCDV, " Control data transaction\n");
01037 hc->data_pid_start = qtd->data_toggle;
01038 break;
01039 case DWC_OTG_CONTROL_STATUS:
01040
01041
01042
01043
01044 DWC_DEBUGPL(DBG_HCDV, " Control status transaction\n");
01045 if (urb->length == 0) {
01046 hc->ep_is_in = 1;
01047 } else {
01048 hc->ep_is_in =
01049 dwc_otg_hcd_is_pipe_out(&urb->pipe_info);
01050 }
01051 if (hc->ep_is_in) {
01052 hc->do_ping = 0;
01053 }
01054
01055 hc->data_pid_start = DWC_OTG_HC_PID_DATA1;
01056
01057 hc->xfer_len = 0;
01058 if (hcd->core_if->dma_enable) {
01059 hc->xfer_buff = (uint8_t *) hcd->status_buf_dma;
01060 } else {
01061 hc->xfer_buff = (uint8_t *) hcd->status_buf;
01062 }
01063 ptr = NULL;
01064 break;
01065 }
01066 break;
01067 case UE_BULK:
01068 hc->ep_type = DWC_OTG_EP_TYPE_BULK;
01069 break;
01070 case UE_INTERRUPT:
01071 hc->ep_type = DWC_OTG_EP_TYPE_INTR;
01072 break;
01073 case UE_ISOCHRONOUS:
01074 {
01075 struct dwc_otg_hcd_iso_packet_desc *frame_desc;
01076
01077 hc->ep_type = DWC_OTG_EP_TYPE_ISOC;
01078
01079 if (hcd->core_if->dma_desc_enable)
01080 break;
01081
01082 frame_desc = &urb->iso_descs[qtd->isoc_frame_index];
01083
01084 frame_desc->status = 0;
01085
01086 if (hcd->core_if->dma_enable) {
01087 hc->xfer_buff = (uint8_t *) urb->dma;
01088 } else {
01089 hc->xfer_buff = (uint8_t *) urb->buf;
01090 }
01091 hc->xfer_buff +=
01092 frame_desc->offset + qtd->isoc_split_offset;
01093 hc->xfer_len =
01094 frame_desc->length - qtd->isoc_split_offset;
01095
01096
01097 if (((unsigned long)hc->xfer_buff & 0x3)
01098 && hcd->core_if->dma_enable) {
01099 ptr =
01100 (uint8_t *) urb->buf + frame_desc->offset +
01101 qtd->isoc_split_offset;
01102 } else
01103 ptr = NULL;
01104
01105 if (hc->xact_pos == DWC_HCSPLIT_XACTPOS_ALL) {
01106 if (hc->xfer_len <= 188) {
01107 hc->xact_pos = DWC_HCSPLIT_XACTPOS_ALL;
01108 } else {
01109 hc->xact_pos =
01110 DWC_HCSPLIT_XACTPOS_BEGIN;
01111 }
01112 }
01113 }
01114 break;
01115 }
01116
01117 if (ptr) {
01118 uint32_t buf_size;
01119 if (hc->ep_type != DWC_OTG_EP_TYPE_ISOC) {
01120 buf_size = hcd->core_if->core_params->max_transfer_size;
01121 } else {
01122 buf_size = 4096;
01123 }
01124 if (!qh->dw_align_buf) {
01125 qh->dw_align_buf = DWC_DMA_ALLOC_ATOMIC(buf_size,
01126 &qh->dw_align_buf_dma);
01127 if (!qh->dw_align_buf) {
01128 DWC_ERROR
01129 ("%s: Failed to allocate memory to handle "
01130 "non-dword aligned buffer case\n",
01131 __func__);
01132 return;
01133 }
01134 }
01135 if (!hc->ep_is_in) {
01136 dwc_memcpy(qh->dw_align_buf, ptr, hc->xfer_len);
01137 }
01138 hc->align_buff = qh->dw_align_buf_dma;
01139 } else {
01140 hc->align_buff = 0;
01141 }
01142
01143 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
01144 hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
01145
01146
01147
01148
01149 hc->multi_count = dwc_hb_mult(qh->maxp);
01150 }
01151
01152 if (hcd->core_if->dma_desc_enable)
01153 hc->desc_list_addr = qh->desc_list_dma;
01154
01155 dwc_otg_hc_init(hcd->core_if, hc);
01156 hc->qh = qh;
01157 }
01158
01168 dwc_otg_transaction_type_e dwc_otg_hcd_select_transactions(dwc_otg_hcd_t * hcd)
01169 {
01170 dwc_list_link_t *qh_ptr;
01171 dwc_otg_qh_t *qh;
01172 int num_channels;
01173 dwc_otg_transaction_type_e ret_val = DWC_OTG_TRANSACTION_NONE;
01174
01175 #ifdef DEBUG_SOF
01176 DWC_DEBUGPL(DBG_HCD, " Select Transactions\n");
01177 #endif
01178
01179
01180 qh_ptr = DWC_LIST_FIRST(&hcd->periodic_sched_ready);
01181
01182 while (qh_ptr != &hcd->periodic_sched_ready &&
01183 !DWC_CIRCLEQ_EMPTY(&hcd->free_hc_list)) {
01184
01185 qh = DWC_LIST_ENTRY(qh_ptr, dwc_otg_qh_t, qh_list_entry);
01186 assign_and_init_hc(hcd, qh);
01187
01188
01189
01190
01191
01192 qh_ptr = DWC_LIST_NEXT(qh_ptr);
01193 DWC_LIST_MOVE_HEAD(&hcd->periodic_sched_assigned,
01194 &qh->qh_list_entry);
01195
01196 ret_val = DWC_OTG_TRANSACTION_PERIODIC;
01197 }
01198
01199
01200
01201
01202
01203
01204 qh_ptr = hcd->non_periodic_sched_inactive.next;
01205 num_channels = hcd->core_if->core_params->host_channels;
01206 while (qh_ptr != &hcd->non_periodic_sched_inactive &&
01207 (hcd->non_periodic_channels <
01208 num_channels - hcd->periodic_channels) &&
01209 !DWC_CIRCLEQ_EMPTY(&hcd->free_hc_list)) {
01210
01211 qh = DWC_LIST_ENTRY(qh_ptr, dwc_otg_qh_t, qh_list_entry);
01212
01213 assign_and_init_hc(hcd, qh);
01214
01215
01216
01217
01218
01219 qh_ptr = DWC_LIST_NEXT(qh_ptr);
01220 DWC_LIST_MOVE_HEAD(&hcd->non_periodic_sched_active,
01221 &qh->qh_list_entry);
01222
01223 if (ret_val == DWC_OTG_TRANSACTION_NONE) {
01224 ret_val = DWC_OTG_TRANSACTION_NON_PERIODIC;
01225 } else {
01226 ret_val = DWC_OTG_TRANSACTION_ALL;
01227 }
01228
01229 hcd->non_periodic_channels++;
01230 }
01231
01232 return ret_val;
01233 }
01234
01253 static int queue_transaction(dwc_otg_hcd_t * hcd,
01254 dwc_hc_t * hc, uint16_t fifo_dwords_avail)
01255 {
01256 int retval;
01257
01258 if (hcd->core_if->dma_enable) {
01259 if (hcd->core_if->dma_desc_enable) {
01260 if (!hc->xfer_started
01261 || (hc->ep_type == DWC_OTG_EP_TYPE_ISOC)) {
01262 dwc_otg_hcd_start_xfer_ddma(hcd, hc->qh);
01263 hc->qh->ping_state = 0;
01264 }
01265 } else if (!hc->xfer_started) {
01266 dwc_otg_hc_start_transfer(hcd->core_if, hc);
01267 hc->qh->ping_state = 0;
01268 }
01269 retval = 0;
01270 } else if (hc->halt_pending) {
01271
01272 retval = 0;
01273 } else if (hc->halt_on_queue) {
01274 dwc_otg_hc_halt(hcd->core_if, hc, hc->halt_status);
01275 retval = 0;
01276 } else if (hc->do_ping) {
01277 if (!hc->xfer_started) {
01278 dwc_otg_hc_start_transfer(hcd->core_if, hc);
01279 }
01280 retval = 0;
01281 } else if (!hc->ep_is_in || hc->data_pid_start == DWC_OTG_HC_PID_SETUP) {
01282 if ((fifo_dwords_avail * 4) >= hc->max_packet) {
01283 if (!hc->xfer_started) {
01284 dwc_otg_hc_start_transfer(hcd->core_if, hc);
01285 retval = 1;
01286 } else {
01287 retval =
01288 dwc_otg_hc_continue_transfer(hcd->core_if,
01289 hc);
01290 }
01291 } else {
01292 retval = -1;
01293 }
01294 } else {
01295 if (!hc->xfer_started) {
01296 dwc_otg_hc_start_transfer(hcd->core_if, hc);
01297 retval = 1;
01298 } else {
01299 retval = dwc_otg_hc_continue_transfer(hcd->core_if, hc);
01300 }
01301 }
01302
01303 return retval;
01304 }
01305
01313 static void process_periodic_channels(dwc_otg_hcd_t * hcd)
01314 {
01315 hptxsts_data_t tx_status;
01316 dwc_list_link_t *qh_ptr;
01317 dwc_otg_qh_t *qh;
01318 int status;
01319 int no_queue_space = 0;
01320 int no_fifo_space = 0;
01321
01322 dwc_otg_host_global_regs_t *host_regs;
01323 host_regs = hcd->core_if->host_if->host_global_regs;
01324
01325 DWC_DEBUGPL(DBG_HCDV, "Queue periodic transactions\n");
01326 #ifdef DEBUG
01327 tx_status.d32 = DWC_READ_REG32(&host_regs->hptxsts);
01328 DWC_DEBUGPL(DBG_HCDV,
01329 " P Tx Req Queue Space Avail (before queue): %d\n",
01330 tx_status.b.ptxqspcavail);
01331 DWC_DEBUGPL(DBG_HCDV, " P Tx FIFO Space Avail (before queue): %d\n",
01332 tx_status.b.ptxfspcavail);
01333 #endif
01334
01335 qh_ptr = hcd->periodic_sched_assigned.next;
01336 while (qh_ptr != &hcd->periodic_sched_assigned) {
01337 tx_status.d32 = DWC_READ_REG32(&host_regs->hptxsts);
01338 if (tx_status.b.ptxqspcavail == 0) {
01339 no_queue_space = 1;
01340 break;
01341 }
01342
01343 qh = DWC_LIST_ENTRY(qh_ptr, dwc_otg_qh_t, qh_list_entry);
01344
01345
01346
01347
01348
01349
01350 if (!hcd->core_if->dma_enable && qh->channel->multi_count > 1) {
01351 hcd->core_if->queuing_high_bandwidth = 1;
01352 }
01353 status =
01354 queue_transaction(hcd, qh->channel,
01355 tx_status.b.ptxfspcavail);
01356 if (status < 0) {
01357 no_fifo_space = 1;
01358 break;
01359 }
01360
01361
01362
01363
01364
01365
01366
01367
01368 if (hcd->core_if->dma_enable || status == 0 ||
01369 qh->channel->requests == qh->channel->multi_count) {
01370 qh_ptr = qh_ptr->next;
01371
01372
01373
01374
01375 DWC_LIST_MOVE_HEAD(&hcd->periodic_sched_queued,
01376 &qh->qh_list_entry);
01377
01378
01379 hcd->core_if->queuing_high_bandwidth = 0;
01380 }
01381 }
01382
01383 if (!hcd->core_if->dma_enable) {
01384 dwc_otg_core_global_regs_t *global_regs;
01385 gintmsk_data_t intr_mask = {.d32 = 0 };
01386
01387 global_regs = hcd->core_if->core_global_regs;
01388 intr_mask.b.ptxfempty = 1;
01389 #ifdef DEBUG
01390 tx_status.d32 = DWC_READ_REG32(&host_regs->hptxsts);
01391 DWC_DEBUGPL(DBG_HCDV,
01392 " P Tx Req Queue Space Avail (after queue): %d\n",
01393 tx_status.b.ptxqspcavail);
01394 DWC_DEBUGPL(DBG_HCDV,
01395 " P Tx FIFO Space Avail (after queue): %d\n",
01396 tx_status.b.ptxfspcavail);
01397 #endif
01398 if (!DWC_LIST_EMPTY(&hcd->periodic_sched_assigned) ||
01399 no_queue_space || no_fifo_space) {
01400
01401
01402
01403
01404
01405
01406
01407 DWC_MODIFY_REG32(&global_regs->gintmsk, 0,
01408 intr_mask.d32);
01409 } else {
01410
01411
01412
01413
01414
01415
01416
01417 DWC_MODIFY_REG32(&global_regs->gintmsk, intr_mask.d32,
01418 0);
01419 }
01420 }
01421 }
01422
01430 static void process_non_periodic_channels(dwc_otg_hcd_t * hcd)
01431 {
01432 gnptxsts_data_t tx_status;
01433 dwc_list_link_t *orig_qh_ptr;
01434 dwc_otg_qh_t *qh;
01435 int status;
01436 int no_queue_space = 0;
01437 int no_fifo_space = 0;
01438 int more_to_do = 0;
01439
01440 dwc_otg_core_global_regs_t *global_regs =
01441 hcd->core_if->core_global_regs;
01442
01443 DWC_DEBUGPL(DBG_HCDV, "Queue non-periodic transactions\n");
01444 #ifdef DEBUG
01445 tx_status.d32 = DWC_READ_REG32(&global_regs->gnptxsts);
01446 DWC_DEBUGPL(DBG_HCDV,
01447 " NP Tx Req Queue Space Avail (before queue): %d\n",
01448 tx_status.b.nptxqspcavail);
01449 DWC_DEBUGPL(DBG_HCDV, " NP Tx FIFO Space Avail (before queue): %d\n",
01450 tx_status.b.nptxfspcavail);
01451 #endif
01452
01453
01454
01455
01456 if (hcd->non_periodic_qh_ptr == &hcd->non_periodic_sched_active) {
01457 hcd->non_periodic_qh_ptr = hcd->non_periodic_qh_ptr->next;
01458 }
01459 orig_qh_ptr = hcd->non_periodic_qh_ptr;
01460
01461
01462
01463
01464
01465 do {
01466 tx_status.d32 = DWC_READ_REG32(&global_regs->gnptxsts);
01467 if (!hcd->core_if->dma_enable && tx_status.b.nptxqspcavail == 0) {
01468 no_queue_space = 1;
01469 break;
01470 }
01471
01472 qh = DWC_LIST_ENTRY(hcd->non_periodic_qh_ptr, dwc_otg_qh_t,
01473 qh_list_entry);
01474 status =
01475 queue_transaction(hcd, qh->channel,
01476 tx_status.b.nptxfspcavail);
01477
01478 if (status > 0) {
01479 more_to_do = 1;
01480 } else if (status < 0) {
01481 no_fifo_space = 1;
01482 break;
01483 }
01484
01485
01486 hcd->non_periodic_qh_ptr = hcd->non_periodic_qh_ptr->next;
01487 if (hcd->non_periodic_qh_ptr == &hcd->non_periodic_sched_active) {
01488 hcd->non_periodic_qh_ptr =
01489 hcd->non_periodic_qh_ptr->next;
01490 }
01491
01492 } while (hcd->non_periodic_qh_ptr != orig_qh_ptr);
01493
01494 if (!hcd->core_if->dma_enable) {
01495 gintmsk_data_t intr_mask = {.d32 = 0 };
01496 intr_mask.b.nptxfempty = 1;
01497
01498 #ifdef DEBUG
01499 tx_status.d32 = DWC_READ_REG32(&global_regs->gnptxsts);
01500 DWC_DEBUGPL(DBG_HCDV,
01501 " NP Tx Req Queue Space Avail (after queue): %d\n",
01502 tx_status.b.nptxqspcavail);
01503 DWC_DEBUGPL(DBG_HCDV,
01504 " NP Tx FIFO Space Avail (after queue): %d\n",
01505 tx_status.b.nptxfspcavail);
01506 #endif
01507 if (more_to_do || no_queue_space || no_fifo_space) {
01508
01509
01510
01511
01512
01513
01514
01515 DWC_MODIFY_REG32(&global_regs->gintmsk, 0,
01516 intr_mask.d32);
01517 } else {
01518
01519
01520
01521
01522
01523
01524
01525 DWC_MODIFY_REG32(&global_regs->gintmsk, intr_mask.d32,
01526 0);
01527 }
01528 }
01529 }
01530
01540 void dwc_otg_hcd_queue_transactions(dwc_otg_hcd_t * hcd,
01541 dwc_otg_transaction_type_e tr_type)
01542 {
01543 #ifdef DEBUG_SOF
01544 DWC_DEBUGPL(DBG_HCD, "Queue Transactions\n");
01545 #endif
01546
01547 if ((tr_type == DWC_OTG_TRANSACTION_PERIODIC ||
01548 tr_type == DWC_OTG_TRANSACTION_ALL) &&
01549 !DWC_LIST_EMPTY(&hcd->periodic_sched_assigned)) {
01550
01551 process_periodic_channels(hcd);
01552 }
01553
01554
01555 if (tr_type == DWC_OTG_TRANSACTION_NON_PERIODIC ||
01556 tr_type == DWC_OTG_TRANSACTION_ALL) {
01557 if (!DWC_LIST_EMPTY(&hcd->non_periodic_sched_active)) {
01558 process_non_periodic_channels(hcd);
01559 } else {
01560
01561
01562
01563
01564 gintmsk_data_t gintmsk = {.d32 = 0 };
01565 gintmsk.b.nptxfempty = 1;
01566 DWC_MODIFY_REG32(&hcd->core_if->
01567 core_global_regs->gintmsk, gintmsk.d32,
01568 0);
01569 }
01570 }
01571 }
01572
01573 #ifdef DWC_HS_ELECT_TST
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587 static dwc_otg_core_global_regs_t *global_regs;
01588 static dwc_otg_host_global_regs_t *hc_global_regs;
01589 static dwc_otg_hc_regs_t *hc_regs;
01590 static uint32_t *data_fifo;
01591
01592 static void do_setup(void)
01593 {
01594 gintsts_data_t gintsts;
01595 hctsiz_data_t hctsiz;
01596 hcchar_data_t hcchar;
01597 haint_data_t haint;
01598 hcint_data_t hcint;
01599
01600
01601 DWC_WRITE_REG32(&hc_global_regs->haintmsk, 0x0001);
01602
01603
01604 DWC_WRITE_REG32(&hc_regs->hcintmsk, 0x04a3);
01605
01606
01607 gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
01608
01609
01610 haint.d32 = DWC_READ_REG32(&hc_global_regs->haint);
01611
01612
01613 hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
01614
01615
01616 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
01617
01618
01619 DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32);
01620
01621
01622 DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32);
01623
01624
01625 DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
01626
01627
01628 gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
01629
01630
01631
01632
01633
01634
01635 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
01636 if (hcchar.b.chen) {
01637 hcchar.b.chdis = 1;
01638
01639 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
01640
01641 dwc_mdelay(1000);
01642
01643
01644 gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
01645
01646
01647 haint.d32 = DWC_READ_REG32(&hc_global_regs->haint);
01648
01649
01650 hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
01651
01652
01653 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
01654
01655
01656 DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32);
01657
01658
01659 DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32);
01660
01661
01662 DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
01663
01664 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
01665 }
01666
01667
01668 hctsiz.d32 = 0;
01669 hctsiz.b.xfersize = 8;
01670 hctsiz.b.pktcnt = 1;
01671 hctsiz.b.pid = DWC_OTG_HC_PID_SETUP;
01672 DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32);
01673
01674
01675 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
01676 hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;
01677 hcchar.b.epdir = 0;
01678 hcchar.b.epnum = 0;
01679 hcchar.b.mps = 8;
01680 hcchar.b.chen = 1;
01681 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
01682
01683
01684 data_fifo = (uint32_t *) ((char *)global_regs + 0x1000);
01685 DWC_WRITE_REG32(data_fifo++, 0x01000680);
01686 DWC_WRITE_REG32(data_fifo++, 0x00080000);
01687
01688 gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
01689
01690
01691 do {
01692 gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
01693 } while (gintsts.b.hcintr == 0);
01694
01695
01696 DWC_WRITE_REG32(&hc_regs->hcintmsk, 0x0000);
01697
01698
01699 DWC_WRITE_REG32(&hc_global_regs->haintmsk, 0x0000);
01700
01701
01702 haint.d32 = DWC_READ_REG32(&hc_global_regs->haint);
01703
01704
01705 hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
01706
01707
01708 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
01709
01710
01711 DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32);
01712
01713
01714 DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32);
01715
01716
01717 DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
01718
01719
01720 gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
01721 }
01722
01723 static void do_in_ack(void)
01724 {
01725 gintsts_data_t gintsts;
01726 hctsiz_data_t hctsiz;
01727 hcchar_data_t hcchar;
01728 haint_data_t haint;
01729 hcint_data_t hcint;
01730 host_grxsts_data_t grxsts;
01731
01732
01733 DWC_WRITE_REG32(&hc_global_regs->haintmsk, 0x0001);
01734
01735
01736 DWC_WRITE_REG32(&hc_regs->hcintmsk, 0x04a3);
01737
01738
01739 gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
01740
01741
01742 haint.d32 = DWC_READ_REG32(&hc_global_regs->haint);
01743
01744
01745 hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
01746
01747
01748 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
01749
01750
01751 DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32);
01752
01753
01754 DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32);
01755
01756
01757 DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
01758
01759
01760 gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
01761
01762
01763
01764
01765
01766
01767 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
01768 if (hcchar.b.chen) {
01769 hcchar.b.chdis = 1;
01770 hcchar.b.chen = 1;
01771 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
01772
01773 dwc_mdelay(1000);
01774
01775
01776 gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
01777
01778
01779 haint.d32 = DWC_READ_REG32(&hc_global_regs->haint);
01780
01781
01782 hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
01783
01784
01785 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
01786
01787
01788 DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32);
01789
01790
01791 DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32);
01792
01793
01794 DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
01795
01796 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
01797 }
01798
01799
01800 hctsiz.d32 = 0;
01801 hctsiz.b.xfersize = 8;
01802 hctsiz.b.pktcnt = 1;
01803 hctsiz.b.pid = DWC_OTG_HC_PID_DATA1;
01804 DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32);
01805
01806
01807 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
01808 hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;
01809 hcchar.b.epdir = 1;
01810 hcchar.b.epnum = 0;
01811 hcchar.b.mps = 8;
01812 hcchar.b.chen = 1;
01813 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
01814
01815 gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
01816
01817
01818 do {
01819 gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
01820 } while (gintsts.b.rxstsqlvl == 0);
01821
01822
01823 grxsts.d32 = DWC_READ_REG32(&global_regs->grxstsp);
01824
01825
01826 gintsts.d32 = 0;
01827 gintsts.b.rxstsqlvl = 1;
01828 DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
01829
01830 switch (grxsts.b.pktsts) {
01831 case DWC_GRXSTS_PKTSTS_IN:
01832
01833 if (grxsts.b.bcnt > 0) {
01834 int i;
01835 int word_count = (grxsts.b.bcnt + 3) / 4;
01836
01837 data_fifo = (uint32_t *) ((char *)global_regs + 0x1000);
01838
01839 for (i = 0; i < word_count; i++) {
01840 (void)DWC_READ_REG32(data_fifo++);
01841 }
01842 }
01843 break;
01844
01845 default:
01846 break;
01847 }
01848
01849 gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
01850
01851
01852 do {
01853 gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
01854 } while (gintsts.b.rxstsqlvl == 0);
01855
01856
01857 grxsts.d32 = DWC_READ_REG32(&global_regs->grxstsp);
01858
01859
01860 gintsts.d32 = 0;
01861 gintsts.b.rxstsqlvl = 1;
01862 DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
01863
01864 switch (grxsts.b.pktsts) {
01865 case DWC_GRXSTS_PKTSTS_IN_XFER_COMP:
01866 break;
01867
01868 default:
01869 break;
01870 }
01871
01872 gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
01873
01874
01875 do {
01876 gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
01877 } while (gintsts.b.hcintr == 0);
01878
01879
01880 haint.d32 = DWC_READ_REG32(&hc_global_regs->haint);
01881
01882
01883 hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
01884
01885
01886 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
01887
01888
01889 DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32);
01890
01891
01892 DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32);
01893
01894
01895 DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
01896
01897
01898 gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
01899
01900
01901
01902 dwc_mdelay(1);
01903
01904
01905
01906
01907
01908
01909 haint.d32 = DWC_READ_REG32(&hc_global_regs->haint);
01910
01911
01912 hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
01913
01914
01915 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
01916
01917
01918 DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32);
01919
01920
01921 DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32);
01922
01923
01924 DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
01925
01926
01927 gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
01928
01929
01930 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
01931 if (hcchar.b.chen) {
01932 hcchar.b.chdis = 1;
01933 hcchar.b.chen = 1;
01934 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
01935
01936 dwc_mdelay(1000);
01937
01938
01939 gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
01940
01941
01942 haint.d32 = DWC_READ_REG32(&hc_global_regs->haint);
01943
01944
01945 hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
01946
01947
01948 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
01949
01950
01951 DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32);
01952
01953
01954 DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32);
01955
01956
01957 DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
01958
01959 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
01960 }
01961
01962
01963 hctsiz.d32 = 0;
01964 hctsiz.b.xfersize = 0;
01965 hctsiz.b.pktcnt = 1;
01966 hctsiz.b.pid = DWC_OTG_HC_PID_DATA1;
01967 DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32);
01968
01969
01970 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
01971 hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;
01972 hcchar.b.epdir = 0;
01973 hcchar.b.epnum = 0;
01974 hcchar.b.mps = 8;
01975 hcchar.b.chen = 1;
01976 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
01977
01978 gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
01979
01980
01981 do {
01982 gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
01983 } while (gintsts.b.hcintr == 0);
01984
01985
01986 DWC_WRITE_REG32(&hc_regs->hcintmsk, 0x0000);
01987
01988
01989 DWC_WRITE_REG32(&hc_global_regs->haintmsk, 0x0000);
01990
01991
01992 haint.d32 = DWC_READ_REG32(&hc_global_regs->haint);
01993
01994
01995 hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
01996
01997
01998 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
01999
02000
02001 DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32);
02002
02003
02004 DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32);
02005
02006
02007 DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
02008
02009
02010 gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
02011 }
02012 #endif
02013
02015 int dwc_otg_hcd_hub_control(dwc_otg_hcd_t * dwc_otg_hcd,
02016 uint16_t typeReq,
02017 uint16_t wValue,
02018 uint16_t wIndex, uint8_t * buf, uint16_t wLength)
02019 {
02020 int retval = 0;
02021
02022 dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
02023 usb_hub_descriptor_t *hub_desc;
02024 hprt0_data_t hprt0 = {.d32 = 0 };
02025
02026 uint32_t port_status;
02027
02028 switch (typeReq) {
02029 case UCR_CLEAR_HUB_FEATURE:
02030 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
02031 "ClearHubFeature 0x%x\n", wValue);
02032 switch (wValue) {
02033 case UHF_C_HUB_LOCAL_POWER:
02034 case UHF_C_HUB_OVER_CURRENT:
02035
02036 break;
02037 default:
02038 retval = -DWC_E_INVALID;
02039 DWC_ERROR("DWC OTG HCD - "
02040 "ClearHubFeature request %xh unknown\n",
02041 wValue);
02042 }
02043 break;
02044 case UCR_CLEAR_PORT_FEATURE:
02045 #ifdef CONFIG_USB_DWC_OTG_LPM
02046 if (wValue != UHF_PORT_L1)
02047 #endif
02048 if (!wIndex || wIndex > 1)
02049 goto error;
02050
02051 switch (wValue) {
02052 case UHF_PORT_ENABLE:
02053 DWC_DEBUGPL(DBG_ANY, "DWC OTG HCD HUB CONTROL - "
02054 "ClearPortFeature USB_PORT_FEAT_ENABLE\n");
02055 hprt0.d32 = dwc_otg_read_hprt0(core_if);
02056 hprt0.b.prtena = 1;
02057 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
02058 break;
02059 case UHF_PORT_SUSPEND:
02060 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
02061 "ClearPortFeature USB_PORT_FEAT_SUSPEND\n");
02062
02063 if (core_if->power_down == 2) {
02064 dwc_otg_host_hibernation_restore(core_if, 0, 0);
02065 } else {
02066 DWC_WRITE_REG32(core_if->pcgcctl, 0);
02067 dwc_mdelay(5);
02068
02069 hprt0.d32 = dwc_otg_read_hprt0(core_if);
02070 hprt0.b.prtres = 1;
02071 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
02072 hprt0.b.prtsusp = 0;
02073
02074 dwc_mdelay(100);
02075 hprt0.b.prtres = 0;
02076 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
02077 }
02078 break;
02079 #ifdef CONFIG_USB_DWC_OTG_LPM
02080 case UHF_PORT_L1:
02081 {
02082 pcgcctl_data_t pcgcctl = {.d32 = 0 };
02083 glpmcfg_data_t lpmcfg = {.d32 = 0 };
02084
02085 lpmcfg.d32 =
02086 DWC_READ_REG32(&core_if->
02087 core_global_regs->glpmcfg);
02088 lpmcfg.b.en_utmi_sleep = 0;
02089 lpmcfg.b.hird_thres &= (~(1 << 4));
02090 lpmcfg.b.prt_sleep_sts = 1;
02091 DWC_WRITE_REG32(&core_if->
02092 core_global_regs->glpmcfg,
02093 lpmcfg.d32);
02094
02095
02096 pcgcctl.b.enbl_sleep_gating = 1;
02097 DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32,
02098 0);
02099
02100 dwc_mdelay(5);
02101
02102 hprt0.d32 = dwc_otg_read_hprt0(core_if);
02103 hprt0.b.prtres = 1;
02104 DWC_WRITE_REG32(core_if->host_if->hprt0,
02105 hprt0.d32);
02106
02107 break;
02108 }
02109 #endif
02110 case UHF_PORT_POWER:
02111 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
02112 "ClearPortFeature USB_PORT_FEAT_POWER\n");
02113 hprt0.d32 = dwc_otg_read_hprt0(core_if);
02114 hprt0.b.prtpwr = 0;
02115 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
02116 break;
02117 case UHF_PORT_INDICATOR:
02118 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
02119 "ClearPortFeature USB_PORT_FEAT_INDICATOR\n");
02120
02121 break;
02122 case UHF_C_PORT_CONNECTION:
02123
02124
02125 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
02126 "ClearPortFeature USB_PORT_FEAT_C_CONNECTION\n");
02127 dwc_otg_hcd->flags.b.port_connect_status_change = 0;
02128 break;
02129 case UHF_C_PORT_RESET:
02130
02131
02132 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
02133 "ClearPortFeature USB_PORT_FEAT_C_RESET\n");
02134 dwc_otg_hcd->flags.b.port_reset_change = 0;
02135 break;
02136 case UHF_C_PORT_ENABLE:
02137
02138
02139 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
02140 "ClearPortFeature USB_PORT_FEAT_C_ENABLE\n");
02141 dwc_otg_hcd->flags.b.port_enable_change = 0;
02142 break;
02143 case UHF_C_PORT_SUSPEND:
02144
02145
02146
02147 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
02148 "ClearPortFeature USB_PORT_FEAT_C_SUSPEND\n");
02149 dwc_otg_hcd->flags.b.port_suspend_change = 0;
02150 break;
02151 #ifdef CONFIG_USB_DWC_OTG_LPM
02152 case UHF_C_PORT_L1:
02153 dwc_otg_hcd->flags.b.port_l1_change = 0;
02154 break;
02155 #endif
02156 case UHF_C_PORT_OVER_CURRENT:
02157 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
02158 "ClearPortFeature USB_PORT_FEAT_C_OVER_CURRENT\n");
02159 dwc_otg_hcd->flags.b.port_over_current_change = 0;
02160 break;
02161 default:
02162 retval = -DWC_E_INVALID;
02163 DWC_ERROR("DWC OTG HCD - "
02164 "ClearPortFeature request %xh "
02165 "unknown or unsupported\n", wValue);
02166 }
02167 break;
02168 case UCR_GET_HUB_DESCRIPTOR:
02169 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
02170 "GetHubDescriptor\n");
02171 hub_desc = (usb_hub_descriptor_t *) buf;
02172 hub_desc->bDescLength = 9;
02173 hub_desc->bDescriptorType = 0x29;
02174 hub_desc->bNbrPorts = 1;
02175 USETW(hub_desc->wHubCharacteristics, 0x08);
02176 hub_desc->bPwrOn2PwrGood = 1;
02177 hub_desc->bHubContrCurrent = 0;
02178 hub_desc->DeviceRemovable[0] = 0;
02179 hub_desc->DeviceRemovable[1] = 0xff;
02180 break;
02181 case UCR_GET_HUB_STATUS:
02182 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
02183 "GetHubStatus\n");
02184 DWC_MEMSET(buf, 0, 4);
02185 break;
02186 case UCR_GET_PORT_STATUS:
02187 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
02188 "GetPortStatus wIndex = 0x%04x FLAGS=0x%08x\n",
02189 wIndex, dwc_otg_hcd->flags.d32);
02190 if (!wIndex || wIndex > 1)
02191 goto error;
02192
02193 port_status = 0;
02194
02195 if (dwc_otg_hcd->flags.b.port_connect_status_change)
02196 port_status |= (1 << UHF_C_PORT_CONNECTION);
02197
02198 if (dwc_otg_hcd->flags.b.port_enable_change)
02199 port_status |= (1 << UHF_C_PORT_ENABLE);
02200
02201 if (dwc_otg_hcd->flags.b.port_suspend_change)
02202 port_status |= (1 << UHF_C_PORT_SUSPEND);
02203
02204 if (dwc_otg_hcd->flags.b.port_l1_change)
02205 port_status |= (1 << UHF_C_PORT_L1);
02206
02207 if (dwc_otg_hcd->flags.b.port_reset_change) {
02208 port_status |= (1 << UHF_C_PORT_RESET);
02209 }
02210
02211 if (dwc_otg_hcd->flags.b.port_over_current_change) {
02212 DWC_WARN("Overcurrent change detected\n");
02213 port_status |= (1 << UHF_C_PORT_OVER_CURRENT);
02214 }
02215
02216 if (!dwc_otg_hcd->flags.b.port_connect_status) {
02217
02218
02219
02220
02221
02222
02223
02224 *((__le32 *) buf) = dwc_cpu_to_le32(&port_status);
02225 break;
02226 }
02227
02228 hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
02229 DWC_DEBUGPL(DBG_HCDV, " HPRT0: 0x%08x\n", hprt0.d32);
02230
02231 if (hprt0.b.prtconnsts)
02232 port_status |= (1 << UHF_PORT_CONNECTION);
02233
02234 if (hprt0.b.prtena)
02235 port_status |= (1 << UHF_PORT_ENABLE);
02236
02237 if (hprt0.b.prtsusp)
02238 port_status |= (1 << UHF_PORT_SUSPEND);
02239
02240 if (hprt0.b.prtovrcurract)
02241 port_status |= (1 << UHF_PORT_OVER_CURRENT);
02242
02243 if (hprt0.b.prtrst)
02244 port_status |= (1 << UHF_PORT_RESET);
02245
02246 if (hprt0.b.prtpwr)
02247 port_status |= (1 << UHF_PORT_POWER);
02248
02249 if (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_HIGH_SPEED)
02250 port_status |= (1 << UHF_PORT_HIGH_SPEED);
02251 else if (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_LOW_SPEED)
02252 port_status |= (1 << UHF_PORT_LOW_SPEED);
02253
02254 if (hprt0.b.prttstctl)
02255 port_status |= (1 << UHF_PORT_TEST);
02256 if (dwc_otg_get_lpm_portsleepstatus(dwc_otg_hcd->core_if)) {
02257 port_status |= (1 << UHF_PORT_L1);
02258 }
02259
02260
02261
02262
02263
02264
02265 if ((core_if->power_down == 2)
02266 && (core_if->hibernation_suspend == 1)) {
02267 port_status |= (1 << UHF_PORT_SUSPEND);
02268 }
02269
02270
02271 *((__le32 *) buf) = dwc_cpu_to_le32(&port_status);
02272
02273 break;
02274 case UCR_SET_HUB_FEATURE:
02275 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
02276 "SetHubFeature\n");
02277
02278 break;
02279 case UCR_SET_PORT_FEATURE:
02280 if (wValue != UHF_PORT_TEST && (!wIndex || wIndex > 1))
02281 goto error;
02282
02283 if (!dwc_otg_hcd->flags.b.port_connect_status) {
02284
02285
02286
02287
02288
02289
02290
02291 break;
02292 }
02293
02294 switch (wValue) {
02295 case UHF_PORT_SUSPEND:
02296 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
02297 "SetPortFeature - USB_PORT_FEAT_SUSPEND\n");
02298 if (dwc_otg_hcd_otg_port(dwc_otg_hcd) != wIndex) {
02299 goto error;
02300 }
02301 if (core_if->power_down == 2) {
02302 int timeout = 300;
02303 dwc_irqflags_t flags;
02304 pcgcctl_data_t pcgcctl = {.d32 = 0 };
02305 gpwrdn_data_t gpwrdn = {.d32 = 0 };
02306 gusbcfg_data_t gusbcfg = {.d32 = 0 };
02307 #ifdef DWC_DEV_SRPCAP
02308 int32_t otg_cap_param = core_if->core_params->otg_cap;
02309 #endif
02310 DWC_PRINTF("Preparing for complete power-off\n");
02311
02312
02313 dwc_otg_save_global_regs(core_if);
02314 dwc_otg_save_host_regs(core_if);
02315
02316 hprt0.d32 = dwc_otg_read_hprt0(core_if);
02317 hprt0.b.prtsusp = 1;
02318 hprt0.b.prtena = 0;
02319 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
02320
02321 do {
02322 hprt0.d32 = dwc_otg_read_hprt0(core_if);
02323 if (hprt0.b.prtsusp) {
02324 break;
02325 }
02326 dwc_mdelay(1);
02327 } while (--timeout);
02328 if (!timeout) {
02329 DWC_WARN("Suspend wasn't genereted\n");
02330 }
02331 dwc_udelay(10);
02332
02333
02334
02335
02336
02337 DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &flags);
02338 core_if->lx_state = DWC_OTG_L2;
02339 #ifdef DWC_DEV_SRPCAP
02340 hprt0.d32 = dwc_otg_read_hprt0(core_if);
02341 hprt0.b.prtpwr = 0;
02342 hprt0.b.prtena = 0;
02343 DWC_WRITE_REG32(core_if->host_if->hprt0,
02344 hprt0.d32);
02345 #endif
02346 gusbcfg.d32 =
02347 DWC_READ_REG32(&core_if->core_global_regs->
02348 gusbcfg);
02349 if (gusbcfg.b.ulpi_utmi_sel == 1) {
02350
02351
02352 pcgcctl.d32 = 0;
02353 pcgcctl.b.stoppclk = 1;
02354 DWC_MODIFY_REG32(core_if->pcgcctl, 0,
02355 pcgcctl.d32);
02356 dwc_udelay(10);
02357 gpwrdn.b.pmuactv = 1;
02358 DWC_MODIFY_REG32(&core_if->
02359 core_global_regs->
02360 gpwrdn, 0, gpwrdn.d32);
02361 } else {
02362
02363 gpwrdn.b.pmuactv = 1;
02364 DWC_MODIFY_REG32(&core_if->
02365 core_global_regs->
02366 gpwrdn, 0, gpwrdn.d32);
02367 dwc_udelay(10);
02368 pcgcctl.b.stoppclk = 1;
02369 DWC_MODIFY_REG32(core_if->pcgcctl, 0, pcgcctl.d32);
02370 dwc_udelay(10);
02371 }
02372 #ifdef DWC_DEV_SRPCAP
02373 gpwrdn.d32 = 0;
02374 gpwrdn.b.dis_vbus = 1;
02375 DWC_MODIFY_REG32(&core_if->core_global_regs->
02376 gpwrdn, 0, gpwrdn.d32);
02377 #endif
02378 gpwrdn.d32 = 0;
02379 gpwrdn.b.pmuintsel = 1;
02380 DWC_MODIFY_REG32(&core_if->core_global_regs->
02381 gpwrdn, 0, gpwrdn.d32);
02382 dwc_udelay(10);
02383
02384 gpwrdn.d32 = 0;
02385 #ifdef DWC_DEV_SRPCAP
02386 gpwrdn.b.srp_det_msk = 1;
02387 #endif
02388 gpwrdn.b.disconn_det_msk = 1;
02389 gpwrdn.b.lnstchng_msk = 1;
02390 gpwrdn.b.sts_chngint_msk = 1;
02391 DWC_MODIFY_REG32(&core_if->core_global_regs->
02392 gpwrdn, 0, gpwrdn.d32);
02393 dwc_udelay(10);
02394
02395
02396 gpwrdn.d32 = 0;
02397 gpwrdn.b.pwrdnclmp = 1;
02398 DWC_MODIFY_REG32(&core_if->core_global_regs->
02399 gpwrdn, 0, gpwrdn.d32);
02400 dwc_udelay(10);
02401
02402
02403 gpwrdn.d32 = 0;
02404 gpwrdn.b.pwrdnswtch = 1;
02405 DWC_MODIFY_REG32(&core_if->core_global_regs->
02406 gpwrdn, 0, gpwrdn.d32);
02407
02408 #ifdef DWC_DEV_SRPCAP
02409 if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE)
02410 {
02411 core_if->pwron_timer_started = 1;
02412 DWC_TIMER_SCHEDULE(core_if->pwron_timer, 6000 );
02413 }
02414 #endif
02415
02416 core_if->gr_backup->gpwrdn_local =
02417 DWC_READ_REG32(&core_if->core_global_regs->gpwrdn);
02418
02419
02420 core_if->hibernation_suspend = 1;
02421 DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock,flags);
02422
02423 DWC_PRINTF("Host hibernation completed\n");
02424
02425 break;
02426
02427 }
02428 if (dwc_otg_hcd_otg_port(dwc_otg_hcd) == wIndex &&
02429 dwc_otg_hcd->fops->get_b_hnp_enable(dwc_otg_hcd)) {
02430 gotgctl_data_t gotgctl = {.d32 = 0 };
02431 gotgctl.b.hstsethnpen = 1;
02432 DWC_MODIFY_REG32(&core_if->core_global_regs->
02433 gotgctl, 0, gotgctl.d32);
02434 core_if->op_state = A_SUSPEND;
02435 }
02436 hprt0.d32 = dwc_otg_read_hprt0(core_if);
02437 hprt0.b.prtsusp = 1;
02438 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
02439 {
02440 dwc_irqflags_t flags;
02441
02442 DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &flags);
02443 core_if->lx_state = DWC_OTG_L2;
02444 DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, flags);
02445 }
02446
02447 {
02448 pcgcctl_data_t pcgcctl = {.d32 = 0 };
02449 pcgcctl.b.stoppclk = 1;
02450 DWC_MODIFY_REG32(core_if->pcgcctl, 0,
02451 pcgcctl.d32);
02452 dwc_udelay(10);
02453 }
02454
02455
02456 if (dwc_otg_hcd->fops->get_b_hnp_enable(dwc_otg_hcd)) {
02457 pcgcctl_data_t pcgcctl = {.d32 = 0 };
02458 pcgcctl.b.stoppclk = 1;
02459 DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32, 0);
02460 dwc_mdelay(200);
02461 }
02462
02464 #if 0 //vahrama !!!!!!!!!!!!!!!!!!
02465 if (core_if->adp_enable) {
02466 gotgctl_data_t gotgctl = {.d32 = 0 };
02467 gpwrdn_data_t gpwrdn;
02468
02469 while (gotgctl.b.asesvld == 1) {
02470 gotgctl.d32 =
02471 DWC_READ_REG32(&core_if->
02472 core_global_regs->
02473 gotgctl);
02474 dwc_mdelay(100);
02475 }
02476
02477
02478 gpwrdn.d32 = 0;
02479 gpwrdn.b.pmuactv = 1;
02480 DWC_MODIFY_REG32(&core_if->core_global_regs->
02481 gpwrdn, 0, gpwrdn.d32);
02482
02483
02484 gpwrdn.d32 = 0;
02485 gpwrdn.b.srp_det_msk = 1;
02486 DWC_MODIFY_REG32(&core_if->core_global_regs->
02487 gpwrdn, 0, gpwrdn.d32);
02488
02489 dwc_otg_adp_probe_start(core_if);
02490 }
02491 #endif
02492 break;
02493 case UHF_PORT_POWER:
02494 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
02495 "SetPortFeature - USB_PORT_FEAT_POWER\n");
02496 hprt0.d32 = dwc_otg_read_hprt0(core_if);
02497 hprt0.b.prtpwr = 1;
02498 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
02499 break;
02500 case UHF_PORT_RESET:
02501 if ((core_if->power_down == 2)
02502 && (core_if->hibernation_suspend == 1)) {
02503
02504
02505
02506 dwc_otg_host_hibernation_restore(core_if, 0, 1);
02507 } else {
02508 hprt0.d32 = dwc_otg_read_hprt0(core_if);
02509
02510 DWC_DEBUGPL(DBG_HCD,
02511 "DWC OTG HCD HUB CONTROL - "
02512 "SetPortFeature - USB_PORT_FEAT_RESET\n");
02513 {
02514 pcgcctl_data_t pcgcctl = {.d32 = 0 };
02515 pcgcctl.b.enbl_sleep_gating = 1;
02516 pcgcctl.b.stoppclk = 1;
02517 DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32, 0);
02518 DWC_WRITE_REG32(core_if->pcgcctl, 0);
02519 }
02520 #ifdef CONFIG_USB_DWC_OTG_LPM
02521 {
02522 glpmcfg_data_t lpmcfg;
02523 lpmcfg.d32 =
02524 DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
02525 if (lpmcfg.b.prt_sleep_sts) {
02526 lpmcfg.b.en_utmi_sleep = 0;
02527 lpmcfg.b.hird_thres &= (~(1 << 4));
02528 DWC_WRITE_REG32
02529 (&core_if->core_global_regs->glpmcfg,
02530 lpmcfg.d32);
02531 dwc_mdelay(1);
02532 }
02533 }
02534 #endif
02535 hprt0.d32 = dwc_otg_read_hprt0(core_if);
02536
02537 hprt0.b.prtsusp = 0;
02538
02539
02540
02541
02542 if (!dwc_otg_hcd_is_b_host(dwc_otg_hcd)) {
02543 hprt0.b.prtpwr = 1;
02544 hprt0.b.prtrst = 1;
02545 DWC_PRINTF("Indeed it is in host mode hprt0 = %08x\n",hprt0.d32);
02546 DWC_WRITE_REG32(core_if->host_if->hprt0,
02547 hprt0.d32);
02548 }
02549
02550 dwc_mdelay(60);
02551 hprt0.b.prtrst = 0;
02552 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
02553 core_if->lx_state = DWC_OTG_L0;
02554 }
02555 break;
02556 #ifdef DWC_HS_ELECT_TST
02557 case UHF_PORT_TEST:
02558 {
02559 uint32_t t;
02560 gintmsk_data_t gintmsk;
02561
02562 t = (wIndex >> 8);
02563 DWC_DEBUGPL(DBG_HCD,
02564 "DWC OTG HCD HUB CONTROL - "
02565 "SetPortFeature - USB_PORT_FEAT_TEST %d\n",
02566 t);
02567 DWC_WARN("USB_PORT_FEAT_TEST %d\n", t);
02568 if (t < 6) {
02569 hprt0.d32 = dwc_otg_read_hprt0(core_if);
02570 hprt0.b.prttstctl = t;
02571 DWC_WRITE_REG32(core_if->host_if->hprt0,
02572 hprt0.d32);
02573 } else {
02574
02575
02576
02577 global_regs = core_if->core_global_regs;
02578 hc_global_regs =
02579 core_if->host_if->host_global_regs;
02580 hc_regs =
02581 (dwc_otg_hc_regs_t *) ((char *)
02582 global_regs +
02583 0x500);
02584 data_fifo =
02585 (uint32_t *) ((char *)global_regs +
02586 0x1000);
02587
02588 if (t == 6) {
02589
02590 gintmsk.d32 =
02591 DWC_READ_REG32
02592 (&global_regs->gintmsk);
02593
02594
02595
02596
02597 DWC_WRITE_REG32(&global_regs->gintmsk, 0);
02598
02599
02600 dwc_mdelay(15000);
02601
02602
02603 hprt0.d32 =
02604 dwc_otg_read_hprt0(core_if);
02605 hprt0.b.prtsusp = 1;
02606 hprt0.b.prtres = 0;
02607 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
02608
02609
02610 dwc_mdelay(15000);
02611
02612
02613 hprt0.d32 =
02614 dwc_otg_read_hprt0(core_if);
02615 hprt0.b.prtsusp = 0;
02616 hprt0.b.prtres = 1;
02617 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
02618 dwc_mdelay(100);
02619
02620
02621 hprt0.b.prtres = 0;
02622 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
02623
02624
02625 DWC_WRITE_REG32(&global_regs->gintmsk, gintmsk.d32);
02626 } else if (t == 7) {
02627
02628 gintmsk.d32 =
02629 DWC_READ_REG32
02630 (&global_regs->gintmsk);
02631
02632
02633
02634
02635 DWC_WRITE_REG32(&global_regs->gintmsk, 0);
02636
02637
02638 dwc_mdelay(15000);
02639
02640
02641 do_setup();
02642
02643
02644 dwc_mdelay(15000);
02645
02646
02647 DWC_WRITE_REG32(&global_regs->gintmsk, gintmsk.d32);
02648 } else if (t == 8) {
02649
02650 gintmsk.d32 =
02651 DWC_READ_REG32
02652 (&global_regs->gintmsk);
02653
02654
02655
02656
02657 DWC_WRITE_REG32(&global_regs->gintmsk, 0);
02658
02659
02660 do_setup();
02661
02662
02663 dwc_mdelay(15000);
02664
02665
02666 do_in_ack();
02667
02668
02669 dwc_mdelay(15000);
02670
02671
02672 DWC_WRITE_REG32(&global_regs->gintmsk, gintmsk.d32);
02673 }
02674 }
02675 break;
02676 }
02677 #endif
02678
02679 case UHF_PORT_INDICATOR:
02680 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
02681 "SetPortFeature - USB_PORT_FEAT_INDICATOR\n");
02682
02683 break;
02684 default:
02685 retval = -DWC_E_INVALID;
02686 DWC_ERROR("DWC OTG HCD - "
02687 "SetPortFeature request %xh "
02688 "unknown or unsupported\n", wValue);
02689 break;
02690 }
02691 break;
02692 #ifdef CONFIG_USB_DWC_OTG_LPM
02693 case UCR_SET_AND_TEST_PORT_FEATURE:
02694 if (wValue != UHF_PORT_L1) {
02695 goto error;
02696 }
02697 {
02698 int portnum, hird, devaddr, remwake;
02699 glpmcfg_data_t lpmcfg;
02700 uint32_t time_usecs;
02701 gintsts_data_t gintsts;
02702 gintmsk_data_t gintmsk;
02703
02704 if (!dwc_otg_get_param_lpm_enable(core_if)) {
02705 goto error;
02706 }
02707 if (wValue != UHF_PORT_L1 || wLength != 1) {
02708 goto error;
02709 }
02710
02711 lpmcfg.d32 =
02712 DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
02713 if (lpmcfg.b.prt_sleep_sts) {
02714 DWC_INFO("Port is already in sleep mode\n");
02715 buf[0] = 0;
02716 break;
02717 }
02718
02719 portnum = wIndex & 0xf;
02720 hird = (wIndex >> 4) & 0xf;
02721 devaddr = (wIndex >> 8) & 0x7f;
02722 remwake = (wIndex >> 15);
02723
02724 if (portnum != 1) {
02725 retval = -DWC_E_INVALID;
02726 DWC_WARN
02727 ("Wrong port number(%d) in SetandTestPortFeature request\n",
02728 portnum);
02729 break;
02730 }
02731
02732 DWC_PRINTF
02733 ("SetandTestPortFeature request: portnum = %d, hird = %d, devaddr = %d, rewake = %d\n",
02734 portnum, hird, devaddr, remwake);
02735
02736 gintmsk.d32 = 0;
02737 gintmsk.b.lpmtranrcvd = 1;
02738 DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk,
02739 gintmsk.d32, 0);
02740
02741 if (dwc_otg_hcd_send_lpm
02742 (dwc_otg_hcd, devaddr, hird, remwake)) {
02743 retval = -DWC_E_INVALID;
02744 break;
02745 }
02746
02747 time_usecs = 10 * (lpmcfg.b.retry_count + 1);
02748
02749
02750
02751
02752
02753 do {
02754 gintsts.d32 =
02755 DWC_READ_REG32(&core_if->core_global_regs->gintsts);
02756 if (gintsts.b.lpmtranrcvd) {
02757 break;
02758 }
02759 dwc_udelay(1);
02760 } while (--time_usecs);
02761
02762
02763
02764
02765
02766
02767
02768 if (!gintsts.b.lpmtranrcvd) {
02769 buf[0] = 0x3;
02770 dwc_otg_hcd_free_hc_from_lpm(dwc_otg_hcd);
02771 } else {
02772 lpmcfg.d32 =
02773 DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
02774 if (lpmcfg.b.lpm_resp == 0x3) {
02775
02776 buf[0] = 0x00;
02777 } else if (lpmcfg.b.lpm_resp == 0x2) {
02778
02779 buf[0] = 0x2;
02780 } else {
02781
02782 buf[0] = 0x3;
02783 }
02784 }
02785 DWC_PRINTF("Device responce to LPM trans is %x\n",
02786 lpmcfg.b.lpm_resp);
02787 DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, 0,
02788 gintmsk.d32);
02789
02790 break;
02791 }
02792 #endif
02793 default:
02794 error:
02795 retval = -DWC_E_INVALID;
02796 DWC_WARN("DWC OTG HCD - "
02797 "Unknown hub control request type or invalid typeReq: %xh wIndex: %xh wValue: %xh\n",
02798 typeReq, wIndex, wValue);
02799 break;
02800 }
02801
02802 return retval;
02803 }
02804
02805 #ifdef CONFIG_USB_DWC_OTG_LPM
02806
02807 int dwc_otg_hcd_get_hc_for_lpm_tran(dwc_otg_hcd_t * hcd, uint8_t devaddr)
02808 {
02809 dwc_otg_core_if_t *core_if = hcd->core_if;
02810 dwc_hc_t *hc;
02811 hcchar_data_t hcchar;
02812 gintmsk_data_t gintmsk = {.d32 = 0 };
02813
02814 if (DWC_CIRCLEQ_EMPTY(&hcd->free_hc_list)) {
02815 DWC_PRINTF("No free channel to select for LPM transaction\n");
02816 return -1;
02817 }
02818
02819 hc = DWC_CIRCLEQ_FIRST(&hcd->free_hc_list);
02820
02821
02822 gintmsk.b.hcintr = 1;
02823 DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, gintmsk.d32, 0);
02824
02825
02826 hcchar.b.devaddr = devaddr;
02827 hcchar.b.epnum = 0;
02828 hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;
02829 hcchar.b.mps = 64;
02830 hcchar.b.lspddev = (hc->speed == DWC_OTG_EP_SPEED_LOW);
02831 hcchar.b.epdir = 0;
02832 DWC_WRITE_REG32(&core_if->host_if->hc_regs[hc->hc_num]->hcchar,
02833 hcchar.d32);
02834
02835
02836 DWC_CIRCLEQ_REMOVE_INIT(&hcd->free_hc_list, hc, hc_list_entry);
02837
02838 DWC_PRINTF("hcnum = %d devaddr = %d\n", hc->hc_num, devaddr);
02839
02840 return hc->hc_num;
02841 }
02842
02844 void dwc_otg_hcd_free_hc_from_lpm(dwc_otg_hcd_t * hcd)
02845 {
02846 dwc_hc_t *hc;
02847 glpmcfg_data_t lpmcfg;
02848 uint8_t hc_num;
02849
02850 lpmcfg.d32 = DWC_READ_REG32(&hcd->core_if->core_global_regs->glpmcfg);
02851 hc_num = lpmcfg.b.lpm_chan_index;
02852
02853 hc = hcd->hc_ptr_array[hc_num];
02854
02855 DWC_PRINTF("Freeing channel %d after LPM\n", hc_num);
02856
02857 DWC_CIRCLEQ_INSERT_TAIL(&hcd->free_hc_list, hc, hc_list_entry);
02858 }
02859
02860 int dwc_otg_hcd_send_lpm(dwc_otg_hcd_t * hcd, uint8_t devaddr, uint8_t hird,
02861 uint8_t bRemoteWake)
02862 {
02863 glpmcfg_data_t lpmcfg;
02864 pcgcctl_data_t pcgcctl = {.d32 = 0 };
02865 int channel;
02866
02867 channel = dwc_otg_hcd_get_hc_for_lpm_tran(hcd, devaddr);
02868 if (channel < 0) {
02869 return channel;
02870 }
02871
02872 pcgcctl.b.enbl_sleep_gating = 1;
02873 DWC_MODIFY_REG32(hcd->core_if->pcgcctl, 0, pcgcctl.d32);
02874
02875
02876 lpmcfg.d32 = DWC_READ_REG32(&hcd->core_if->core_global_regs->glpmcfg);
02877
02878
02879 lpmcfg.b.rem_wkup_en = bRemoteWake;
02880 lpmcfg.b.hird = hird;
02881 lpmcfg.b.hird_thres = 0x1c;
02882 lpmcfg.b.lpm_chan_index = channel;
02883 lpmcfg.b.en_utmi_sleep = 1;
02884
02885 DWC_WRITE_REG32(&hcd->core_if->core_global_regs->glpmcfg, lpmcfg.d32);
02886
02887
02888 lpmcfg.b.send_lpm = 1;
02889 DWC_WRITE_REG32(&hcd->core_if->core_global_regs->glpmcfg, lpmcfg.d32);
02890
02891 return 0;
02892 }
02893
02894 #endif
02895
02896 int dwc_otg_hcd_is_status_changed(dwc_otg_hcd_t * hcd, int port)
02897 {
02898 int retval;
02899
02900 if (port != 1) {
02901 return -DWC_E_INVALID;
02902 }
02903
02904 retval = (hcd->flags.b.port_connect_status_change ||
02905 hcd->flags.b.port_reset_change ||
02906 hcd->flags.b.port_enable_change ||
02907 hcd->flags.b.port_suspend_change ||
02908 hcd->flags.b.port_over_current_change);
02909 #ifdef DEBUG
02910 if (retval) {
02911 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB STATUS DATA:"
02912 " Root port status changed\n");
02913 DWC_DEBUGPL(DBG_HCDV, " port_connect_status_change: %d\n",
02914 hcd->flags.b.port_connect_status_change);
02915 DWC_DEBUGPL(DBG_HCDV, " port_reset_change: %d\n",
02916 hcd->flags.b.port_reset_change);
02917 DWC_DEBUGPL(DBG_HCDV, " port_enable_change: %d\n",
02918 hcd->flags.b.port_enable_change);
02919 DWC_DEBUGPL(DBG_HCDV, " port_suspend_change: %d\n",
02920 hcd->flags.b.port_suspend_change);
02921 DWC_DEBUGPL(DBG_HCDV, " port_over_current_change: %d\n",
02922 hcd->flags.b.port_over_current_change);
02923 }
02924 #endif
02925 return retval;
02926 }
02927
02928 int dwc_otg_hcd_get_frame_number(dwc_otg_hcd_t * dwc_otg_hcd)
02929 {
02930 hfnum_data_t hfnum;
02931 hfnum.d32 =
02932 DWC_READ_REG32(&dwc_otg_hcd->core_if->host_if->host_global_regs->
02933 hfnum);
02934
02935 #ifdef DEBUG_SOF
02936 DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD GET FRAME NUMBER %d\n",
02937 hfnum.b.frnum);
02938 #endif
02939 return hfnum.b.frnum;
02940 }
02941
02942 int dwc_otg_hcd_start(dwc_otg_hcd_t * hcd,
02943 struct dwc_otg_hcd_function_ops *fops)
02944 {
02945 int retval = 0;
02946
02947 hcd->fops = fops;
02948 if (!dwc_otg_is_device_mode(hcd->core_if) &&
02949 (!hcd->core_if->adp_enable || hcd->core_if->adp.adp_started)) {
02950 dwc_otg_hcd_reinit(hcd);
02951 } else {
02952 retval = -DWC_E_NO_DEVICE;
02953 }
02954
02955 return retval;
02956 }
02957
02958 void *dwc_otg_hcd_get_priv_data(dwc_otg_hcd_t * hcd)
02959 {
02960 return hcd->priv;
02961 }
02962
02963 void dwc_otg_hcd_set_priv_data(dwc_otg_hcd_t * hcd, void *priv_data)
02964 {
02965 hcd->priv = priv_data;
02966 }
02967
02968 uint32_t dwc_otg_hcd_otg_port(dwc_otg_hcd_t * hcd)
02969 {
02970 return hcd->otg_port;
02971 }
02972
02973 uint32_t dwc_otg_hcd_is_b_host(dwc_otg_hcd_t * hcd)
02974 {
02975 uint32_t is_b_host;
02976 if (hcd->core_if->op_state == B_HOST) {
02977 is_b_host = 1;
02978 } else {
02979 is_b_host = 0;
02980 }
02981
02982 return is_b_host;
02983 }
02984
02985 dwc_otg_hcd_urb_t *dwc_otg_hcd_urb_alloc(dwc_otg_hcd_t * hcd,
02986 int iso_desc_count, int atomic_alloc)
02987 {
02988 dwc_otg_hcd_urb_t *dwc_otg_urb;
02989 uint32_t size;
02990
02991 size =
02992 sizeof(*dwc_otg_urb) +
02993 iso_desc_count * sizeof(struct dwc_otg_hcd_iso_packet_desc);
02994 if (atomic_alloc)
02995 dwc_otg_urb = DWC_ALLOC_ATOMIC(size);
02996 else
02997 dwc_otg_urb = DWC_ALLOC(size);
02998
02999 dwc_otg_urb->packet_count = iso_desc_count;
03000
03001 return dwc_otg_urb;
03002 }
03003
03004 void dwc_otg_hcd_urb_set_pipeinfo(dwc_otg_hcd_urb_t * dwc_otg_urb,
03005 uint8_t dev_addr, uint8_t ep_num,
03006 uint8_t ep_type, uint8_t ep_dir, uint16_t mps)
03007 {
03008 dwc_otg_hcd_fill_pipe(&dwc_otg_urb->pipe_info, dev_addr, ep_num,
03009 ep_type, ep_dir, mps);
03010 #if 0
03011 DWC_PRINTF
03012 ("addr = %d, ep_num = %d, ep_dir = 0x%x, ep_type = 0x%x, mps = %d\n",
03013 dev_addr, ep_num, ep_dir, ep_type, mps);
03014 #endif
03015 }
03016
03017 void dwc_otg_hcd_urb_set_params(dwc_otg_hcd_urb_t * dwc_otg_urb,
03018 void *urb_handle, void *buf, dwc_dma_t dma,
03019 uint32_t buflen, void *setup_packet,
03020 dwc_dma_t setup_dma, uint32_t flags,
03021 uint16_t interval)
03022 {
03023 dwc_otg_urb->priv = urb_handle;
03024 dwc_otg_urb->buf = buf;
03025 dwc_otg_urb->dma = dma;
03026 dwc_otg_urb->length = buflen;
03027 dwc_otg_urb->setup_packet = setup_packet;
03028 dwc_otg_urb->setup_dma = setup_dma;
03029 dwc_otg_urb->flags = flags;
03030 dwc_otg_urb->interval = interval;
03031 dwc_otg_urb->status = -DWC_E_IN_PROGRESS;
03032 }
03033
03034 uint32_t dwc_otg_hcd_urb_get_status(dwc_otg_hcd_urb_t * dwc_otg_urb)
03035 {
03036 return dwc_otg_urb->status;
03037 }
03038
03039 uint32_t dwc_otg_hcd_urb_get_actual_length(dwc_otg_hcd_urb_t * dwc_otg_urb)
03040 {
03041 return dwc_otg_urb->actual_length;
03042 }
03043
03044 uint32_t dwc_otg_hcd_urb_get_error_count(dwc_otg_hcd_urb_t * dwc_otg_urb)
03045 {
03046 return dwc_otg_urb->error_count;
03047 }
03048
03049 void dwc_otg_hcd_urb_set_iso_desc_params(dwc_otg_hcd_urb_t * dwc_otg_urb,
03050 int desc_num, uint32_t offset,
03051 uint32_t length)
03052 {
03053 dwc_otg_urb->iso_descs[desc_num].offset = offset;
03054 dwc_otg_urb->iso_descs[desc_num].length = length;
03055 }
03056
03057 uint32_t dwc_otg_hcd_urb_get_iso_desc_status(dwc_otg_hcd_urb_t * dwc_otg_urb,
03058 int desc_num)
03059 {
03060 return dwc_otg_urb->iso_descs[desc_num].status;
03061 }
03062
03063 uint32_t dwc_otg_hcd_urb_get_iso_desc_actual_length(dwc_otg_hcd_urb_t *
03064 dwc_otg_urb, int desc_num)
03065 {
03066 return dwc_otg_urb->iso_descs[desc_num].actual_length;
03067 }
03068
03069 int dwc_otg_hcd_is_bandwidth_allocated(dwc_otg_hcd_t * hcd, void *ep_handle)
03070 {
03071 int allocated = 0;
03072 dwc_otg_qh_t *qh = (dwc_otg_qh_t *) ep_handle;
03073
03074 if (qh) {
03075 if (!DWC_LIST_EMPTY(&qh->qh_list_entry)) {
03076 allocated = 1;
03077 }
03078 }
03079 return allocated;
03080 }
03081
03082 int dwc_otg_hcd_is_bandwidth_freed(dwc_otg_hcd_t * hcd, void *ep_handle)
03083 {
03084 dwc_otg_qh_t *qh = (dwc_otg_qh_t *) ep_handle;
03085 int freed = 0;
03086 DWC_ASSERT(qh, "qh is not allocated\n");
03087
03088 if (DWC_LIST_EMPTY(&qh->qh_list_entry)) {
03089 freed = 1;
03090 }
03091
03092 return freed;
03093 }
03094
03095 uint8_t dwc_otg_hcd_get_ep_bandwidth(dwc_otg_hcd_t * hcd, void *ep_handle)
03096 {
03097 dwc_otg_qh_t *qh = (dwc_otg_qh_t *) ep_handle;
03098 DWC_ASSERT(qh, "qh is not allocated\n");
03099 return qh->usecs;
03100 }
03101
03102 void dwc_otg_hcd_dump_state(dwc_otg_hcd_t * hcd)
03103 {
03104 #ifdef DEBUG
03105 int num_channels;
03106 int i;
03107 gnptxsts_data_t np_tx_status;
03108 hptxsts_data_t p_tx_status;
03109
03110 num_channels = hcd->core_if->core_params->host_channels;
03111 DWC_PRINTF("\n");
03112 DWC_PRINTF
03113 ("************************************************************\n");
03114 DWC_PRINTF("HCD State:\n");
03115 DWC_PRINTF(" Num channels: %d\n", num_channels);
03116 for (i = 0; i < num_channels; i++) {
03117 dwc_hc_t *hc = hcd->hc_ptr_array[i];
03118 DWC_PRINTF(" Channel %d:\n", i);
03119 DWC_PRINTF(" dev_addr: %d, ep_num: %d, ep_is_in: %d\n",
03120 hc->dev_addr, hc->ep_num, hc->ep_is_in);
03121 DWC_PRINTF(" speed: %d\n", hc->speed);
03122 DWC_PRINTF(" ep_type: %d\n", hc->ep_type);
03123 DWC_PRINTF(" max_packet: %d\n", hc->max_packet);
03124 DWC_PRINTF(" data_pid_start: %d\n", hc->data_pid_start);
03125 DWC_PRINTF(" multi_count: %d\n", hc->multi_count);
03126 DWC_PRINTF(" xfer_started: %d\n", hc->xfer_started);
03127 DWC_PRINTF(" xfer_buff: %p\n", hc->xfer_buff);
03128 DWC_PRINTF(" xfer_len: %d\n", hc->xfer_len);
03129 DWC_PRINTF(" xfer_count: %d\n", hc->xfer_count);
03130 DWC_PRINTF(" halt_on_queue: %d\n", hc->halt_on_queue);
03131 DWC_PRINTF(" halt_pending: %d\n", hc->halt_pending);
03132 DWC_PRINTF(" halt_status: %d\n", hc->halt_status);
03133 DWC_PRINTF(" do_split: %d\n", hc->do_split);
03134 DWC_PRINTF(" complete_split: %d\n", hc->complete_split);
03135 DWC_PRINTF(" hub_addr: %d\n", hc->hub_addr);
03136 DWC_PRINTF(" port_addr: %d\n", hc->port_addr);
03137 DWC_PRINTF(" xact_pos: %d\n", hc->xact_pos);
03138 DWC_PRINTF(" requests: %d\n", hc->requests);
03139 DWC_PRINTF(" qh: %p\n", hc->qh);
03140 if (hc->xfer_started) {
03141 hfnum_data_t hfnum;
03142 hcchar_data_t hcchar;
03143 hctsiz_data_t hctsiz;
03144 hcint_data_t hcint;
03145 hcintmsk_data_t hcintmsk;
03146 hfnum.d32 =
03147 DWC_READ_REG32(&hcd->core_if->
03148 host_if->host_global_regs->hfnum);
03149 hcchar.d32 =
03150 DWC_READ_REG32(&hcd->core_if->host_if->
03151 hc_regs[i]->hcchar);
03152 hctsiz.d32 =
03153 DWC_READ_REG32(&hcd->core_if->host_if->
03154 hc_regs[i]->hctsiz);
03155 hcint.d32 =
03156 DWC_READ_REG32(&hcd->core_if->host_if->
03157 hc_regs[i]->hcint);
03158 hcintmsk.d32 =
03159 DWC_READ_REG32(&hcd->core_if->host_if->
03160 hc_regs[i]->hcintmsk);
03161 DWC_PRINTF(" hfnum: 0x%08x\n", hfnum.d32);
03162 DWC_PRINTF(" hcchar: 0x%08x\n", hcchar.d32);
03163 DWC_PRINTF(" hctsiz: 0x%08x\n", hctsiz.d32);
03164 DWC_PRINTF(" hcint: 0x%08x\n", hcint.d32);
03165 DWC_PRINTF(" hcintmsk: 0x%08x\n", hcintmsk.d32);
03166 }
03167 if (hc->xfer_started && hc->qh) {
03168 dwc_otg_qtd_t *qtd;
03169 dwc_otg_hcd_urb_t *urb;
03170
03171 DWC_CIRCLEQ_FOREACH(qtd, &hc->qh->qtd_list, qtd_list_entry) {
03172 if (!qtd->in_process)
03173 break;
03174
03175 urb = qtd->urb;
03176 DWC_PRINTF(" URB Info:\n");
03177 DWC_PRINTF(" qtd: %p, urb: %p\n", qtd, urb);
03178 if (urb) {
03179 DWC_PRINTF(" Dev: %d, EP: %d %s\n",
03180 dwc_otg_hcd_get_dev_addr(&urb->
03181 pipe_info),
03182 dwc_otg_hcd_get_ep_num(&urb->
03183 pipe_info),
03184 dwc_otg_hcd_is_pipe_in(&urb->
03185 pipe_info) ?
03186 "IN" : "OUT");
03187 DWC_PRINTF(" Max packet size: %d\n",
03188 dwc_otg_hcd_get_mps(&urb->
03189 pipe_info));
03190 DWC_PRINTF(" transfer_buffer: %p\n",
03191 urb->buf);
03192 DWC_PRINTF(" transfer_dma: %p\n",
03193 (void *)urb->dma);
03194 DWC_PRINTF(" transfer_buffer_length: %d\n",
03195 urb->length);
03196 DWC_PRINTF(" actual_length: %d\n",
03197 urb->actual_length);
03198 }
03199 }
03200 }
03201 }
03202 DWC_PRINTF(" non_periodic_channels: %d\n", hcd->non_periodic_channels);
03203 DWC_PRINTF(" periodic_channels: %d\n", hcd->periodic_channels);
03204 DWC_PRINTF(" periodic_usecs: %d\n", hcd->periodic_usecs);
03205 np_tx_status.d32 =
03206 DWC_READ_REG32(&hcd->core_if->core_global_regs->gnptxsts);
03207 DWC_PRINTF(" NP Tx Req Queue Space Avail: %d\n",
03208 np_tx_status.b.nptxqspcavail);
03209 DWC_PRINTF(" NP Tx FIFO Space Avail: %d\n",
03210 np_tx_status.b.nptxfspcavail);
03211 p_tx_status.d32 =
03212 DWC_READ_REG32(&hcd->core_if->host_if->host_global_regs->hptxsts);
03213 DWC_PRINTF(" P Tx Req Queue Space Avail: %d\n",
03214 p_tx_status.b.ptxqspcavail);
03215 DWC_PRINTF(" P Tx FIFO Space Avail: %d\n", p_tx_status.b.ptxfspcavail);
03216 dwc_otg_hcd_dump_frrem(hcd);
03217 dwc_otg_dump_global_registers(hcd->core_if);
03218 dwc_otg_dump_host_registers(hcd->core_if);
03219 DWC_PRINTF
03220 ("************************************************************\n");
03221 DWC_PRINTF("\n");
03222 #endif
03223 }
03224
03225 #ifdef DEBUG
03226 void dwc_print_setup_data(uint8_t * setup)
03227 {
03228 int i;
03229 if (CHK_DEBUG_LEVEL(DBG_HCD)) {
03230 DWC_PRINTF("Setup Data = MSB ");
03231 for (i = 7; i >= 0; i--)
03232 DWC_PRINTF("%02x ", setup[i]);
03233 DWC_PRINTF("\n");
03234 DWC_PRINTF(" bmRequestType Tranfer = %s\n",
03235 (setup[0] & 0x80) ? "Device-to-Host" :
03236 "Host-to-Device");
03237 DWC_PRINTF(" bmRequestType Type = ");
03238 switch ((setup[0] & 0x60) >> 5) {
03239 case 0:
03240 DWC_PRINTF("Standard\n");
03241 break;
03242 case 1:
03243 DWC_PRINTF("Class\n");
03244 break;
03245 case 2:
03246 DWC_PRINTF("Vendor\n");
03247 break;
03248 case 3:
03249 DWC_PRINTF("Reserved\n");
03250 break;
03251 }
03252 DWC_PRINTF(" bmRequestType Recipient = ");
03253 switch (setup[0] & 0x1f) {
03254 case 0:
03255 DWC_PRINTF("Device\n");
03256 break;
03257 case 1:
03258 DWC_PRINTF("Interface\n");
03259 break;
03260 case 2:
03261 DWC_PRINTF("Endpoint\n");
03262 break;
03263 case 3:
03264 DWC_PRINTF("Other\n");
03265 break;
03266 default:
03267 DWC_PRINTF("Reserved\n");
03268 break;
03269 }
03270 DWC_PRINTF(" bRequest = 0x%0x\n", setup[1]);
03271 DWC_PRINTF(" wValue = 0x%0x\n", *((uint16_t *) & setup[2]));
03272 DWC_PRINTF(" wIndex = 0x%0x\n", *((uint16_t *) & setup[4]));
03273 DWC_PRINTF(" wLength = 0x%0x\n\n", *((uint16_t *) & setup[6]));
03274 }
03275 }
03276 #endif
03277
03278 void dwc_otg_hcd_dump_frrem(dwc_otg_hcd_t * hcd)
03279 {
03280 #if 0
03281 DWC_PRINTF("Frame remaining at SOF:\n");
03282 DWC_PRINTF(" samples %u, accum %llu, avg %llu\n",
03283 hcd->frrem_samples, hcd->frrem_accum,
03284 (hcd->frrem_samples > 0) ?
03285 hcd->frrem_accum / hcd->frrem_samples : 0);
03286
03287 DWC_PRINTF("\n");
03288 DWC_PRINTF("Frame remaining at start_transfer (uframe 7):\n");
03289 DWC_PRINTF(" samples %u, accum %llu, avg %llu\n",
03290 hcd->core_if->hfnum_7_samples,
03291 hcd->core_if->hfnum_7_frrem_accum,
03292 (hcd->core_if->hfnum_7_samples >
03293 0) ? hcd->core_if->hfnum_7_frrem_accum /
03294 hcd->core_if->hfnum_7_samples : 0);
03295 DWC_PRINTF("Frame remaining at start_transfer (uframe 0):\n");
03296 DWC_PRINTF(" samples %u, accum %llu, avg %llu\n",
03297 hcd->core_if->hfnum_0_samples,
03298 hcd->core_if->hfnum_0_frrem_accum,
03299 (hcd->core_if->hfnum_0_samples >
03300 0) ? hcd->core_if->hfnum_0_frrem_accum /
03301 hcd->core_if->hfnum_0_samples : 0);
03302 DWC_PRINTF("Frame remaining at start_transfer (uframe 1-6):\n");
03303 DWC_PRINTF(" samples %u, accum %llu, avg %llu\n",
03304 hcd->core_if->hfnum_other_samples,
03305 hcd->core_if->hfnum_other_frrem_accum,
03306 (hcd->core_if->hfnum_other_samples >
03307 0) ? hcd->core_if->hfnum_other_frrem_accum /
03308 hcd->core_if->hfnum_other_samples : 0);
03309
03310 DWC_PRINTF("\n");
03311 DWC_PRINTF("Frame remaining at sample point A (uframe 7):\n");
03312 DWC_PRINTF(" samples %u, accum %llu, avg %llu\n",
03313 hcd->hfnum_7_samples_a, hcd->hfnum_7_frrem_accum_a,
03314 (hcd->hfnum_7_samples_a > 0) ?
03315 hcd->hfnum_7_frrem_accum_a / hcd->hfnum_7_samples_a : 0);
03316 DWC_PRINTF("Frame remaining at sample point A (uframe 0):\n");
03317 DWC_PRINTF(" samples %u, accum %llu, avg %llu\n",
03318 hcd->hfnum_0_samples_a, hcd->hfnum_0_frrem_accum_a,
03319 (hcd->hfnum_0_samples_a > 0) ?
03320 hcd->hfnum_0_frrem_accum_a / hcd->hfnum_0_samples_a : 0);
03321 DWC_PRINTF("Frame remaining at sample point A (uframe 1-6):\n");
03322 DWC_PRINTF(" samples %u, accum %llu, avg %llu\n",
03323 hcd->hfnum_other_samples_a, hcd->hfnum_other_frrem_accum_a,
03324 (hcd->hfnum_other_samples_a > 0) ?
03325 hcd->hfnum_other_frrem_accum_a /
03326 hcd->hfnum_other_samples_a : 0);
03327
03328 DWC_PRINTF("\n");
03329 DWC_PRINTF("Frame remaining at sample point B (uframe 7):\n");
03330 DWC_PRINTF(" samples %u, accum %llu, avg %llu\n",
03331 hcd->hfnum_7_samples_b, hcd->hfnum_7_frrem_accum_b,
03332 (hcd->hfnum_7_samples_b > 0) ?
03333 hcd->hfnum_7_frrem_accum_b / hcd->hfnum_7_samples_b : 0);
03334 DWC_PRINTF("Frame remaining at sample point B (uframe 0):\n");
03335 DWC_PRINTF(" samples %u, accum %llu, avg %llu\n",
03336 hcd->hfnum_0_samples_b, hcd->hfnum_0_frrem_accum_b,
03337 (hcd->hfnum_0_samples_b > 0) ?
03338 hcd->hfnum_0_frrem_accum_b / hcd->hfnum_0_samples_b : 0);
03339 DWC_PRINTF("Frame remaining at sample point B (uframe 1-6):\n");
03340 DWC_PRINTF(" samples %u, accum %llu, avg %llu\n",
03341 hcd->hfnum_other_samples_b, hcd->hfnum_other_frrem_accum_b,
03342 (hcd->hfnum_other_samples_b > 0) ?
03343 hcd->hfnum_other_frrem_accum_b /
03344 hcd->hfnum_other_samples_b : 0);
03345 #endif
03346 }
03347
03348 #endif