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
00060 #include "dwc_os.h"
00061 #include "dwc_otg_regs.h"
00062 #include "dwc_otg_cil.h"
00063
00064 static int dwc_otg_setup_params(dwc_otg_core_if_t * core_if);
00065
00078 dwc_otg_core_if_t *dwc_otg_cil_init(const uint32_t * reg_base_addr)
00079 {
00080 dwc_otg_core_if_t *core_if = 0;
00081 dwc_otg_dev_if_t *dev_if = 0;
00082 dwc_otg_host_if_t *host_if = 0;
00083 uint8_t *reg_base = (uint8_t *) reg_base_addr;
00084 int i = 0;
00085
00086 DWC_DEBUGPL(DBG_CILV, "%s(%p)\n", __func__, reg_base_addr);
00087
00088 core_if = DWC_ALLOC(sizeof(dwc_otg_core_if_t));
00089
00090 if (core_if == NULL) {
00091 DWC_DEBUGPL(DBG_CIL,
00092 "Allocation of dwc_otg_core_if_t failed\n");
00093 return 0;
00094 }
00095 core_if->core_global_regs = (dwc_otg_core_global_regs_t *) reg_base;
00096
00097
00098
00099
00100 dev_if = DWC_ALLOC(sizeof(dwc_otg_dev_if_t));
00101
00102 if (dev_if == NULL) {
00103 DWC_DEBUGPL(DBG_CIL, "Allocation of dwc_otg_dev_if_t failed\n");
00104 DWC_FREE(core_if);
00105 return 0;
00106 }
00107
00108 dev_if->dev_global_regs =
00109 (dwc_otg_device_global_regs_t *) (reg_base +
00110 DWC_DEV_GLOBAL_REG_OFFSET);
00111
00112 for (i = 0; i < MAX_EPS_CHANNELS; i++) {
00113 dev_if->in_ep_regs[i] = (dwc_otg_dev_in_ep_regs_t *)
00114 (reg_base + DWC_DEV_IN_EP_REG_OFFSET +
00115 (i * DWC_EP_REG_OFFSET));
00116
00117 dev_if->out_ep_regs[i] = (dwc_otg_dev_out_ep_regs_t *)
00118 (reg_base + DWC_DEV_OUT_EP_REG_OFFSET +
00119 (i * DWC_EP_REG_OFFSET));
00120 DWC_DEBUGPL(DBG_CILV, "in_ep_regs[%d]->diepctl=%p\n",
00121 i, &dev_if->in_ep_regs[i]->diepctl);
00122 DWC_DEBUGPL(DBG_CILV, "out_ep_regs[%d]->doepctl=%p\n",
00123 i, &dev_if->out_ep_regs[i]->doepctl);
00124 }
00125
00126 dev_if->speed = 0;
00127
00128 core_if->dev_if = dev_if;
00129
00130
00131
00132
00133 host_if = DWC_ALLOC(sizeof(dwc_otg_host_if_t));
00134
00135 if (host_if == NULL) {
00136 DWC_DEBUGPL(DBG_CIL,
00137 "Allocation of dwc_otg_host_if_t failed\n");
00138 DWC_FREE(dev_if);
00139 DWC_FREE(core_if);
00140 return 0;
00141 }
00142
00143 host_if->host_global_regs = (dwc_otg_host_global_regs_t *)
00144 (reg_base + DWC_OTG_HOST_GLOBAL_REG_OFFSET);
00145
00146 host_if->hprt0 =
00147 (uint32_t *) (reg_base + DWC_OTG_HOST_PORT_REGS_OFFSET);
00148
00149 for (i = 0; i < MAX_EPS_CHANNELS; i++) {
00150 host_if->hc_regs[i] = (dwc_otg_hc_regs_t *)
00151 (reg_base + DWC_OTG_HOST_CHAN_REGS_OFFSET +
00152 (i * DWC_OTG_CHAN_REGS_OFFSET));
00153 DWC_DEBUGPL(DBG_CILV, "hc_reg[%d]->hcchar=%p\n",
00154 i, &host_if->hc_regs[i]->hcchar);
00155 }
00156
00157 host_if->num_host_channels = MAX_EPS_CHANNELS;
00158 core_if->host_if = host_if;
00159
00160 for (i = 0; i < MAX_EPS_CHANNELS; i++) {
00161 core_if->data_fifo[i] =
00162 (uint32_t *) (reg_base + DWC_OTG_DATA_FIFO_OFFSET +
00163 (i * DWC_OTG_DATA_FIFO_SIZE));
00164 DWC_DEBUGPL(DBG_CILV, "data_fifo[%d]=0x%08lx\n",
00165 i, (unsigned long)core_if->data_fifo[i]);
00166 }
00167
00168 core_if->pcgcctl = (uint32_t *) (reg_base + DWC_OTG_PCGCCTL_OFFSET);
00169
00170
00171 core_if->lx_state = DWC_OTG_L3;
00172
00173
00174
00175
00176 core_if->hwcfg1.d32 =
00177 DWC_READ_REG32(&core_if->core_global_regs->ghwcfg1);
00178 core_if->hwcfg2.d32 =
00179 DWC_READ_REG32(&core_if->core_global_regs->ghwcfg2);
00180 core_if->hwcfg3.d32 =
00181 DWC_READ_REG32(&core_if->core_global_regs->ghwcfg3);
00182 core_if->hwcfg4.d32 =
00183 DWC_READ_REG32(&core_if->core_global_regs->ghwcfg4);
00184
00185
00186 {
00187 gusbcfg_data_t gusbcfg = {.d32 = 0 };
00188 gusbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
00189 gusbcfg.b.force_host_mode = 1;
00190 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gusbcfg.d32);
00191 dwc_mdelay(100);
00192 core_if->hptxfsiz.d32 =
00193 DWC_READ_REG32(&core_if->core_global_regs->hptxfsiz);
00194 gusbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
00195 gusbcfg.b.force_host_mode = 0;
00196 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gusbcfg.d32);
00197 dwc_mdelay(100);
00198 }
00199
00200 DWC_DEBUGPL(DBG_CILV, "hwcfg1=%08x\n", core_if->hwcfg1.d32);
00201 DWC_DEBUGPL(DBG_CILV, "hwcfg2=%08x\n", core_if->hwcfg2.d32);
00202 DWC_DEBUGPL(DBG_CILV, "hwcfg3=%08x\n", core_if->hwcfg3.d32);
00203 DWC_DEBUGPL(DBG_CILV, "hwcfg4=%08x\n", core_if->hwcfg4.d32);
00204
00205 core_if->hcfg.d32 =
00206 DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg);
00207 core_if->dcfg.d32 =
00208 DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
00209
00210 DWC_DEBUGPL(DBG_CILV, "hcfg=%08x\n", core_if->hcfg.d32);
00211 DWC_DEBUGPL(DBG_CILV, "dcfg=%08x\n", core_if->dcfg.d32);
00212
00213 DWC_DEBUGPL(DBG_CILV, "op_mode=%0x\n", core_if->hwcfg2.b.op_mode);
00214 DWC_DEBUGPL(DBG_CILV, "arch=%0x\n", core_if->hwcfg2.b.architecture);
00215 DWC_DEBUGPL(DBG_CILV, "num_dev_ep=%d\n", core_if->hwcfg2.b.num_dev_ep);
00216 DWC_DEBUGPL(DBG_CILV, "num_host_chan=%d\n",
00217 core_if->hwcfg2.b.num_host_chan);
00218 DWC_DEBUGPL(DBG_CILV, "nonperio_tx_q_depth=0x%0x\n",
00219 core_if->hwcfg2.b.nonperio_tx_q_depth);
00220 DWC_DEBUGPL(DBG_CILV, "host_perio_tx_q_depth=0x%0x\n",
00221 core_if->hwcfg2.b.host_perio_tx_q_depth);
00222 DWC_DEBUGPL(DBG_CILV, "dev_token_q_depth=0x%0x\n",
00223 core_if->hwcfg2.b.dev_token_q_depth);
00224
00225 DWC_DEBUGPL(DBG_CILV, "Total FIFO SZ=%d\n",
00226 core_if->hwcfg3.b.dfifo_depth);
00227 DWC_DEBUGPL(DBG_CILV, "xfer_size_cntr_width=%0x\n",
00228 core_if->hwcfg3.b.xfer_size_cntr_width);
00229
00230
00231
00232
00233 core_if->srp_success = 0;
00234 core_if->srp_timer_started = 0;
00235
00236
00237
00238
00239 core_if->wq_otg = DWC_WORKQ_ALLOC("dwc_otg");
00240 if (core_if->wq_otg == 0) {
00241 DWC_WARN("DWC_WORKQ_ALLOC failed\n");
00242 DWC_FREE(host_if);
00243 DWC_FREE(dev_if);
00244 DWC_FREE(core_if);
00245 return 0;
00246 }
00247
00248 core_if->snpsid = DWC_READ_REG32(&core_if->core_global_regs->gsnpsid);
00249
00250 DWC_PRINTF("Core Release: %x.%x%x%x\n",
00251 (core_if->snpsid >> 12 & 0xF),
00252 (core_if->snpsid >> 8 & 0xF),
00253 (core_if->snpsid >> 4 & 0xF), (core_if->snpsid & 0xF));
00254
00255 core_if->wkp_timer = DWC_TIMER_ALLOC("Wake Up Timer",
00256 w_wakeup_detected, core_if);
00257 if (core_if->wkp_timer == 0) {
00258 DWC_WARN("DWC_TIMER_ALLOC failed\n");
00259 DWC_FREE(host_if);
00260 DWC_FREE(dev_if);
00261 DWC_WORKQ_FREE(core_if->wq_otg);
00262 DWC_FREE(core_if);
00263 return 0;
00264 }
00265
00266 if (dwc_otg_setup_params(core_if)) {
00267 DWC_WARN("Error while setting core params\n");
00268 }
00269
00270 core_if->hibernation_suspend = 0;
00271
00273 dwc_otg_adp_init(core_if);
00274
00275 return core_if;
00276 }
00277
00285 void dwc_otg_cil_remove(dwc_otg_core_if_t * core_if)
00286 {
00287
00288 DWC_MODIFY_REG32(&core_if->core_global_regs->gahbcfg, 1, 0);
00289 DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, 0);
00290
00291 if (core_if->wq_otg) {
00292 DWC_WORKQ_WAIT_WORK_DONE(core_if->wq_otg, 500);
00293 DWC_WORKQ_FREE(core_if->wq_otg);
00294 }
00295 if (core_if->dev_if) {
00296 DWC_FREE(core_if->dev_if);
00297 }
00298 if (core_if->host_if) {
00299 DWC_FREE(core_if->host_if);
00300 }
00301
00303 dwc_otg_adp_remove(core_if);
00304 if (core_if->core_params) {
00305 DWC_FREE(core_if->core_params);
00306 }
00307 if (core_if->wkp_timer) {
00308 DWC_TIMER_FREE(core_if->wkp_timer);
00309 }
00310 if (core_if->srp_timer) {
00311 DWC_TIMER_FREE(core_if->srp_timer);
00312 }
00313 DWC_FREE(core_if);
00314 }
00315
00322 void dwc_otg_enable_global_interrupts(dwc_otg_core_if_t * core_if)
00323 {
00324 gahbcfg_data_t ahbcfg = {.d32 = 0 };
00325 ahbcfg.b.glblintrmsk = 1;
00326 DWC_MODIFY_REG32(&core_if->core_global_regs->gahbcfg, 0, ahbcfg.d32);
00327 }
00328
00335 void dwc_otg_disable_global_interrupts(dwc_otg_core_if_t * core_if)
00336 {
00337 gahbcfg_data_t ahbcfg = {.d32 = 0 };
00338 ahbcfg.b.glblintrmsk = 1;
00339 DWC_MODIFY_REG32(&core_if->core_global_regs->gahbcfg, ahbcfg.d32, 0);
00340 }
00341
00349 static void dwc_otg_enable_common_interrupts(dwc_otg_core_if_t * core_if)
00350 {
00351 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
00352 gintmsk_data_t intr_mask = {.d32 = 0 };
00353
00354
00355 DWC_WRITE_REG32(&global_regs->gotgint, 0xFFFFFFFF);
00356
00357
00358 DWC_WRITE_REG32(&global_regs->gintsts, 0xFFFFFFFF);
00359
00360
00361
00362
00363 intr_mask.b.modemismatch = 1;
00364 intr_mask.b.otgintr = 1;
00365
00366 if (!core_if->dma_enable) {
00367 intr_mask.b.rxstsqlvl = 1;
00368 }
00369
00370 intr_mask.b.conidstschng = 1;
00371 intr_mask.b.wkupintr = 1;
00372 intr_mask.b.disconnect = 0;
00373 intr_mask.b.usbsuspend = 1;
00374 intr_mask.b.sessreqintr = 1;
00375 #ifdef CONFIG_USB_DWC_OTG_LPM
00376 if (core_if->core_params->lpm_enable) {
00377 intr_mask.b.lpmtranrcvd = 1;
00378 }
00379 #endif
00380 DWC_WRITE_REG32(&global_regs->gintmsk, intr_mask.d32);
00381 }
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391 int dwc_otg_device_hibernation_restore(dwc_otg_core_if_t * core_if,
00392 int rem_wakeup, int reset)
00393 {
00394 gpwrdn_data_t gpwrdn = {.d32 = 0 };
00395 pcgcctl_data_t pcgcctl = {.d32 = 0 };
00396 dctl_data_t dctl = {.d32 = 0 };
00397
00398 int timeout = 2000;
00399
00400 if (!core_if->hibernation_suspend) {
00401 DWC_PRINTF("Already exited from Hibernation\n");
00402 return 1;
00403 }
00404
00405 DWC_DEBUGPL(DBG_PCD, "%s called\n", __FUNCTION__);
00406
00407 gpwrdn.b.pwrdnswtch = 1;
00408 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00409 dwc_udelay(10);
00410
00411
00412 gpwrdn.d32 = 0;
00413 gpwrdn.b.pwrdnrstn = 1;
00414 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00415 dwc_udelay(10);
00416
00417
00418 gpwrdn.d32 = 0;
00419 gpwrdn.b.restore = 1;
00420 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
00421 dwc_udelay(10);
00422
00423
00424 gpwrdn.d32 = 0;
00425 gpwrdn.b.pwrdnclmp = 1;
00426 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00427
00428 if (rem_wakeup) {
00429 dwc_udelay(70);
00430 }
00431
00432
00433 gpwrdn.d32 = 0;
00434 gpwrdn.b.pwrdnrstn = 1;
00435 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
00436 dwc_udelay(10);
00437
00438
00439 gpwrdn.d32 = 0;
00440 gpwrdn.b.pmuintsel = 1;
00441 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00442
00443
00444 gpwrdn.d32 = 0;
00445 gpwrdn.b.connect_det_msk = 1;
00446 gpwrdn.b.srp_det_msk = 1;
00447 gpwrdn.b.disconn_det_msk = 1;
00448 gpwrdn.b.rst_det_msk = 1;
00449 gpwrdn.b.lnstchng_msk = 1;
00450 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00451
00452
00453 core_if->hibernation_suspend = 0;
00454
00455
00456
00457
00458
00459 restore_essential_regs(core_if, rem_wakeup, 0);
00460
00461
00462
00463
00464
00465 dwc_udelay(10);
00466
00467 if (core_if->hibernation_suspend == 0) {
00468
00469
00470
00471
00472 do {
00473 gintsts_data_t gintsts;
00474 gintsts.d32 =
00475 DWC_READ_REG32(&core_if->core_global_regs->gintsts);
00476 if (gintsts.b.restoredone) {
00477 gintsts.d32 = 0;
00478 gintsts.b.restoredone = 1;
00479 DWC_WRITE_REG32(&core_if->core_global_regs->
00480 gintsts, gintsts.d32);
00481 DWC_PRINTF("Restore Done Interrupt seen\n");
00482 break;
00483 }
00484 dwc_udelay(10);
00485 } while (--timeout);
00486 if (!timeout) {
00487 DWC_PRINTF("Restore Done interrupt wasn't generated here\n");
00488 }
00489 }
00490
00491 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
00492
00493
00494 gpwrdn.d32 = 0;
00495 gpwrdn.b.restore = 1;
00496 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00497 dwc_udelay(10);
00498
00499 if (!rem_wakeup) {
00500 pcgcctl.d32 = 0;
00501 pcgcctl.b.rstpdwnmodule = 1;
00502 DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32, 0);
00503 }
00504
00505
00506 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg,
00507 core_if->gr_backup->gusbcfg_local);
00508 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg,
00509 core_if->dr_backup->dcfg);
00510
00511
00512 gpwrdn.d32 = 0;
00513 gpwrdn.b.pmuactv = 1;
00514 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00515 dwc_udelay(10);
00516
00517 if (!rem_wakeup) {
00518
00519 dctl.b.pwronprgdone = 1;
00520 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, 0, dctl.d32);
00521 } else {
00522
00523 dctl.d32 = core_if->dr_backup->dctl;
00524 dctl.b.rmtwkupsig = 1;
00525 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32);
00526 }
00527
00528 dwc_mdelay(2);
00529
00530 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
00531
00532
00533 dwc_otg_restore_global_regs(core_if);
00534
00535 dwc_otg_restore_dev_regs(core_if, rem_wakeup);
00536
00537 if (rem_wakeup) {
00538 dwc_mdelay(7);
00539 dctl.d32 = 0;
00540 dctl.b.rmtwkupsig = 1;
00541 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32, 0);
00542 }
00543
00544 core_if->hibernation_suspend = 0;
00545
00546 core_if->lx_state = DWC_OTG_L0;
00547 DWC_PRINTF("Hibernation recovery completes here\n");
00548
00549 return 1;
00550 }
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560 int dwc_otg_host_hibernation_restore(dwc_otg_core_if_t * core_if,
00561 int rem_wakeup, int reset)
00562 {
00563 gpwrdn_data_t gpwrdn = {.d32 = 0 };
00564 hprt0_data_t hprt0 = {.d32 = 0 };
00565
00566 int timeout = 2000;
00567
00568 DWC_DEBUGPL(DBG_HCD, "%s called\n", __FUNCTION__);
00569
00570 gpwrdn.b.pwrdnswtch = 1;
00571 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00572 dwc_udelay(10);
00573
00574
00575 gpwrdn.d32 = 0;
00576 gpwrdn.b.pwrdnrstn = 1;
00577 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00578 dwc_udelay(10);
00579
00580
00581 gpwrdn.d32 = 0;
00582 gpwrdn.b.restore = 1;
00583 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
00584 dwc_udelay(10);
00585
00586
00587 gpwrdn.d32 = 0;
00588 gpwrdn.b.pwrdnclmp = 1;
00589 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00590
00591 if (!rem_wakeup) {
00592 dwc_udelay(50);
00593 }
00594
00595
00596 gpwrdn.d32 = 0;
00597 gpwrdn.b.pwrdnrstn = 1;
00598 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
00599 dwc_udelay(10);
00600
00601
00602 gpwrdn.d32 = 0;
00603 gpwrdn.b.pmuintsel = 1;
00604 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00605
00606 gpwrdn.d32 = 0;
00607 gpwrdn.b.connect_det_msk = 1;
00608 gpwrdn.b.srp_det_msk = 1;
00609 gpwrdn.b.disconn_det_msk = 1;
00610 gpwrdn.b.rst_det_msk = 1;
00611 gpwrdn.b.lnstchng_msk = 1;
00612 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00613
00614
00615 core_if->hibernation_suspend = 0;
00616
00617
00618 restore_essential_regs(core_if, rem_wakeup, 1);
00619
00620
00621
00622 dwc_udelay(10);
00623
00624 if (core_if->hibernation_suspend == 0) {
00625
00626
00627
00628 do {
00629 gintsts_data_t gintsts;
00630 gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
00631 if (gintsts.b.restoredone) {
00632 gintsts.d32 = 0;
00633 gintsts.b.restoredone = 1;
00634 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
00635 DWC_DEBUGPL(DBG_HCD,"Restore Done Interrupt seen\n");
00636 break;
00637 }
00638 dwc_udelay(10);
00639 } while (--timeout);
00640 if (!timeout) {
00641 DWC_WARN("Restore Done interrupt wasn't generated\n");
00642 }
00643 }
00644
00645
00646 core_if->hibernation_suspend = 0;
00647
00648
00649
00650
00651 dwc_mdelay(100);
00652
00653
00654 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
00655
00656
00657 gpwrdn.d32 = 0;
00658 gpwrdn.b.restore = 1;
00659 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00660 dwc_udelay(10);
00661
00662
00663 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg,
00664 core_if->gr_backup->gusbcfg_local);
00665 DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hcfg,
00666 core_if->hr_backup->hcfg_local);
00667
00668
00669 gpwrdn.d32 = 0;
00670 gpwrdn.b.pmuactv = 1;
00671 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00672 dwc_udelay(10);
00673
00674
00675 hprt0.d32 = core_if->hr_backup->hprt0_local;
00676 hprt0.b.prtpwr = 1;
00677 hprt0.b.prtena = 0;
00678 hprt0.b.prtsusp = 0;
00679 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
00680
00681 DWC_PRINTF("Resume Starts Now\n");
00682 if (!reset) {
00683 hprt0.d32 = core_if->hr_backup->hprt0_local;
00684 hprt0.b.prtres = 1;
00685 hprt0.b.prtpwr = 1;
00686 hprt0.b.prtena = 0;
00687 hprt0.b.prtsusp = 0;
00688 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
00689
00690 if (!rem_wakeup)
00691 hprt0.b.prtres = 0;
00692
00693 dwc_mdelay(100);
00694 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
00695
00696 } else {
00697 hprt0.d32 = core_if->hr_backup->hprt0_local;
00698 hprt0.b.prtrst = 1;
00699 hprt0.b.prtpwr = 1;
00700 hprt0.b.prtena = 0;
00701 hprt0.b.prtsusp = 0;
00702 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
00703
00704 dwc_mdelay(60);
00705 hprt0.b.prtrst = 0;
00706 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
00707 }
00708
00709 hprt0.d32 = dwc_otg_read_hprt0(core_if);
00710 hprt0.b.prtconndet = 1;
00711 hprt0.b.prtenchng = 1;
00712 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
00713
00714
00715 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
00716
00717
00718 dwc_otg_restore_global_regs(core_if);
00719
00720 dwc_otg_restore_host_regs(core_if, reset);
00721
00722
00723 core_if->lx_state = DWC_OTG_L0;
00724 DWC_PRINTF("Hibernation recovery is complete here\n");
00725 return 0;
00726 }
00727
00729 int dwc_otg_save_global_regs(dwc_otg_core_if_t * core_if)
00730 {
00731 struct dwc_otg_global_regs_backup *gr;
00732 int i;
00733
00734 gr = core_if->gr_backup;
00735 if (!gr) {
00736 gr = DWC_ALLOC(sizeof(*gr));
00737 if (!gr) {
00738 return -DWC_E_NO_MEMORY;
00739 }
00740 core_if->gr_backup = gr;
00741 }
00742
00743 gr->gotgctl_local = DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
00744 gr->gintmsk_local = DWC_READ_REG32(&core_if->core_global_regs->gintmsk);
00745 gr->gahbcfg_local = DWC_READ_REG32(&core_if->core_global_regs->gahbcfg);
00746 gr->gusbcfg_local = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
00747 gr->grxfsiz_local = DWC_READ_REG32(&core_if->core_global_regs->grxfsiz);
00748 gr->gnptxfsiz_local = DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz);
00749 gr->hptxfsiz_local = DWC_READ_REG32(&core_if->core_global_regs->hptxfsiz);
00750 #ifdef CONFIG_USB_DWC_OTG_LPM
00751 gr->glpmcfg_local = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
00752 #endif
00753 gr->gi2cctl_local = DWC_READ_REG32(&core_if->core_global_regs->gi2cctl);
00754 gr->pcgcctl_local = DWC_READ_REG32(core_if->pcgcctl);
00755 gr->gdfifocfg_local =
00756 DWC_READ_REG32(&core_if->core_global_regs->gdfifocfg);
00757 for (i = 0; i < MAX_EPS_CHANNELS; i++) {
00758 gr->dtxfsiz_local[i] =
00759 DWC_READ_REG32(&(core_if->core_global_regs->dtxfsiz[i]));
00760 }
00761
00762 DWC_DEBUGPL(DBG_ANY, "===========Backing Global registers==========\n");
00763 DWC_DEBUGPL(DBG_ANY, "Backed up gotgctl = %08x\n", gr->gotgctl_local);
00764 DWC_DEBUGPL(DBG_ANY, "Backed up gintmsk = %08x\n", gr->gintmsk_local);
00765 DWC_DEBUGPL(DBG_ANY, "Backed up gahbcfg = %08x\n", gr->gahbcfg_local);
00766 DWC_DEBUGPL(DBG_ANY, "Backed up gusbcfg = %08x\n", gr->gusbcfg_local);
00767 DWC_DEBUGPL(DBG_ANY, "Backed up grxfsiz = %08x\n", gr->grxfsiz_local);
00768 DWC_DEBUGPL(DBG_ANY, "Backed up gnptxfsiz = %08x\n",
00769 gr->gnptxfsiz_local);
00770 DWC_DEBUGPL(DBG_ANY, "Backed up hptxfsiz = %08x\n",
00771 gr->hptxfsiz_local);
00772 #ifdef CONFIG_USB_DWC_OTG_LPM
00773 DWC_DEBUGPL(DBG_ANY, "Backed up glpmcfg = %08x\n", gr->glpmcfg_local);
00774 #endif
00775 DWC_DEBUGPL(DBG_ANY, "Backed up gi2cctl = %08x\n", gr->gi2cctl_local);
00776 DWC_DEBUGPL(DBG_ANY, "Backed up pcgcctl = %08x\n", gr->pcgcctl_local);
00777 DWC_DEBUGPL(DBG_ANY,"Backed up gdfifocfg = %08x\n",gr->gdfifocfg_local);
00778
00779 return 0;
00780 }
00781
00783 int dwc_otg_save_gintmsk_reg(dwc_otg_core_if_t * core_if)
00784 {
00785 struct dwc_otg_global_regs_backup *gr;
00786
00787 gr = core_if->gr_backup;
00788 if (!gr) {
00789 gr = DWC_ALLOC(sizeof(*gr));
00790 if (!gr) {
00791 return -DWC_E_NO_MEMORY;
00792 }
00793 core_if->gr_backup = gr;
00794 }
00795
00796 gr->gintmsk_local = DWC_READ_REG32(&core_if->core_global_regs->gintmsk);
00797
00798 DWC_DEBUGPL(DBG_ANY,"=============Backing GINTMSK registers============\n");
00799 DWC_DEBUGPL(DBG_ANY, "Backed up gintmsk = %08x\n", gr->gintmsk_local);
00800
00801 return 0;
00802 }
00803
00804 int dwc_otg_save_dev_regs(dwc_otg_core_if_t * core_if)
00805 {
00806 struct dwc_otg_dev_regs_backup *dr;
00807 int i;
00808
00809 dr = core_if->dr_backup;
00810 if (!dr) {
00811 dr = DWC_ALLOC(sizeof(*dr));
00812 if (!dr) {
00813 return -DWC_E_NO_MEMORY;
00814 }
00815 core_if->dr_backup = dr;
00816 }
00817
00818 dr->dcfg = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
00819 dr->dctl = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl);
00820 dr->daintmsk =
00821 DWC_READ_REG32(&core_if->dev_if->dev_global_regs->daintmsk);
00822 dr->diepmsk =
00823 DWC_READ_REG32(&core_if->dev_if->dev_global_regs->diepmsk);
00824 dr->doepmsk =
00825 DWC_READ_REG32(&core_if->dev_if->dev_global_regs->doepmsk);
00826
00827 for (i = 0; i < core_if->dev_if->num_in_eps; ++i) {
00828 dr->diepctl[i] =
00829 DWC_READ_REG32(&core_if->dev_if->in_ep_regs[i]->diepctl);
00830 dr->dieptsiz[i] =
00831 DWC_READ_REG32(&core_if->dev_if->in_ep_regs[i]->dieptsiz);
00832 dr->diepdma[i] =
00833 DWC_READ_REG32(&core_if->dev_if->in_ep_regs[i]->diepdma);
00834 }
00835
00836 DWC_DEBUGPL(DBG_ANY,
00837 "=============Backing Host registers==============\n");
00838 DWC_DEBUGPL(DBG_ANY, "Backed up dcfg = %08x\n", dr->dcfg);
00839 DWC_DEBUGPL(DBG_ANY, "Backed up dctl = %08x\n", dr->dctl);
00840 DWC_DEBUGPL(DBG_ANY, "Backed up daintmsk = %08x\n",
00841 dr->daintmsk);
00842 DWC_DEBUGPL(DBG_ANY, "Backed up diepmsk = %08x\n", dr->diepmsk);
00843 DWC_DEBUGPL(DBG_ANY, "Backed up doepmsk = %08x\n", dr->doepmsk);
00844 for (i = 0; i < core_if->dev_if->num_in_eps; ++i) {
00845 DWC_DEBUGPL(DBG_ANY, "Backed up diepctl[%d] = %08x\n", i,
00846 dr->diepctl[i]);
00847 DWC_DEBUGPL(DBG_ANY, "Backed up dieptsiz[%d] = %08x\n",
00848 i, dr->dieptsiz[i]);
00849 DWC_DEBUGPL(DBG_ANY, "Backed up diepdma[%d] = %08x\n", i,
00850 dr->diepdma[i]);
00851 }
00852
00853 return 0;
00854 }
00855
00856 int dwc_otg_save_host_regs(dwc_otg_core_if_t * core_if)
00857 {
00858 struct dwc_otg_host_regs_backup *hr;
00859 int i;
00860
00861 hr = core_if->hr_backup;
00862 if (!hr) {
00863 hr = DWC_ALLOC(sizeof(*hr));
00864 if (!hr) {
00865 return -DWC_E_NO_MEMORY;
00866 }
00867 core_if->hr_backup = hr;
00868 }
00869
00870 hr->hcfg_local =
00871 DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg);
00872 hr->haintmsk_local =
00873 DWC_READ_REG32(&core_if->host_if->host_global_regs->haintmsk);
00874 for (i = 0; i < dwc_otg_get_param_host_channels(core_if); ++i) {
00875 hr->hcintmsk_local[i] =
00876 DWC_READ_REG32(&core_if->host_if->hc_regs[i]->hcintmsk);
00877 }
00878 hr->hprt0_local = DWC_READ_REG32(core_if->host_if->hprt0);
00879 hr->hfir_local =
00880 DWC_READ_REG32(&core_if->host_if->host_global_regs->hfir);
00881
00882 DWC_DEBUGPL(DBG_ANY,
00883 "=============Backing Host registers===============\n");
00884 DWC_DEBUGPL(DBG_ANY, "Backed up hcfg = %08x\n",
00885 hr->hcfg_local);
00886 DWC_DEBUGPL(DBG_ANY, "Backed up haintmsk = %08x\n", hr->haintmsk_local);
00887 for (i = 0; i < dwc_otg_get_param_host_channels(core_if); ++i) {
00888 DWC_DEBUGPL(DBG_ANY, "Backed up hcintmsk[%02d]=%08x\n", i,
00889 hr->hcintmsk_local[i]);
00890 }
00891 DWC_DEBUGPL(DBG_ANY, "Backed up hprt0 = %08x\n",
00892 hr->hprt0_local);
00893 DWC_DEBUGPL(DBG_ANY, "Backed up hfir = %08x\n",
00894 hr->hfir_local);
00895
00896 return 0;
00897 }
00898
00899 int dwc_otg_restore_global_regs(dwc_otg_core_if_t *core_if)
00900 {
00901 struct dwc_otg_global_regs_backup *gr;
00902 int i;
00903
00904 gr = core_if->gr_backup;
00905 if (!gr) {
00906 return -DWC_E_INVALID;
00907 }
00908
00909 DWC_WRITE_REG32(&core_if->core_global_regs->gotgctl, gr->gotgctl_local);
00910 DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, gr->gintmsk_local);
00911 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gr->gusbcfg_local);
00912 DWC_WRITE_REG32(&core_if->core_global_regs->gahbcfg, gr->gahbcfg_local);
00913 DWC_WRITE_REG32(&core_if->core_global_regs->grxfsiz, gr->grxfsiz_local);
00914 DWC_WRITE_REG32(&core_if->core_global_regs->gnptxfsiz,
00915 gr->gnptxfsiz_local);
00916 DWC_WRITE_REG32(&core_if->core_global_regs->hptxfsiz,
00917 gr->hptxfsiz_local);
00918 DWC_WRITE_REG32(&core_if->core_global_regs->gdfifocfg,
00919 gr->gdfifocfg_local);
00920 for (i = 0; i < MAX_EPS_CHANNELS; i++) {
00921 DWC_WRITE_REG32(&core_if->core_global_regs->dtxfsiz[i],
00922 gr->dtxfsiz_local[i]);
00923 }
00924
00925 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
00926 DWC_WRITE_REG32(core_if->host_if->hprt0, 0x0000100A);
00927 DWC_WRITE_REG32(&core_if->core_global_regs->gahbcfg,
00928 (gr->gahbcfg_local));
00929 return 0;
00930 }
00931
00932 int dwc_otg_restore_dev_regs(dwc_otg_core_if_t * core_if, int rem_wakeup)
00933 {
00934 struct dwc_otg_dev_regs_backup *dr;
00935 int i;
00936
00937 dr = core_if->dr_backup;
00938
00939 if (!dr) {
00940 return -DWC_E_INVALID;
00941 }
00942
00943 if (!rem_wakeup)
00944 {
00945 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl, dr->dctl);
00946 }
00947
00948 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->daintmsk, dr->daintmsk);
00949 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->diepmsk, dr->diepmsk);
00950 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->doepmsk, dr->doepmsk);
00951
00952 for (i = 0; i < core_if->dev_if->num_in_eps; ++i) {
00953 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[i]->diepctl, dr->diepctl[i]);
00954 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[i]->dieptsiz, dr->dieptsiz[i]);
00955 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[i]->diepdma, dr->diepdma[i]);
00956 }
00957
00958 return 0;
00959 }
00960
00961 int dwc_otg_restore_host_regs(dwc_otg_core_if_t * core_if, int reset)
00962 {
00963 struct dwc_otg_host_regs_backup *hr;
00964 int i;
00965 hr = core_if->hr_backup;
00966
00967 if (!hr) {
00968 return -DWC_E_INVALID;
00969 }
00970
00971 DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hcfg, hr->hcfg_local);
00972
00973
00974
00975
00976
00977 DWC_WRITE_REG32(&core_if->host_if->host_global_regs->haintmsk,
00978 hr->haintmsk_local);
00979 for (i = 0; i < dwc_otg_get_param_host_channels(core_if); ++i) {
00980 DWC_WRITE_REG32(&core_if->host_if->hc_regs[i]->hcintmsk,
00981 hr->hcintmsk_local[i]);
00982 }
00983
00984 return 0;
00985 }
00986
00987 int restore_lpm_i2c_regs(dwc_otg_core_if_t * core_if)
00988 {
00989 struct dwc_otg_global_regs_backup *gr;
00990
00991 gr = core_if->gr_backup;
00992
00993
00994 #ifdef CONFIG_USB_DWC_OTG_LPM
00995 DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg, gr->glpmcfg_local);
00996 #endif
00997 DWC_WRITE_REG32(&core_if->core_global_regs->gi2cctl, gr->gi2cctl_local);
00998
00999 return 0;
01000 }
01001
01002 int restore_essential_regs(dwc_otg_core_if_t * core_if, int rmode, int is_host)
01003 {
01004 struct dwc_otg_global_regs_backup *gr;
01005 pcgcctl_data_t pcgcctl = {.d32 = 0 };
01006 gahbcfg_data_t gahbcfg = {.d32 = 0 };
01007 gusbcfg_data_t gusbcfg = {.d32 = 0 };
01008 gintmsk_data_t gintmsk = {.d32 = 0 };
01009
01010
01011 restore_lpm_i2c_regs(core_if);
01012
01013
01014 DWC_WRITE_REG32(core_if->pcgcctl, 0x00000000);
01015
01016 gr = core_if->gr_backup;
01017
01018 DWC_WRITE_REG32(core_if->pcgcctl,
01019 ((gr->pcgcctl_local & 0xffffc000) | 0x00020000));
01020
01021
01022 gahbcfg.d32 = gr->gahbcfg_local;
01023 gahbcfg.b.glblintrmsk = 1;
01024 DWC_WRITE_REG32(&core_if->core_global_regs->gahbcfg, gahbcfg.d32);
01025
01026
01027 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
01028
01029
01030 gintmsk.b.restoredone = 1;
01031 DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, gintmsk.d32);
01032
01033
01034 gusbcfg.d32 = core_if->gr_backup->gusbcfg_local;
01035 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gusbcfg.d32);
01036
01037 if (is_host) {
01038 hcfg_data_t hcfg = {.d32 = 0 };
01039 hcfg.d32 = core_if->hr_backup->hcfg_local;
01040 DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hcfg,
01041 hcfg.d32);
01042
01043
01044 pcgcctl.d32 = gr->pcgcctl_local & 0xffffc000;
01045 pcgcctl.d32 = gr->pcgcctl_local | 0x00020000;
01046
01047 if (rmode)
01048 pcgcctl.b.restoremode = 1;
01049 DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
01050 dwc_udelay(10);
01051
01052
01053 pcgcctl.d32 = gr->pcgcctl_local | 0xffffc000;
01054 pcgcctl.d32 = gr->pcgcctl_local & 0xffffc000;
01055 pcgcctl.b.ess_reg_restored = 1;
01056 if (rmode)
01057 pcgcctl.b.restoremode = 1;
01058 DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
01059 } else {
01060 dcfg_data_t dcfg = {.d32 = 0 };
01061 dcfg.d32 = core_if->dr_backup->dcfg;
01062 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg, dcfg.d32);
01063
01064
01065 pcgcctl.d32 = gr->pcgcctl_local & 0xffffc000;
01066 pcgcctl.d32 = gr->pcgcctl_local | 0x00020000;
01067 if (!rmode) {
01068 pcgcctl.d32 |= 0x208;
01069 }
01070 DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
01071 dwc_udelay(10);
01072
01073
01074 pcgcctl.d32 = gr->pcgcctl_local & 0xffffc000;
01075 pcgcctl.d32 = gr->pcgcctl_local | 0x00020000;
01076 pcgcctl.b.ess_reg_restored = 1;
01077 if (!rmode)
01078 pcgcctl.d32 |= 0x208;
01079 DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
01080 }
01081
01082 return 0;
01083 }
01084
01089 static void init_fslspclksel(dwc_otg_core_if_t * core_if)
01090 {
01091 uint32_t val;
01092 hcfg_data_t hcfg;
01093
01094 if (((core_if->hwcfg2.b.hs_phy_type == 2) &&
01095 (core_if->hwcfg2.b.fs_phy_type == 1) &&
01096 (core_if->core_params->ulpi_fs_ls)) ||
01097 (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
01098
01099 val = DWC_HCFG_48_MHZ;
01100 } else {
01101
01102 val = DWC_HCFG_30_60_MHZ;
01103 }
01104
01105 DWC_DEBUGPL(DBG_CIL, "Initializing HCFG.FSLSPClkSel to 0x%1x\n", val);
01106 hcfg.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg);
01107 hcfg.b.fslspclksel = val;
01108 DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hcfg, hcfg.d32);
01109 }
01110
01115 static void init_devspd(dwc_otg_core_if_t * core_if)
01116 {
01117 uint32_t val;
01118 dcfg_data_t dcfg;
01119
01120 if (((core_if->hwcfg2.b.hs_phy_type == 2) &&
01121 (core_if->hwcfg2.b.fs_phy_type == 1) &&
01122 (core_if->core_params->ulpi_fs_ls)) ||
01123 (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
01124
01125 val = 0x3;
01126 } else if (core_if->core_params->speed == DWC_SPEED_PARAM_FULL) {
01127
01128 val = 0x1;
01129 } else {
01130
01131 val = 0x0;
01132 }
01133
01134 DWC_DEBUGPL(DBG_CIL, "Initializing DCFG.DevSpd to 0x%1x\n", val);
01135
01136 dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
01137 dcfg.b.devspd = val;
01138 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg, dcfg.d32);
01139 }
01140
01147 static uint32_t calc_num_in_eps(dwc_otg_core_if_t * core_if)
01148 {
01149 uint32_t num_in_eps = 0;
01150 uint32_t num_eps = core_if->hwcfg2.b.num_dev_ep;
01151 uint32_t hwcfg1 = core_if->hwcfg1.d32 >> 3;
01152 uint32_t num_tx_fifos = core_if->hwcfg4.b.num_in_eps;
01153 int i;
01154
01155 for (i = 0; i < num_eps; ++i) {
01156 if (!(hwcfg1 & 0x1))
01157 num_in_eps++;
01158
01159 hwcfg1 >>= 2;
01160 }
01161
01162 if (core_if->hwcfg4.b.ded_fifo_en) {
01163 num_in_eps =
01164 (num_in_eps > num_tx_fifos) ? num_tx_fifos : num_in_eps;
01165 }
01166
01167 return num_in_eps;
01168 }
01169
01176 static uint32_t calc_num_out_eps(dwc_otg_core_if_t * core_if)
01177 {
01178 uint32_t num_out_eps = 0;
01179 uint32_t num_eps = core_if->hwcfg2.b.num_dev_ep;
01180 uint32_t hwcfg1 = core_if->hwcfg1.d32 >> 2;
01181 int i;
01182
01183 for (i = 0; i < num_eps; ++i) {
01184 if (!(hwcfg1 & 0x1))
01185 num_out_eps++;
01186
01187 hwcfg1 >>= 2;
01188 }
01189 return num_out_eps;
01190 }
01191
01199 void dwc_otg_core_init(dwc_otg_core_if_t * core_if)
01200 {
01201 int i = 0;
01202 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
01203 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
01204 gahbcfg_data_t ahbcfg = {.d32 = 0 };
01205 gusbcfg_data_t usbcfg = {.d32 = 0 };
01206 gi2cctl_data_t i2cctl = {.d32 = 0 };
01207
01208 DWC_DEBUGPL(DBG_CILV, "dwc_otg_core_init(%p)\n", core_if);
01209
01210
01211 usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
01212
01213
01214 usbcfg.b.ulpi_ext_vbus_drv =
01215 (core_if->core_params->phy_ulpi_ext_vbus ==
01216 DWC_PHY_ULPI_EXTERNAL_VBUS) ? 1 : 0;
01217
01218
01219 usbcfg.b.term_sel_dl_pulse =
01220 (core_if->core_params->ts_dline == 1) ? 1 : 0;
01221 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
01222
01223
01224 dwc_otg_core_reset(core_if);
01225
01226 core_if->adp_enable = core_if->core_params->adp_supp_enable;
01227 core_if->power_down = core_if->core_params->power_down;
01228 core_if->otg_sts = 0;
01229
01230
01231 dev_if->num_in_eps = calc_num_in_eps(core_if);
01232 dev_if->num_out_eps = calc_num_out_eps(core_if);
01233
01234 DWC_DEBUGPL(DBG_CIL, "num_dev_perio_in_ep=%d\n",
01235 core_if->hwcfg4.b.num_dev_perio_in_ep);
01236
01237 for (i = 0; i < core_if->hwcfg4.b.num_dev_perio_in_ep; i++) {
01238 dev_if->perio_tx_fifo_size[i] =
01239 DWC_READ_REG32(&global_regs->dtxfsiz[i]) >> 16;
01240 DWC_DEBUGPL(DBG_CIL, "Periodic Tx FIFO SZ #%d=0x%0x\n",
01241 i, dev_if->perio_tx_fifo_size[i]);
01242 }
01243
01244 for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) {
01245 dev_if->tx_fifo_size[i] =
01246 DWC_READ_REG32(&global_regs->dtxfsiz[i]) >> 16;
01247 DWC_DEBUGPL(DBG_CIL, "Tx FIFO SZ #%d=0x%0x\n",
01248 i, dev_if->tx_fifo_size[i]);
01249 }
01250
01251 core_if->total_fifo_size = core_if->hwcfg3.b.dfifo_depth;
01252 core_if->rx_fifo_size = DWC_READ_REG32(&global_regs->grxfsiz);
01253 core_if->nperio_tx_fifo_size =
01254 DWC_READ_REG32(&global_regs->gnptxfsiz) >> 16;
01255
01256 DWC_DEBUGPL(DBG_CIL, "Total FIFO SZ=%d\n", core_if->total_fifo_size);
01257 DWC_DEBUGPL(DBG_CIL, "Rx FIFO SZ=%d\n", core_if->rx_fifo_size);
01258 DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO SZ=%d\n",
01259 core_if->nperio_tx_fifo_size);
01260
01261
01262
01263 if ((core_if->core_params->speed == DWC_SPEED_PARAM_FULL) &&
01264 (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
01265
01266
01267
01268
01269 if (!core_if->phy_init_done) {
01270 core_if->phy_init_done = 1;
01271 DWC_DEBUGPL(DBG_CIL, "FS_PHY detected\n");
01272 usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
01273 usbcfg.b.physel = 1;
01274 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
01275
01276
01277 dwc_otg_core_reset(core_if);
01278 }
01279
01280
01281
01282
01283 if (dwc_otg_is_host_mode(core_if)) {
01284 init_fslspclksel(core_if);
01285 } else {
01286 init_devspd(core_if);
01287 }
01288
01289 if (core_if->core_params->i2c_enable) {
01290 DWC_DEBUGPL(DBG_CIL, "FS_PHY Enabling I2c\n");
01291
01292 usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
01293 usbcfg.b.otgutmifssel = 1;
01294 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
01295
01296
01297 i2cctl.d32 = DWC_READ_REG32(&global_regs->gi2cctl);
01298 i2cctl.b.i2cdevaddr = 1;
01299 i2cctl.b.i2cen = 0;
01300 DWC_WRITE_REG32(&global_regs->gi2cctl, i2cctl.d32);
01301 i2cctl.b.i2cen = 1;
01302 DWC_WRITE_REG32(&global_regs->gi2cctl, i2cctl.d32);
01303 }
01304
01305 }
01306 else {
01307
01308 if (!core_if->phy_init_done) {
01309 core_if->phy_init_done = 1;
01310
01311
01312
01313
01314 if (core_if->core_params->phy_type == 2) {
01315
01316 usbcfg.b.ulpi_utmi_sel = 1;
01317 usbcfg.b.phyif = 0;
01318 usbcfg.b.ddrsel =
01319 core_if->core_params->phy_ulpi_ddr;
01320 } else if (core_if->core_params->phy_type == 1) {
01321
01322 usbcfg.b.ulpi_utmi_sel = 0;
01323 if (core_if->core_params->phy_utmi_width == 16) {
01324 usbcfg.b.phyif = 1;
01325
01326 } else {
01327 usbcfg.b.phyif = 0;
01328 }
01329 } else {
01330 DWC_ERROR("FS PHY TYPE\n");
01331 }
01332 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
01333
01334 dwc_otg_core_reset(core_if);
01335 }
01336 }
01337
01338 if ((core_if->hwcfg2.b.hs_phy_type == 2) &&
01339 (core_if->hwcfg2.b.fs_phy_type == 1) &&
01340 (core_if->core_params->ulpi_fs_ls)) {
01341 DWC_DEBUGPL(DBG_CIL, "Setting ULPI FSLS\n");
01342 usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
01343 usbcfg.b.ulpi_fsls = 1;
01344 usbcfg.b.ulpi_clk_sus_m = 1;
01345 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
01346 } else {
01347 usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
01348 usbcfg.b.ulpi_fsls = 0;
01349 usbcfg.b.ulpi_clk_sus_m = 0;
01350 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
01351 }
01352
01353
01354 switch (core_if->hwcfg2.b.architecture) {
01355
01356 case DWC_SLAVE_ONLY_ARCH:
01357 DWC_DEBUGPL(DBG_CIL, "Slave Only Mode\n");
01358 ahbcfg.b.nptxfemplvl_txfemplvl =
01359 DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
01360 ahbcfg.b.ptxfemplvl = DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
01361 core_if->dma_enable = 0;
01362 core_if->dma_desc_enable = 0;
01363 break;
01364
01365 case DWC_EXT_DMA_ARCH:
01366 DWC_DEBUGPL(DBG_CIL, "External DMA Mode\n");
01367 {
01368 uint8_t brst_sz = core_if->core_params->dma_burst_size;
01369 ahbcfg.b.hburstlen = 0;
01370 while (brst_sz > 1) {
01371 ahbcfg.b.hburstlen++;
01372 brst_sz >>= 1;
01373 }
01374 }
01375 core_if->dma_enable = (core_if->core_params->dma_enable != 0);
01376 core_if->dma_desc_enable =
01377 (core_if->core_params->dma_desc_enable != 0);
01378 break;
01379
01380 case DWC_INT_DMA_ARCH:
01381 DWC_DEBUGPL(DBG_CIL, "Internal DMA Mode\n");
01382
01383
01384 ahbcfg.b.hburstlen = DWC_GAHBCFG_INT_DMA_BURST_INCR4;
01385 core_if->dma_enable = (core_if->core_params->dma_enable != 0);
01386 core_if->dma_desc_enable =
01387 (core_if->core_params->dma_desc_enable != 0);
01388 break;
01389
01390 }
01391 if (core_if->dma_enable) {
01392 if (core_if->dma_desc_enable) {
01393 DWC_PRINTF("Using Descriptor DMA mode\n");
01394 } else {
01395 DWC_PRINTF("Using Buffer DMA mode\n");
01396
01397 }
01398 } else {
01399 DWC_PRINTF("Using Slave mode\n");
01400 core_if->dma_desc_enable = 0;
01401 }
01402
01403 if (core_if->core_params->ahb_single) {
01404 ahbcfg.b.ahbsingle = 1;
01405 }
01406
01407 ahbcfg.b.dmaenable = core_if->dma_enable;
01408 DWC_WRITE_REG32(&global_regs->gahbcfg, ahbcfg.d32);
01409
01410 core_if->en_multiple_tx_fifo = core_if->hwcfg4.b.ded_fifo_en;
01411
01412 core_if->pti_enh_enable = core_if->core_params->pti_enable != 0;
01413 core_if->multiproc_int_enable = core_if->core_params->mpi_enable;
01414 DWC_PRINTF("Periodic Transfer Interrupt Enhancement - %s\n",
01415 ((core_if->pti_enh_enable) ? "enabled" : "disabled"));
01416 DWC_PRINTF("Multiprocessor Interrupt Enhancement - %s\n",
01417 ((core_if->multiproc_int_enable) ? "enabled" : "disabled"));
01418
01419
01420
01421
01422 usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
01423
01424 switch (core_if->hwcfg2.b.op_mode) {
01425 case DWC_MODE_HNP_SRP_CAPABLE:
01426 usbcfg.b.hnpcap = (core_if->core_params->otg_cap ==
01427 DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE);
01428 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
01429 DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
01430 break;
01431
01432 case DWC_MODE_SRP_ONLY_CAPABLE:
01433 usbcfg.b.hnpcap = 0;
01434 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
01435 DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
01436 break;
01437
01438 case DWC_MODE_NO_HNP_SRP_CAPABLE:
01439 usbcfg.b.hnpcap = 0;
01440 usbcfg.b.srpcap = 0;
01441 break;
01442
01443 case DWC_MODE_SRP_CAPABLE_DEVICE:
01444 usbcfg.b.hnpcap = 0;
01445 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
01446 DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
01447 break;
01448
01449 case DWC_MODE_NO_SRP_CAPABLE_DEVICE:
01450 usbcfg.b.hnpcap = 0;
01451 usbcfg.b.srpcap = 0;
01452 break;
01453
01454 case DWC_MODE_SRP_CAPABLE_HOST:
01455 usbcfg.b.hnpcap = 0;
01456 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
01457 DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
01458 break;
01459
01460 case DWC_MODE_NO_SRP_CAPABLE_HOST:
01461 usbcfg.b.hnpcap = 0;
01462 usbcfg.b.srpcap = 0;
01463 break;
01464 }
01465
01466 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
01467
01468 #ifdef CONFIG_USB_DWC_OTG_LPM
01469 if (core_if->core_params->lpm_enable) {
01470 glpmcfg_data_t lpmcfg = {.d32 = 0 };
01471
01472
01473 lpmcfg.b.lpm_cap_en = 1;
01474
01475
01476 lpmcfg.b.appl_resp = 1;
01477
01478
01479 lpmcfg.b.retry_count = 3;
01480
01481 DWC_MODIFY_REG32(&core_if->core_global_regs->glpmcfg,
01482 0, lpmcfg.d32);
01483
01484 }
01485 #endif
01486 if (core_if->core_params->ic_usb_cap) {
01487 gusbcfg_data_t gusbcfg = {.d32 = 0 };
01488 gusbcfg.b.ic_usb_cap = 1;
01489 DWC_MODIFY_REG32(&core_if->core_global_regs->gusbcfg,
01490 0, gusbcfg.d32);
01491 }
01492 {
01493 gotgctl_data_t gotgctl = {.d32 = 0 };
01494 gotgctl.b.otgver = core_if->core_params->otg_ver;
01495 DWC_MODIFY_REG32(&core_if->core_global_regs->gotgctl, 0,
01496 gotgctl.d32);
01497
01498 core_if->otg_ver = core_if->core_params->otg_ver;
01499 DWC_PRINTF("OTG VER PARAM: %d, OTG VER FLAG: %d\n",
01500 core_if->core_params->otg_ver, core_if->otg_ver);
01501 }
01502
01503
01504
01505 dwc_otg_enable_common_interrupts(core_if);
01506
01507
01508
01509 if (dwc_otg_is_host_mode(core_if)) {
01510 DWC_DEBUGPL(DBG_ANY, "Host Mode\n");
01511 core_if->op_state = A_HOST;
01512 } else {
01513 DWC_DEBUGPL(DBG_ANY, "Device Mode\n");
01514 core_if->op_state = B_PERIPHERAL;
01515 #ifdef DWC_DEVICE_ONLY
01516 dwc_otg_core_dev_init(core_if);
01517 #endif
01518 }
01519 }
01520
01526 void dwc_otg_enable_device_interrupts(dwc_otg_core_if_t * core_if)
01527 {
01528 gintmsk_data_t intr_mask = {.d32 = 0 };
01529 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
01530
01531 DWC_DEBUGPL(DBG_CIL, "%s()\n", __func__);
01532
01533
01534 DWC_WRITE_REG32(&global_regs->gintmsk, 0);
01535
01536
01537 DWC_WRITE_REG32(&global_regs->gintsts, 0xFFFFFFFF);
01538
01539
01540 dwc_otg_enable_common_interrupts(core_if);
01541
01542
01543 intr_mask.b.usbreset = 1;
01544 intr_mask.b.enumdone = 1;
01545
01546 intr_mask.b.disconnect = 0;
01547
01548 if (!core_if->multiproc_int_enable) {
01549 intr_mask.b.inepintr = 1;
01550 intr_mask.b.outepintr = 1;
01551 }
01552
01553 intr_mask.b.erlysuspend = 1;
01554
01555 if (core_if->en_multiple_tx_fifo == 0) {
01556 intr_mask.b.epmismatch = 1;
01557 }
01558
01559
01560 intr_mask.b.incomplisoin = 1;
01561
01562
01563
01564 #if 0
01565 #ifdef DWC_UTE_PER_IO
01566 if (core_if->dma_enable) {
01567 if (core_if->dma_desc_enable) {
01568 dctl_data_t dctl1 = {.d32 = 0 };
01569 dctl1.b.ifrmnum = 1;
01570 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->
01571 dctl, 0, dctl1.d32);
01572 DWC_DEBUG("----Enabled Ignore frame number (0x%08x)",
01573 DWC_READ_REG32(&core_if->dev_if->
01574 dev_global_regs->dctl));
01575 }
01576 }
01577 #endif
01578 #endif
01579 #ifdef DWC_EN_ISOC
01580 if (core_if->dma_enable) {
01581 if (core_if->dma_desc_enable == 0) {
01582 if (core_if->pti_enh_enable) {
01583 dctl_data_t dctl = {.d32 = 0 };
01584 dctl.b.ifrmnum = 1;
01585 DWC_MODIFY_REG32(&core_if->
01586 dev_if->dev_global_regs->dctl,
01587 0, dctl.d32);
01588 } else {
01589 intr_mask.b.incomplisoin = 1;
01590 intr_mask.b.incomplisoout = 1;
01591 }
01592 }
01593 } else {
01594 intr_mask.b.incomplisoin = 1;
01595 intr_mask.b.incomplisoout = 1;
01596 }
01597 #endif
01598
01600 #ifdef USE_PERIODIC_EP
01601 intr_mask.b.isooutdrop = 1;
01602 intr_mask.b.eopframe = 1;
01603 intr_mask.b.incomplisoin = 1;
01604 intr_mask.b.incomplisoout = 1;
01605 #endif
01606
01607 DWC_MODIFY_REG32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
01608
01609 DWC_DEBUGPL(DBG_CIL, "%s() gintmsk=%0x\n", __func__,
01610 DWC_READ_REG32(&global_regs->gintmsk));
01611 }
01612
01620 void dwc_otg_core_dev_init(dwc_otg_core_if_t * core_if)
01621 {
01622 int i;
01623 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
01624 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
01625 dwc_otg_core_params_t *params = core_if->core_params;
01626 dcfg_data_t dcfg = {.d32 = 0 };
01627 depctl_data_t diepctl = {.d32 = 0 };
01628 grstctl_t resetctl = {.d32 = 0 };
01629 uint32_t rx_fifo_size;
01630 fifosize_data_t nptxfifosize;
01631 fifosize_data_t txfifosize;
01632 dthrctl_data_t dthrctl;
01633 fifosize_data_t ptxfifosize;
01634 uint16_t rxfsiz, nptxfsiz;
01635 gdfifocfg_data_t gdfifocfg = {.d32 = 0 };
01636 hwcfg3_data_t hwcfg3 = {.d32 = 0 };
01637
01638
01639 DWC_WRITE_REG32(core_if->pcgcctl, 0);
01640
01641
01642 init_devspd(core_if);
01643 dcfg.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dcfg);
01644 dcfg.b.descdma = (core_if->dma_desc_enable) ? 1 : 0;
01645 dcfg.b.perfrint = DWC_DCFG_FRAME_INTERVAL_80;
01646
01647 if (core_if->core_params->dev_out_nak) {
01648 dcfg.b.endevoutnak = 1;
01649 }
01650
01651 if (core_if->core_params->cont_on_bna) {
01652 dctl_data_t dctl = {.d32 = 0 };
01653 dctl.b.encontonbna = 1;
01654 DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl, 0, dctl.d32);
01655 }
01656
01657
01658 DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
01659
01660
01661 if (core_if->hwcfg2.b.dynamic_fifo && params->enable_dynamic_fifo) {
01662 DWC_DEBUGPL(DBG_CIL, "Total FIFO Size=%d\n",
01663 core_if->total_fifo_size);
01664 DWC_DEBUGPL(DBG_CIL, "Rx FIFO Size=%d\n",
01665 params->dev_rx_fifo_size);
01666 DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO Size=%d\n",
01667 params->dev_nperio_tx_fifo_size);
01668
01669
01670 DWC_DEBUGPL(DBG_CIL, "initial grxfsiz=%08x\n",
01671 DWC_READ_REG32(&global_regs->grxfsiz));
01672
01673 #ifdef DWC_UTE_CFI
01674 core_if->pwron_rxfsiz = DWC_READ_REG32(&global_regs->grxfsiz);
01675 core_if->init_rxfsiz = params->dev_rx_fifo_size;
01676 #endif
01677 rx_fifo_size = params->dev_rx_fifo_size;
01678 DWC_WRITE_REG32(&global_regs->grxfsiz, rx_fifo_size);
01679
01680 DWC_DEBUGPL(DBG_CIL, "new grxfsiz=%08x\n",
01681 DWC_READ_REG32(&global_regs->grxfsiz));
01682
01684 core_if->p_tx_msk = 0;
01685
01687 core_if->tx_msk = 0;
01688
01689 if (core_if->en_multiple_tx_fifo == 0) {
01690
01691 DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n",
01692 DWC_READ_REG32(&global_regs->gnptxfsiz));
01693
01694 nptxfifosize.b.depth = params->dev_nperio_tx_fifo_size;
01695 nptxfifosize.b.startaddr = params->dev_rx_fifo_size;
01696
01697 DWC_WRITE_REG32(&global_regs->gnptxfsiz,
01698 nptxfifosize.d32);
01699
01700 DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",
01701 DWC_READ_REG32(&global_regs->gnptxfsiz));
01702
01704
01705
01706
01707
01708
01709
01711 ptxfifosize.b.startaddr =
01712 nptxfifosize.b.startaddr + nptxfifosize.b.depth;
01713 for (i = 0; i < core_if->hwcfg4.b.num_dev_perio_in_ep; i++) {
01714 ptxfifosize.b.depth =
01715 params->dev_perio_tx_fifo_size[i];
01716 DWC_DEBUGPL(DBG_CIL,
01717 "initial dtxfsiz[%d]=%08x\n", i,
01718 DWC_READ_REG32(&global_regs->dtxfsiz
01719 [i]));
01720 DWC_WRITE_REG32(&global_regs->dtxfsiz[i],
01721 ptxfifosize.d32);
01722 DWC_DEBUGPL(DBG_CIL, "new dtxfsiz[%d]=%08x\n",
01723 i,
01724 DWC_READ_REG32(&global_regs->dtxfsiz
01725 [i]));
01726 ptxfifosize.b.startaddr += ptxfifosize.b.depth;
01727 }
01728 } else {
01729
01730
01731
01732
01733
01734
01735
01736
01737 DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n",
01738 DWC_READ_REG32(&global_regs->gnptxfsiz));
01739
01740 #ifdef DWC_UTE_CFI
01741 core_if->pwron_gnptxfsiz =
01742 (DWC_READ_REG32(&global_regs->gnptxfsiz) >> 16);
01743 core_if->init_gnptxfsiz =
01744 params->dev_nperio_tx_fifo_size;
01745 #endif
01746 nptxfifosize.b.depth = params->dev_nperio_tx_fifo_size;
01747 nptxfifosize.b.startaddr = params->dev_rx_fifo_size;
01748
01749 DWC_WRITE_REG32(&global_regs->gnptxfsiz,
01750 nptxfifosize.d32);
01751
01752 DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",
01753 DWC_READ_REG32(&global_regs->gnptxfsiz));
01754
01755 txfifosize.b.startaddr =
01756 nptxfifosize.b.startaddr + nptxfifosize.b.depth;
01757
01758 for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) {
01759
01760 txfifosize.b.depth =
01761 params->dev_tx_fifo_size[i];
01762
01763 DWC_DEBUGPL(DBG_CIL,
01764 "initial dtxfsiz[%d]=%08x\n",
01765 i,
01766 DWC_READ_REG32(&global_regs->dtxfsiz
01767 [i]));
01768
01769 #ifdef DWC_UTE_CFI
01770 core_if->pwron_txfsiz[i] =
01771 (DWC_READ_REG32
01772 (&global_regs->dtxfsiz[i]) >> 16);
01773 core_if->init_txfsiz[i] =
01774 params->dev_tx_fifo_size[i];
01775 #endif
01776 DWC_WRITE_REG32(&global_regs->dtxfsiz[i],
01777 txfifosize.d32);
01778
01779 DWC_DEBUGPL(DBG_CIL,
01780 "new dtxfsiz[%d]=%08x\n",
01781 i,
01782 DWC_READ_REG32(&global_regs->dtxfsiz
01783 [i]));
01784
01785 txfifosize.b.startaddr += txfifosize.b.depth;
01786 }
01787
01788 gdfifocfg.d32 = DWC_READ_REG32(&global_regs->gdfifocfg);
01789 hwcfg3.d32 = DWC_READ_REG32(&global_regs->ghwcfg3);
01790 gdfifocfg.b.gdfifocfg = (DWC_READ_REG32(&global_regs->ghwcfg3) >> 16);
01791 DWC_WRITE_REG32(&global_regs->gdfifocfg, gdfifocfg.d32);
01792 rxfsiz = (DWC_READ_REG32(&global_regs->grxfsiz) & 0x0000ffff);
01793 nptxfsiz = (DWC_READ_REG32(&global_regs->gnptxfsiz) >> 16);
01794 gdfifocfg.b.epinfobase = rxfsiz + nptxfsiz;
01795 DWC_WRITE_REG32(&global_regs->gdfifocfg, gdfifocfg.d32);
01796 }
01797 }
01798
01799
01800 dwc_otg_flush_tx_fifo(core_if, 0x10);
01801 dwc_otg_flush_rx_fifo(core_if);
01802
01803
01804 resetctl.b.intknqflsh = 1;
01805 DWC_WRITE_REG32(&core_if->core_global_regs->grstctl, resetctl.d32);
01806
01807 if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable) {
01808 core_if->start_predict = 0;
01809 for (i = 0; i<= core_if->dev_if->num_in_eps; ++i) {
01810 core_if->nextep_seq[i] = 0xff;
01811 }
01812 core_if->nextep_seq[0] = 0;
01813 core_if->first_in_nextep_seq = 0;
01814 diepctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[0]->diepctl);
01815 diepctl.b.nextep = 0;
01816 DWC_WRITE_REG32(&dev_if->in_ep_regs[0]->diepctl, diepctl.d32);
01817
01818
01819 dcfg.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dcfg);
01820 dcfg.b.epmscnt = 2;
01821 DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
01822
01823 DWC_DEBUGPL(DBG_CILV,"%s first_in_nextep_seq= %2d; nextep_seq[]:\n",
01824 __func__, core_if->first_in_nextep_seq);
01825 for (i=0; i <= core_if->dev_if->num_in_eps; i++) {
01826 DWC_DEBUGPL(DBG_CILV, "%2d ", core_if->nextep_seq[i]);
01827 }
01828 DWC_DEBUGPL(DBG_CILV,"\n");
01829 }
01830
01831
01835 if (core_if->multiproc_int_enable) {
01836 for (i = 0; i < core_if->dev_if->num_in_eps; ++i) {
01837 DWC_WRITE_REG32(&dev_if->
01838 dev_global_regs->diepeachintmsk[i], 0);
01839 }
01840
01841 for (i = 0; i < core_if->dev_if->num_out_eps; ++i) {
01842 DWC_WRITE_REG32(&dev_if->
01843 dev_global_regs->doepeachintmsk[i], 0);
01844 }
01845
01846 DWC_WRITE_REG32(&dev_if->dev_global_regs->deachint, 0xFFFFFFFF);
01847 DWC_WRITE_REG32(&dev_if->dev_global_regs->deachintmsk, 0);
01848 } else {
01849 DWC_WRITE_REG32(&dev_if->dev_global_regs->diepmsk, 0);
01850 DWC_WRITE_REG32(&dev_if->dev_global_regs->doepmsk, 0);
01851 DWC_WRITE_REG32(&dev_if->dev_global_regs->daint, 0xFFFFFFFF);
01852 DWC_WRITE_REG32(&dev_if->dev_global_regs->daintmsk, 0);
01853 }
01854
01855 for (i = 0; i <= dev_if->num_in_eps; i++) {
01856 depctl_data_t depctl;
01857 depctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl);
01858 if (depctl.b.epena) {
01859 depctl.d32 = 0;
01860 depctl.b.epdis = 1;
01861 depctl.b.snak = 1;
01862 } else {
01863 depctl.d32 = 0;
01864 }
01865
01866 DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepctl, depctl.d32);
01867
01868 DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->dieptsiz, 0);
01869 DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepdma, 0);
01870 DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepint, 0xFF);
01871 }
01872
01873 for (i = 0; i <= dev_if->num_out_eps; i++) {
01874 depctl_data_t depctl;
01875 depctl.d32 = DWC_READ_REG32(&dev_if->out_ep_regs[i]->doepctl);
01876 if (depctl.b.epena) {
01877 depctl.d32 = 0;
01878 depctl.b.epdis = 1;
01879 depctl.b.snak = 1;
01880 } else {
01881 depctl.d32 = 0;
01882 }
01883
01884 DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepctl, depctl.d32);
01885
01886 DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doeptsiz, 0);
01887 DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepdma, 0);
01888 DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepint, 0xFF);
01889 }
01890
01891 if (core_if->en_multiple_tx_fifo && core_if->dma_enable) {
01892 dev_if->non_iso_tx_thr_en = params->thr_ctl & 0x1;
01893 dev_if->iso_tx_thr_en = (params->thr_ctl >> 1) & 0x1;
01894 dev_if->rx_thr_en = (params->thr_ctl >> 2) & 0x1;
01895
01896 dev_if->rx_thr_length = params->rx_thr_length;
01897 dev_if->tx_thr_length = params->tx_thr_length;
01898
01899 dev_if->setup_desc_index = 0;
01900
01901 dthrctl.d32 = 0;
01902 dthrctl.b.non_iso_thr_en = dev_if->non_iso_tx_thr_en;
01903 dthrctl.b.iso_thr_en = dev_if->iso_tx_thr_en;
01904 dthrctl.b.tx_thr_len = dev_if->tx_thr_length;
01905 dthrctl.b.rx_thr_en = dev_if->rx_thr_en;
01906 dthrctl.b.rx_thr_len = dev_if->rx_thr_length;
01907 dthrctl.b.ahb_thr_ratio = params->ahb_thr_ratio;
01908
01909 DWC_WRITE_REG32(&dev_if->dev_global_regs->dtknqr3_dthrctl,
01910 dthrctl.d32);
01911
01912 DWC_DEBUGPL(DBG_CIL,
01913 "Non ISO Tx Thr - %d\nISO Tx Thr - %d\nRx Thr - %d\nTx Thr Len - %d\nRx Thr Len - %d\n",
01914 dthrctl.b.non_iso_thr_en, dthrctl.b.iso_thr_en,
01915 dthrctl.b.rx_thr_en, dthrctl.b.tx_thr_len,
01916 dthrctl.b.rx_thr_len);
01917
01918 }
01919
01920 dwc_otg_enable_device_interrupts(core_if);
01921
01922 {
01923 diepmsk_data_t msk = {.d32 = 0 };
01924 msk.b.txfifoundrn = 1;
01925 if (core_if->multiproc_int_enable) {
01926 DWC_MODIFY_REG32(&dev_if->
01927 dev_global_regs->diepeachintmsk[0],
01928 msk.d32, msk.d32);
01929 } else {
01930 DWC_MODIFY_REG32(&dev_if->dev_global_regs->diepmsk,
01931 msk.d32, msk.d32);
01932 }
01933 }
01934
01935 if (core_if->multiproc_int_enable) {
01936
01937 dctl_data_t dctl = {.d32 = 0 };
01938 dctl.b.nakonbble = 1;
01939 DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl, 0, dctl.d32);
01940 }
01941
01942 if (core_if->snpsid >= OTG_CORE_REV_2_94a) {
01943 dctl_data_t dctl = {.d32 = 0 };
01944 dctl.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dctl);
01945 dctl.b.sftdiscon = 0;
01946 DWC_WRITE_REG32(&dev_if->dev_global_regs->dctl, dctl.d32);
01947 }
01948 }
01949
01955 void dwc_otg_enable_host_interrupts(dwc_otg_core_if_t * core_if)
01956 {
01957 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
01958 gintmsk_data_t intr_mask = {.d32 = 0 };
01959
01960 DWC_DEBUGPL(DBG_CIL, "%s()\n", __func__);
01961
01962
01963 DWC_WRITE_REG32(&global_regs->gintmsk, 0);
01964
01965
01966 DWC_WRITE_REG32(&global_regs->gintsts, 0xFFFFFFFF);
01967
01968
01969 dwc_otg_enable_common_interrupts(core_if);
01970
01971
01972
01973
01974
01975
01976 intr_mask.b.disconnect = 1;
01977 intr_mask.b.portintr = 1;
01978 intr_mask.b.hcintr = 1;
01979
01980 DWC_MODIFY_REG32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
01981 }
01982
01988 void dwc_otg_disable_host_interrupts(dwc_otg_core_if_t * core_if)
01989 {
01990 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
01991 gintmsk_data_t intr_mask = {.d32 = 0 };
01992
01993 DWC_DEBUGPL(DBG_CILV, "%s()\n", __func__);
01994
01995
01996
01997
01998
01999 intr_mask.b.sofintr = 1;
02000 intr_mask.b.portintr = 1;
02001 intr_mask.b.hcintr = 1;
02002 intr_mask.b.ptxfempty = 1;
02003 intr_mask.b.nptxfempty = 1;
02004
02005 DWC_MODIFY_REG32(&global_regs->gintmsk, intr_mask.d32, 0);
02006 }
02007
02019 void dwc_otg_core_host_init(dwc_otg_core_if_t * core_if)
02020 {
02021 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
02022 dwc_otg_host_if_t *host_if = core_if->host_if;
02023 dwc_otg_core_params_t *params = core_if->core_params;
02024 hprt0_data_t hprt0 = {.d32 = 0 };
02025 fifosize_data_t nptxfifosize;
02026 fifosize_data_t ptxfifosize;
02027 uint16_t rxfsiz, nptxfsiz, hptxfsiz;
02028 gdfifocfg_data_t gdfifocfg = {.d32 = 0 };
02029 int i;
02030 hcchar_data_t hcchar;
02031 hcfg_data_t hcfg;
02032 hfir_data_t hfir;
02033 dwc_otg_hc_regs_t *hc_regs;
02034 int num_channels;
02035 gotgctl_data_t gotgctl = {.d32 = 0 };
02036
02037 DWC_DEBUGPL(DBG_CILV, "%s(%p)\n", __func__, core_if);
02038
02039
02040 DWC_WRITE_REG32(core_if->pcgcctl, 0);
02041
02042
02043 init_fslspclksel(core_if);
02044 if (core_if->core_params->speed == DWC_SPEED_PARAM_FULL) {
02045 hcfg.d32 = DWC_READ_REG32(&host_if->host_global_regs->hcfg);
02046 hcfg.b.fslssupp = 1;
02047 DWC_WRITE_REG32(&host_if->host_global_regs->hcfg, hcfg.d32);
02048
02049 }
02050
02051
02052
02053
02054
02055 if (core_if->core_params->reload_ctl == 1) {
02056 hfir.d32 = DWC_READ_REG32(&host_if->host_global_regs->hfir);
02057 hfir.b.hfirrldctrl = 1;
02058 DWC_WRITE_REG32(&host_if->host_global_regs->hfir, hfir.d32);
02059 }
02060
02061 if (core_if->core_params->dma_desc_enable) {
02062 uint8_t op_mode = core_if->hwcfg2.b.op_mode;
02063 if (!
02064 (core_if->hwcfg4.b.desc_dma
02065 && (core_if->snpsid >= OTG_CORE_REV_2_90a)
02066 && ((op_mode == DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
02067 || (op_mode == DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG)
02068 || (op_mode ==
02069 DWC_HWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE_OTG)
02070 || (op_mode == DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)
02071 || (op_mode ==
02072 DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST)))) {
02073
02074 DWC_ERROR("Host can't operate in Descriptor DMA mode.\n"
02075 "Either core version is below 2.90a or "
02076 "GHWCFG2, GHWCFG4 registers' values do not allow Descriptor DMA in host mode.\n"
02077 "To run the driver in Buffer DMA host mode set dma_desc_enable "
02078 "module parameter to 0.\n");
02079 return;
02080 }
02081 hcfg.d32 = DWC_READ_REG32(&host_if->host_global_regs->hcfg);
02082 hcfg.b.descdma = 1;
02083 DWC_WRITE_REG32(&host_if->host_global_regs->hcfg, hcfg.d32);
02084 }
02085
02086
02087 if (core_if->hwcfg2.b.dynamic_fifo && params->enable_dynamic_fifo) {
02088 DWC_DEBUGPL(DBG_CIL, "Total FIFO Size=%d\n",
02089 core_if->total_fifo_size);
02090 DWC_DEBUGPL(DBG_CIL, "Rx FIFO Size=%d\n",
02091 params->host_rx_fifo_size);
02092 DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO Size=%d\n",
02093 params->host_nperio_tx_fifo_size);
02094 DWC_DEBUGPL(DBG_CIL, "P Tx FIFO Size=%d\n",
02095 params->host_perio_tx_fifo_size);
02096
02097
02098 DWC_DEBUGPL(DBG_CIL, "initial grxfsiz=%08x\n",
02099 DWC_READ_REG32(&global_regs->grxfsiz));
02100 DWC_WRITE_REG32(&global_regs->grxfsiz,
02101 params->host_rx_fifo_size);
02102 DWC_DEBUGPL(DBG_CIL, "new grxfsiz=%08x\n",
02103 DWC_READ_REG32(&global_regs->grxfsiz));
02104
02105
02106 DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n",
02107 DWC_READ_REG32(&global_regs->gnptxfsiz));
02108 nptxfifosize.b.depth = params->host_nperio_tx_fifo_size;
02109 nptxfifosize.b.startaddr = params->host_rx_fifo_size;
02110 DWC_WRITE_REG32(&global_regs->gnptxfsiz, nptxfifosize.d32);
02111 DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",
02112 DWC_READ_REG32(&global_regs->gnptxfsiz));
02113
02114
02115 DWC_DEBUGPL(DBG_CIL, "initial hptxfsiz=%08x\n",
02116 DWC_READ_REG32(&global_regs->hptxfsiz));
02117 ptxfifosize.b.depth = params->host_perio_tx_fifo_size;
02118 ptxfifosize.b.startaddr =
02119 nptxfifosize.b.startaddr + nptxfifosize.b.depth;
02120 DWC_WRITE_REG32(&global_regs->hptxfsiz, ptxfifosize.d32);
02121 DWC_DEBUGPL(DBG_CIL, "new hptxfsiz=%08x\n",
02122 DWC_READ_REG32(&global_regs->hptxfsiz));
02123
02124 if (core_if->en_multiple_tx_fifo) {
02125
02126 gdfifocfg.d32 = DWC_READ_REG32(&global_regs->gdfifocfg);
02127 rxfsiz = (DWC_READ_REG32(&global_regs->grxfsiz) & 0x0000ffff);
02128 nptxfsiz = (DWC_READ_REG32(&global_regs->gnptxfsiz) >> 16);
02129 hptxfsiz = (DWC_READ_REG32(&global_regs->hptxfsiz) >> 16);
02130 gdfifocfg.b.epinfobase = rxfsiz + nptxfsiz + hptxfsiz;
02131 DWC_WRITE_REG32(&global_regs->gdfifocfg, gdfifocfg.d32);
02132 }
02133 }
02134
02135
02136
02137 gotgctl.b.hstsethnpen = 1;
02138 DWC_MODIFY_REG32(&global_regs->gotgctl, gotgctl.d32, 0);
02139
02140 dwc_otg_flush_tx_fifo(core_if, 0x10 );
02141 dwc_otg_flush_rx_fifo(core_if);
02142
02143
02144 gotgctl.b.hstsethnpen = 1;
02145 DWC_MODIFY_REG32(&global_regs->gotgctl, gotgctl.d32, 0);
02146
02147 if (!core_if->core_params->dma_desc_enable) {
02148
02149 num_channels = core_if->core_params->host_channels;
02150
02151 for (i = 0; i < num_channels; i++) {
02152 hc_regs = core_if->host_if->hc_regs[i];
02153 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
02154 hcchar.b.chen = 0;
02155 hcchar.b.chdis = 1;
02156 hcchar.b.epdir = 0;
02157 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
02158 }
02159
02160
02161 for (i = 0; i < num_channels; i++) {
02162 int count = 0;
02163 hc_regs = core_if->host_if->hc_regs[i];
02164 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
02165 hcchar.b.chen = 1;
02166 hcchar.b.chdis = 1;
02167 hcchar.b.epdir = 0;
02168 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
02169 DWC_DEBUGPL(DBG_HCDV, "%s: Halt channel %d\n", __func__, i);
02170 do {
02171 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
02172 if (++count > 1000) {
02173 DWC_ERROR
02174 ("%s: Unable to clear halt on channel %d\n",
02175 __func__, i);
02176 break;
02177 }
02178 dwc_udelay(1);
02179 } while (hcchar.b.chen);
02180 }
02181 }
02182
02183
02184 DWC_PRINTF("Init: Port Power? op_state=%d\n", core_if->op_state);
02185 if (core_if->op_state == A_HOST) {
02186 hprt0.d32 = dwc_otg_read_hprt0(core_if);
02187 DWC_PRINTF("Init: Power Port (%d)\n", hprt0.b.prtpwr);
02188 if (hprt0.b.prtpwr == 0) {
02189 hprt0.b.prtpwr = 1;
02190 DWC_WRITE_REG32(host_if->hprt0, hprt0.d32);
02191 }
02192 }
02193
02194 dwc_otg_enable_host_interrupts(core_if);
02195 }
02196
02206 void dwc_otg_hc_init(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
02207 {
02208 uint32_t intr_enable;
02209 hcintmsk_data_t hc_intr_mask;
02210 gintmsk_data_t gintmsk = {.d32 = 0 };
02211 hcchar_data_t hcchar;
02212 hcsplt_data_t hcsplt;
02213
02214 uint8_t hc_num = hc->hc_num;
02215 dwc_otg_host_if_t *host_if = core_if->host_if;
02216 dwc_otg_hc_regs_t *hc_regs = host_if->hc_regs[hc_num];
02217
02218
02219 hc_intr_mask.d32 = 0xFFFFFFFF;
02220 hc_intr_mask.b.reserved14_31 = 0;
02221 DWC_WRITE_REG32(&hc_regs->hcint, hc_intr_mask.d32);
02222
02223
02224 hc_intr_mask.d32 = 0;
02225 hc_intr_mask.b.chhltd = 1;
02226 if (core_if->dma_enable) {
02227
02228 if (!core_if->dma_desc_enable)
02229 hc_intr_mask.b.ahberr = 1;
02230 else {
02231 if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC)
02232 hc_intr_mask.b.xfercompl = 1;
02233 }
02234
02235 if (hc->error_state && !hc->do_split &&
02236 hc->ep_type != DWC_OTG_EP_TYPE_ISOC) {
02237 hc_intr_mask.b.ack = 1;
02238 if (hc->ep_is_in) {
02239 hc_intr_mask.b.datatglerr = 1;
02240 if (hc->ep_type != DWC_OTG_EP_TYPE_INTR) {
02241 hc_intr_mask.b.nak = 1;
02242 }
02243 }
02244 }
02245 } else {
02246 switch (hc->ep_type) {
02247 case DWC_OTG_EP_TYPE_CONTROL:
02248 case DWC_OTG_EP_TYPE_BULK:
02249 hc_intr_mask.b.xfercompl = 1;
02250 hc_intr_mask.b.stall = 1;
02251 hc_intr_mask.b.xacterr = 1;
02252 hc_intr_mask.b.datatglerr = 1;
02253 if (hc->ep_is_in) {
02254 hc_intr_mask.b.bblerr = 1;
02255 } else {
02256 hc_intr_mask.b.nak = 1;
02257 hc_intr_mask.b.nyet = 1;
02258 if (hc->do_ping) {
02259 hc_intr_mask.b.ack = 1;
02260 }
02261 }
02262
02263 if (hc->do_split) {
02264 hc_intr_mask.b.nak = 1;
02265 if (hc->complete_split) {
02266 hc_intr_mask.b.nyet = 1;
02267 } else {
02268 hc_intr_mask.b.ack = 1;
02269 }
02270 }
02271
02272 if (hc->error_state) {
02273 hc_intr_mask.b.ack = 1;
02274 }
02275 break;
02276 case DWC_OTG_EP_TYPE_INTR:
02277 hc_intr_mask.b.xfercompl = 1;
02278 hc_intr_mask.b.nak = 1;
02279 hc_intr_mask.b.stall = 1;
02280 hc_intr_mask.b.xacterr = 1;
02281 hc_intr_mask.b.datatglerr = 1;
02282 hc_intr_mask.b.frmovrun = 1;
02283
02284 if (hc->ep_is_in) {
02285 hc_intr_mask.b.bblerr = 1;
02286 }
02287 if (hc->error_state) {
02288 hc_intr_mask.b.ack = 1;
02289 }
02290 if (hc->do_split) {
02291 if (hc->complete_split) {
02292 hc_intr_mask.b.nyet = 1;
02293 } else {
02294 hc_intr_mask.b.ack = 1;
02295 }
02296 }
02297 break;
02298 case DWC_OTG_EP_TYPE_ISOC:
02299 hc_intr_mask.b.xfercompl = 1;
02300 hc_intr_mask.b.frmovrun = 1;
02301 hc_intr_mask.b.ack = 1;
02302
02303 if (hc->ep_is_in) {
02304 hc_intr_mask.b.xacterr = 1;
02305 hc_intr_mask.b.bblerr = 1;
02306 }
02307 break;
02308 }
02309 }
02310 DWC_WRITE_REG32(&hc_regs->hcintmsk, hc_intr_mask.d32);
02311
02312
02313 intr_enable = (1 << hc_num);
02314 DWC_MODIFY_REG32(&host_if->host_global_regs->haintmsk, 0, intr_enable);
02315
02316
02317 gintmsk.b.hcintr = 1;
02318 DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, 0, gintmsk.d32);
02319
02320
02321
02322
02323
02324 hcchar.d32 = 0;
02325 hcchar.b.devaddr = hc->dev_addr;
02326 hcchar.b.epnum = hc->ep_num;
02327 hcchar.b.epdir = hc->ep_is_in;
02328 hcchar.b.lspddev = (hc->speed == DWC_OTG_EP_SPEED_LOW);
02329 hcchar.b.eptype = hc->ep_type;
02330 hcchar.b.mps = hc->max_packet;
02331
02332 DWC_WRITE_REG32(&host_if->hc_regs[hc_num]->hcchar, hcchar.d32);
02333
02334 DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
02335 DWC_DEBUGPL(DBG_HCDV, " Dev Addr: %d\n", hcchar.b.devaddr);
02336 DWC_DEBUGPL(DBG_HCDV, " Ep Num: %d\n", hcchar.b.epnum);
02337 DWC_DEBUGPL(DBG_HCDV, " Is In: %d\n", hcchar.b.epdir);
02338 DWC_DEBUGPL(DBG_HCDV, " Is Low Speed: %d\n", hcchar.b.lspddev);
02339 DWC_DEBUGPL(DBG_HCDV, " Ep Type: %d\n", hcchar.b.eptype);
02340 DWC_DEBUGPL(DBG_HCDV, " Max Pkt: %d\n", hcchar.b.mps);
02341 DWC_DEBUGPL(DBG_HCDV, " Multi Cnt: %d\n", hcchar.b.multicnt);
02342
02343
02344
02345
02346 hcsplt.d32 = 0;
02347 if (hc->do_split) {
02348 DWC_DEBUGPL(DBG_HCDV, "Programming HC %d with split --> %s\n",
02349 hc->hc_num,
02350 hc->complete_split ? "CSPLIT" : "SSPLIT");
02351 hcsplt.b.compsplt = hc->complete_split;
02352 hcsplt.b.xactpos = hc->xact_pos;
02353 hcsplt.b.hubaddr = hc->hub_addr;
02354 hcsplt.b.prtaddr = hc->port_addr;
02355 DWC_DEBUGPL(DBG_HCDV, " comp split %d\n", hc->complete_split);
02356 DWC_DEBUGPL(DBG_HCDV, " xact pos %d\n", hc->xact_pos);
02357 DWC_DEBUGPL(DBG_HCDV, " hub addr %d\n", hc->hub_addr);
02358 DWC_DEBUGPL(DBG_HCDV, " port addr %d\n", hc->port_addr);
02359 DWC_DEBUGPL(DBG_HCDV, " is_in %d\n", hc->ep_is_in);
02360 DWC_DEBUGPL(DBG_HCDV, " Max Pkt: %d\n", hcchar.b.mps);
02361 DWC_DEBUGPL(DBG_HCDV, " xferlen: %d\n", hc->xfer_len);
02362 }
02363 DWC_WRITE_REG32(&host_if->hc_regs[hc_num]->hcsplt, hcsplt.d32);
02364
02365 }
02366
02394 void dwc_otg_hc_halt(dwc_otg_core_if_t * core_if,
02395 dwc_hc_t * hc, dwc_otg_halt_status_e halt_status)
02396 {
02397 gnptxsts_data_t nptxsts;
02398 hptxsts_data_t hptxsts;
02399 hcchar_data_t hcchar;
02400 dwc_otg_hc_regs_t *hc_regs;
02401 dwc_otg_core_global_regs_t *global_regs;
02402 dwc_otg_host_global_regs_t *host_global_regs;
02403
02404 hc_regs = core_if->host_if->hc_regs[hc->hc_num];
02405 global_regs = core_if->core_global_regs;
02406 host_global_regs = core_if->host_if->host_global_regs;
02407
02408 DWC_ASSERT(!(halt_status == DWC_OTG_HC_XFER_NO_HALT_STATUS),
02409 "halt_status = %d\n", halt_status);
02410
02411 if (halt_status == DWC_OTG_HC_XFER_URB_DEQUEUE ||
02412 halt_status == DWC_OTG_HC_XFER_AHB_ERR) {
02413
02414
02415
02416
02417
02418
02419 hcintmsk_data_t hcintmsk;
02420 hcintmsk.d32 = 0;
02421 hcintmsk.b.chhltd = 1;
02422 DWC_WRITE_REG32(&hc_regs->hcintmsk, hcintmsk.d32);
02423
02424
02425
02426
02427
02428
02429 DWC_WRITE_REG32(&hc_regs->hcint, ~hcintmsk.d32);
02430
02431
02432
02433
02434
02435
02436 hc->halt_status = halt_status;
02437
02438 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
02439 if (hcchar.b.chen == 0) {
02440
02441
02442
02443
02444
02445
02446
02447
02448
02449
02450
02451 return;
02452 }
02453 }
02454 if (hc->halt_pending) {
02455
02456
02457
02458
02459
02460 #ifdef DEBUG
02461 DWC_PRINTF
02462 ("*** %s: Channel %d, _hc->halt_pending already set ***\n",
02463 __func__, hc->hc_num);
02464
02465 #endif
02466 return;
02467 }
02468
02469 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
02470
02471
02472
02473 if (!core_if->core_params->dma_desc_enable)
02474 hcchar.b.chen = 1;
02475 hcchar.b.chdis = 1;
02476
02477 if (!core_if->dma_enable) {
02478
02479 if (hc->ep_type == DWC_OTG_EP_TYPE_CONTROL ||
02480 hc->ep_type == DWC_OTG_EP_TYPE_BULK) {
02481 nptxsts.d32 = DWC_READ_REG32(&global_regs->gnptxsts);
02482 if (nptxsts.b.nptxqspcavail == 0) {
02483 hcchar.b.chen = 0;
02484 }
02485 } else {
02486 hptxsts.d32 =
02487 DWC_READ_REG32(&host_global_regs->hptxsts);
02488 if ((hptxsts.b.ptxqspcavail == 0)
02489 || (core_if->queuing_high_bandwidth)) {
02490 hcchar.b.chen = 0;
02491 }
02492 }
02493 }
02494 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
02495
02496 hc->halt_status = halt_status;
02497
02498 if (hcchar.b.chen) {
02499 hc->halt_pending = 1;
02500 hc->halt_on_queue = 0;
02501 } else {
02502 hc->halt_on_queue = 1;
02503 }
02504
02505 DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
02506 DWC_DEBUGPL(DBG_HCDV, " hcchar: 0x%08x\n", hcchar.d32);
02507 DWC_DEBUGPL(DBG_HCDV, " halt_pending: %d\n", hc->halt_pending);
02508 DWC_DEBUGPL(DBG_HCDV, " halt_on_queue: %d\n", hc->halt_on_queue);
02509 DWC_DEBUGPL(DBG_HCDV, " halt_status: %d\n", hc->halt_status);
02510
02511 return;
02512 }
02513
02521 void dwc_otg_hc_cleanup(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
02522 {
02523 dwc_otg_hc_regs_t *hc_regs;
02524
02525 hc->xfer_started = 0;
02526
02527
02528
02529
02530
02531 hc_regs = core_if->host_if->hc_regs[hc->hc_num];
02532 DWC_WRITE_REG32(&hc_regs->hcintmsk, 0);
02533 DWC_WRITE_REG32(&hc_regs->hcint, 0xFFFFFFFF);
02534 #ifdef DEBUG
02535 DWC_TIMER_CANCEL(core_if->hc_xfer_timer[hc->hc_num]);
02536 #endif
02537 }
02538
02549 static inline void hc_set_even_odd_frame(dwc_otg_core_if_t * core_if,
02550 dwc_hc_t * hc, hcchar_data_t * hcchar)
02551 {
02552 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
02553 hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
02554 hfnum_data_t hfnum;
02555 hfnum.d32 =
02556 DWC_READ_REG32(&core_if->host_if->host_global_regs->hfnum);
02557
02558
02559 hcchar->b.oddfrm = (hfnum.b.frnum & 0x1) ? 0 : 1;
02560 #ifdef DEBUG
02561 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR && hc->do_split
02562 && !hc->complete_split) {
02563 switch (hfnum.b.frnum & 0x7) {
02564 case 7:
02565 core_if->hfnum_7_samples++;
02566 core_if->hfnum_7_frrem_accum += hfnum.b.frrem;
02567 break;
02568 case 0:
02569 core_if->hfnum_0_samples++;
02570 core_if->hfnum_0_frrem_accum += hfnum.b.frrem;
02571 break;
02572 default:
02573 core_if->hfnum_other_samples++;
02574 core_if->hfnum_other_frrem_accum +=
02575 hfnum.b.frrem;
02576 break;
02577 }
02578 }
02579 #endif
02580 }
02581 }
02582
02583 #ifdef DEBUG
02584 void hc_xfer_timeout(void *ptr)
02585 {
02586 hc_xfer_info_t *xfer_info = NULL;
02587 int hc_num = 0;
02588
02589 if (ptr)
02590 xfer_info = (hc_xfer_info_t *) ptr;
02591
02592 if (!xfer_info->hc) {
02593 DWC_ERROR("xfer_info->hc = %p\n", xfer_info->hc);
02594 return;
02595 }
02596
02597 hc_num = xfer_info->hc->hc_num;
02598 DWC_WARN("%s: timeout on channel %d\n", __func__, hc_num);
02599 DWC_WARN(" start_hcchar_val 0x%08x\n",
02600 xfer_info->core_if->start_hcchar_val[hc_num]);
02601 }
02602 #endif
02603
02604 void ep_xfer_timeout(void *ptr)
02605 {
02606 ep_xfer_info_t *xfer_info = NULL;
02607 int ep_num = 0;
02608 dctl_data_t dctl = {.d32 = 0 };
02609 gintsts_data_t gintsts = {.d32 = 0 };
02610 gintmsk_data_t gintmsk = {.d32 = 0 };
02611
02612 if (ptr)
02613 xfer_info = (ep_xfer_info_t *) ptr;
02614
02615 if (!xfer_info->ep) {
02616 DWC_ERROR("xfer_info->ep = %p\n", xfer_info->ep);
02617 return;
02618 }
02619
02620 ep_num = xfer_info->ep->num;
02621 DWC_WARN("%s: timeout on endpoit %d\n", __func__, ep_num);
02622
02623 xfer_info->state = 2;
02624
02625 dctl.d32 = DWC_READ_REG32(&xfer_info->core_if->
02626 dev_if->dev_global_regs->dctl);
02627 gintsts.d32 = DWC_READ_REG32(&xfer_info->core_if->
02628 core_global_regs->gintsts);
02629 gintmsk.d32 = DWC_READ_REG32(&xfer_info->core_if->
02630 core_global_regs->gintmsk);
02631
02632 if (!gintmsk.b.goutnakeff) {
02633
02634 gintmsk.b.goutnakeff = 1;
02635 DWC_WRITE_REG32(&xfer_info->core_if->
02636 core_global_regs->gintmsk, gintmsk.d32);
02637
02638 }
02639
02640 if (!gintsts.b.goutnakeff) {
02641 dctl.b.sgoutnak = 1;
02642 }
02643 DWC_WRITE_REG32(&xfer_info->core_if->dev_if->
02644 dev_global_regs->dctl, dctl.d32);
02645
02646 }
02647
02648 void set_pid_isoc(dwc_hc_t * hc)
02649 {
02650
02651 if (hc->speed == DWC_OTG_EP_SPEED_HIGH) {
02652 if (hc->ep_is_in) {
02653 if (hc->multi_count == 1) {
02654 hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
02655 } else if (hc->multi_count == 2) {
02656 hc->data_pid_start = DWC_OTG_HC_PID_DATA1;
02657 } else {
02658 hc->data_pid_start = DWC_OTG_HC_PID_DATA2;
02659 }
02660 } else {
02661 if (hc->multi_count == 1) {
02662 hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
02663 } else {
02664 hc->data_pid_start = DWC_OTG_HC_PID_MDATA;
02665 }
02666 }
02667 } else {
02668 hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
02669 }
02670 }
02671
02703 void dwc_otg_hc_start_transfer(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
02704 {
02705 hcchar_data_t hcchar;
02706 hctsiz_data_t hctsiz;
02707 uint16_t num_packets;
02708 uint32_t max_hc_xfer_size = core_if->core_params->max_transfer_size;
02709 uint16_t max_hc_pkt_count = core_if->core_params->max_packet_count;
02710 dwc_otg_hc_regs_t *hc_regs = core_if->host_if->hc_regs[hc->hc_num];
02711
02712 hctsiz.d32 = 0;
02713
02714 if (hc->do_ping) {
02715 if (!core_if->dma_enable) {
02716 dwc_otg_hc_do_ping(core_if, hc);
02717 hc->xfer_started = 1;
02718 return;
02719 } else {
02720 hctsiz.b.dopng = 1;
02721 }
02722 }
02723
02724 if (hc->do_split) {
02725 num_packets = 1;
02726
02727 if (hc->complete_split && !hc->ep_is_in) {
02728
02729
02730 hc->xfer_len = 0;
02731 } else if (hc->ep_is_in || (hc->xfer_len > hc->max_packet)) {
02732 hc->xfer_len = hc->max_packet;
02733 } else if (!hc->ep_is_in && (hc->xfer_len > 188)) {
02734 hc->xfer_len = 188;
02735 }
02736
02737 hctsiz.b.xfersize = hc->xfer_len;
02738 } else {
02739
02740
02741
02742
02743 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
02744 hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
02745
02746
02747
02748
02749
02750
02751
02752 uint32_t max_periodic_len =
02753 hc->multi_count * hc->max_packet;
02754 if (hc->xfer_len > max_periodic_len) {
02755 hc->xfer_len = max_periodic_len;
02756 } else {
02757 }
02758 } else if (hc->xfer_len > max_hc_xfer_size) {
02759
02760 hc->xfer_len = max_hc_xfer_size - hc->max_packet + 1;
02761 }
02762
02763 if (hc->xfer_len > 0) {
02764 num_packets =
02765 (hc->xfer_len + hc->max_packet -
02766 1) / hc->max_packet;
02767 if (num_packets > max_hc_pkt_count) {
02768 num_packets = max_hc_pkt_count;
02769 hc->xfer_len = num_packets * hc->max_packet;
02770 }
02771 } else {
02772
02773 num_packets = 1;
02774 }
02775
02776 if (hc->ep_is_in) {
02777
02778 hc->xfer_len = num_packets * hc->max_packet;
02779 }
02780
02781 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
02782 hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
02783
02784
02785
02786
02787 hc->multi_count = num_packets;
02788 }
02789
02790 if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC)
02791 set_pid_isoc(hc);
02792
02793 hctsiz.b.xfersize = hc->xfer_len;
02794 }
02795
02796 hc->start_pkt_count = num_packets;
02797 hctsiz.b.pktcnt = num_packets;
02798 hctsiz.b.pid = hc->data_pid_start;
02799 DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32);
02800
02801 DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
02802 DWC_DEBUGPL(DBG_HCDV, " Xfer Size: %d\n", hctsiz.b.xfersize);
02803 DWC_DEBUGPL(DBG_HCDV, " Num Pkts: %d\n", hctsiz.b.pktcnt);
02804 DWC_DEBUGPL(DBG_HCDV, " Start PID: %d\n", hctsiz.b.pid);
02805
02806 if (core_if->dma_enable) {
02807 dwc_dma_t dma_addr;
02808 if (hc->align_buff) {
02809 dma_addr = hc->align_buff;
02810 } else {
02811 dma_addr = ((unsigned long)hc->xfer_buff & 0xffffffff);
02812 }
02813 DWC_WRITE_REG32(&hc_regs->hcdma, dma_addr);
02814 }
02815
02816
02817 if (hc->do_split) {
02818 hcsplt_data_t hcsplt;
02819 hcsplt.d32 = DWC_READ_REG32(&hc_regs->hcsplt);
02820 hcsplt.b.spltena = 1;
02821 DWC_WRITE_REG32(&hc_regs->hcsplt, hcsplt.d32);
02822 }
02823
02824 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
02825 hcchar.b.multicnt = hc->multi_count;
02826 hc_set_even_odd_frame(core_if, hc, &hcchar);
02827 #ifdef DEBUG
02828 core_if->start_hcchar_val[hc->hc_num] = hcchar.d32;
02829 if (hcchar.b.chdis) {
02830 DWC_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n",
02831 __func__, hc->hc_num, hcchar.d32);
02832 }
02833 #endif
02834
02835
02836 hcchar.b.chen = 1;
02837 hcchar.b.chdis = 0;
02838 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
02839
02840 hc->xfer_started = 1;
02841 hc->requests++;
02842
02843 if (!core_if->dma_enable && !hc->ep_is_in && hc->xfer_len > 0) {
02844
02845 dwc_otg_hc_write_packet(core_if, hc);
02846 }
02847 #ifdef DEBUG
02848 if (hc->ep_type != DWC_OTG_EP_TYPE_INTR) {
02849 core_if->hc_xfer_info[hc->hc_num].core_if = core_if;
02850 core_if->hc_xfer_info[hc->hc_num].hc = hc;
02851
02852
02853 DWC_TIMER_SCHEDULE(core_if->hc_xfer_timer[hc->hc_num], 10000);
02854 }
02855 #endif
02856 }
02857
02872 void dwc_otg_hc_start_transfer_ddma(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
02873 {
02874 dwc_otg_hc_regs_t *hc_regs = core_if->host_if->hc_regs[hc->hc_num];
02875 hcchar_data_t hcchar;
02876 hctsiz_data_t hctsiz;
02877 hcdma_data_t hcdma;
02878
02879 hctsiz.d32 = 0;
02880
02881 if (hc->do_ping)
02882 hctsiz.b_ddma.dopng = 1;
02883
02884 if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC)
02885 set_pid_isoc(hc);
02886
02887
02888 hctsiz.b_ddma.pid = hc->data_pid_start;
02889 hctsiz.b_ddma.ntd = hc->ntd - 1;
02890 hctsiz.b_ddma.schinfo = hc->schinfo;
02891
02892 DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
02893 DWC_DEBUGPL(DBG_HCDV, " Start PID: %d\n", hctsiz.b.pid);
02894 DWC_DEBUGPL(DBG_HCDV, " NTD: %d\n", hctsiz.b_ddma.ntd);
02895
02896 DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32);
02897
02898 hcdma.d32 = 0;
02899 hcdma.b.dma_addr = ((uint32_t) hc->desc_list_addr) >> 11;
02900
02901
02902 hcdma.b.ctd = 0;
02903 DWC_WRITE_REG32(&hc_regs->hcdma, hcdma.d32);
02904
02905 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
02906 hcchar.b.multicnt = hc->multi_count;
02907
02908 #ifdef DEBUG
02909 core_if->start_hcchar_val[hc->hc_num] = hcchar.d32;
02910 if (hcchar.b.chdis) {
02911 DWC_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n",
02912 __func__, hc->hc_num, hcchar.d32);
02913 }
02914 #endif
02915
02916
02917 hcchar.b.chen = 1;
02918 hcchar.b.chdis = 0;
02919
02920 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
02921
02922 hc->xfer_started = 1;
02923 hc->requests++;
02924
02925 #ifdef DEBUG
02926 if ((hc->ep_type != DWC_OTG_EP_TYPE_INTR)
02927 && (hc->ep_type != DWC_OTG_EP_TYPE_ISOC)) {
02928 core_if->hc_xfer_info[hc->hc_num].core_if = core_if;
02929 core_if->hc_xfer_info[hc->hc_num].hc = hc;
02930
02931 DWC_TIMER_SCHEDULE(core_if->hc_xfer_timer[hc->hc_num], 10000);
02932 }
02933 #endif
02934
02935 }
02936
02952 int dwc_otg_hc_continue_transfer(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
02953 {
02954 DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
02955
02956 if (hc->do_split) {
02957
02958 return 0;
02959 } else if (hc->data_pid_start == DWC_OTG_HC_PID_SETUP) {
02960
02961 return 0;
02962 } else if (hc->ep_is_in) {
02963
02964
02965
02966
02967
02968
02969
02970
02971
02972
02973
02974
02975 hcchar_data_t hcchar;
02976 dwc_otg_hc_regs_t *hc_regs =
02977 core_if->host_if->hc_regs[hc->hc_num];
02978
02979 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
02980 hc_set_even_odd_frame(core_if, hc, &hcchar);
02981 hcchar.b.chen = 1;
02982 hcchar.b.chdis = 0;
02983 DWC_DEBUGPL(DBG_HCDV, " IN xfer: hcchar = 0x%08x\n",
02984 hcchar.d32);
02985 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
02986 hc->requests++;
02987 return 1;
02988 } else {
02989
02990 if (hc->xfer_count < hc->xfer_len) {
02991 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
02992 hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
02993 hcchar_data_t hcchar;
02994 dwc_otg_hc_regs_t *hc_regs;
02995 hc_regs = core_if->host_if->hc_regs[hc->hc_num];
02996 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
02997 hc_set_even_odd_frame(core_if, hc, &hcchar);
02998 }
02999
03000
03001 dwc_otg_hc_write_packet(core_if, hc);
03002 hc->requests++;
03003 return 1;
03004 } else {
03005 return 0;
03006 }
03007 }
03008 }
03009
03014 void dwc_otg_hc_do_ping(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
03015 {
03016 hcchar_data_t hcchar;
03017 hctsiz_data_t hctsiz;
03018 dwc_otg_hc_regs_t *hc_regs = core_if->host_if->hc_regs[hc->hc_num];
03019
03020 DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
03021
03022 hctsiz.d32 = 0;
03023 hctsiz.b.dopng = 1;
03024 hctsiz.b.pktcnt = 1;
03025 DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32);
03026
03027 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
03028 hcchar.b.chen = 1;
03029 hcchar.b.chdis = 0;
03030 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
03031 }
03032
03033
03034
03035
03036
03037
03038
03039
03040
03041
03042
03043 void dwc_otg_hc_write_packet(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
03044 {
03045 uint32_t i;
03046 uint32_t remaining_count;
03047 uint32_t byte_count;
03048 uint32_t dword_count;
03049
03050 uint32_t *data_buff = (uint32_t *) (hc->xfer_buff);
03051 uint32_t *data_fifo = core_if->data_fifo[hc->hc_num];
03052
03053 remaining_count = hc->xfer_len - hc->xfer_count;
03054 if (remaining_count > hc->max_packet) {
03055 byte_count = hc->max_packet;
03056 } else {
03057 byte_count = remaining_count;
03058 }
03059
03060 dword_count = (byte_count + 3) / 4;
03061
03062 if ((((unsigned long)data_buff) & 0x3) == 0) {
03063
03064 for (i = 0; i < dword_count; i++, data_buff++) {
03065 DWC_WRITE_REG32(data_fifo, *data_buff);
03066 }
03067 } else {
03068
03069 for (i = 0; i < dword_count; i++, data_buff++) {
03070 uint32_t data;
03071 data =
03072 (data_buff[0] | data_buff[1] << 8 | data_buff[2] <<
03073 16 | data_buff[3] << 24);
03074 DWC_WRITE_REG32(data_fifo, data);
03075 }
03076 }
03077
03078 hc->xfer_count += byte_count;
03079 hc->xfer_buff += byte_count;
03080 }
03081
03086 uint32_t dwc_otg_get_frame_number(dwc_otg_core_if_t * core_if)
03087 {
03088 dsts_data_t dsts;
03089 dsts.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);
03090
03091
03092 return dsts.b.soffn;
03093 }
03094
03102 uint32_t calc_frame_interval(dwc_otg_core_if_t * core_if)
03103 {
03104 gusbcfg_data_t usbcfg;
03105 hwcfg2_data_t hwcfg2;
03106 hprt0_data_t hprt0;
03107 int clock = 60;
03108 usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
03109 hwcfg2.d32 = DWC_READ_REG32(&core_if->core_global_regs->ghwcfg2);
03110 hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
03111 if (!usbcfg.b.physel && usbcfg.b.ulpi_utmi_sel && !usbcfg.b.phyif)
03112 clock = 60;
03113 if (usbcfg.b.physel && hwcfg2.b.fs_phy_type == 3)
03114 clock = 48;
03115 if (!usbcfg.b.phylpwrclksel && !usbcfg.b.physel &&
03116 !usbcfg.b.ulpi_utmi_sel && usbcfg.b.phyif)
03117 clock = 30;
03118 if (!usbcfg.b.phylpwrclksel && !usbcfg.b.physel &&
03119 !usbcfg.b.ulpi_utmi_sel && !usbcfg.b.phyif)
03120 clock = 60;
03121 if (usbcfg.b.phylpwrclksel && !usbcfg.b.physel &&
03122 !usbcfg.b.ulpi_utmi_sel && usbcfg.b.phyif)
03123 clock = 48;
03124 if (usbcfg.b.physel && !usbcfg.b.phyif && hwcfg2.b.fs_phy_type == 2)
03125 clock = 48;
03126 if (usbcfg.b.physel && hwcfg2.b.fs_phy_type == 1)
03127 clock = 48;
03128 if (hprt0.b.prtspd == 0)
03129
03130 return 125 * clock;
03131 else
03132
03133 return 1000 * clock;
03134 }
03135
03144 void dwc_otg_read_setup_packet(dwc_otg_core_if_t * core_if, uint32_t * dest)
03145 {
03146
03147
03148
03149 dest[0] = DWC_READ_REG32(core_if->data_fifo[0]);
03150 dest[1] = DWC_READ_REG32(core_if->data_fifo[0]);
03151 }
03152
03161 void dwc_otg_ep0_activate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
03162 {
03163 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
03164 dsts_data_t dsts;
03165 depctl_data_t diepctl;
03166 depctl_data_t doepctl;
03167 dctl_data_t dctl = {.d32 = 0 };
03168
03169
03170 dsts.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dsts);
03171 diepctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[0]->diepctl);
03172 doepctl.d32 = DWC_READ_REG32(&dev_if->out_ep_regs[0]->doepctl);
03173
03174
03175 switch (dsts.b.enumspd) {
03176 case DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
03177 case DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
03178 case DWC_DSTS_ENUMSPD_FS_PHY_48MHZ:
03179 diepctl.b.mps = DWC_DEP0CTL_MPS_64;
03180 break;
03181 case DWC_DSTS_ENUMSPD_LS_PHY_6MHZ:
03182 diepctl.b.mps = DWC_DEP0CTL_MPS_8;
03183 break;
03184 }
03185
03186 DWC_WRITE_REG32(&dev_if->in_ep_regs[0]->diepctl, diepctl.d32);
03187
03188
03189 doepctl.b.epena = 1;
03190 DWC_WRITE_REG32(&dev_if->out_ep_regs[0]->doepctl, doepctl.d32);
03191
03192 #ifdef VERBOSE
03193 DWC_DEBUGPL(DBG_PCDV, "doepctl0=%0x\n",
03194 DWC_READ_REG32(&dev_if->out_ep_regs[0]->doepctl));
03195 DWC_DEBUGPL(DBG_PCDV, "diepctl0=%0x\n",
03196 DWC_READ_REG32(&dev_if->in_ep_regs[0]->diepctl));
03197 #endif
03198 dctl.b.cgnpinnak = 1;
03199
03200 DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl, dctl.d32, dctl.d32);
03201 DWC_DEBUGPL(DBG_PCDV, "dctl=%0x\n",
03202 DWC_READ_REG32(&dev_if->dev_global_regs->dctl));
03203
03204 }
03205
03214 void dwc_otg_ep_activate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
03215 {
03216 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
03217 depctl_data_t depctl;
03218 volatile uint32_t *addr;
03219 daint_data_t daintmsk = {.d32 = 0 };
03220 dcfg_data_t dcfg;
03221 uint8_t i;
03222
03223 DWC_DEBUGPL(DBG_PCDV, "%s() EP%d-%s\n", __func__, ep->num,
03224 (ep->is_in ? "IN" : "OUT"));
03225
03226 #ifdef DWC_UTE_PER_IO
03227 ep->xiso_frame_num = 0xFFFFFFFF;
03228 ep->xiso_active_xfers = 0;
03229 ep->xiso_queued_xfers = 0;
03230 #endif
03231
03232 if (ep->is_in == 1) {
03233 addr = &dev_if->in_ep_regs[ep->num]->diepctl;
03234 daintmsk.ep.in = 1 << ep->num;
03235 } else {
03236 addr = &dev_if->out_ep_regs[ep->num]->doepctl;
03237 daintmsk.ep.out = 1 << ep->num;
03238 }
03239
03240
03241
03242 depctl.d32 = DWC_READ_REG32(addr);
03243 if (!depctl.b.usbactep) {
03244 depctl.b.mps = ep->maxpacket;
03245 depctl.b.eptype = ep->type;
03246 depctl.b.txfnum = ep->tx_fifo_num;
03247
03248 if (ep->type == DWC_OTG_EP_TYPE_ISOC) {
03249 depctl.b.setd0pid = 1;
03250 } else {
03251 depctl.b.setd0pid = 1;
03252 }
03253 depctl.b.usbactep = 1;
03254
03255
03256 if (!(depctl.b.eptype & 1) && (ep->is_in == 1)) {
03257 for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
03258 if (core_if->nextep_seq[i] == core_if->first_in_nextep_seq)
03259 break;
03260 }
03261 core_if->nextep_seq[i] = ep->num;
03262 core_if->nextep_seq[ep->num] = core_if->first_in_nextep_seq;
03263 depctl.b.nextep = core_if->nextep_seq[ep->num];
03264 dcfg.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dcfg);
03265 dcfg.b.epmscnt++;
03266 DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
03267
03268 DWC_DEBUGPL(DBG_PCDV,"%s first_in_nextep_seq= %2d; nextep_seq[]:\n",
03269 __func__, core_if->first_in_nextep_seq);
03270 for (i=0; i <= core_if->dev_if->num_in_eps; i++) {
03271 DWC_DEBUGPL(DBG_PCDV, "%2d\n", core_if->nextep_seq[i]);
03272 }
03273
03274 }
03275
03276
03277 DWC_WRITE_REG32(addr, depctl.d32);
03278 DWC_DEBUGPL(DBG_PCDV, "DEPCTL=%08x\n", DWC_READ_REG32(addr));
03279 }
03280
03281
03282 if (core_if->multiproc_int_enable) {
03283 if (ep->is_in == 1) {
03284 diepmsk_data_t diepmsk = {.d32 = 0 };
03285 diepmsk.b.xfercompl = 1;
03286 diepmsk.b.timeout = 1;
03287 diepmsk.b.epdisabled = 1;
03288 diepmsk.b.ahberr = 1;
03289 diepmsk.b.intknepmis = 1;
03290 if (!core_if->en_multiple_tx_fifo && core_if->dma_enable)
03291 diepmsk.b.intknepmis = 0;
03292 diepmsk.b.txfifoundrn = 1;
03293 if (ep->type == DWC_OTG_EP_TYPE_ISOC) {
03294 diepmsk.b.nak = 1;
03295 }
03296
03297
03298
03299
03300
03301
03302
03303
03304
03305
03306
03307
03308
03309 DWC_WRITE_REG32(&dev_if->dev_global_regs->
03310 diepeachintmsk[ep->num], diepmsk.d32);
03311
03312 } else {
03313 doepmsk_data_t doepmsk = {.d32 = 0 };
03314 doepmsk.b.xfercompl = 1;
03315 doepmsk.b.ahberr = 1;
03316 doepmsk.b.epdisabled = 1;
03317 if (ep->type == DWC_OTG_EP_TYPE_ISOC)
03318 doepmsk.b.outtknepdis = 1;
03319
03320
03321
03322
03323
03324
03325
03326
03327
03328
03329
03330
03331 DWC_WRITE_REG32(&dev_if->dev_global_regs->
03332 doepeachintmsk[ep->num], doepmsk.d32);
03333 }
03334 DWC_MODIFY_REG32(&dev_if->dev_global_regs->deachintmsk,
03335 0, daintmsk.d32);
03336 } else {
03337 if (ep->type == DWC_OTG_EP_TYPE_ISOC) {
03338 if (ep->is_in)
03339 {
03340 diepmsk_data_t diepmsk = {.d32 = 0 };
03341 diepmsk.b.nak = 1;
03342 DWC_MODIFY_REG32(&dev_if->dev_global_regs->diepmsk, 0, diepmsk.d32);
03343 } else {
03344 doepmsk_data_t doepmsk = {.d32 = 0 };
03345 doepmsk.b.outtknepdis = 1;
03346 DWC_MODIFY_REG32(&dev_if->dev_global_regs->doepmsk, 0, doepmsk.d32);
03347 }
03348 }
03349 DWC_MODIFY_REG32(&dev_if->dev_global_regs->daintmsk,
03350 0, daintmsk.d32);
03351 }
03352
03353 DWC_DEBUGPL(DBG_PCDV, "DAINTMSK=%0x\n",
03354 DWC_READ_REG32(&dev_if->dev_global_regs->daintmsk));
03355
03356 ep->stall_clear_flag = 0;
03357
03358 return;
03359 }
03360
03369 void dwc_otg_ep_deactivate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
03370 {
03371 depctl_data_t depctl = {.d32 = 0 };
03372 volatile uint32_t *addr;
03373 daint_data_t daintmsk = {.d32 = 0 };
03374 dcfg_data_t dcfg;
03375 uint8_t i = 0;
03376
03377 #ifdef DWC_UTE_PER_IO
03378 ep->xiso_frame_num = 0xFFFFFFFF;
03379 ep->xiso_active_xfers = 0;
03380 ep->xiso_queued_xfers = 0;
03381 #endif
03382
03383
03384 if (ep->is_in == 1) {
03385 addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl;
03386 daintmsk.ep.in = 1 << ep->num;
03387 } else {
03388 addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl;
03389 daintmsk.ep.out = 1 << ep->num;
03390 }
03391
03392 depctl.d32 = DWC_READ_REG32(addr);
03393
03394 depctl.b.usbactep = 0;
03395
03396
03397 if (!(depctl.b.eptype & 1) && ep->is_in == 1) {
03398 for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
03399 if (core_if->nextep_seq[i] == ep->num)
03400 break;
03401 }
03402 core_if->nextep_seq[i] = core_if->nextep_seq[ep->num];
03403 if (core_if->first_in_nextep_seq == ep->num)
03404 core_if->first_in_nextep_seq = i;
03405 core_if->nextep_seq[ep->num] = 0xff;
03406 depctl.b.nextep = 0;
03407 dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
03408 dcfg.b.epmscnt--;
03409 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg, dcfg.d32);
03410
03411 DWC_DEBUGPL(DBG_PCDV,"%s first_in_nextep_seq= %2d; nextep_seq[]:\n",
03412 __func__, core_if->first_in_nextep_seq);
03413 for (i=0; i <= core_if->dev_if->num_in_eps; i++) {
03414 DWC_DEBUGPL(DBG_PCDV, "%2d\n", core_if->nextep_seq[i]);
03415 }
03416 }
03417
03418 if (ep->is_in == 1)
03419 depctl.b.txfnum = 0;
03420
03421 if (core_if->dma_desc_enable)
03422 depctl.b.epdis = 1;
03423
03424 DWC_WRITE_REG32(addr, depctl.d32);
03425 depctl.d32 = DWC_READ_REG32(addr);
03426 if (core_if->dma_enable && ep->type == DWC_OTG_EP_TYPE_ISOC && depctl.b.epena)
03427 {
03428 depctl_data_t depctl = {.d32 = 0};
03429 if (ep->is_in)
03430 {
03431 diepint_data_t diepint = {.d32 = 0};
03432
03433 depctl.b.snak = 1;
03434 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[ep->num]->diepctl, depctl.d32);
03435 do
03436 {
03437 dwc_udelay(10);
03438 diepint.d32 = DWC_READ_REG32(&core_if->dev_if->
03439 in_ep_regs[ep->num]->diepint);
03440 } while (!diepint.b.inepnakeff);
03441 diepint.b.inepnakeff = 1;
03442 DWC_WRITE_REG32(&core_if->dev_if->
03443 in_ep_regs[ep->num]->diepint, diepint.d32);
03444 depctl.d32 = 0;
03445 depctl.b.epdis = 1;
03446 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[ep->num]->diepctl, depctl.d32);
03447 do
03448 {
03449 dwc_udelay(10);
03450 diepint.d32 = DWC_READ_REG32(&core_if->dev_if->
03451 in_ep_regs[ep->num]->diepint);
03452 } while (!diepint.b.epdisabled);
03453 diepint.b.epdisabled = 1;
03454 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[ep->num]->diepint, diepint.d32);
03455 } else {
03456 dctl_data_t dctl = {.d32 = 0};
03457 gintmsk_data_t gintsts = {.d32 = 0};
03458 doepint_data_t doepint = {.d32 = 0};
03459 dctl.b.sgoutnak = 1;
03460 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, 0, dctl.d32);
03461 do
03462 {
03463 dwc_udelay(10);
03464 gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
03465 } while (!gintsts.b.goutnakeff);
03466 gintsts.d32 = 0;
03467 gintsts.b.goutnakeff = 1;
03468 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
03469
03470 depctl.d32 = 0;
03471 depctl.b.epdis = 1;
03472 depctl.b.snak = 1;
03473 DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[ep->num]->doepctl, depctl.d32);
03474 do
03475 {
03476 dwc_udelay(10);
03477 doepint.d32 = DWC_READ_REG32(&core_if->dev_if->
03478 out_ep_regs[ep->num]->doepint);
03479 } while (!doepint.b.epdisabled);
03480
03481 doepint.b.epdisabled = 1;
03482 DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[ep->num]->doepint, doepint.d32);
03483
03484 dctl.d32 = 0;
03485 dctl.b.cgoutnak = 1;
03486 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, 0, dctl.d32);
03487 }
03488 }
03489
03490
03491 if (core_if->multiproc_int_enable) {
03492 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->deachintmsk,
03493 daintmsk.d32, 0);
03494
03495 if (ep->is_in == 1) {
03496 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->
03497 diepeachintmsk[ep->num], 0);
03498 } else {
03499 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->
03500 doepeachintmsk[ep->num], 0);
03501 }
03502 } else {
03503 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->daintmsk,
03504 daintmsk.d32, 0);
03505 }
03506
03507 }
03508
03515 static void init_dma_desc_chain(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
03516 {
03517 dwc_otg_dev_dma_desc_t *dma_desc;
03518 uint32_t offset;
03519 uint32_t xfer_est;
03520 int i;
03521 unsigned maxxfer_local, total_len;
03522
03523 if (!ep->is_in && ep->type == DWC_OTG_EP_TYPE_INTR &&
03524 (ep->maxpacket%4)) {
03525 maxxfer_local = ep->maxpacket;
03526 total_len = ep->xfer_len;
03527 } else {
03528 maxxfer_local = ep->maxxfer;
03529 total_len = ep->total_len;
03530 }
03531
03532 ep->desc_cnt = (total_len / maxxfer_local) +
03533 ((total_len % maxxfer_local) ? 1 : 0);
03534
03535 if (!ep->desc_cnt)
03536 ep->desc_cnt = 1;
03537
03538 if (ep->desc_cnt > MAX_DMA_DESC_CNT)
03539 ep->desc_cnt = MAX_DMA_DESC_CNT;
03540
03541 dma_desc = ep->desc_addr;
03542 if (maxxfer_local == ep->maxpacket) {
03543 if ((total_len % maxxfer_local) &&
03544 (total_len/maxxfer_local < MAX_DMA_DESC_CNT)) {
03545 xfer_est = (ep->desc_cnt - 1) * maxxfer_local +
03546 (total_len % maxxfer_local);
03547 } else
03548 xfer_est = ep->desc_cnt * maxxfer_local;
03549 }
03550 else
03551 xfer_est = total_len;
03552 offset = 0;
03553 for (i = 0; i < ep->desc_cnt; ++i) {
03555 if (xfer_est > maxxfer_local) {
03556 dma_desc->status.b.bs = BS_HOST_BUSY;
03557 dma_desc->status.b.l = 0;
03558 dma_desc->status.b.ioc = 0;
03559 dma_desc->status.b.sp = 0;
03560 dma_desc->status.b.bytes = maxxfer_local;
03561 dma_desc->buf = ep->dma_addr + offset;
03562 dma_desc->status.b.sts = 0;
03563 dma_desc->status.b.bs = BS_HOST_READY;
03564
03565 xfer_est -= maxxfer_local;
03566 offset += maxxfer_local;
03567 } else {
03568 dma_desc->status.b.bs = BS_HOST_BUSY;
03569 dma_desc->status.b.l = 1;
03570 dma_desc->status.b.ioc = 1;
03571 if (ep->is_in) {
03572 dma_desc->status.b.sp =
03573 (xfer_est %
03574 ep->maxpacket) ? 1 : ((ep->
03575 sent_zlp) ? 1 : 0);
03576 dma_desc->status.b.bytes = xfer_est;
03577 } else {
03578 if (maxxfer_local == ep->maxpacket)
03579 dma_desc->status.b.bytes = xfer_est;
03580 else
03581 dma_desc->status.b.bytes =
03582 xfer_est + ((4 - (xfer_est & 0x3)) & 0x3);
03583 }
03584
03585 dma_desc->buf = ep->dma_addr + offset;
03586 dma_desc->status.b.sts = 0;
03587 dma_desc->status.b.bs = BS_HOST_READY;
03588 }
03589 dma_desc++;
03590 }
03591 }
03596 static int32_t write_isoc_tx_fifo(dwc_otg_core_if_t * core_if, dwc_ep_t * dwc_ep)
03597 {
03598 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
03599 dwc_otg_dev_in_ep_regs_t *ep_regs;
03600 dtxfsts_data_t txstatus = {.d32 = 0 };
03601 uint32_t len = 0;
03602 int epnum = dwc_ep->num;
03603 int dwords;
03604
03605 DWC_DEBUGPL(DBG_PCD, "Dedicated TxFifo Empty: %d \n", epnum);
03606
03607 ep_regs = core_if->dev_if->in_ep_regs[epnum];
03608
03609 len = dwc_ep->xfer_len - dwc_ep->xfer_count;
03610
03611 if (len > dwc_ep->maxpacket) {
03612 len = dwc_ep->maxpacket;
03613 }
03614
03615 dwords = (len + 3) / 4;
03616
03617
03618
03619 txstatus.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts);
03620 DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", epnum, txstatus.d32);
03621
03622 while (txstatus.b.txfspcavail > dwords &&
03623 dwc_ep->xfer_count < dwc_ep->xfer_len &&
03624 dwc_ep->xfer_len != 0) {
03625
03626 dwc_otg_ep_write_packet(core_if, dwc_ep, 0);
03627
03628 len = dwc_ep->xfer_len - dwc_ep->xfer_count;
03629 if (len > dwc_ep->maxpacket) {
03630 len = dwc_ep->maxpacket;
03631 }
03632
03633 dwords = (len + 3) / 4;
03634 txstatus.d32 =
03635 DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts);
03636 DWC_DEBUGPL(DBG_PCDV, "dtxfsts[%d]=0x%08x\n", epnum,
03637 txstatus.d32);
03638 }
03639
03640 DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", epnum,
03641 DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts));
03642
03643 return 1;
03644 }
03655 void dwc_otg_ep_start_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
03656 {
03657 depctl_data_t depctl;
03658 deptsiz_data_t deptsiz;
03659 gintmsk_data_t intr_mask = {.d32 = 0 };
03660
03661 DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s()\n", __func__);
03662 DWC_DEBUGPL(DBG_PCD, "ep%d-%s xfer_len=%d xfer_cnt=%d "
03663 "xfer_buff=%p start_xfer_buff=%p, total_len = %d\n",
03664 ep->num, (ep->is_in ? "IN" : "OUT"), ep->xfer_len,
03665 ep->xfer_count, ep->xfer_buff, ep->start_xfer_buff,
03666 ep->total_len);
03667
03668 if (ep->is_in == 1) {
03669 dwc_otg_dev_in_ep_regs_t *in_regs =
03670 core_if->dev_if->in_ep_regs[ep->num];
03671
03672 gnptxsts_data_t gtxstatus;
03673
03674 gtxstatus.d32 =
03675 DWC_READ_REG32(&core_if->core_global_regs->gnptxsts);
03676
03677 if (core_if->en_multiple_tx_fifo == 0
03678 && gtxstatus.b.nptxqspcavail == 0
03679 && !core_if->dma_enable) {
03680 #ifdef DEBUG
03681 DWC_PRINTF("TX Queue Full (0x%0x)\n", gtxstatus.d32);
03682 #endif
03683 return;
03684 }
03685
03686 depctl.d32 = DWC_READ_REG32(&(in_regs->diepctl));
03687 deptsiz.d32 = DWC_READ_REG32(&(in_regs->dieptsiz));
03688
03689 if (ep->maxpacket > ep->maxxfer / MAX_PKT_CNT)
03690 ep->xfer_len += (ep->maxxfer < (ep->total_len - ep->xfer_len)) ?
03691 ep->maxxfer : (ep->total_len - ep->xfer_len);
03692 else
03693 ep->xfer_len += (MAX_PKT_CNT * ep->maxpacket < (ep->total_len - ep->xfer_len)) ?
03694 MAX_PKT_CNT * ep->maxpacket : (ep->total_len - ep->xfer_len);
03695
03696
03697
03698 if ((ep->xfer_len - ep->xfer_count) == 0) {
03699 deptsiz.b.xfersize = 0;
03700 deptsiz.b.pktcnt = 1;
03701 } else {
03702
03703
03704
03705
03706
03707 deptsiz.b.xfersize = ep->xfer_len - ep->xfer_count;
03708 deptsiz.b.pktcnt =
03709 (ep->xfer_len - ep->xfer_count - 1 +
03710 ep->maxpacket) / ep->maxpacket;
03711 if (deptsiz.b.pktcnt > MAX_PKT_CNT) {
03712 deptsiz.b.pktcnt = MAX_PKT_CNT;
03713 deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket;
03714 }
03715 if (ep->type == DWC_OTG_EP_TYPE_ISOC)
03716 deptsiz.b.mc = deptsiz.b.pktcnt;
03717 }
03718
03719
03720 if (core_if->dma_enable) {
03721 if (core_if->dma_desc_enable == 0) {
03722 if (ep->type != DWC_OTG_EP_TYPE_ISOC)
03723 deptsiz.b.mc = 1;
03724 DWC_WRITE_REG32(&in_regs->dieptsiz,
03725 deptsiz.d32);
03726 DWC_WRITE_REG32(&(in_regs->diepdma),
03727 (uint32_t) ep->dma_addr);
03728 } else {
03729 #ifdef DWC_UTE_CFI
03730
03731 if (ep->buff_mode != BM_STANDARD) {
03732 DWC_WRITE_REG32(&in_regs->diepdma,
03733 ep->descs_dma_addr);
03734 } else {
03735 #endif
03736 init_dma_desc_chain(core_if, ep);
03738 DWC_WRITE_REG32(&in_regs->diepdma,
03739 ep->dma_desc_addr);
03740 #ifdef DWC_UTE_CFI
03741 }
03742 #endif
03743 }
03744 } else {
03745 DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32);
03746 if (ep->type != DWC_OTG_EP_TYPE_ISOC) {
03752 if (core_if->en_multiple_tx_fifo == 0) {
03753 intr_mask.b.nptxfempty = 1;
03754 DWC_MODIFY_REG32
03755 (&core_if->core_global_regs->gintmsk,
03756 intr_mask.d32, intr_mask.d32);
03757 } else {
03758
03759 if (ep->xfer_len > 0) {
03760 uint32_t fifoemptymsk = 0;
03761 fifoemptymsk = 1 << ep->num;
03762 DWC_MODIFY_REG32
03763 (&core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
03764 0, fifoemptymsk);
03765
03766 }
03767 }
03768 } else {
03769 write_isoc_tx_fifo(core_if, ep);
03770 }
03771 }
03772 if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable)
03773 depctl.b.nextep = core_if->nextep_seq[ep->num];
03774
03775 if (ep->type == DWC_OTG_EP_TYPE_ISOC)
03776 {
03777 dsts_data_t dsts = {.d32 = 0};
03778 if (ep->bInterval == 1) {
03779 dsts.d32 =
03780 DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);
03781 ep->frame_num = dsts.b.soffn + ep->bInterval;
03782 if (ep->frame_num > 0x3FFF)
03783 {
03784 ep->frm_overrun = 1;
03785 ep->frame_num &= 0x3FFF;
03786 } else
03787 ep->frm_overrun = 0;
03788 if (ep->frame_num & 0x1) {
03789 depctl.b.setd1pid = 1;
03790 } else {
03791 depctl.b.setd0pid = 1;
03792 }
03793 }
03794 }
03795
03796 depctl.b.cnak = 1;
03797 depctl.b.epena = 1;
03798 DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32);
03799
03800 } else {
03801
03802 dwc_otg_dev_out_ep_regs_t *out_regs =
03803 core_if->dev_if->out_ep_regs[ep->num];
03804
03805 depctl.d32 = DWC_READ_REG32(&(out_regs->doepctl));
03806 deptsiz.d32 = DWC_READ_REG32(&(out_regs->doeptsiz));
03807
03808 if (!core_if->dma_desc_enable) {
03809 if (ep->maxpacket > ep->maxxfer / MAX_PKT_CNT)
03810 ep->xfer_len += (ep->maxxfer < (ep->total_len - ep->xfer_len)) ?
03811 ep->maxxfer : (ep->total_len - ep->xfer_len);
03812 else
03813 ep->xfer_len += (MAX_PKT_CNT * ep->maxpacket < (ep->total_len
03814 - ep->xfer_len)) ? MAX_PKT_CNT * ep->maxpacket : (ep->total_len - ep->xfer_len);
03815 }
03816
03817
03818
03819
03820
03821
03822 if ((ep->xfer_len - ep->xfer_count) == 0) {
03823
03824 deptsiz.b.xfersize = ep->maxpacket;
03825 deptsiz.b.pktcnt = 1;
03826 } else {
03827 deptsiz.b.pktcnt =
03828 (ep->xfer_len - ep->xfer_count +
03829 (ep->maxpacket - 1)) / ep->maxpacket;
03830 if (deptsiz.b.pktcnt > MAX_PKT_CNT) {
03831 deptsiz.b.pktcnt = MAX_PKT_CNT;
03832 }
03833 if (!core_if->dma_desc_enable) {
03834 ep->xfer_len =
03835 deptsiz.b.pktcnt * ep->maxpacket + ep->xfer_count;
03836 }
03837 deptsiz.b.xfersize = ep->xfer_len - ep->xfer_count;
03838 }
03839
03840 DWC_DEBUGPL(DBG_PCDV, "ep%d xfersize=%d pktcnt=%d\n",
03841 ep->num, deptsiz.b.xfersize, deptsiz.b.pktcnt);
03842
03843 if (core_if->dma_enable) {
03844 if (!core_if->dma_desc_enable) {
03845 DWC_WRITE_REG32(&out_regs->doeptsiz,
03846 deptsiz.d32);
03847
03848 DWC_WRITE_REG32(&(out_regs->doepdma),
03849 (uint32_t) ep->dma_addr);
03850 } else {
03851 #ifdef DWC_UTE_CFI
03852
03853 if (ep->buff_mode != BM_STANDARD) {
03854 DWC_WRITE_REG32(&out_regs->doepdma,
03855 ep->descs_dma_addr);
03856 } else {
03857 #endif
03858
03859 if (!ep->xfer_len)
03860 ep->xfer_len = ep->total_len;
03861 init_dma_desc_chain(core_if, ep);
03862
03863 if (core_if->core_params->dev_out_nak) {
03864 if (ep->type == DWC_OTG_EP_TYPE_BULK) {
03865 deptsiz.b.pktcnt = (ep->total_len +
03866 (ep->maxpacket - 1)) / ep->maxpacket;
03867 deptsiz.b.xfersize = ep->total_len;
03868
03869 core_if->start_doeptsiz_val[ep->num] = deptsiz.d32;
03870 DWC_WRITE_REG32(&out_regs->doeptsiz,
03871 deptsiz.d32);
03872 }
03873 }
03875 DWC_WRITE_REG32(&out_regs->doepdma,
03876 ep->dma_desc_addr);
03877 #ifdef DWC_UTE_CFI
03878 }
03879 #endif
03880 }
03881 } else {
03882 DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32);
03883 }
03884
03885 if (ep->type == DWC_OTG_EP_TYPE_ISOC)
03886 {
03887 dsts_data_t dsts = {.d32 = 0};
03888 if (ep->bInterval == 1) {
03889 dsts.d32 =
03890 DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);
03891 ep->frame_num = dsts.b.soffn + ep->bInterval;
03892 if (ep->frame_num > 0x3FFF)
03893 {
03894 ep->frm_overrun = 1;
03895 ep->frame_num &= 0x3FFF;
03896 } else
03897 ep->frm_overrun = 0;
03898
03899 if (ep->frame_num & 0x1) {
03900 depctl.b.setd1pid = 1;
03901 } else {
03902 depctl.b.setd0pid = 1;
03903 }
03904 }
03905 }
03906
03907
03908 depctl.b.cnak = 1;
03909 depctl.b.epena = 1;
03910
03911 DWC_WRITE_REG32(&out_regs->doepctl, depctl.d32);
03912
03913 DWC_DEBUGPL(DBG_PCD, "DOEPCTL=%08x DOEPTSIZ=%08x\n",
03914 DWC_READ_REG32(&out_regs->doepctl),
03915 DWC_READ_REG32(&out_regs->doeptsiz));
03916 DWC_DEBUGPL(DBG_PCD, "DAINTMSK=%08x GINTMSK=%08x\n",
03917 DWC_READ_REG32(&core_if->dev_if->
03918 dev_global_regs->daintmsk),
03919 DWC_READ_REG32(&core_if->
03920 core_global_regs->gintmsk));
03921
03922
03923
03924
03925
03926
03927 if (core_if->core_params->dev_out_nak) {
03928 if (ep->type == DWC_OTG_EP_TYPE_BULK) {
03929 core_if->ep_xfer_info[ep->num].core_if = core_if;
03930 core_if->ep_xfer_info[ep->num].ep = ep;
03931 core_if->ep_xfer_info[ep->num].state = 1;
03932
03933
03934 DWC_TIMER_SCHEDULE(core_if->ep_xfer_timer[ep->num], 10000);
03935 }
03936 }
03937 }
03938 }
03939
03948 void dwc_otg_ep_start_zl_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
03949 {
03950
03951 depctl_data_t depctl;
03952 deptsiz_data_t deptsiz;
03953 gintmsk_data_t intr_mask = {.d32 = 0 };
03954
03955 DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s()\n", __func__);
03956 DWC_PRINTF("zero length transfer is called\n");
03957
03958
03959 if (ep->is_in == 1) {
03960 dwc_otg_dev_in_ep_regs_t *in_regs =
03961 core_if->dev_if->in_ep_regs[ep->num];
03962
03963 depctl.d32 = DWC_READ_REG32(&(in_regs->diepctl));
03964 deptsiz.d32 = DWC_READ_REG32(&(in_regs->dieptsiz));
03965
03966 deptsiz.b.xfersize = 0;
03967 deptsiz.b.pktcnt = 1;
03968
03969
03970 if (core_if->dma_enable) {
03971 if (core_if->dma_desc_enable == 0) {
03972 deptsiz.b.mc = 1;
03973 DWC_WRITE_REG32(&in_regs->dieptsiz,
03974 deptsiz.d32);
03975 DWC_WRITE_REG32(&(in_regs->diepdma),
03976 (uint32_t) ep->dma_addr);
03977 }
03978 } else {
03979 DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32);
03985 if (core_if->en_multiple_tx_fifo == 0) {
03986 intr_mask.b.nptxfempty = 1;
03987 DWC_MODIFY_REG32(&core_if->
03988 core_global_regs->gintmsk,
03989 intr_mask.d32, intr_mask.d32);
03990 } else {
03991
03992 if (ep->xfer_len > 0) {
03993 uint32_t fifoemptymsk = 0;
03994 fifoemptymsk = 1 << ep->num;
03995 DWC_MODIFY_REG32(&core_if->
03996 dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
03997 0, fifoemptymsk);
03998 }
03999 }
04000 }
04001
04002 if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable)
04003 depctl.b.nextep = core_if->nextep_seq[ep->num];
04004
04005 depctl.b.cnak = 1;
04006 depctl.b.epena = 1;
04007 DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32);
04008
04009 } else {
04010
04011 dwc_otg_dev_out_ep_regs_t *out_regs =
04012 core_if->dev_if->out_ep_regs[ep->num];
04013
04014 depctl.d32 = DWC_READ_REG32(&(out_regs->doepctl));
04015 deptsiz.d32 = DWC_READ_REG32(&(out_regs->doeptsiz));
04016
04017
04018 deptsiz.b.xfersize = ep->maxpacket;
04019 deptsiz.b.pktcnt = 1;
04020
04021 if (core_if->dma_enable) {
04022 if (!core_if->dma_desc_enable) {
04023 DWC_WRITE_REG32(&out_regs->doeptsiz,
04024 deptsiz.d32);
04025
04026 DWC_WRITE_REG32(&(out_regs->doepdma),
04027 (uint32_t) ep->dma_addr);
04028 }
04029 } else {
04030 DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32);
04031 }
04032
04033
04034 depctl.b.cnak = 1;
04035 depctl.b.epena = 1;
04036
04037 DWC_WRITE_REG32(&out_regs->doepctl, depctl.d32);
04038
04039 }
04040 }
04041
04051 void dwc_otg_ep0_start_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
04052 {
04053 depctl_data_t depctl;
04054 deptsiz0_data_t deptsiz;
04055 gintmsk_data_t intr_mask = {.d32 = 0 };
04056 dwc_otg_dev_dma_desc_t *dma_desc;
04057
04058 DWC_DEBUGPL(DBG_PCD, "ep%d-%s xfer_len=%d xfer_cnt=%d "
04059 "xfer_buff=%p start_xfer_buff=%p \n",
04060 ep->num, (ep->is_in ? "IN" : "OUT"), ep->xfer_len,
04061 ep->xfer_count, ep->xfer_buff, ep->start_xfer_buff);
04062
04063 ep->total_len = ep->xfer_len;
04064
04065
04066 if (ep->is_in == 1) {
04067 dwc_otg_dev_in_ep_regs_t *in_regs =
04068 core_if->dev_if->in_ep_regs[0];
04069
04070 gnptxsts_data_t gtxstatus;
04071
04072 gtxstatus.d32 =
04073 DWC_READ_REG32(&core_if->core_global_regs->gnptxsts);
04074
04075 if (core_if->en_multiple_tx_fifo == 0
04076 && gtxstatus.b.nptxqspcavail == 0
04077 && !core_if->dma_enable) {
04078 #ifdef DEBUG
04079 deptsiz.d32 = DWC_READ_REG32(&in_regs->dieptsiz);
04080 DWC_DEBUGPL(DBG_PCD, "DIEPCTL0=%0x\n",
04081 DWC_READ_REG32(&in_regs->diepctl));
04082 DWC_DEBUGPL(DBG_PCD, "DIEPTSIZ0=%0x (sz=%d, pcnt=%d)\n",
04083 deptsiz.d32,
04084 deptsiz.b.xfersize, deptsiz.b.pktcnt);
04085 DWC_PRINTF("TX Queue or FIFO Full (0x%0x)\n",
04086 gtxstatus.d32);
04087 #endif
04088 return;
04089 }
04090
04091 depctl.d32 = DWC_READ_REG32(&in_regs->diepctl);
04092 deptsiz.d32 = DWC_READ_REG32(&in_regs->dieptsiz);
04093
04094
04095 if (ep->xfer_len == 0) {
04096 deptsiz.b.xfersize = 0;
04097 deptsiz.b.pktcnt = 1;
04098 } else {
04099
04100
04101
04102
04103
04104 if (ep->xfer_len > ep->maxpacket) {
04105 ep->xfer_len = ep->maxpacket;
04106 deptsiz.b.xfersize = ep->maxpacket;
04107 } else {
04108 deptsiz.b.xfersize = ep->xfer_len;
04109 }
04110 deptsiz.b.pktcnt = 1;
04111
04112 }
04113 DWC_DEBUGPL(DBG_PCDV,
04114 "IN len=%d xfersize=%d pktcnt=%d [%08x]\n",
04115 ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt,
04116 deptsiz.d32);
04117
04118
04119 if (core_if->dma_enable) {
04120 if (core_if->dma_desc_enable == 0) {
04121 DWC_WRITE_REG32(&in_regs->dieptsiz,
04122 deptsiz.d32);
04123
04124 DWC_WRITE_REG32(&(in_regs->diepdma),
04125 (uint32_t) ep->dma_addr);
04126 } else {
04127 dma_desc = core_if->dev_if->in_desc_addr;
04128
04130 dma_desc->status.b.bs = BS_HOST_BUSY;
04131 dma_desc->status.b.l = 1;
04132 dma_desc->status.b.ioc = 1;
04133 dma_desc->status.b.sp =
04134 (ep->xfer_len == ep->maxpacket) ? 0 : 1;
04135 dma_desc->status.b.bytes = ep->xfer_len;
04136 dma_desc->buf = ep->dma_addr;
04137 dma_desc->status.b.sts = 0;
04138 dma_desc->status.b.bs = BS_HOST_READY;
04139
04141 DWC_WRITE_REG32(&in_regs->diepdma,
04142 core_if->
04143 dev_if->dma_in_desc_addr);
04144 }
04145 } else {
04146 DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32);
04147 }
04148
04149 if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable)
04150 depctl.b.nextep = core_if->nextep_seq[ep->num];
04151
04152 depctl.b.cnak = 1;
04153 depctl.b.epena = 1;
04154 DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32);
04155
04160 if (!core_if->dma_enable) {
04161 if (core_if->en_multiple_tx_fifo == 0) {
04162 intr_mask.b.nptxfempty = 1;
04163 DWC_MODIFY_REG32(&core_if->
04164 core_global_regs->gintmsk,
04165 intr_mask.d32, intr_mask.d32);
04166 } else {
04167
04168 if (ep->xfer_len > 0) {
04169 uint32_t fifoemptymsk = 0;
04170 fifoemptymsk |= 1 << ep->num;
04171 DWC_MODIFY_REG32(&core_if->
04172 dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
04173 0, fifoemptymsk);
04174 }
04175 }
04176 }
04177 } else {
04178
04179 dwc_otg_dev_out_ep_regs_t *out_regs =
04180 core_if->dev_if->out_ep_regs[0];
04181
04182 depctl.d32 = DWC_READ_REG32(&out_regs->doepctl);
04183 deptsiz.d32 = DWC_READ_REG32(&out_regs->doeptsiz);
04184
04185
04186
04187
04188
04189 deptsiz.b.xfersize = ep->maxpacket;
04190 deptsiz.b.pktcnt = 1;
04191
04192 DWC_DEBUGPL(DBG_PCDV, "len=%d xfersize=%d pktcnt=%d\n",
04193 ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt);
04194
04195 if (core_if->dma_enable) {
04196 if (!core_if->dma_desc_enable) {
04197 DWC_WRITE_REG32(&out_regs->doeptsiz,
04198 deptsiz.d32);
04199
04200 DWC_WRITE_REG32(&(out_regs->doepdma),
04201 (uint32_t) ep->dma_addr);
04202 } else {
04203 dma_desc = core_if->dev_if->out_desc_addr;
04204
04206 dma_desc->status.b.bs = BS_HOST_BUSY;
04207 dma_desc->status.b.l = 1;
04208 dma_desc->status.b.ioc = 1;
04209 dma_desc->status.b.bytes = ep->maxpacket;
04210 dma_desc->buf = ep->dma_addr;
04211 dma_desc->status.b.sts = 0;
04212 dma_desc->status.b.bs = BS_HOST_READY;
04213
04215 DWC_WRITE_REG32(&out_regs->doepdma,
04216 core_if->
04217 dev_if->dma_out_desc_addr);
04218 }
04219 } else {
04220 DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32);
04221 }
04222
04223
04224 depctl.b.cnak = 1;
04225 depctl.b.epena = 1;
04226 DWC_WRITE_REG32(&(out_regs->doepctl), depctl.d32);
04227 }
04228 }
04229
04239 void dwc_otg_ep0_continue_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
04240 {
04241 depctl_data_t depctl;
04242 deptsiz0_data_t deptsiz;
04243 gintmsk_data_t intr_mask = {.d32 = 0 };
04244 dwc_otg_dev_dma_desc_t *dma_desc;
04245
04246 if (ep->is_in == 1) {
04247 dwc_otg_dev_in_ep_regs_t *in_regs =
04248 core_if->dev_if->in_ep_regs[0];
04249 gnptxsts_data_t tx_status = {.d32 = 0 };
04250
04251 tx_status.d32 =
04252 DWC_READ_REG32(&core_if->core_global_regs->gnptxsts);
04256 depctl.d32 = DWC_READ_REG32(&in_regs->diepctl);
04257 deptsiz.d32 = DWC_READ_REG32(&in_regs->dieptsiz);
04258
04259
04260
04261
04262
04263
04264
04265 if (core_if->dma_desc_enable == 0) {
04266 deptsiz.b.xfersize =
04267 (ep->total_len - ep->xfer_count) >
04268 ep->maxpacket ? ep->maxpacket : (ep->total_len -
04269 ep->xfer_count);
04270 deptsiz.b.pktcnt = 1;
04271 if (core_if->dma_enable == 0) {
04272 ep->xfer_len += deptsiz.b.xfersize;
04273 } else {
04274 ep->xfer_len = deptsiz.b.xfersize;
04275 }
04276 DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32);
04277 } else {
04278 ep->xfer_len =
04279 (ep->total_len - ep->xfer_count) >
04280 ep->maxpacket ? ep->maxpacket : (ep->total_len -
04281 ep->xfer_count);
04282
04283 dma_desc = core_if->dev_if->in_desc_addr;
04284
04286 dma_desc->status.b.bs = BS_HOST_BUSY;
04287 dma_desc->status.b.l = 1;
04288 dma_desc->status.b.ioc = 1;
04289 dma_desc->status.b.sp =
04290 (ep->xfer_len == ep->maxpacket) ? 0 : 1;
04291 dma_desc->status.b.bytes = ep->xfer_len;
04292 dma_desc->buf = ep->dma_addr;
04293 dma_desc->status.b.sts = 0;
04294 dma_desc->status.b.bs = BS_HOST_READY;
04295
04297 DWC_WRITE_REG32(&in_regs->diepdma,
04298 core_if->dev_if->dma_in_desc_addr);
04299 }
04300
04301 DWC_DEBUGPL(DBG_PCDV,
04302 "IN len=%d xfersize=%d pktcnt=%d [%08x]\n",
04303 ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt,
04304 deptsiz.d32);
04305
04306
04307 if (core_if->hwcfg2.b.architecture == DWC_INT_DMA_ARCH) {
04308 if (core_if->dma_desc_enable == 0)
04309 DWC_WRITE_REG32(&(in_regs->diepdma),
04310 (uint32_t) ep->dma_addr);
04311 }
04312 if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable)
04313 depctl.b.nextep = core_if->nextep_seq[ep->num];
04314
04315 depctl.b.cnak = 1;
04316 depctl.b.epena = 1;
04317 DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32);
04318
04323 if (!core_if->dma_enable) {
04324 if (core_if->en_multiple_tx_fifo == 0) {
04325
04326 intr_mask.b.nptxfempty = 1;
04327 DWC_MODIFY_REG32(&core_if->
04328 core_global_regs->gintmsk,
04329 intr_mask.d32, intr_mask.d32);
04330
04331 } else {
04332
04333 if (ep->xfer_len > 0) {
04334 uint32_t fifoemptymsk = 0;
04335 fifoemptymsk |= 1 << ep->num;
04336 DWC_MODIFY_REG32(&core_if->
04337 dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
04338 0, fifoemptymsk);
04339 }
04340 }
04341 }
04342 } else {
04343 dwc_otg_dev_out_ep_regs_t *out_regs =
04344 core_if->dev_if->out_ep_regs[0];
04345
04346 depctl.d32 = DWC_READ_REG32(&out_regs->doepctl);
04347 deptsiz.d32 = DWC_READ_REG32(&out_regs->doeptsiz);
04348
04349
04350
04351
04352
04353
04354 deptsiz.b.xfersize = ep->maxpacket;
04355 deptsiz.b.pktcnt = 1;
04356
04357 if (core_if->dma_desc_enable == 0) {
04358 DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32);
04359 } else {
04360 dma_desc = core_if->dev_if->out_desc_addr;
04361
04363 dma_desc->status.b.bs = BS_HOST_BUSY;
04364 dma_desc->status.b.l = 1;
04365 dma_desc->status.b.ioc = 1;
04366 dma_desc->status.b.bytes = ep->maxpacket;
04367 dma_desc->buf = ep->dma_addr;
04368 dma_desc->status.b.sts = 0;
04369 dma_desc->status.b.bs = BS_HOST_READY;
04370
04372 DWC_WRITE_REG32(&out_regs->doepdma,
04373 core_if->dev_if->dma_out_desc_addr);
04374 }
04375
04376 DWC_DEBUGPL(DBG_PCDV,
04377 "IN len=%d xfersize=%d pktcnt=%d [%08x]\n",
04378 ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt,
04379 deptsiz.d32);
04380
04381
04382 if (core_if->hwcfg2.b.architecture == DWC_INT_DMA_ARCH) {
04383 if (core_if->dma_desc_enable == 0)
04384 DWC_WRITE_REG32(&(out_regs->doepdma),
04385 (uint32_t) ep->dma_addr);
04386
04387 }
04388
04389
04390 depctl.b.cnak = 1;
04391 depctl.b.epena = 1;
04392 DWC_WRITE_REG32(&out_regs->doepctl, depctl.d32);
04393
04394 }
04395 }
04396
04397 #ifdef DEBUG
04398 void dump_msg(const u8 * buf, unsigned int length)
04399 {
04400 unsigned int start, num, i;
04401 char line[52], *p;
04402
04403 if (length >= 512)
04404 return;
04405 start = 0;
04406 while (length > 0) {
04407 num = length < 16u ? length : 16u;
04408 p = line;
04409 for (i = 0; i < num; ++i) {
04410 if (i == 8)
04411 *p++ = ' ';
04412 DWC_SPRINTF(p, " %02x", buf[i]);
04413 p += 3;
04414 }
04415 *p = 0;
04416 DWC_PRINTF("%6x: %s\n", start, line);
04417 buf += num;
04418 start += num;
04419 length -= num;
04420 }
04421 }
04422 #else
04423 static inline void dump_msg(const u8 * buf, unsigned int length)
04424 {
04425 }
04426 #endif
04427
04438 void dwc_otg_ep_write_packet(dwc_otg_core_if_t * core_if, dwc_ep_t * ep,
04439 int dma)
04440 {
04456 uint32_t i;
04457 uint32_t byte_count;
04458 uint32_t dword_count;
04459 uint32_t *fifo;
04460 uint32_t *data_buff = (uint32_t *) ep->xfer_buff;
04461
04462 DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s(%p,%p)\n", __func__, core_if,
04463 ep);
04464 if (ep->xfer_count >= ep->xfer_len) {
04465 DWC_WARN("%s() No data for EP%d!!!\n", __func__, ep->num);
04466 return;
04467 }
04468
04469
04470 if ((ep->xfer_len - ep->xfer_count) < ep->maxpacket) {
04471 byte_count = ep->xfer_len - ep->xfer_count;
04472 } else {
04473 byte_count = ep->maxpacket;
04474 }
04475
04476
04477
04478 dword_count = (byte_count + 3) / 4;
04479
04480 #ifdef VERBOSE
04481 dump_msg(ep->xfer_buff, byte_count);
04482 #endif
04483
04487 fifo = core_if->data_fifo[ep->num];
04488
04489 DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "fifo=%p buff=%p *p=%08x bc=%d\n",
04490 fifo, data_buff, *data_buff, byte_count);
04491
04492 if (!dma) {
04493 for (i = 0; i < dword_count; i++, data_buff++) {
04494 DWC_WRITE_REG32(fifo, *data_buff);
04495 }
04496 }
04497
04498 ep->xfer_count += byte_count;
04499 ep->xfer_buff += byte_count;
04500 ep->dma_addr += byte_count;
04501 }
04502
04509 void dwc_otg_ep_set_stall(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
04510 {
04511 depctl_data_t depctl;
04512 volatile uint32_t *depctl_addr;
04513
04514 DWC_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, ep->num,
04515 (ep->is_in ? "IN" : "OUT"));
04516
04517 if (ep->is_in == 1) {
04518 depctl_addr = &(core_if->dev_if->in_ep_regs[ep->num]->diepctl);
04519 depctl.d32 = DWC_READ_REG32(depctl_addr);
04520
04521
04522 if (depctl.b.epena) {
04523 depctl.b.epdis = 1;
04524 }
04525 depctl.b.stall = 1;
04526 DWC_WRITE_REG32(depctl_addr, depctl.d32);
04527 } else {
04528 depctl_addr = &(core_if->dev_if->out_ep_regs[ep->num]->doepctl);
04529 depctl.d32 = DWC_READ_REG32(depctl_addr);
04530
04531
04532 depctl.b.stall = 1;
04533 DWC_WRITE_REG32(depctl_addr, depctl.d32);
04534 }
04535
04536 DWC_DEBUGPL(DBG_PCD, "DEPCTL=%0x\n", DWC_READ_REG32(depctl_addr));
04537
04538 return;
04539 }
04540
04547 void dwc_otg_ep_clear_stall(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
04548 {
04549 depctl_data_t depctl;
04550 volatile uint32_t *depctl_addr;
04551
04552 DWC_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, ep->num,
04553 (ep->is_in ? "IN" : "OUT"));
04554
04555 if (ep->is_in == 1) {
04556 depctl_addr = &(core_if->dev_if->in_ep_regs[ep->num]->diepctl);
04557 } else {
04558 depctl_addr = &(core_if->dev_if->out_ep_regs[ep->num]->doepctl);
04559 }
04560
04561 depctl.d32 = DWC_READ_REG32(depctl_addr);
04562
04563
04564 depctl.b.stall = 0;
04565
04566
04567
04568
04569
04570
04571
04572 if (ep->type == DWC_OTG_EP_TYPE_INTR ||
04573 ep->type == DWC_OTG_EP_TYPE_BULK) {
04574 depctl.b.setd0pid = 1;
04575 }
04576
04577 DWC_WRITE_REG32(depctl_addr, depctl.d32);
04578 DWC_DEBUGPL(DBG_PCD, "DEPCTL=%0x\n", DWC_READ_REG32(depctl_addr));
04579 return;
04580 }
04581
04590 void dwc_otg_read_packet(dwc_otg_core_if_t * core_if,
04591 uint8_t * dest, uint16_t bytes)
04592 {
04593 int i;
04594 int word_count = (bytes + 3) / 4;
04595
04596 volatile uint32_t *fifo = core_if->data_fifo[0];
04597 uint32_t *data_buff = (uint32_t *) dest;
04598
04605 DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s(%p,%p,%d)\n", __func__,
04606 core_if, dest, bytes);
04607
04608 for (i = 0; i < word_count; i++, data_buff++) {
04609 *data_buff = DWC_READ_REG32(fifo);
04610 }
04611
04612 return;
04613 }
04614
04620 void dwc_otg_dump_dev_registers(dwc_otg_core_if_t * core_if)
04621 {
04622 int i;
04623 volatile uint32_t *addr;
04624
04625 DWC_PRINTF("Device Global Registers\n");
04626 addr = &core_if->dev_if->dev_global_regs->dcfg;
04627 DWC_PRINTF("DCFG @0x%08lX : 0x%08X\n", (unsigned long) addr,
04628 DWC_READ_REG32(addr));
04629 addr = &core_if->dev_if->dev_global_regs->dctl;
04630 DWC_PRINTF("DCTL @0x%08lX : 0x%08X\n", (unsigned long) addr,
04631 DWC_READ_REG32(addr));
04632 addr = &core_if->dev_if->dev_global_regs->dsts;
04633 DWC_PRINTF("DSTS @0x%08lX : 0x%08X\n", (unsigned long) addr,
04634 DWC_READ_REG32(addr));
04635 addr = &core_if->dev_if->dev_global_regs->diepmsk;
04636 DWC_PRINTF("DIEPMSK @0x%08lX : 0x%08X\n", (unsigned long)addr,
04637 DWC_READ_REG32(addr));
04638 addr = &core_if->dev_if->dev_global_regs->doepmsk;
04639 DWC_PRINTF("DOEPMSK @0x%08lX : 0x%08X\n", (unsigned long)addr,
04640 DWC_READ_REG32(addr));
04641 addr = &core_if->dev_if->dev_global_regs->daint;
04642 DWC_PRINTF("DAINT @0x%08lX : 0x%08X\n", (unsigned long)addr,
04643 DWC_READ_REG32(addr));
04644 addr = &core_if->dev_if->dev_global_regs->daintmsk;
04645 DWC_PRINTF("DAINTMSK @0x%08lX : 0x%08X\n", (unsigned long)addr,
04646 DWC_READ_REG32(addr));
04647 addr = &core_if->dev_if->dev_global_regs->dtknqr1;
04648 DWC_PRINTF("DTKNQR1 @0x%08lX : 0x%08X\n", (unsigned long)addr,
04649 DWC_READ_REG32(addr));
04650 if (core_if->hwcfg2.b.dev_token_q_depth > 6) {
04651 addr = &core_if->dev_if->dev_global_regs->dtknqr2;
04652 DWC_PRINTF("DTKNQR2 @0x%08lX : 0x%08X\n",
04653 (unsigned long)addr, DWC_READ_REG32(addr));
04654 }
04655
04656 addr = &core_if->dev_if->dev_global_regs->dvbusdis;
04657 DWC_PRINTF("DVBUSID @0x%08lX : 0x%08X\n", (unsigned long)addr,
04658 DWC_READ_REG32(addr));
04659
04660 addr = &core_if->dev_if->dev_global_regs->dvbuspulse;
04661 DWC_PRINTF("DVBUSPULSE @0x%08lX : 0x%08X\n",
04662 (unsigned long)addr, DWC_READ_REG32(addr));
04663
04664 addr = &core_if->dev_if->dev_global_regs->dtknqr3_dthrctl;
04665 DWC_PRINTF("DTKNQR3_DTHRCTL @0x%08lX : 0x%08X\n",
04666 (unsigned long)addr, DWC_READ_REG32(addr));
04667
04668 if (core_if->hwcfg2.b.dev_token_q_depth > 22) {
04669 addr = &core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk;
04670 DWC_PRINTF("DTKNQR4 @0x%08lX : 0x%08X\n",
04671 (unsigned long)addr, DWC_READ_REG32(addr));
04672 }
04673
04674 addr = &core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk;
04675 DWC_PRINTF("FIFOEMPMSK @0x%08lX : 0x%08X\n", (unsigned long)addr,
04676 DWC_READ_REG32(addr));
04677
04678 if (core_if->hwcfg2.b.multi_proc_int) {
04679
04680 addr = &core_if->dev_if->dev_global_regs->deachint;
04681 DWC_PRINTF("DEACHINT @0x%08lX : 0x%08X\n",
04682 (unsigned long)addr, DWC_READ_REG32(addr));
04683 addr = &core_if->dev_if->dev_global_regs->deachintmsk;
04684 DWC_PRINTF("DEACHINTMSK @0x%08lX : 0x%08X\n",
04685 (unsigned long)addr, DWC_READ_REG32(addr));
04686
04687 for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
04688 addr =
04689 &core_if->dev_if->dev_global_regs->
04690 diepeachintmsk[i];
04691 DWC_PRINTF("DIEPEACHINTMSK[%d] @0x%08lX : 0x%08X\n",
04692 i, (unsigned long)addr,
04693 DWC_READ_REG32(addr));
04694 }
04695
04696 for (i = 0; i <= core_if->dev_if->num_out_eps; i++) {
04697 addr =
04698 &core_if->dev_if->dev_global_regs->
04699 doepeachintmsk[i];
04700 DWC_PRINTF("DOEPEACHINTMSK[%d] @0x%08lX : 0x%08X\n",
04701 i, (unsigned long)addr,
04702 DWC_READ_REG32(addr));
04703 }
04704 }
04705
04706 for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
04707 DWC_PRINTF("Device IN EP %d Registers\n", i);
04708 addr = &core_if->dev_if->in_ep_regs[i]->diepctl;
04709 DWC_PRINTF("DIEPCTL @0x%08lX : 0x%08X\n",
04710 (unsigned long)addr, DWC_READ_REG32(addr));
04711 addr = &core_if->dev_if->in_ep_regs[i]->diepint;
04712 DWC_PRINTF("DIEPINT @0x%08lX : 0x%08X\n",
04713 (unsigned long)addr, DWC_READ_REG32(addr));
04714 addr = &core_if->dev_if->in_ep_regs[i]->dieptsiz;
04715 DWC_PRINTF("DIETSIZ @0x%08lX : 0x%08X\n",
04716 (unsigned long)addr, DWC_READ_REG32(addr));
04717 addr = &core_if->dev_if->in_ep_regs[i]->diepdma;
04718 DWC_PRINTF("DIEPDMA @0x%08lX : 0x%08X\n",
04719 (unsigned long)addr, DWC_READ_REG32(addr));
04720 addr = &core_if->dev_if->in_ep_regs[i]->dtxfsts;
04721 DWC_PRINTF("DTXFSTS @0x%08lX : 0x%08X\n",
04722 (unsigned long)addr, DWC_READ_REG32(addr));
04723 addr = &core_if->dev_if->in_ep_regs[i]->diepdmab;
04724 DWC_PRINTF("DIEPDMAB @0x%08lX : 0x%08X\n",
04725 (unsigned long)addr, 0 );
04726 }
04727
04728 for (i = 0; i <= core_if->dev_if->num_out_eps; i++) {
04729 DWC_PRINTF("Device OUT EP %d Registers\n", i);
04730 addr = &core_if->dev_if->out_ep_regs[i]->doepctl;
04731 DWC_PRINTF("DOEPCTL @0x%08lX : 0x%08X\n",
04732 (unsigned long)addr, DWC_READ_REG32(addr));
04733 addr = &core_if->dev_if->out_ep_regs[i]->doepint;
04734 DWC_PRINTF("DOEPINT @0x%08lX : 0x%08X\n",
04735 (unsigned long)addr, DWC_READ_REG32(addr));
04736 addr = &core_if->dev_if->out_ep_regs[i]->doeptsiz;
04737 DWC_PRINTF("DOETSIZ @0x%08lX : 0x%08X\n",
04738 (unsigned long)addr, DWC_READ_REG32(addr));
04739 addr = &core_if->dev_if->out_ep_regs[i]->doepdma;
04740 DWC_PRINTF("DOEPDMA @0x%08lX : 0x%08X\n",
04741 (unsigned long)addr, DWC_READ_REG32(addr));
04742 if (core_if->dma_enable) {
04743 addr = &core_if->dev_if->out_ep_regs[i]->doepdmab;
04744 DWC_PRINTF("DOEPDMAB @0x%08lX : 0x%08X\n",
04745 (unsigned long)addr, DWC_READ_REG32(addr));
04746 }
04747
04748 }
04749 }
04750
04756 void dwc_otg_dump_spram(dwc_otg_core_if_t * core_if)
04757 {
04758 volatile uint8_t *addr, *start_addr, *end_addr;
04759
04760 DWC_PRINTF("SPRAM Data:\n");
04761 start_addr = (void *)core_if->core_global_regs;
04762 DWC_PRINTF("Base Address: 0x%8lX\n", (unsigned long)start_addr);
04763 start_addr += 0x00028000;
04764 end_addr = (void *)core_if->core_global_regs;
04765 end_addr += 0x000280e0;
04766
04767 for (addr = start_addr; addr < end_addr; addr += 16) {
04768 DWC_PRINTF
04769 ("0x%8lX:\t%2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X\n",
04770 (unsigned long)addr, addr[0], addr[1], addr[2], addr[3],
04771 addr[4], addr[5], addr[6], addr[7], addr[8], addr[9],
04772 addr[10], addr[11], addr[12], addr[13], addr[14], addr[15]
04773 );
04774 }
04775
04776 return;
04777 }
04778
04784 void dwc_otg_dump_host_registers(dwc_otg_core_if_t * core_if)
04785 {
04786 int i;
04787 volatile uint32_t *addr;
04788
04789 DWC_PRINTF("Host Global Registers\n");
04790 addr = &core_if->host_if->host_global_regs->hcfg;
04791 DWC_PRINTF("HCFG @0x%08lX : 0x%08X\n",
04792 (unsigned long)addr, DWC_READ_REG32(addr));
04793 addr = &core_if->host_if->host_global_regs->hfir;
04794 DWC_PRINTF("HFIR @0x%08lX : 0x%08X\n",
04795 (unsigned long)addr, DWC_READ_REG32(addr));
04796 addr = &core_if->host_if->host_global_regs->hfnum;
04797 DWC_PRINTF("HFNUM @0x%08lX : 0x%08X\n", (unsigned long)addr,
04798 DWC_READ_REG32(addr));
04799 addr = &core_if->host_if->host_global_regs->hptxsts;
04800 DWC_PRINTF("HPTXSTS @0x%08lX : 0x%08X\n", (unsigned long)addr,
04801 DWC_READ_REG32(addr));
04802 addr = &core_if->host_if->host_global_regs->haint;
04803 DWC_PRINTF("HAINT @0x%08lX : 0x%08X\n", (unsigned long)addr,
04804 DWC_READ_REG32(addr));
04805 addr = &core_if->host_if->host_global_regs->haintmsk;
04806 DWC_PRINTF("HAINTMSK @0x%08lX : 0x%08X\n", (unsigned long)addr,
04807 DWC_READ_REG32(addr));
04808 if (core_if->dma_desc_enable) {
04809 addr = &core_if->host_if->host_global_regs->hflbaddr;
04810 DWC_PRINTF("HFLBADDR @0x%08lX : 0x%08X\n",
04811 (unsigned long)addr, DWC_READ_REG32(addr));
04812 }
04813
04814 addr = core_if->host_if->hprt0;
04815 DWC_PRINTF("HPRT0 @0x%08lX : 0x%08X\n", (unsigned long)addr,
04816 DWC_READ_REG32(addr));
04817
04818 for (i = 0; i < core_if->core_params->host_channels; i++) {
04819 DWC_PRINTF("Host Channel %d Specific Registers\n", i);
04820 addr = &core_if->host_if->hc_regs[i]->hcchar;
04821 DWC_PRINTF("HCCHAR @0x%08lX : 0x%08X\n",
04822 (unsigned long)addr, DWC_READ_REG32(addr));
04823 addr = &core_if->host_if->hc_regs[i]->hcsplt;
04824 DWC_PRINTF("HCSPLT @0x%08lX : 0x%08X\n",
04825 (unsigned long)addr, DWC_READ_REG32(addr));
04826 addr = &core_if->host_if->hc_regs[i]->hcint;
04827 DWC_PRINTF("HCINT @0x%08lX : 0x%08X\n",
04828 (unsigned long)addr, DWC_READ_REG32(addr));
04829 addr = &core_if->host_if->hc_regs[i]->hcintmsk;
04830 DWC_PRINTF("HCINTMSK @0x%08lX : 0x%08X\n",
04831 (unsigned long)addr, DWC_READ_REG32(addr));
04832 addr = &core_if->host_if->hc_regs[i]->hctsiz;
04833 DWC_PRINTF("HCTSIZ @0x%08lX : 0x%08X\n",
04834 (unsigned long)addr, DWC_READ_REG32(addr));
04835 addr = &core_if->host_if->hc_regs[i]->hcdma;
04836 DWC_PRINTF("HCDMA @0x%08lX : 0x%08X\n",
04837 (unsigned long)addr, DWC_READ_REG32(addr));
04838 if (core_if->dma_desc_enable) {
04839 addr = &core_if->host_if->hc_regs[i]->hcdmab;
04840 DWC_PRINTF("HCDMAB @0x%08lX : 0x%08X\n",
04841 (unsigned long)addr, DWC_READ_REG32(addr));
04842 }
04843
04844 }
04845 return;
04846 }
04847
04853 void dwc_otg_dump_global_registers(dwc_otg_core_if_t * core_if)
04854 {
04855 int i, ep_num;
04856 volatile uint32_t *addr;
04857 char *txfsiz;
04858
04859 DWC_PRINTF("Core Global Registers\n");
04860 addr = &core_if->core_global_regs->gotgctl;
04861 DWC_PRINTF("GOTGCTL @0x%08lX : 0x%08X\n", (unsigned long)addr,
04862 DWC_READ_REG32(addr));
04863 addr = &core_if->core_global_regs->gotgint;
04864 DWC_PRINTF("GOTGINT @0x%08lX : 0x%08X\n", (unsigned long)addr,
04865 DWC_READ_REG32(addr));
04866 addr = &core_if->core_global_regs->gahbcfg;
04867 DWC_PRINTF("GAHBCFG @0x%08lX : 0x%08X\n", (unsigned long)addr,
04868 DWC_READ_REG32(addr));
04869 addr = &core_if->core_global_regs->gusbcfg;
04870 DWC_PRINTF("GUSBCFG @0x%08lX : 0x%08X\n", (unsigned long)addr,
04871 DWC_READ_REG32(addr));
04872 addr = &core_if->core_global_regs->grstctl;
04873 DWC_PRINTF("GRSTCTL @0x%08lX : 0x%08X\n", (unsigned long)addr,
04874 DWC_READ_REG32(addr));
04875 addr = &core_if->core_global_regs->gintsts;
04876 DWC_PRINTF("GINTSTS @0x%08lX : 0x%08X\n", (unsigned long)addr,
04877 DWC_READ_REG32(addr));
04878 addr = &core_if->core_global_regs->gintmsk;
04879 DWC_PRINTF("GINTMSK @0x%08lX : 0x%08X\n", (unsigned long)addr,
04880 DWC_READ_REG32(addr));
04881 addr = &core_if->core_global_regs->grxstsr;
04882 DWC_PRINTF("GRXSTSR @0x%08lX : 0x%08X\n", (unsigned long)addr,
04883 DWC_READ_REG32(addr));
04884 addr = &core_if->core_global_regs->grxfsiz;
04885 DWC_PRINTF("GRXFSIZ @0x%08lX : 0x%08X\n", (unsigned long)addr,
04886 DWC_READ_REG32(addr));
04887 addr = &core_if->core_global_regs->gnptxfsiz;
04888 DWC_PRINTF("GNPTXFSIZ @0x%08lX : 0x%08X\n", (unsigned long)addr,
04889 DWC_READ_REG32(addr));
04890 addr = &core_if->core_global_regs->gnptxsts;
04891 DWC_PRINTF("GNPTXSTS @0x%08lX : 0x%08X\n", (unsigned long)addr,
04892 DWC_READ_REG32(addr));
04893 addr = &core_if->core_global_regs->gi2cctl;
04894 DWC_PRINTF("GI2CCTL @0x%08lX : 0x%08X\n", (unsigned long)addr,
04895 DWC_READ_REG32(addr));
04896 addr = &core_if->core_global_regs->gpvndctl;
04897 DWC_PRINTF("GPVNDCTL @0x%08lX : 0x%08X\n", (unsigned long)addr,
04898 DWC_READ_REG32(addr));
04899 addr = &core_if->core_global_regs->ggpio;
04900 DWC_PRINTF("GGPIO @0x%08lX : 0x%08X\n", (unsigned long)addr,
04901 DWC_READ_REG32(addr));
04902 addr = &core_if->core_global_regs->guid;
04903 DWC_PRINTF("GUID @0x%08lX : 0x%08X\n",
04904 (unsigned long)addr, DWC_READ_REG32(addr));
04905 addr = &core_if->core_global_regs->gsnpsid;
04906 DWC_PRINTF("GSNPSID @0x%08lX : 0x%08X\n", (unsigned long)addr,
04907 DWC_READ_REG32(addr));
04908 addr = &core_if->core_global_regs->ghwcfg1;
04909 DWC_PRINTF("GHWCFG1 @0x%08lX : 0x%08X\n", (unsigned long)addr,
04910 DWC_READ_REG32(addr));
04911 addr = &core_if->core_global_regs->ghwcfg2;
04912 DWC_PRINTF("GHWCFG2 @0x%08lX : 0x%08X\n", (unsigned long)addr,
04913 DWC_READ_REG32(addr));
04914 addr = &core_if->core_global_regs->ghwcfg3;
04915 DWC_PRINTF("GHWCFG3 @0x%08lX : 0x%08X\n", (unsigned long)addr,
04916 DWC_READ_REG32(addr));
04917 addr = &core_if->core_global_regs->ghwcfg4;
04918 DWC_PRINTF("GHWCFG4 @0x%08lX : 0x%08X\n", (unsigned long)addr,
04919 DWC_READ_REG32(addr));
04920 addr = &core_if->core_global_regs->glpmcfg;
04921 DWC_PRINTF("GLPMCFG @0x%08lX : 0x%08X\n", (unsigned long)addr,
04922 DWC_READ_REG32(addr));
04923 addr = &core_if->core_global_regs->gpwrdn;
04924 DWC_PRINTF("GPWRDN @0x%08lX : 0x%08X\n", (unsigned long)addr,
04925 DWC_READ_REG32(addr));
04926 addr = &core_if->core_global_regs->gdfifocfg;
04927 DWC_PRINTF("GDFIFOCFG @0x%08lX : 0x%08X\n", (unsigned long)addr,
04928 DWC_READ_REG32(addr));
04929 addr = &core_if->core_global_regs->adpctl;
04930 DWC_PRINTF("ADPCTL @0x%08lX : 0x%08X\n", (unsigned long)addr,
04931 dwc_otg_adp_read_reg(core_if));
04932 addr = &core_if->core_global_regs->hptxfsiz;
04933 DWC_PRINTF("HPTXFSIZ @0x%08lX : 0x%08X\n", (unsigned long)addr,
04934 DWC_READ_REG32(addr));
04935
04936 if (core_if->en_multiple_tx_fifo == 0) {
04937 ep_num = core_if->hwcfg4.b.num_dev_perio_in_ep;
04938 txfsiz = "DPTXFSIZ";
04939 } else {
04940 ep_num = core_if->hwcfg4.b.num_in_eps;
04941 txfsiz = "DIENPTXF";
04942 }
04943 for (i = 0; i < ep_num; i++) {
04944 addr = &core_if->core_global_regs->dtxfsiz[i];
04945 DWC_PRINTF("%s[%d] @0x%08lX : 0x%08X\n", txfsiz, i + 1,
04946 (unsigned long)addr, DWC_READ_REG32(addr));
04947 }
04948 addr = core_if->pcgcctl;
04949 DWC_PRINTF("PCGCCTL @0x%08lX : 0x%08X\n", (unsigned long)addr,
04950 DWC_READ_REG32(addr));
04951 }
04952
04959 void dwc_otg_flush_tx_fifo(dwc_otg_core_if_t * core_if, const int num)
04960 {
04961 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
04962 volatile grstctl_t greset = {.d32 = 0 };
04963 int count = 0;
04964
04965 DWC_DEBUGPL((DBG_CIL | DBG_PCDV), "Flush Tx FIFO %d\n", num);
04966
04967 greset.b.txfflsh = 1;
04968 greset.b.txfnum = num;
04969 DWC_WRITE_REG32(&global_regs->grstctl, greset.d32);
04970
04971 do {
04972 greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
04973 if (++count > 10000) {
04974 DWC_WARN("%s() HANG! GRSTCTL=%0x GNPTXSTS=0x%08x\n",
04975 __func__, greset.d32,
04976 DWC_READ_REG32(&global_regs->gnptxsts));
04977 break;
04978 }
04979 dwc_udelay(1);
04980 } while (greset.b.txfflsh == 1);
04981
04982
04983 dwc_udelay(1);
04984 }
04985
04991 void dwc_otg_flush_rx_fifo(dwc_otg_core_if_t * core_if)
04992 {
04993 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
04994 volatile grstctl_t greset = {.d32 = 0 };
04995 int count = 0;
04996
04997 DWC_DEBUGPL((DBG_CIL | DBG_PCDV), "%s\n", __func__);
04998
04999
05000
05001 greset.b.rxfflsh = 1;
05002 DWC_WRITE_REG32(&global_regs->grstctl, greset.d32);
05003
05004 do {
05005 greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
05006 if (++count > 10000) {
05007 DWC_WARN("%s() HANG! GRSTCTL=%0x\n", __func__,
05008 greset.d32);
05009 break;
05010 }
05011 dwc_udelay(1);
05012 } while (greset.b.rxfflsh == 1);
05013
05014
05015 dwc_udelay(1);
05016 }
05017
05022 void dwc_otg_core_reset(dwc_otg_core_if_t * core_if)
05023 {
05024 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
05025 volatile grstctl_t greset = {.d32 = 0 };
05026 int count = 0;
05027
05028 DWC_DEBUGPL(DBG_CILV, "%s\n", __func__);
05029
05030 do {
05031 dwc_udelay(10);
05032 greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
05033 if (++count > 100000) {
05034 DWC_WARN("%s() HANG! AHB Idle GRSTCTL=%0x\n", __func__,
05035 greset.d32);
05036 return;
05037 }
05038 }
05039 while (greset.b.ahbidle == 0);
05040
05041
05042 count = 0;
05043 greset.b.csftrst = 1;
05044 DWC_WRITE_REG32(&global_regs->grstctl, greset.d32);
05045 do {
05046 greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
05047 if (++count > 10000) {
05048 DWC_WARN("%s() HANG! Soft Reset GRSTCTL=%0x\n",
05049 __func__, greset.d32);
05050 break;
05051 }
05052 dwc_udelay(1);
05053 }
05054 while (greset.b.csftrst == 1);
05055
05056
05057 dwc_mdelay(100);
05058 }
05059
05060 uint8_t dwc_otg_is_device_mode(dwc_otg_core_if_t * _core_if)
05061 {
05062 return (dwc_otg_mode(_core_if) != DWC_HOST_MODE);
05063 }
05064
05065 uint8_t dwc_otg_is_host_mode(dwc_otg_core_if_t * _core_if)
05066 {
05067 return (dwc_otg_mode(_core_if) == DWC_HOST_MODE);
05068 }
05069
05078 void dwc_otg_cil_register_hcd_callbacks(dwc_otg_core_if_t * core_if,
05079 dwc_otg_cil_callbacks_t * cb, void *p)
05080 {
05081 core_if->hcd_cb = cb;
05082 cb->p = p;
05083 }
05084
05093 void dwc_otg_cil_register_pcd_callbacks(dwc_otg_core_if_t * core_if,
05094 dwc_otg_cil_callbacks_t * cb, void *p)
05095 {
05096 core_if->pcd_cb = cb;
05097 cb->p = p;
05098 }
05099
05100 #ifdef DWC_EN_ISOC
05101
05109 void write_isoc_frame_data(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
05110 {
05111 dwc_otg_dev_in_ep_regs_t *ep_regs;
05112 dtxfsts_data_t txstatus = {.d32 = 0 };
05113 uint32_t len = 0;
05114 uint32_t dwords;
05115
05116 ep->xfer_len = ep->data_per_frame;
05117 ep->xfer_count = 0;
05118
05119 ep_regs = core_if->dev_if->in_ep_regs[ep->num];
05120
05121 len = ep->xfer_len - ep->xfer_count;
05122
05123 if (len > ep->maxpacket) {
05124 len = ep->maxpacket;
05125 }
05126
05127 dwords = (len + 3) / 4;
05128
05129
05130
05131 txstatus.d32 =
05132 DWC_READ_REG32(&core_if->dev_if->in_ep_regs[ep->num]->dtxfsts);
05133 DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", ep->num, txstatus.d32);
05134
05135 while (txstatus.b.txfspcavail > dwords &&
05136 ep->xfer_count < ep->xfer_len && ep->xfer_len != 0) {
05137
05138 dwc_otg_ep_write_packet(core_if, ep, 0);
05139
05140 len = ep->xfer_len - ep->xfer_count;
05141 if (len > ep->maxpacket) {
05142 len = ep->maxpacket;
05143 }
05144
05145 dwords = (len + 3) / 4;
05146 txstatus.d32 =
05147 DWC_READ_REG32(&core_if->dev_if->
05148 in_ep_regs[ep->num]->dtxfsts);
05149 DWC_DEBUGPL(DBG_PCDV, "dtxfsts[%d]=0x%08x\n", ep->num,
05150 txstatus.d32);
05151 }
05152 }
05153
05161 void dwc_otg_iso_ep_start_frm_transfer(dwc_otg_core_if_t * core_if,
05162 dwc_ep_t * ep)
05163 {
05164 deptsiz_data_t deptsiz = {.d32 = 0 };
05165 depctl_data_t depctl = {.d32 = 0 };
05166 dsts_data_t dsts = {.d32 = 0 };
05167 volatile uint32_t *addr;
05168
05169 if (ep->is_in) {
05170 addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl;
05171 } else {
05172 addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl;
05173 }
05174
05175 ep->xfer_len = ep->data_per_frame;
05176 ep->xfer_count = 0;
05177 ep->xfer_buff = ep->cur_pkt_addr;
05178 ep->dma_addr = ep->cur_pkt_dma_addr;
05179
05180 if (ep->is_in) {
05181
05182
05183
05184
05185
05186 deptsiz.b.xfersize = ep->xfer_len;
05187 deptsiz.b.pktcnt =
05188 (ep->xfer_len - 1 + ep->maxpacket) / ep->maxpacket;
05189 deptsiz.b.mc = deptsiz.b.pktcnt;
05190 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[ep->num]->dieptsiz,
05191 deptsiz.d32);
05192
05193
05194 if (core_if->dma_enable) {
05195 DWC_WRITE_REG32(&
05196 (core_if->dev_if->in_ep_regs[ep->num]->
05197 diepdma), (uint32_t) ep->dma_addr);
05198 }
05199 } else {
05200 deptsiz.b.pktcnt =
05201 (ep->xfer_len + (ep->maxpacket - 1)) / ep->maxpacket;
05202 deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket;
05203
05204 DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[ep->num]->
05205 doeptsiz, deptsiz.d32);
05206
05207 if (core_if->dma_enable) {
05208 DWC_WRITE_REG32(&
05209 (core_if->dev_if->out_ep_regs[ep->num]->
05210 doepdma), (uint32_t) ep->dma_addr);
05211 }
05212 }
05213
05216 depctl.d32 = 0;
05217 if (ep->bInterval == 1) {
05218 dsts.d32 =
05219 DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);
05220 ep->next_frame = dsts.b.soffn + ep->bInterval;
05221
05222 if (ep->next_frame & 0x1) {
05223 depctl.b.setd1pid = 1;
05224 } else {
05225 depctl.b.setd0pid = 1;
05226 }
05227 } else {
05228 ep->next_frame += ep->bInterval;
05229
05230 if (ep->next_frame & 0x1) {
05231 depctl.b.setd1pid = 1;
05232 } else {
05233 depctl.b.setd0pid = 1;
05234 }
05235 }
05236 depctl.b.epena = 1;
05237 depctl.b.cnak = 1;
05238
05239 DWC_MODIFY_REG32(addr, 0, depctl.d32);
05240 depctl.d32 = DWC_READ_REG32(addr);
05241
05242 if (ep->is_in && core_if->dma_enable == 0) {
05243 write_isoc_frame_data(core_if, ep);
05244 }
05245
05246 }
05247 #endif
05248
05249 static void dwc_otg_set_uninitialized(int32_t * p, int size)
05250 {
05251 int i;
05252 for (i = 0; i < size; i++) {
05253 p[i] = -1;
05254 }
05255 }
05256
05257 static int dwc_otg_param_initialized(int32_t val)
05258 {
05259 return val != -1;
05260 }
05261
05262 static int dwc_otg_setup_params(dwc_otg_core_if_t * core_if)
05263 {
05264 int i;
05265 core_if->core_params = DWC_ALLOC(sizeof(*core_if->core_params));
05266 if (!core_if->core_params) {
05267 return -DWC_E_NO_MEMORY;
05268 }
05269 dwc_otg_set_uninitialized((int32_t *) core_if->core_params,
05270 sizeof(*core_if->core_params) /
05271 sizeof(int32_t));
05272 DWC_PRINTF("Setting default values for core params\n");
05273 dwc_otg_set_param_otg_cap(core_if, dwc_param_otg_cap_default);
05274 dwc_otg_set_param_dma_enable(core_if, dwc_param_dma_enable_default);
05275 dwc_otg_set_param_dma_desc_enable(core_if,
05276 dwc_param_dma_desc_enable_default);
05277 dwc_otg_set_param_opt(core_if, dwc_param_opt_default);
05278 dwc_otg_set_param_dma_burst_size(core_if,
05279 dwc_param_dma_burst_size_default);
05280 dwc_otg_set_param_host_support_fs_ls_low_power(core_if,
05281 dwc_param_host_support_fs_ls_low_power_default);
05282 dwc_otg_set_param_enable_dynamic_fifo(core_if,
05283 dwc_param_enable_dynamic_fifo_default);
05284 dwc_otg_set_param_data_fifo_size(core_if,
05285 dwc_param_data_fifo_size_default);
05286 dwc_otg_set_param_dev_rx_fifo_size(core_if,
05287 dwc_param_dev_rx_fifo_size_default);
05288 dwc_otg_set_param_dev_nperio_tx_fifo_size(core_if,
05289 dwc_param_dev_nperio_tx_fifo_size_default);
05290 dwc_otg_set_param_host_rx_fifo_size(core_if,
05291 dwc_param_host_rx_fifo_size_default);
05292 dwc_otg_set_param_host_nperio_tx_fifo_size(core_if,
05293 dwc_param_host_nperio_tx_fifo_size_default);
05294 dwc_otg_set_param_host_perio_tx_fifo_size(core_if,
05295 dwc_param_host_perio_tx_fifo_size_default);
05296 dwc_otg_set_param_max_transfer_size(core_if,
05297 dwc_param_max_transfer_size_default);
05298 dwc_otg_set_param_max_packet_count(core_if,
05299 dwc_param_max_packet_count_default);
05300 dwc_otg_set_param_host_channels(core_if,
05301 dwc_param_host_channels_default);
05302 dwc_otg_set_param_dev_endpoints(core_if,
05303 dwc_param_dev_endpoints_default);
05304 dwc_otg_set_param_phy_type(core_if, dwc_param_phy_type_default);
05305 dwc_otg_set_param_speed(core_if, dwc_param_speed_default);
05306 dwc_otg_set_param_host_ls_low_power_phy_clk(core_if,
05307 dwc_param_host_ls_low_power_phy_clk_default);
05308 dwc_otg_set_param_phy_ulpi_ddr(core_if, dwc_param_phy_ulpi_ddr_default);
05309 dwc_otg_set_param_phy_ulpi_ext_vbus(core_if,
05310 dwc_param_phy_ulpi_ext_vbus_default);
05311 dwc_otg_set_param_phy_utmi_width(core_if,
05312 dwc_param_phy_utmi_width_default);
05313 dwc_otg_set_param_ts_dline(core_if, dwc_param_ts_dline_default);
05314 dwc_otg_set_param_i2c_enable(core_if, dwc_param_i2c_enable_default);
05315 dwc_otg_set_param_ulpi_fs_ls(core_if, dwc_param_ulpi_fs_ls_default);
05316 dwc_otg_set_param_en_multiple_tx_fifo(core_if,
05317 dwc_param_en_multiple_tx_fifo_default);
05318 for (i = 0; i < 15; i++) {
05319 dwc_otg_set_param_dev_perio_tx_fifo_size(core_if,
05320 dwc_param_dev_perio_tx_fifo_size_default,
05321 i);
05322 }
05323
05324 for (i = 0; i < 15; i++) {
05325 dwc_otg_set_param_dev_tx_fifo_size(core_if,
05326 dwc_param_dev_tx_fifo_size_default,
05327 i);
05328 }
05329 dwc_otg_set_param_thr_ctl(core_if, dwc_param_thr_ctl_default);
05330 dwc_otg_set_param_mpi_enable(core_if, dwc_param_mpi_enable_default);
05331 dwc_otg_set_param_pti_enable(core_if, dwc_param_pti_enable_default);
05332 dwc_otg_set_param_lpm_enable(core_if, dwc_param_lpm_enable_default);
05333 dwc_otg_set_param_ic_usb_cap(core_if, dwc_param_ic_usb_cap_default);
05334 dwc_otg_set_param_tx_thr_length(core_if,
05335 dwc_param_tx_thr_length_default);
05336 dwc_otg_set_param_rx_thr_length(core_if,
05337 dwc_param_rx_thr_length_default);
05338 dwc_otg_set_param_ahb_thr_ratio(core_if,
05339 dwc_param_ahb_thr_ratio_default);
05340 dwc_otg_set_param_power_down(core_if, dwc_param_power_down_default);
05341 dwc_otg_set_param_reload_ctl(core_if, dwc_param_reload_ctl_default);
05342 dwc_otg_set_param_dev_out_nak(core_if, dwc_param_dev_out_nak_default);
05343 dwc_otg_set_param_cont_on_bna(core_if, dwc_param_cont_on_bna_default);
05344 dwc_otg_set_param_ahb_single(core_if, dwc_param_ahb_single_default);
05345 dwc_otg_set_param_otg_ver(core_if, dwc_param_otg_ver_default);
05346 dwc_otg_set_param_adp_enable(core_if, dwc_param_adp_enable_default);
05347 return 0;
05348 }
05349
05350 uint8_t dwc_otg_is_dma_enable(dwc_otg_core_if_t * core_if)
05351 {
05352 return core_if->dma_enable;
05353 }
05354
05355
05356 #define DWC_OTG_PARAM_TEST(_param_, _low_, _high_) \
05357 (((_param_) < (_low_)) || \
05358 ((_param_) > (_high_)))
05359
05360
05361 int dwc_otg_set_param_otg_cap(dwc_otg_core_if_t * core_if, int32_t val)
05362 {
05363 int valid;
05364 int retval = 0;
05365 if (DWC_OTG_PARAM_TEST(val, 0, 2)) {
05366 DWC_WARN("Wrong value for otg_cap parameter\n");
05367 DWC_WARN("otg_cap parameter must be 0,1 or 2\n");
05368 retval = -DWC_E_INVALID;
05369 goto out;
05370 }
05371
05372 valid = 1;
05373 switch (val) {
05374 case DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE:
05375 if (core_if->hwcfg2.b.op_mode !=
05376 DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
05377 valid = 0;
05378 break;
05379 case DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE:
05380 if ((core_if->hwcfg2.b.op_mode !=
05381 DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
05382 && (core_if->hwcfg2.b.op_mode !=
05383 DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG)
05384 && (core_if->hwcfg2.b.op_mode !=
05385 DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE)
05386 && (core_if->hwcfg2.b.op_mode !=
05387 DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)) {
05388 valid = 0;
05389 }
05390 break;
05391 case DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE:
05392
05393 break;
05394 }
05395 if (!valid) {
05396 if (dwc_otg_param_initialized(core_if->core_params->otg_cap)) {
05397 DWC_ERROR
05398 ("%d invalid for otg_cap paremter. Check HW configuration.\n",
05399 val);
05400 }
05401 val =
05402 (((core_if->hwcfg2.b.op_mode ==
05403 DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
05404 || (core_if->hwcfg2.b.op_mode ==
05405 DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG)
05406 || (core_if->hwcfg2.b.op_mode ==
05407 DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE)
05408 || (core_if->hwcfg2.b.op_mode ==
05409 DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)) ?
05410 DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE :
05411 DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
05412 retval = -DWC_E_INVALID;
05413 }
05414
05415 core_if->core_params->otg_cap = val;
05416 out:
05417 return retval;
05418 }
05419
05420 int32_t dwc_otg_get_param_otg_cap(dwc_otg_core_if_t * core_if)
05421 {
05422 return core_if->core_params->otg_cap;
05423 }
05424
05425 int dwc_otg_set_param_opt(dwc_otg_core_if_t * core_if, int32_t val)
05426 {
05427 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
05428 DWC_WARN("Wrong value for opt parameter\n");
05429 return -DWC_E_INVALID;
05430 }
05431 core_if->core_params->opt = val;
05432 return 0;
05433 }
05434
05435 int32_t dwc_otg_get_param_opt(dwc_otg_core_if_t * core_if)
05436 {
05437 return core_if->core_params->opt;
05438 }
05439
05440 int dwc_otg_set_param_dma_enable(dwc_otg_core_if_t * core_if, int32_t val)
05441 {
05442 int retval = 0;
05443 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
05444 DWC_WARN("Wrong value for dma enable\n");
05445 return -DWC_E_INVALID;
05446 }
05447
05448 if ((val == 1) && (core_if->hwcfg2.b.architecture == 0)) {
05449 if (dwc_otg_param_initialized(core_if->core_params->dma_enable)) {
05450 DWC_ERROR
05451 ("%d invalid for dma_enable paremter. Check HW configuration.\n",
05452 val);
05453 }
05454 val = 0;
05455 retval = -DWC_E_INVALID;
05456 }
05457
05458 core_if->core_params->dma_enable = val;
05459 if (val == 0) {
05460 dwc_otg_set_param_dma_desc_enable(core_if, 0);
05461 }
05462 return retval;
05463 }
05464
05465 int32_t dwc_otg_get_param_dma_enable(dwc_otg_core_if_t * core_if)
05466 {
05467 return core_if->core_params->dma_enable;
05468 }
05469
05470 int dwc_otg_set_param_dma_desc_enable(dwc_otg_core_if_t * core_if, int32_t val)
05471 {
05472 int retval = 0;
05473 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
05474 DWC_WARN("Wrong value for dma_enable\n");
05475 DWC_WARN("dma_desc_enable must be 0 or 1\n");
05476 return -DWC_E_INVALID;
05477 }
05478
05479 if ((val == 1)
05480 && ((dwc_otg_get_param_dma_enable(core_if) == 0)
05481 || (core_if->hwcfg4.b.desc_dma == 0))) {
05482 if (dwc_otg_param_initialized
05483 (core_if->core_params->dma_desc_enable)) {
05484 DWC_ERROR
05485 ("%d invalid for dma_desc_enable paremter. Check HW configuration.\n",
05486 val);
05487 }
05488 val = 0;
05489 retval = -DWC_E_INVALID;
05490 }
05491 core_if->core_params->dma_desc_enable = val;
05492 return retval;
05493 }
05494
05495 int32_t dwc_otg_get_param_dma_desc_enable(dwc_otg_core_if_t * core_if)
05496 {
05497 return core_if->core_params->dma_desc_enable;
05498 }
05499
05500 int dwc_otg_set_param_host_support_fs_ls_low_power(dwc_otg_core_if_t * core_if,
05501 int32_t val)
05502 {
05503 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
05504 DWC_WARN("Wrong value for host_support_fs_low_power\n");
05505 DWC_WARN("host_support_fs_low_power must be 0 or 1\n");
05506 return -DWC_E_INVALID;
05507 }
05508 core_if->core_params->host_support_fs_ls_low_power = val;
05509 return 0;
05510 }
05511
05512 int32_t dwc_otg_get_param_host_support_fs_ls_low_power(dwc_otg_core_if_t *
05513 core_if)
05514 {
05515 return core_if->core_params->host_support_fs_ls_low_power;
05516 }
05517
05518 int dwc_otg_set_param_enable_dynamic_fifo(dwc_otg_core_if_t * core_if,
05519 int32_t val)
05520 {
05521 int retval = 0;
05522 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
05523 DWC_WARN("Wrong value for enable_dynamic_fifo\n");
05524 DWC_WARN("enable_dynamic_fifo must be 0 or 1\n");
05525 return -DWC_E_INVALID;
05526 }
05527
05528 if ((val == 1) && (core_if->hwcfg2.b.dynamic_fifo == 0)) {
05529 if (dwc_otg_param_initialized
05530 (core_if->core_params->enable_dynamic_fifo)) {
05531 DWC_ERROR
05532 ("%d invalid for enable_dynamic_fifo paremter. Check HW configuration.\n",
05533 val);
05534 }
05535 val = 0;
05536 retval = -DWC_E_INVALID;
05537 }
05538 core_if->core_params->enable_dynamic_fifo = val;
05539 return retval;
05540 }
05541
05542 int32_t dwc_otg_get_param_enable_dynamic_fifo(dwc_otg_core_if_t * core_if)
05543 {
05544 return core_if->core_params->enable_dynamic_fifo;
05545 }
05546
05547 int dwc_otg_set_param_data_fifo_size(dwc_otg_core_if_t * core_if, int32_t val)
05548 {
05549 int retval = 0;
05550 if (DWC_OTG_PARAM_TEST(val, 32, 32768)) {
05551 DWC_WARN("Wrong value for data_fifo_size\n");
05552 DWC_WARN("data_fifo_size must be 32-32768\n");
05553 return -DWC_E_INVALID;
05554 }
05555
05556 if (val > core_if->hwcfg3.b.dfifo_depth) {
05557 if (dwc_otg_param_initialized
05558 (core_if->core_params->data_fifo_size)) {
05559 DWC_ERROR
05560 ("%d invalid for data_fifo_size parameter. Check HW configuration.\n",
05561 val);
05562 }
05563 val = core_if->hwcfg3.b.dfifo_depth;
05564 retval = -DWC_E_INVALID;
05565 }
05566
05567 core_if->core_params->data_fifo_size = val;
05568 return retval;
05569 }
05570
05571 int32_t dwc_otg_get_param_data_fifo_size(dwc_otg_core_if_t * core_if)
05572 {
05573 return core_if->core_params->data_fifo_size;
05574 }
05575
05576 int dwc_otg_set_param_dev_rx_fifo_size(dwc_otg_core_if_t * core_if, int32_t val)
05577 {
05578 int retval = 0;
05579 if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
05580 DWC_WARN("Wrong value for dev_rx_fifo_size\n");
05581 DWC_WARN("dev_rx_fifo_size must be 16-32768\n");
05582 return -DWC_E_INVALID;
05583 }
05584
05585 if (val > DWC_READ_REG32(&core_if->core_global_regs->grxfsiz)) {
05586 if (dwc_otg_param_initialized(core_if->core_params->dev_rx_fifo_size)) {
05587 DWC_WARN("%d invalid for dev_rx_fifo_size parameter\n", val);
05588 }
05589 val = DWC_READ_REG32(&core_if->core_global_regs->grxfsiz);
05590 retval = -DWC_E_INVALID;
05591 }
05592
05593 core_if->core_params->dev_rx_fifo_size = val;
05594 return retval;
05595 }
05596
05597 int32_t dwc_otg_get_param_dev_rx_fifo_size(dwc_otg_core_if_t * core_if)
05598 {
05599 return core_if->core_params->dev_rx_fifo_size;
05600 }
05601
05602 int dwc_otg_set_param_dev_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if,
05603 int32_t val)
05604 {
05605 int retval = 0;
05606
05607 if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
05608 DWC_WARN("Wrong value for dev_nperio_tx_fifo\n");
05609 DWC_WARN("dev_nperio_tx_fifo must be 16-32768\n");
05610 return -DWC_E_INVALID;
05611 }
05612
05613 if (val > (DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz) >> 16)) {
05614 if (dwc_otg_param_initialized
05615 (core_if->core_params->dev_nperio_tx_fifo_size)) {
05616 DWC_ERROR
05617 ("%d invalid for dev_nperio_tx_fifo_size. Check HW configuration.\n",
05618 val);
05619 }
05620 val =
05621 (DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz) >>
05622 16);
05623 retval = -DWC_E_INVALID;
05624 }
05625
05626 core_if->core_params->dev_nperio_tx_fifo_size = val;
05627 return retval;
05628 }
05629
05630 int32_t dwc_otg_get_param_dev_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if)
05631 {
05632 return core_if->core_params->dev_nperio_tx_fifo_size;
05633 }
05634
05635 int dwc_otg_set_param_host_rx_fifo_size(dwc_otg_core_if_t * core_if,
05636 int32_t val)
05637 {
05638 int retval = 0;
05639
05640 if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
05641 DWC_WARN("Wrong value for host_rx_fifo_size\n");
05642 DWC_WARN("host_rx_fifo_size must be 16-32768\n");
05643 return -DWC_E_INVALID;
05644 }
05645
05646 if (val > DWC_READ_REG32(&core_if->core_global_regs->grxfsiz)) {
05647 if (dwc_otg_param_initialized
05648 (core_if->core_params->host_rx_fifo_size)) {
05649 DWC_ERROR
05650 ("%d invalid for host_rx_fifo_size. Check HW configuration.\n",
05651 val);
05652 }
05653 val = DWC_READ_REG32(&core_if->core_global_regs->grxfsiz);
05654 retval = -DWC_E_INVALID;
05655 }
05656
05657 core_if->core_params->host_rx_fifo_size = val;
05658 return retval;
05659
05660 }
05661
05662 int32_t dwc_otg_get_param_host_rx_fifo_size(dwc_otg_core_if_t * core_if)
05663 {
05664 return core_if->core_params->host_rx_fifo_size;
05665 }
05666
05667 int dwc_otg_set_param_host_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if,
05668 int32_t val)
05669 {
05670 int retval = 0;
05671
05672 if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
05673 DWC_WARN("Wrong value for host_nperio_tx_fifo_size\n");
05674 DWC_WARN("host_nperio_tx_fifo_size must be 16-32768\n");
05675 return -DWC_E_INVALID;
05676 }
05677
05678 if (val > (DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz) >> 16)) {
05679 if (dwc_otg_param_initialized
05680 (core_if->core_params->host_nperio_tx_fifo_size)) {
05681 DWC_ERROR
05682 ("%d invalid for host_nperio_tx_fifo_size. Check HW configuration.\n",
05683 val);
05684 }
05685 val =
05686 (DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz) >>
05687 16);
05688 retval = -DWC_E_INVALID;
05689 }
05690
05691 core_if->core_params->host_nperio_tx_fifo_size = val;
05692 return retval;
05693 }
05694
05695 int32_t dwc_otg_get_param_host_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if)
05696 {
05697 return core_if->core_params->host_nperio_tx_fifo_size;
05698 }
05699
05700 int dwc_otg_set_param_host_perio_tx_fifo_size(dwc_otg_core_if_t * core_if,
05701 int32_t val)
05702 {
05703 int retval = 0;
05704 if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
05705 DWC_WARN("Wrong value for host_perio_tx_fifo_size\n");
05706 DWC_WARN("host_perio_tx_fifo_size must be 16-32768\n");
05707 return -DWC_E_INVALID;
05708 }
05709
05710 if (val >
05711 ((core_if->hptxfsiz.d32)>> 16)) {
05712 if (dwc_otg_param_initialized
05713 (core_if->core_params->host_perio_tx_fifo_size)) {
05714 DWC_ERROR
05715 ("%d invalid for host_perio_tx_fifo_size. Check HW configuration.\n",
05716 val);
05717 }
05718 val = (core_if->hptxfsiz.d32) >> 16;
05719 retval = -DWC_E_INVALID;
05720 }
05721
05722 core_if->core_params->host_perio_tx_fifo_size = val;
05723 return retval;
05724 }
05725
05726 int32_t dwc_otg_get_param_host_perio_tx_fifo_size(dwc_otg_core_if_t * core_if)
05727 {
05728 return core_if->core_params->host_perio_tx_fifo_size;
05729 }
05730
05731 int dwc_otg_set_param_max_transfer_size(dwc_otg_core_if_t * core_if,
05732 int32_t val)
05733 {
05734 int retval = 0;
05735
05736 if (DWC_OTG_PARAM_TEST(val, 2047, 524288)) {
05737 DWC_WARN("Wrong value for max_transfer_size\n");
05738 DWC_WARN("max_transfer_size must be 2047-524288\n");
05739 return -DWC_E_INVALID;
05740 }
05741
05742 if (val >= (1 << (core_if->hwcfg3.b.xfer_size_cntr_width + 11))) {
05743 if (dwc_otg_param_initialized
05744 (core_if->core_params->max_transfer_size)) {
05745 DWC_ERROR
05746 ("%d invalid for max_transfer_size. Check HW configuration.\n",
05747 val);
05748 }
05749 val =
05750 ((1 << (core_if->hwcfg3.b.packet_size_cntr_width + 11)) -
05751 1);
05752 retval = -DWC_E_INVALID;
05753 }
05754
05755 core_if->core_params->max_transfer_size = val;
05756 return retval;
05757 }
05758
05759 int32_t dwc_otg_get_param_max_transfer_size(dwc_otg_core_if_t * core_if)
05760 {
05761 return core_if->core_params->max_transfer_size;
05762 }
05763
05764 int dwc_otg_set_param_max_packet_count(dwc_otg_core_if_t * core_if, int32_t val)
05765 {
05766 int retval = 0;
05767
05768 if (DWC_OTG_PARAM_TEST(val, 15, 511)) {
05769 DWC_WARN("Wrong value for max_packet_count\n");
05770 DWC_WARN("max_packet_count must be 15-511\n");
05771 return -DWC_E_INVALID;
05772 }
05773
05774 if (val > (1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4))) {
05775 if (dwc_otg_param_initialized
05776 (core_if->core_params->max_packet_count)) {
05777 DWC_ERROR
05778 ("%d invalid for max_packet_count. Check HW configuration.\n",
05779 val);
05780 }
05781 val =
05782 ((1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4)) - 1);
05783 retval = -DWC_E_INVALID;
05784 }
05785
05786 core_if->core_params->max_packet_count = val;
05787 return retval;
05788 }
05789
05790 int32_t dwc_otg_get_param_max_packet_count(dwc_otg_core_if_t * core_if)
05791 {
05792 return core_if->core_params->max_packet_count;
05793 }
05794
05795 int dwc_otg_set_param_host_channels(dwc_otg_core_if_t * core_if, int32_t val)
05796 {
05797 int retval = 0;
05798
05799 if (DWC_OTG_PARAM_TEST(val, 1, 16)) {
05800 DWC_WARN("Wrong value for host_channels\n");
05801 DWC_WARN("host_channels must be 1-16\n");
05802 return -DWC_E_INVALID;
05803 }
05804
05805 if (val > (core_if->hwcfg2.b.num_host_chan + 1)) {
05806 if (dwc_otg_param_initialized
05807 (core_if->core_params->host_channels)) {
05808 DWC_ERROR
05809 ("%d invalid for host_channels. Check HW configurations.\n",
05810 val);
05811 }
05812 val = (core_if->hwcfg2.b.num_host_chan + 1);
05813 retval = -DWC_E_INVALID;
05814 }
05815
05816 core_if->core_params->host_channels = val;
05817 return retval;
05818 }
05819
05820 int32_t dwc_otg_get_param_host_channels(dwc_otg_core_if_t * core_if)
05821 {
05822 return core_if->core_params->host_channels;
05823 }
05824
05825 int dwc_otg_set_param_dev_endpoints(dwc_otg_core_if_t * core_if, int32_t val)
05826 {
05827 int retval = 0;
05828
05829 if (DWC_OTG_PARAM_TEST(val, 1, 15)) {
05830 DWC_WARN("Wrong value for dev_endpoints\n");
05831 DWC_WARN("dev_endpoints must be 1-15\n");
05832 return -DWC_E_INVALID;
05833 }
05834
05835 if (val > (core_if->hwcfg2.b.num_dev_ep)) {
05836 if (dwc_otg_param_initialized
05837 (core_if->core_params->dev_endpoints)) {
05838 DWC_ERROR
05839 ("%d invalid for dev_endpoints. Check HW configurations.\n",
05840 val);
05841 }
05842 val = core_if->hwcfg2.b.num_dev_ep;
05843 retval = -DWC_E_INVALID;
05844 }
05845
05846 core_if->core_params->dev_endpoints = val;
05847 return retval;
05848 }
05849
05850 int32_t dwc_otg_get_param_dev_endpoints(dwc_otg_core_if_t * core_if)
05851 {
05852 return core_if->core_params->dev_endpoints;
05853 }
05854
05855 int dwc_otg_set_param_phy_type(dwc_otg_core_if_t * core_if, int32_t val)
05856 {
05857 int retval = 0;
05858 int valid = 0;
05859
05860 if (DWC_OTG_PARAM_TEST(val, 0, 2)) {
05861 DWC_WARN("Wrong value for phy_type\n");
05862 DWC_WARN("phy_type must be 0,1 or 2\n");
05863 return -DWC_E_INVALID;
05864 }
05865 #ifndef NO_FS_PHY_HW_CHECKS
05866 if ((val == DWC_PHY_TYPE_PARAM_UTMI) &&
05867 ((core_if->hwcfg2.b.hs_phy_type == 1) ||
05868 (core_if->hwcfg2.b.hs_phy_type == 3))) {
05869 valid = 1;
05870 } else if ((val == DWC_PHY_TYPE_PARAM_ULPI) &&
05871 ((core_if->hwcfg2.b.hs_phy_type == 2) ||
05872 (core_if->hwcfg2.b.hs_phy_type == 3))) {
05873 valid = 1;
05874 } else if ((val == DWC_PHY_TYPE_PARAM_FS) &&
05875 (core_if->hwcfg2.b.fs_phy_type == 1)) {
05876 valid = 1;
05877 }
05878 if (!valid) {
05879 if (dwc_otg_param_initialized(core_if->core_params->phy_type)) {
05880 DWC_ERROR
05881 ("%d invalid for phy_type. Check HW configurations.\n",
05882 val);
05883 }
05884 if (core_if->hwcfg2.b.hs_phy_type) {
05885 if ((core_if->hwcfg2.b.hs_phy_type == 3) ||
05886 (core_if->hwcfg2.b.hs_phy_type == 1)) {
05887 val = DWC_PHY_TYPE_PARAM_UTMI;
05888 } else {
05889 val = DWC_PHY_TYPE_PARAM_ULPI;
05890 }
05891 }
05892 retval = -DWC_E_INVALID;
05893 }
05894 #endif
05895 core_if->core_params->phy_type = val;
05896 return retval;
05897 }
05898
05899 int32_t dwc_otg_get_param_phy_type(dwc_otg_core_if_t * core_if)
05900 {
05901 return core_if->core_params->phy_type;
05902 }
05903
05904 int dwc_otg_set_param_speed(dwc_otg_core_if_t * core_if, int32_t val)
05905 {
05906 int retval = 0;
05907 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
05908 DWC_WARN("Wrong value for speed parameter\n");
05909 DWC_WARN("max_speed parameter must be 0 or 1\n");
05910 return -DWC_E_INVALID;
05911 }
05912 if ((val == 0)
05913 && dwc_otg_get_param_phy_type(core_if) == DWC_PHY_TYPE_PARAM_FS) {
05914 if (dwc_otg_param_initialized(core_if->core_params->speed)) {
05915 DWC_ERROR
05916 ("%d invalid for speed paremter. Check HW configuration.\n",
05917 val);
05918 }
05919 val =
05920 (dwc_otg_get_param_phy_type(core_if) ==
05921 DWC_PHY_TYPE_PARAM_FS ? 1 : 0);
05922 retval = -DWC_E_INVALID;
05923 }
05924 core_if->core_params->speed = val;
05925 return retval;
05926 }
05927
05928 int32_t dwc_otg_get_param_speed(dwc_otg_core_if_t * core_if)
05929 {
05930 return core_if->core_params->speed;
05931 }
05932
05933 int dwc_otg_set_param_host_ls_low_power_phy_clk(dwc_otg_core_if_t * core_if,
05934 int32_t val)
05935 {
05936 int retval = 0;
05937
05938 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
05939 DWC_WARN
05940 ("Wrong value for host_ls_low_power_phy_clk parameter\n");
05941 DWC_WARN("host_ls_low_power_phy_clk must be 0 or 1\n");
05942 return -DWC_E_INVALID;
05943 }
05944
05945 if ((val == DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ)
05946 && (dwc_otg_get_param_phy_type(core_if) == DWC_PHY_TYPE_PARAM_FS)) {
05947 if (dwc_otg_param_initialized
05948 (core_if->core_params->host_ls_low_power_phy_clk)) {
05949 DWC_ERROR
05950 ("%d invalid for host_ls_low_power_phy_clk. Check HW configuration.\n",
05951 val);
05952 }
05953 val =
05954 (dwc_otg_get_param_phy_type(core_if) ==
05955 DWC_PHY_TYPE_PARAM_FS) ?
05956 DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ :
05957 DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ;
05958 retval = -DWC_E_INVALID;
05959 }
05960
05961 core_if->core_params->host_ls_low_power_phy_clk = val;
05962 return retval;
05963 }
05964
05965 int32_t dwc_otg_get_param_host_ls_low_power_phy_clk(dwc_otg_core_if_t * core_if)
05966 {
05967 return core_if->core_params->host_ls_low_power_phy_clk;
05968 }
05969
05970 int dwc_otg_set_param_phy_ulpi_ddr(dwc_otg_core_if_t * core_if, int32_t val)
05971 {
05972 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
05973 DWC_WARN("Wrong value for phy_ulpi_ddr\n");
05974 DWC_WARN("phy_upli_ddr must be 0 or 1\n");
05975 return -DWC_E_INVALID;
05976 }
05977
05978 core_if->core_params->phy_ulpi_ddr = val;
05979 return 0;
05980 }
05981
05982 int32_t dwc_otg_get_param_phy_ulpi_ddr(dwc_otg_core_if_t * core_if)
05983 {
05984 return core_if->core_params->phy_ulpi_ddr;
05985 }
05986
05987 int dwc_otg_set_param_phy_ulpi_ext_vbus(dwc_otg_core_if_t * core_if,
05988 int32_t val)
05989 {
05990 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
05991 DWC_WARN("Wrong valaue for phy_ulpi_ext_vbus\n");
05992 DWC_WARN("phy_ulpi_ext_vbus must be 0 or 1\n");
05993 return -DWC_E_INVALID;
05994 }
05995
05996 core_if->core_params->phy_ulpi_ext_vbus = val;
05997 return 0;
05998 }
05999
06000 int32_t dwc_otg_get_param_phy_ulpi_ext_vbus(dwc_otg_core_if_t * core_if)
06001 {
06002 return core_if->core_params->phy_ulpi_ext_vbus;
06003 }
06004
06005 int dwc_otg_set_param_phy_utmi_width(dwc_otg_core_if_t * core_if, int32_t val)
06006 {
06007 if (DWC_OTG_PARAM_TEST(val, 8, 8) && DWC_OTG_PARAM_TEST(val, 16, 16)) {
06008 DWC_WARN("Wrong valaue for phy_utmi_width\n");
06009 DWC_WARN("phy_utmi_width must be 8 or 16\n");
06010 return -DWC_E_INVALID;
06011 }
06012
06013 core_if->core_params->phy_utmi_width = val;
06014 return 0;
06015 }
06016
06017 int32_t dwc_otg_get_param_phy_utmi_width(dwc_otg_core_if_t * core_if)
06018 {
06019 return core_if->core_params->phy_utmi_width;
06020 }
06021
06022 int dwc_otg_set_param_ulpi_fs_ls(dwc_otg_core_if_t * core_if, int32_t val)
06023 {
06024 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
06025 DWC_WARN("Wrong valaue for ulpi_fs_ls\n");
06026 DWC_WARN("ulpi_fs_ls must be 0 or 1\n");
06027 return -DWC_E_INVALID;
06028 }
06029
06030 core_if->core_params->ulpi_fs_ls = val;
06031 return 0;
06032 }
06033
06034 int32_t dwc_otg_get_param_ulpi_fs_ls(dwc_otg_core_if_t * core_if)
06035 {
06036 return core_if->core_params->ulpi_fs_ls;
06037 }
06038
06039 int dwc_otg_set_param_ts_dline(dwc_otg_core_if_t * core_if, int32_t val)
06040 {
06041 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
06042 DWC_WARN("Wrong valaue for ts_dline\n");
06043 DWC_WARN("ts_dline must be 0 or 1\n");
06044 return -DWC_E_INVALID;
06045 }
06046
06047 core_if->core_params->ts_dline = val;
06048 return 0;
06049 }
06050
06051 int32_t dwc_otg_get_param_ts_dline(dwc_otg_core_if_t * core_if)
06052 {
06053 return core_if->core_params->ts_dline;
06054 }
06055
06056 int dwc_otg_set_param_i2c_enable(dwc_otg_core_if_t * core_if, int32_t val)
06057 {
06058 int retval = 0;
06059 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
06060 DWC_WARN("Wrong valaue for i2c_enable\n");
06061 DWC_WARN("i2c_enable must be 0 or 1\n");
06062 return -DWC_E_INVALID;
06063 }
06064 #ifndef NO_FS_PHY_HW_CHECK
06065 if (val == 1 && core_if->hwcfg3.b.i2c == 0) {
06066 if (dwc_otg_param_initialized(core_if->core_params->i2c_enable)) {
06067 DWC_ERROR
06068 ("%d invalid for i2c_enable. Check HW configuration.\n",
06069 val);
06070 }
06071 val = 0;
06072 retval = -DWC_E_INVALID;
06073 }
06074 #endif
06075
06076 core_if->core_params->i2c_enable = val;
06077 return retval;
06078 }
06079
06080 int32_t dwc_otg_get_param_i2c_enable(dwc_otg_core_if_t * core_if)
06081 {
06082 return core_if->core_params->i2c_enable;
06083 }
06084
06085 int dwc_otg_set_param_dev_perio_tx_fifo_size(dwc_otg_core_if_t * core_if,
06086 int32_t val, int fifo_num)
06087 {
06088 int retval = 0;
06089
06090 if (DWC_OTG_PARAM_TEST(val, 4, 768)) {
06091 DWC_WARN("Wrong value for dev_perio_tx_fifo_size\n");
06092 DWC_WARN("dev_perio_tx_fifo_size must be 4-768\n");
06093 return -DWC_E_INVALID;
06094 }
06095
06096 if (val >
06097 (DWC_READ_REG32(&core_if->core_global_regs->dtxfsiz[fifo_num]))) {
06098 if (dwc_otg_param_initialized
06099 (core_if->core_params->dev_perio_tx_fifo_size[fifo_num])) {
06100 DWC_ERROR
06101 ("`%d' invalid for parameter `dev_perio_fifo_size_%d'. Check HW configuration.\n",
06102 val, fifo_num);
06103 }
06104 val = (DWC_READ_REG32(&core_if->core_global_regs->dtxfsiz[fifo_num]));
06105 retval = -DWC_E_INVALID;
06106 }
06107
06108 core_if->core_params->dev_perio_tx_fifo_size[fifo_num] = val;
06109 return retval;
06110 }
06111
06112 int32_t dwc_otg_get_param_dev_perio_tx_fifo_size(dwc_otg_core_if_t * core_if,
06113 int fifo_num)
06114 {
06115 return core_if->core_params->dev_perio_tx_fifo_size[fifo_num];
06116 }
06117
06118 int dwc_otg_set_param_en_multiple_tx_fifo(dwc_otg_core_if_t * core_if,
06119 int32_t val)
06120 {
06121 int retval = 0;
06122 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
06123 DWC_WARN("Wrong valaue for en_multiple_tx_fifo,\n");
06124 DWC_WARN("en_multiple_tx_fifo must be 0 or 1\n");
06125 return -DWC_E_INVALID;
06126 }
06127
06128 if (val == 1 && core_if->hwcfg4.b.ded_fifo_en == 0) {
06129 if (dwc_otg_param_initialized
06130 (core_if->core_params->en_multiple_tx_fifo)) {
06131 DWC_ERROR
06132 ("%d invalid for parameter en_multiple_tx_fifo. Check HW configuration.\n",
06133 val);
06134 }
06135 val = 0;
06136 retval = -DWC_E_INVALID;
06137 }
06138
06139 core_if->core_params->en_multiple_tx_fifo = val;
06140 return retval;
06141 }
06142
06143 int32_t dwc_otg_get_param_en_multiple_tx_fifo(dwc_otg_core_if_t * core_if)
06144 {
06145 return core_if->core_params->en_multiple_tx_fifo;
06146 }
06147
06148 int dwc_otg_set_param_dev_tx_fifo_size(dwc_otg_core_if_t * core_if, int32_t val,
06149 int fifo_num)
06150 {
06151 int retval = 0;
06152
06153 if (DWC_OTG_PARAM_TEST(val, 4, 768)) {
06154 DWC_WARN("Wrong value for dev_tx_fifo_size\n");
06155 DWC_WARN("dev_tx_fifo_size must be 4-768\n");
06156 return -DWC_E_INVALID;
06157 }
06158
06159 if (val >
06160 (DWC_READ_REG32(&core_if->core_global_regs->dtxfsiz[fifo_num]))) {
06161 if (dwc_otg_param_initialized
06162 (core_if->core_params->dev_tx_fifo_size[fifo_num])) {
06163 DWC_ERROR
06164 ("`%d' invalid for parameter `dev_tx_fifo_size_%d'. Check HW configuration.\n",
06165 val, fifo_num);
06166 }
06167 val = (DWC_READ_REG32(&core_if->core_global_regs->dtxfsiz[fifo_num]));
06168 retval = -DWC_E_INVALID;
06169 }
06170
06171 core_if->core_params->dev_tx_fifo_size[fifo_num] = val;
06172 return retval;
06173 }
06174
06175 int32_t dwc_otg_get_param_dev_tx_fifo_size(dwc_otg_core_if_t * core_if,
06176 int fifo_num)
06177 {
06178 return core_if->core_params->dev_tx_fifo_size[fifo_num];
06179 }
06180
06181 int dwc_otg_set_param_thr_ctl(dwc_otg_core_if_t * core_if, int32_t val)
06182 {
06183 int retval = 0;
06184
06185 if (DWC_OTG_PARAM_TEST(val, 0, 7)) {
06186 DWC_WARN("Wrong value for thr_ctl\n");
06187 DWC_WARN("thr_ctl must be 0-7\n");
06188 return -DWC_E_INVALID;
06189 }
06190
06191 if ((val != 0) &&
06192 (!dwc_otg_get_param_dma_enable(core_if) ||
06193 !core_if->hwcfg4.b.ded_fifo_en)) {
06194 if (dwc_otg_param_initialized(core_if->core_params->thr_ctl)) {
06195 DWC_ERROR
06196 ("%d invalid for parameter thr_ctl. Check HW configuration.\n",
06197 val);
06198 }
06199 val = 0;
06200 retval = -DWC_E_INVALID;
06201 }
06202
06203 core_if->core_params->thr_ctl = val;
06204 return retval;
06205 }
06206
06207 int32_t dwc_otg_get_param_thr_ctl(dwc_otg_core_if_t * core_if)
06208 {
06209 return core_if->core_params->thr_ctl;
06210 }
06211
06212 int dwc_otg_set_param_lpm_enable(dwc_otg_core_if_t * core_if, int32_t val)
06213 {
06214 int retval = 0;
06215
06216 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
06217 DWC_WARN("Wrong value for lpm_enable\n");
06218 DWC_WARN("lpm_enable must be 0 or 1\n");
06219 return -DWC_E_INVALID;
06220 }
06221
06222 if (val && !core_if->hwcfg3.b.otg_lpm_en) {
06223 if (dwc_otg_param_initialized(core_if->core_params->lpm_enable)) {
06224 DWC_ERROR
06225 ("%d invalid for parameter lpm_enable. Check HW configuration.\n",
06226 val);
06227 }
06228 val = 0;
06229 retval = -DWC_E_INVALID;
06230 }
06231
06232 core_if->core_params->lpm_enable = val;
06233 return retval;
06234 }
06235
06236 int32_t dwc_otg_get_param_lpm_enable(dwc_otg_core_if_t * core_if)
06237 {
06238 return core_if->core_params->lpm_enable;
06239 }
06240
06241 int dwc_otg_set_param_tx_thr_length(dwc_otg_core_if_t * core_if, int32_t val)
06242 {
06243 if (DWC_OTG_PARAM_TEST(val, 8, 128)) {
06244 DWC_WARN("Wrong valaue for tx_thr_length\n");
06245 DWC_WARN("tx_thr_length must be 8 - 128\n");
06246 return -DWC_E_INVALID;
06247 }
06248
06249 core_if->core_params->tx_thr_length = val;
06250 return 0;
06251 }
06252
06253 int32_t dwc_otg_get_param_tx_thr_length(dwc_otg_core_if_t * core_if)
06254 {
06255 return core_if->core_params->tx_thr_length;
06256 }
06257
06258 int dwc_otg_set_param_rx_thr_length(dwc_otg_core_if_t * core_if, int32_t val)
06259 {
06260 if (DWC_OTG_PARAM_TEST(val, 8, 128)) {
06261 DWC_WARN("Wrong valaue for rx_thr_length\n");
06262 DWC_WARN("rx_thr_length must be 8 - 128\n");
06263 return -DWC_E_INVALID;
06264 }
06265
06266 core_if->core_params->rx_thr_length = val;
06267 return 0;
06268 }
06269
06270 int32_t dwc_otg_get_param_rx_thr_length(dwc_otg_core_if_t * core_if)
06271 {
06272 return core_if->core_params->rx_thr_length;
06273 }
06274
06275 int dwc_otg_set_param_dma_burst_size(dwc_otg_core_if_t * core_if, int32_t val)
06276 {
06277 if (DWC_OTG_PARAM_TEST(val, 1, 1) &&
06278 DWC_OTG_PARAM_TEST(val, 4, 4) &&
06279 DWC_OTG_PARAM_TEST(val, 8, 8) &&
06280 DWC_OTG_PARAM_TEST(val, 16, 16) &&
06281 DWC_OTG_PARAM_TEST(val, 32, 32) &&
06282 DWC_OTG_PARAM_TEST(val, 64, 64) &&
06283 DWC_OTG_PARAM_TEST(val, 128, 128) &&
06284 DWC_OTG_PARAM_TEST(val, 256, 256)) {
06285 DWC_WARN("`%d' invalid for parameter `dma_burst_size'\n", val);
06286 return -DWC_E_INVALID;
06287 }
06288 core_if->core_params->dma_burst_size = val;
06289 return 0;
06290 }
06291
06292 int32_t dwc_otg_get_param_dma_burst_size(dwc_otg_core_if_t * core_if)
06293 {
06294 return core_if->core_params->dma_burst_size;
06295 }
06296
06297 int dwc_otg_set_param_pti_enable(dwc_otg_core_if_t * core_if, int32_t val)
06298 {
06299 int retval = 0;
06300 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
06301 DWC_WARN("`%d' invalid for parameter `pti_enable'\n", val);
06302 return -DWC_E_INVALID;
06303 }
06304 if (val && (core_if->snpsid < OTG_CORE_REV_2_72a)) {
06305 if (dwc_otg_param_initialized(core_if->core_params->pti_enable)) {
06306 DWC_ERROR
06307 ("%d invalid for parameter pti_enable. Check HW configuration.\n",
06308 val);
06309 }
06310 retval = -DWC_E_INVALID;
06311 val = 0;
06312 }
06313 core_if->core_params->pti_enable = val;
06314 return retval;
06315 }
06316
06317 int32_t dwc_otg_get_param_pti_enable(dwc_otg_core_if_t * core_if)
06318 {
06319 return core_if->core_params->pti_enable;
06320 }
06321
06322 int dwc_otg_set_param_mpi_enable(dwc_otg_core_if_t * core_if, int32_t val)
06323 {
06324 int retval = 0;
06325 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
06326 DWC_WARN("`%d' invalid for parameter `mpi_enable'\n", val);
06327 return -DWC_E_INVALID;
06328 }
06329 if (val && (core_if->hwcfg2.b.multi_proc_int == 0)) {
06330 if (dwc_otg_param_initialized(core_if->core_params->mpi_enable)) {
06331 DWC_ERROR
06332 ("%d invalid for parameter mpi_enable. Check HW configuration.\n",
06333 val);
06334 }
06335 retval = -DWC_E_INVALID;
06336 val = 0;
06337 }
06338 core_if->core_params->mpi_enable = val;
06339 return retval;
06340 }
06341
06342 int32_t dwc_otg_get_param_mpi_enable(dwc_otg_core_if_t * core_if)
06343 {
06344 return core_if->core_params->mpi_enable;
06345 }
06346
06347 int dwc_otg_set_param_adp_enable(dwc_otg_core_if_t * core_if, int32_t val)
06348 {
06349 int retval = 0;
06350 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
06351 DWC_WARN("`%d' invalid for parameter `adp_enable'\n", val);
06352 return -DWC_E_INVALID;
06353 }
06354 if (val && (core_if->hwcfg3.b.adp_supp == 0)) {
06355 if (dwc_otg_param_initialized
06356 (core_if->core_params->adp_supp_enable)) {
06357 DWC_ERROR
06358 ("%d invalid for parameter adp_enable. Check HW configuration.\n",
06359 val);
06360 }
06361 retval = -DWC_E_INVALID;
06362 val = 0;
06363 }
06364 core_if->core_params->adp_supp_enable = val;
06365
06366 if (val)
06367 dwc_otg_set_param_otg_ver(core_if, 1);
06368
06369 return retval;
06370 }
06371
06372 int32_t dwc_otg_get_param_adp_enable(dwc_otg_core_if_t * core_if)
06373 {
06374 return core_if->core_params->adp_supp_enable;
06375 }
06376
06377 int dwc_otg_set_param_ic_usb_cap(dwc_otg_core_if_t * core_if, int32_t val)
06378 {
06379 int retval = 0;
06380 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
06381 DWC_WARN("`%d' invalid for parameter `ic_usb_cap'\n", val);
06382 DWC_WARN("ic_usb_cap must be 0 or 1\n");
06383 return -DWC_E_INVALID;
06384 }
06385
06386 if (val && (core_if->hwcfg2.b.otg_enable_ic_usb == 0)) {
06387 if (dwc_otg_param_initialized(core_if->core_params->ic_usb_cap)) {
06388 DWC_ERROR
06389 ("%d invalid for parameter ic_usb_cap. Check HW configuration.\n",
06390 val);
06391 }
06392 retval = -DWC_E_INVALID;
06393 val = 0;
06394 }
06395 core_if->core_params->ic_usb_cap = val;
06396 return retval;
06397 }
06398
06399 int32_t dwc_otg_get_param_ic_usb_cap(dwc_otg_core_if_t * core_if)
06400 {
06401 return core_if->core_params->ic_usb_cap;
06402 }
06403
06404 int dwc_otg_set_param_ahb_thr_ratio(dwc_otg_core_if_t * core_if, int32_t val)
06405 {
06406 int retval = 0;
06407 int valid = 1;
06408
06409 if (DWC_OTG_PARAM_TEST(val, 0, 3)) {
06410 DWC_WARN("`%d' invalid for parameter `ahb_thr_ratio'\n", val);
06411 DWC_WARN("ahb_thr_ratio must be 0 - 3\n");
06412 return -DWC_E_INVALID;
06413 }
06414
06415 if (val
06416 && (core_if->snpsid < OTG_CORE_REV_2_81a
06417 || !dwc_otg_get_param_thr_ctl(core_if))) {
06418 valid = 0;
06419 } else if (val
06420 && ((dwc_otg_get_param_tx_thr_length(core_if) / (1 << val)) <
06421 4)) {
06422 valid = 0;
06423 }
06424 if (valid == 0) {
06425 if (dwc_otg_param_initialized
06426 (core_if->core_params->ahb_thr_ratio)) {
06427 DWC_ERROR
06428 ("%d invalid for parameter ahb_thr_ratio. Check HW configuration.\n",
06429 val);
06430 }
06431 retval = -DWC_E_INVALID;
06432 val = 0;
06433 }
06434
06435 core_if->core_params->ahb_thr_ratio = val;
06436 return retval;
06437 }
06438
06439 int32_t dwc_otg_get_param_ahb_thr_ratio(dwc_otg_core_if_t * core_if)
06440 {
06441 return core_if->core_params->ahb_thr_ratio;
06442 }
06443
06444 int dwc_otg_set_param_power_down(dwc_otg_core_if_t * core_if, int32_t val)
06445 {
06446 int retval = 0;
06447 int valid = 1;
06448
06449 if (DWC_OTG_PARAM_TEST(val, 0, 2)) {
06450 DWC_WARN("`%d' invalid for parameter `power_down'\n", val);
06451 DWC_WARN("power_down must be 0 - 2\n");
06452 return -DWC_E_INVALID;
06453 }
06454
06455 if ((val == 2) && (core_if->snpsid < OTG_CORE_REV_2_91a)) {
06456 valid = 0;
06457 }
06458 if (valid == 0) {
06459 if (dwc_otg_param_initialized(core_if->core_params->power_down)) {
06460 DWC_ERROR
06461 ("%d invalid for parameter power_down. Check HW configuration.\n",
06462 val);
06463 }
06464 retval = -DWC_E_INVALID;
06465 val = 0;
06466 }
06467 core_if->core_params->power_down = val;
06468 return retval;
06469 }
06470
06471 int32_t dwc_otg_get_param_power_down(dwc_otg_core_if_t * core_if)
06472 {
06473 return core_if->core_params->power_down;
06474 }
06475
06476 int dwc_otg_set_param_reload_ctl(dwc_otg_core_if_t * core_if, int32_t val)
06477 {
06478 int retval = 0;
06479 int valid = 1;
06480
06481 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
06482 DWC_WARN("`%d' invalid for parameter `reload_ctl'\n", val);
06483 DWC_WARN("reload_ctl must be 0 or 1\n");
06484 return -DWC_E_INVALID;
06485 }
06486
06487 if ((val == 1) && (core_if->snpsid < OTG_CORE_REV_2_92a)) {
06488 valid = 0;
06489 }
06490 if (valid == 0) {
06491 if (dwc_otg_param_initialized(core_if->core_params->reload_ctl)) {
06492 DWC_ERROR("%d invalid for parameter reload_ctl."
06493 "Check HW configuration.\n", val);
06494 }
06495 retval = -DWC_E_INVALID;
06496 val = 0;
06497 }
06498 core_if->core_params->reload_ctl = val;
06499 return retval;
06500 }
06501
06502 int32_t dwc_otg_get_param_reload_ctl(dwc_otg_core_if_t * core_if)
06503 {
06504 return core_if->core_params->reload_ctl;
06505 }
06506
06507 int dwc_otg_set_param_dev_out_nak(dwc_otg_core_if_t * core_if, int32_t val)
06508 {
06509 int retval = 0;
06510 int valid = 1;
06511
06512 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
06513 DWC_WARN("`%d' invalid for parameter `dev_out_nak'\n", val);
06514 DWC_WARN("dev_out_nak must be 0 or 1\n");
06515 return -DWC_E_INVALID;
06516 }
06517
06518 if ((val == 1) && ((core_if->snpsid < OTG_CORE_REV_2_93a) ||
06519 !(core_if->core_params->dma_desc_enable))) {
06520 valid = 0;
06521 }
06522 if (valid == 0) {
06523 if (dwc_otg_param_initialized(core_if->core_params->dev_out_nak)) {
06524 DWC_ERROR("%d invalid for parameter dev_out_nak."
06525 "Check HW configuration.\n", val);
06526 }
06527 retval = -DWC_E_INVALID;
06528 val = 0;
06529 }
06530 core_if->core_params->dev_out_nak = val;
06531 return retval;
06532 }
06533
06534 int32_t dwc_otg_get_param_dev_out_nak(dwc_otg_core_if_t * core_if)
06535 {
06536 return core_if->core_params->dev_out_nak;
06537 }
06538
06539 int dwc_otg_set_param_cont_on_bna(dwc_otg_core_if_t * core_if, int32_t val)
06540 {
06541 int retval = 0;
06542 int valid = 1;
06543
06544 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
06545 DWC_WARN("`%d' invalid for parameter `cont_on_bna'\n", val);
06546 DWC_WARN("cont_on_bna must be 0 or 1\n");
06547 return -DWC_E_INVALID;
06548 }
06549
06550 if ((val == 1) && ((core_if->snpsid < OTG_CORE_REV_2_94a) ||
06551 !(core_if->core_params->dma_desc_enable))) {
06552 valid = 0;
06553 }
06554 if (valid == 0) {
06555 if (dwc_otg_param_initialized(core_if->core_params->cont_on_bna)) {
06556 DWC_ERROR("%d invalid for parameter cont_on_bna."
06557 "Check HW configuration.\n", val);
06558 }
06559 retval = -DWC_E_INVALID;
06560 val = 0;
06561 }
06562 core_if->core_params->cont_on_bna = val;
06563 return retval;
06564 }
06565
06566 int32_t dwc_otg_get_param_cont_on_bna(dwc_otg_core_if_t * core_if)
06567 {
06568 return core_if->core_params->cont_on_bna;
06569 }
06570
06571 int dwc_otg_set_param_ahb_single(dwc_otg_core_if_t * core_if, int32_t val)
06572 {
06573 int retval = 0;
06574 int valid = 1;
06575
06576 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
06577 DWC_WARN("`%d' invalid for parameter `ahb_single'\n", val);
06578 DWC_WARN("ahb_single must be 0 or 1\n");
06579 return -DWC_E_INVALID;
06580 }
06581
06582 if ((val == 1) && (core_if->snpsid < OTG_CORE_REV_2_94a)) {
06583 valid = 0;
06584 }
06585 if (valid == 0) {
06586 if (dwc_otg_param_initialized(core_if->core_params->ahb_single)) {
06587 DWC_ERROR("%d invalid for parameter ahb_single."
06588 "Check HW configuration.\n", val);
06589 }
06590 retval = -DWC_E_INVALID;
06591 val = 0;
06592 }
06593 core_if->core_params->ahb_single = val;
06594 return retval;
06595 }
06596
06597 int32_t dwc_otg_get_param_ahb_single(dwc_otg_core_if_t * core_if)
06598 {
06599 return core_if->core_params->ahb_single;
06600 }
06601
06602 int dwc_otg_set_param_otg_ver(dwc_otg_core_if_t * core_if, int32_t val)
06603 {
06604 int retval = 0;
06605
06606 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
06607 DWC_WARN("`%d' invalid for parameter `otg_ver'\n", val);
06608 DWC_WARN
06609 ("otg_ver must be 0(for OTG 1.3 support) or 1(for OTG 2.0 support)\n");
06610 return -DWC_E_INVALID;
06611 }
06612
06613 core_if->core_params->otg_ver = val;
06614 return retval;
06615 }
06616
06617 int32_t dwc_otg_get_param_otg_ver(dwc_otg_core_if_t * core_if)
06618 {
06619 return core_if->core_params->otg_ver;
06620 }
06621
06622 uint32_t dwc_otg_get_hnpstatus(dwc_otg_core_if_t * core_if)
06623 {
06624 gotgctl_data_t otgctl;
06625 otgctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
06626 return otgctl.b.hstnegscs;
06627 }
06628
06629 uint32_t dwc_otg_get_srpstatus(dwc_otg_core_if_t * core_if)
06630 {
06631 gotgctl_data_t otgctl;
06632 otgctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
06633 return otgctl.b.sesreqscs;
06634 }
06635
06636 void dwc_otg_set_hnpreq(dwc_otg_core_if_t * core_if, uint32_t val)
06637 {
06638 if(core_if->otg_ver == 0) {
06639 gotgctl_data_t otgctl;
06640 otgctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
06641 otgctl.b.hnpreq = val;
06642 DWC_WRITE_REG32(&core_if->core_global_regs->gotgctl, otgctl.d32);
06643 } else {
06644 core_if->otg_sts = val;
06645 }
06646 }
06647
06648 uint32_t dwc_otg_get_gsnpsid(dwc_otg_core_if_t * core_if)
06649 {
06650 return core_if->snpsid;
06651 }
06652
06653 uint32_t dwc_otg_get_mode(dwc_otg_core_if_t * core_if)
06654 {
06655 gintsts_data_t gintsts;
06656 gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
06657 return gintsts.b.curmode;
06658 }
06659
06660 uint32_t dwc_otg_get_hnpcapable(dwc_otg_core_if_t * core_if)
06661 {
06662 gusbcfg_data_t usbcfg;
06663 usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
06664 return usbcfg.b.hnpcap;
06665 }
06666
06667 void dwc_otg_set_hnpcapable(dwc_otg_core_if_t * core_if, uint32_t val)
06668 {
06669 gusbcfg_data_t usbcfg;
06670 usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
06671 usbcfg.b.hnpcap = val;
06672 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, usbcfg.d32);
06673 }
06674
06675 uint32_t dwc_otg_get_srpcapable(dwc_otg_core_if_t * core_if)
06676 {
06677 gusbcfg_data_t usbcfg;
06678 usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
06679 return usbcfg.b.srpcap;
06680 }
06681
06682 void dwc_otg_set_srpcapable(dwc_otg_core_if_t * core_if, uint32_t val)
06683 {
06684 gusbcfg_data_t usbcfg;
06685 usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
06686 usbcfg.b.srpcap = val;
06687 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, usbcfg.d32);
06688 }
06689
06690 uint32_t dwc_otg_get_devspeed(dwc_otg_core_if_t * core_if)
06691 {
06692 dcfg_data_t dcfg;
06693 dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
06694 return dcfg.b.devspd;
06695 }
06696
06697 void dwc_otg_set_devspeed(dwc_otg_core_if_t * core_if, uint32_t val)
06698 {
06699 dcfg_data_t dcfg;
06700 dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
06701 dcfg.b.devspd = val;
06702 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg, dcfg.d32);
06703 }
06704
06705 uint32_t dwc_otg_get_busconnected(dwc_otg_core_if_t * core_if)
06706 {
06707 hprt0_data_t hprt0;
06708 hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
06709 return hprt0.b.prtconnsts;
06710 }
06711
06712 uint32_t dwc_otg_get_enumspeed(dwc_otg_core_if_t * core_if)
06713 {
06714 dsts_data_t dsts;
06715 dsts.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);
06716 return dsts.b.enumspd;
06717 }
06718
06719 uint32_t dwc_otg_get_prtpower(dwc_otg_core_if_t * core_if)
06720 {
06721 hprt0_data_t hprt0;
06722 hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
06723 return hprt0.b.prtpwr;
06724
06725 }
06726
06727 uint32_t dwc_otg_get_core_state(dwc_otg_core_if_t * core_if)
06728 {
06729 return core_if->hibernation_suspend;
06730 }
06731
06732 void dwc_otg_set_prtpower(dwc_otg_core_if_t * core_if, uint32_t val)
06733 {
06734 hprt0_data_t hprt0;
06735 hprt0.d32 = dwc_otg_read_hprt0(core_if);
06736 hprt0.b.prtpwr = val;
06737 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
06738 }
06739
06740 uint32_t dwc_otg_get_prtsuspend(dwc_otg_core_if_t * core_if)
06741 {
06742 hprt0_data_t hprt0;
06743 hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
06744 return hprt0.b.prtsusp;
06745
06746 }
06747
06748 void dwc_otg_set_prtsuspend(dwc_otg_core_if_t * core_if, uint32_t val)
06749 {
06750 hprt0_data_t hprt0;
06751 hprt0.d32 = dwc_otg_read_hprt0(core_if);
06752 hprt0.b.prtsusp = val;
06753 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
06754 }
06755
06756 uint32_t dwc_otg_get_fr_interval(dwc_otg_core_if_t * core_if)
06757 {
06758 hfir_data_t hfir;
06759 hfir.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->hfir);
06760 return hfir.b.frint;
06761
06762 }
06763
06764 void dwc_otg_set_fr_interval(dwc_otg_core_if_t * core_if, uint32_t val)
06765 {
06766 hfir_data_t hfir;
06767 uint32_t fram_int;
06768 fram_int = calc_frame_interval(core_if);
06769 hfir.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->hfir);
06770 if (!core_if->core_params->reload_ctl) {
06771 DWC_WARN("\nCannot reload HFIR register.HFIR.HFIRRldCtrl bit is"
06772 "not set to 1.\nShould load driver with reload_ctl=1"
06773 " module parameter\n");
06774 return;
06775 }
06776 switch (fram_int) {
06777 case 3750:
06778 if ((val < 3350) || (val > 4150)) {
06779 DWC_WARN("HFIR interval for HS core and 30 MHz"
06780 "clock freq should be from 3350 to 4150\n");
06781 return;
06782 }
06783 break;
06784 case 30000:
06785 if ((val < 26820) || (val > 33180)) {
06786 DWC_WARN("HFIR interval for FS/LS core and 30 MHz"
06787 "clock freq should be from 26820 to 33180\n");
06788 return;
06789 }
06790 break;
06791 case 6000:
06792 if ((val < 5360) || (val > 6640)) {
06793 DWC_WARN("HFIR interval for HS core and 48 MHz"
06794 "clock freq should be from 5360 to 6640\n");
06795 return;
06796 }
06797 break;
06798 case 48000:
06799 if ((val < 42912) || (val > 53088)) {
06800 DWC_WARN("HFIR interval for FS/LS core and 48 MHz"
06801 "clock freq should be from 42912 to 53088\n");
06802 return;
06803 }
06804 break;
06805 case 7500:
06806 if ((val < 6700) || (val > 8300)) {
06807 DWC_WARN("HFIR interval for HS core and 60 MHz"
06808 "clock freq should be from 6700 to 8300\n");
06809 return;
06810 }
06811 break;
06812 case 60000:
06813 if ((val < 53640) || (val > 65536)) {
06814 DWC_WARN("HFIR interval for FS/LS core and 60 MHz"
06815 "clock freq should be from 53640 to 65536\n");
06816 return;
06817 }
06818 break;
06819 default:
06820 DWC_WARN("Unknown frame interval\n");
06821 return;
06822 break;
06823
06824 }
06825 hfir.b.frint = val;
06826 DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hfir, hfir.d32);
06827 }
06828
06829 uint32_t dwc_otg_get_mode_ch_tim(dwc_otg_core_if_t * core_if)
06830 {
06831 hcfg_data_t hcfg;
06832 hcfg.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg);
06833 return hcfg.b.modechtimen;
06834
06835 }
06836
06837 void dwc_otg_set_mode_ch_tim(dwc_otg_core_if_t * core_if, uint32_t val)
06838 {
06839 hcfg_data_t hcfg;
06840 hcfg.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg);
06841 hcfg.b.modechtimen = val;
06842 DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hcfg, hcfg.d32);
06843 }
06844
06845 void dwc_otg_set_prtresume(dwc_otg_core_if_t * core_if, uint32_t val)
06846 {
06847 hprt0_data_t hprt0;
06848 hprt0.d32 = dwc_otg_read_hprt0(core_if);
06849 hprt0.b.prtres = val;
06850 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
06851 }
06852
06853 uint32_t dwc_otg_get_remotewakesig(dwc_otg_core_if_t * core_if)
06854 {
06855 dctl_data_t dctl;
06856 dctl.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl);
06857 return dctl.b.rmtwkupsig;
06858 }
06859
06860 uint32_t dwc_otg_get_lpm_portsleepstatus(dwc_otg_core_if_t * core_if)
06861 {
06862 glpmcfg_data_t lpmcfg;
06863 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
06864
06865 DWC_ASSERT(!
06866 ((core_if->lx_state == DWC_OTG_L1) ^ lpmcfg.b.prt_sleep_sts),
06867 "lx_state = %d, lmpcfg.prt_sleep_sts = %d\n",
06868 core_if->lx_state, lpmcfg.b.prt_sleep_sts);
06869
06870 return lpmcfg.b.prt_sleep_sts;
06871 }
06872
06873 uint32_t dwc_otg_get_lpm_remotewakeenabled(dwc_otg_core_if_t * core_if)
06874 {
06875 glpmcfg_data_t lpmcfg;
06876 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
06877 return lpmcfg.b.rem_wkup_en;
06878 }
06879
06880 uint32_t dwc_otg_get_lpmresponse(dwc_otg_core_if_t * core_if)
06881 {
06882 glpmcfg_data_t lpmcfg;
06883 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
06884 return lpmcfg.b.appl_resp;
06885 }
06886
06887 void dwc_otg_set_lpmresponse(dwc_otg_core_if_t * core_if, uint32_t val)
06888 {
06889 glpmcfg_data_t lpmcfg;
06890 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
06891 lpmcfg.b.appl_resp = val;
06892 DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg, lpmcfg.d32);
06893 }
06894
06895 uint32_t dwc_otg_get_hsic_connect(dwc_otg_core_if_t * core_if)
06896 {
06897 glpmcfg_data_t lpmcfg;
06898 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
06899 return lpmcfg.b.hsic_connect;
06900 }
06901
06902 void dwc_otg_set_hsic_connect(dwc_otg_core_if_t * core_if, uint32_t val)
06903 {
06904 glpmcfg_data_t lpmcfg;
06905 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
06906 lpmcfg.b.hsic_connect = val;
06907 DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg, lpmcfg.d32);
06908 }
06909
06910 uint32_t dwc_otg_get_inv_sel_hsic(dwc_otg_core_if_t * core_if)
06911 {
06912 glpmcfg_data_t lpmcfg;
06913 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
06914 return lpmcfg.b.inv_sel_hsic;
06915
06916 }
06917
06918 void dwc_otg_set_inv_sel_hsic(dwc_otg_core_if_t * core_if, uint32_t val)
06919 {
06920 glpmcfg_data_t lpmcfg;
06921 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
06922 lpmcfg.b.inv_sel_hsic = val;
06923 DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg, lpmcfg.d32);
06924 }
06925
06926 uint32_t dwc_otg_get_gotgctl(dwc_otg_core_if_t * core_if)
06927 {
06928 return DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
06929 }
06930
06931 void dwc_otg_set_gotgctl(dwc_otg_core_if_t * core_if, uint32_t val)
06932 {
06933 DWC_WRITE_REG32(&core_if->core_global_regs->gotgctl, val);
06934 }
06935
06936 uint32_t dwc_otg_get_gusbcfg(dwc_otg_core_if_t * core_if)
06937 {
06938 return DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
06939 }
06940
06941 void dwc_otg_set_gusbcfg(dwc_otg_core_if_t * core_if, uint32_t val)
06942 {
06943 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, val);
06944 }
06945
06946 uint32_t dwc_otg_get_grxfsiz(dwc_otg_core_if_t * core_if)
06947 {
06948 return DWC_READ_REG32(&core_if->core_global_regs->grxfsiz);
06949 }
06950
06951 void dwc_otg_set_grxfsiz(dwc_otg_core_if_t * core_if, uint32_t val)
06952 {
06953 DWC_WRITE_REG32(&core_if->core_global_regs->grxfsiz, val);
06954 }
06955
06956 uint32_t dwc_otg_get_gnptxfsiz(dwc_otg_core_if_t * core_if)
06957 {
06958 return DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz);
06959 }
06960
06961 void dwc_otg_set_gnptxfsiz(dwc_otg_core_if_t * core_if, uint32_t val)
06962 {
06963 DWC_WRITE_REG32(&core_if->core_global_regs->gnptxfsiz, val);
06964 }
06965
06966 uint32_t dwc_otg_get_gpvndctl(dwc_otg_core_if_t * core_if)
06967 {
06968 return DWC_READ_REG32(&core_if->core_global_regs->gpvndctl);
06969 }
06970
06971 void dwc_otg_set_gpvndctl(dwc_otg_core_if_t * core_if, uint32_t val)
06972 {
06973 DWC_WRITE_REG32(&core_if->core_global_regs->gpvndctl, val);
06974 }
06975
06976 uint32_t dwc_otg_get_ggpio(dwc_otg_core_if_t * core_if)
06977 {
06978 return DWC_READ_REG32(&core_if->core_global_regs->ggpio);
06979 }
06980
06981 void dwc_otg_set_ggpio(dwc_otg_core_if_t * core_if, uint32_t val)
06982 {
06983 DWC_WRITE_REG32(&core_if->core_global_regs->ggpio, val);
06984 }
06985
06986 uint32_t dwc_otg_get_hprt0(dwc_otg_core_if_t * core_if)
06987 {
06988 return DWC_READ_REG32(core_if->host_if->hprt0);
06989
06990 }
06991
06992 void dwc_otg_set_hprt0(dwc_otg_core_if_t * core_if, uint32_t val)
06993 {
06994 DWC_WRITE_REG32(core_if->host_if->hprt0, val);
06995 }
06996
06997 uint32_t dwc_otg_get_guid(dwc_otg_core_if_t * core_if)
06998 {
06999 return DWC_READ_REG32(&core_if->core_global_regs->guid);
07000 }
07001
07002 void dwc_otg_set_guid(dwc_otg_core_if_t * core_if, uint32_t val)
07003 {
07004 DWC_WRITE_REG32(&core_if->core_global_regs->guid, val);
07005 }
07006
07007 uint32_t dwc_otg_get_hptxfsiz(dwc_otg_core_if_t * core_if)
07008 {
07009 return DWC_READ_REG32(&core_if->core_global_regs->hptxfsiz);
07010 }
07011
07012 uint16_t dwc_otg_get_otg_version(dwc_otg_core_if_t * core_if)
07013 {
07014 return ((core_if->otg_ver == 1) ? (uint16_t)0x0200 : (uint16_t)0x0103);
07015 }
07016
07023 void dwc_otg_pcd_start_srp_timer(dwc_otg_core_if_t * core_if)
07024 {
07025 core_if->srp_timer_started = 1;
07026 DWC_TIMER_SCHEDULE(core_if->srp_timer, 6000 );
07027 }
07028
07029 void dwc_otg_initiate_srp(dwc_otg_core_if_t * core_if)
07030 {
07031 uint32_t *addr = (uint32_t *) & (core_if->core_global_regs->gotgctl);
07032 gotgctl_data_t mem;
07033 gotgctl_data_t val;
07034
07035 val.d32 = DWC_READ_REG32(addr);
07036 if (val.b.sesreq) {
07037 DWC_ERROR("Session Request Already active!\n");
07038 return;
07039 }
07040
07041 DWC_INFO("Session Request Initated\n");
07042 mem.d32 = DWC_READ_REG32(addr);
07043 mem.b.sesreq = 1;
07044 DWC_WRITE_REG32(addr, mem.d32);
07045
07046
07047 dwc_otg_pcd_start_srp_timer(core_if);
07048 return;
07049 }